summaryrefslogtreecommitdiff
path: root/scripts/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/contrib')
-rwxr-xr-xscripts/contrib/bb-perf/bb-matrix-plot.sh137
-rwxr-xr-xscripts/contrib/bb-perf/bb-matrix.sh79
-rwxr-xr-xscripts/contrib/bb-perf/buildstats.sh90
-rwxr-xr-xscripts/contrib/bbvars.py186
-rwxr-xr-xscripts/contrib/build-perf-test.sh400
-rwxr-xr-xscripts/contrib/ddimage104
-rwxr-xr-xscripts/contrib/devtool-stress.py242
-rwxr-xr-xscripts/contrib/dialog-power-control53
-rwxr-xr-xscripts/contrib/documentation-audit.sh94
-rwxr-xr-xscripts/contrib/graph-tool92
-rwxr-xr-xscripts/contrib/list-packageconfig-flags.py179
-rwxr-xr-xscripts/contrib/mkefidisk.sh459
-rwxr-xr-xscripts/contrib/python/generate-manifest-2.7.py397
-rwxr-xr-xscripts/contrib/python/generate-manifest-3.5.py396
-rwxr-xr-xscripts/contrib/serdevtry60
-rwxr-xr-xscripts/contrib/test_build_time.sh237
-rwxr-xr-xscripts/contrib/test_build_time_worker.sh37
-rwxr-xr-xscripts/contrib/verify-homepage.py62
18 files changed, 3304 insertions, 0 deletions
diff --git a/scripts/contrib/bb-perf/bb-matrix-plot.sh b/scripts/contrib/bb-perf/bb-matrix-plot.sh
new file mode 100755
index 0000000..136a255
--- /dev/null
+++ b/scripts/contrib/bb-perf/bb-matrix-plot.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+#
+# Copyright (c) 2011, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# DESCRIPTION
+# This script operates on the .dat file generated by bb-matrix.sh. It tolerates
+# the header by skipping the first line, but error messages and bad data records
+# need to be removed first. It will generate three views of the plot, and leave
+# an interactive view open for further analysis.
+#
+# AUTHORS
+# Darren Hart <dvhart@linux.intel.com>
+#
+
+# Setup the defaults
+DATFILE="bb-matrix.dat"
+XLABEL="BB_NUMBER_THREADS"
+YLABEL="PARALLEL_MAKE"
+FIELD=3
+DEF_TITLE="Elapsed Time (seconds)"
+PM3D_FRAGMENT="unset surface; set pm3d at s hidden3d 100"
+SIZE="640,480"
+
+function usage {
+CMD=$(basename $0)
+cat <<EOM
+Usage: $CMD [-d datfile] [-f field] [-h] [-t title] [-w]
+ -d datfile The data file generated by bb-matrix.sh (default: $DATFILE)
+ -f field The field index to plot as the Z axis from the data file
+ (default: $FIELD, "$DEF_TITLE")
+ -h Display this help message
+ -s W,H PNG and window size in pixels (default: $SIZE)
+ -t title The title to display, should describe the field (-f) and units
+ (default: "$DEF_TITLE")
+ -w Render the plot as wireframe with a 2D colormap projected on the
+ XY plane rather than as the texture for the surface
+EOM
+}
+
+# Parse and validate arguments
+while getopts "d:f:hs:t:w" OPT; do
+ case $OPT in
+ d)
+ DATFILE="$OPTARG"
+ ;;
+ f)
+ FIELD="$OPTARG"
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ s)
+ SIZE="$OPTARG"
+ ;;
+ t)
+ TITLE="$OPTARG"
+ ;;
+ w)
+ PM3D_FRAGMENT="set pm3d at b"
+ W="-w"
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+# Ensure the data file exists
+if [ ! -f "$DATFILE" ]; then
+ echo "ERROR: $DATFILE does not exist"
+ usage
+ exit 1
+fi
+PLOT_BASENAME=${DATFILE%.*}-f$FIELD$W
+
+# Set a sane title
+# TODO: parse the header and define titles for each format parameter for TIME(1)
+if [ -z "$TITLE" ]; then
+ if [ ! "$FIELD" == "3" ]; then
+ TITLE="Field $FIELD"
+ else
+ TITLE="$DEF_TITLE"
+ fi
+fi
+
+# Determine the dgrid3d mesh dimensions size
+MIN=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 1 | sed 's/^0*//' | sort -n | uniq | head -n1)
+MAX=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 1 | sed 's/^0*//' | sort -n | uniq | tail -n1)
+BB_CNT=$[${MAX} - $MIN + 1]
+MIN=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 2 | sed 's/^0*//' | sort -n | uniq | head -n1)
+MAX=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 2 | sed 's/^0*//' | sort -n | uniq | tail -n1)
+PM_CNT=$[${MAX} - $MIN + 1]
+
+
+(cat <<EOF
+set title "$TITLE"
+set xlabel "$XLABEL"
+set ylabel "$YLABEL"
+set style line 100 lt 5 lw 1.5
+$PM3D_FRAGMENT
+set dgrid3d $PM_CNT,$BB_CNT splines
+set ticslevel 0.2
+
+set term png size $SIZE
+set output "$PLOT_BASENAME.png"
+splot "$DATFILE" every ::1 using 1:2:$FIELD with lines ls 100
+
+set view 90,0
+set output "$PLOT_BASENAME-bb.png"
+replot
+
+set view 90,90
+set output "$PLOT_BASENAME-pm.png"
+replot
+
+set view 60,30
+set term wxt size $SIZE
+replot
+EOF
+) | gnuplot --persist
diff --git a/scripts/contrib/bb-perf/bb-matrix.sh b/scripts/contrib/bb-perf/bb-matrix.sh
new file mode 100755
index 0000000..1064565
--- /dev/null
+++ b/scripts/contrib/bb-perf/bb-matrix.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+#
+# Copyright (c) 2011, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# DESCRIPTION
+# This script runs BB_CMD (typically building core-image-sato) for all
+# combincations of BB_RANGE and PM_RANGE values. It saves off all the console
+# logs, the buildstats directories, and creates a bb-pm-runtime.dat file which
+# can be used to postprocess the results with a plotting tool, spreadsheet, etc.
+# Before running this script, it is recommended that you pre-download all the
+# necessary sources by performing the BB_CMD once manually. It is also a good
+# idea to disable cron to avoid runtime variations caused by things like the
+# locate process. Be sure to sanitize the dat file prior to post-processing as
+# it may contain error messages or bad runs that should be removed.
+#
+# AUTHORS
+# Darren Hart <dvhart@linux.intel.com>
+#
+
+# The following ranges are appropriate for a 4 core system with 8 logical units
+# Use leading 0s to ensure all digits are the same string length, this results
+# in nice log file names and columnar dat files.
+BB_RANGE="04 05 06 07 08 09 10 11 12 13 14 15 16"
+PM_RANGE="04 05 06 07 08 09 10 11 12 13 14 15 16"
+
+DATADIR="bb-matrix-$$"
+BB_CMD="bitbake core-image-minimal"
+RUNTIME_LOG="$DATADIR/bb-matrix.dat"
+
+# See TIME(1) for a description of the time format parameters
+# The following all report 0: W K r s t w
+TIME_STR="%e %S %U %P %c %w %R %F %M %x"
+
+# Prepare the DATADIR
+mkdir $DATADIR
+if [ $? -ne 0 ]; then
+ echo "Failed to create $DATADIR."
+ exit 1
+fi
+
+# Add a simple header
+echo "BB PM $TIME_STR" > $RUNTIME_LOG
+for BB in $BB_RANGE; do
+ for PM in $PM_RANGE; do
+ RUNDIR="$DATADIR/$BB-$PM-build"
+ mkdir $RUNDIR
+ BB_LOG=$RUNDIR/$BB-$PM-bitbake.log
+ date
+ echo "BB=$BB PM=$PM Logging to $BB_LOG"
+
+ echo -n " Preparing the work directory... "
+ rm -rf pseudodone tmp sstate-cache tmp-eglibc &> /dev/null
+ echo "done"
+
+ # Export the variables under test and run the bitbake command
+ # Strip any leading zeroes before passing to bitbake
+ export BB_NUMBER_THREADS=$(echo $BB | sed 's/^0*//')
+ export PARALLEL_MAKE="-j $(echo $PM | sed 's/^0*//')"
+ /usr/bin/time -f "$BB $PM $TIME_STR" -a -o $RUNTIME_LOG $BB_CMD &> $BB_LOG
+
+ echo " $(tail -n1 $RUNTIME_LOG)"
+ cp -a tmp/buildstats $RUNDIR/$BB-$PM-buildstats
+ done
+done
diff --git a/scripts/contrib/bb-perf/buildstats.sh b/scripts/contrib/bb-perf/buildstats.sh
new file mode 100755
index 0000000..96158a9
--- /dev/null
+++ b/scripts/contrib/bb-perf/buildstats.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+#
+# Copyright (c) 2011, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# DESCRIPTION
+# Given a 'buildstats' path (created by bitbake when setting
+# USER_CLASSES ?= "buildstats" on local.conf) and task names, outputs
+# '<task> <recipe> <elapsed time>' for all recipes. Elapsed times are in
+# seconds, and task should be given without the 'do_' prefix.
+#
+# Some useful pipelines
+#
+# 1. Tasks with largest elapsed times
+# $ buildstats.sh -b <buildstats> | sort -k3 -n -r | head
+#
+# 2. Min, max, sum per task (in needs GNU datamash)
+# $ buildstats.sh -b <buildstats> | datamash -t' ' -g1 min 3 max 3 sum 3 | sort -k4 -n -r
+#
+# AUTHORS
+# Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
+#
+BS_DIR="tmp/buildstats"
+TASKS="compile:configure:fetch:install:patch:populate_lic:populate_sysroot:unpack"
+
+function usage {
+CMD=$(basename $0)
+cat <<EOM
+Usage: $CMD [-b buildstats_dir] [-t do_task]
+ -b buildstats The path where the folder resides
+ (default: "$BS_DIR")
+ -t tasks The tasks to be computed
+ (default: "$TASKS")
+ -h Display this help message
+EOM
+}
+
+# Parse and validate arguments
+while getopts "b:t:h" OPT; do
+ case $OPT in
+ b)
+ BS_DIR="$OPTARG"
+ ;;
+ t)
+ TASKS="$OPTARG"
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+# Ensure the buildstats folder exists
+if [ ! -d "$BS_DIR" ]; then
+ echo "ERROR: $BS_DIR does not exist"
+ usage
+ exit 1
+fi
+
+RECIPE_FIELD=1
+TIME_FIELD=4
+
+tasks=(${TASKS//:/ })
+for task in "${tasks[@]}"; do
+ task="do_${task}"
+ for file in $(find ${BS_DIR} -type f -name ${task}); do
+ recipe=$(sed -n -e "/$task/p" ${file} | cut -d ':' -f${RECIPE_FIELD})
+ time=$(sed -n -e "/$task/p" ${file} | cut -d ':' -f${TIME_FIELD} | cut -d ' ' -f2)
+ echo "${task} ${recipe} ${time}"
+ done
+done
diff --git a/scripts/contrib/bbvars.py b/scripts/contrib/bbvars.py
new file mode 100755
index 0000000..0896d64
--- /dev/null
+++ b/scripts/contrib/bbvars.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) Darren Hart <dvhart@linux.intel.com>, 2010
+
+
+import sys
+import getopt
+import os
+import os.path
+import re
+
+def usage():
+ print 'Usage: %s -d FILENAME [-d FILENAME]* -m METADIR [-m MATADIR]*' % os.path.basename(sys.argv[0])
+ print ' -d FILENAME documentation file to search'
+ print ' -h, --help display this help and exit'
+ print ' -m METADIR meta directory to search for recipes'
+ print ' -t FILENAME documentation config file (for doc tags)'
+ print ' -T Only display variables with doc tags (requires -t)'
+
+def recipe_bbvars(recipe):
+ ''' Return a unique set of every bbvar encountered in the recipe '''
+ prog = re.compile("[A-Z_]+")
+ vset = set()
+ try:
+ r = open(recipe)
+ except IOError as (errno, strerror):
+ print 'WARNING: Failed to open recipe ', recipe
+ print strerror
+
+ for line in r:
+ # Strip any comments from the line
+ line = line.rsplit('#')[0]
+ vset = vset.union(set(prog.findall(line)))
+ r.close()
+
+ bbvars = {}
+ for v in vset:
+ bbvars[v] = 1
+
+ return bbvars
+
+def collect_bbvars(metadir):
+ ''' Walk the metadir and collect the bbvars from each recipe found '''
+ bbvars = {}
+ for root,dirs,files in os.walk(metadir):
+ for name in files:
+ if name.find(".bb") >= 0:
+ for key in recipe_bbvars(os.path.join(root,name)).iterkeys():
+ if bbvars.has_key(key):
+ bbvars[key] = bbvars[key] + 1
+ else:
+ bbvars[key] = 1
+ return bbvars
+
+def bbvar_is_documented(var, docfiles):
+ prog = re.compile(".*($|[^A-Z_])%s([^A-Z_]|$)" % (var))
+ for doc in docfiles:
+ try:
+ f = open(doc)
+ except IOError as (errno, strerror):
+ print 'WARNING: Failed to open doc ', doc
+ print strerror
+ for line in f:
+ if prog.match(line):
+ return True
+ f.close()
+ return False
+
+def bbvar_doctag(var, docconf):
+ prog = re.compile('^%s\[doc\] *= *"(.*)"' % (var))
+ if docconf == "":
+ return "?"
+
+ try:
+ f = open(docconf)
+ except IOError as (errno, strerror):
+ return strerror
+
+ for line in f:
+ m = prog.search(line)
+ if m:
+ return m.group(1)
+
+ f.close()
+ return ""
+
+def main():
+ docfiles = []
+ metadirs = []
+ bbvars = {}
+ undocumented = []
+ docconf = ""
+ onlydoctags = False
+
+ # Collect and validate input
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "d:hm:t:T", ["help"])
+ except getopt.GetoptError, err:
+ print '%s' % str(err)
+ usage()
+ sys.exit(2)
+
+ for o, a in opts:
+ if o in ('-h', '--help'):
+ usage()
+ sys.exit(0)
+ elif o == '-d':
+ if os.path.isfile(a):
+ docfiles.append(a)
+ else:
+ print 'ERROR: documentation file %s is not a regular file' % (a)
+ sys.exit(3)
+ elif o == '-m':
+ if os.path.isdir(a):
+ metadirs.append(a)
+ else:
+ print 'ERROR: meta directory %s is not a directory' % (a)
+ sys.exit(4)
+ elif o == "-t":
+ if os.path.isfile(a):
+ docconf = a
+ elif o == "-T":
+ onlydoctags = True
+ else:
+ assert False, "unhandled option"
+
+ if len(docfiles) == 0:
+ print 'ERROR: no docfile specified'
+ usage()
+ sys.exit(5)
+
+ if len(metadirs) == 0:
+ print 'ERROR: no metadir specified'
+ usage()
+ sys.exit(6)
+
+ if onlydoctags and docconf == "":
+ print 'ERROR: no docconf specified'
+ usage()
+ sys.exit(7)
+
+ # Collect all the variable names from the recipes in the metadirs
+ for m in metadirs:
+ for key,cnt in collect_bbvars(m).iteritems():
+ if bbvars.has_key(key):
+ bbvars[key] = bbvars[key] + cnt
+ else:
+ bbvars[key] = cnt
+
+ # Check each var for documentation
+ varlen = 0
+ for v in bbvars.iterkeys():
+ if len(v) > varlen:
+ varlen = len(v)
+ if not bbvar_is_documented(v, docfiles):
+ undocumented.append(v)
+ undocumented.sort()
+ varlen = varlen + 1
+
+ # Report all undocumented variables
+ print 'Found %d undocumented bb variables (out of %d):' % (len(undocumented), len(bbvars))
+ header = '%s%s%s' % (str("VARIABLE").ljust(varlen), str("COUNT").ljust(6), str("DOCTAG").ljust(7))
+ print header
+ print str("").ljust(len(header), '=')
+ for v in undocumented:
+ doctag = bbvar_doctag(v, docconf)
+ if not onlydoctags or not doctag == "":
+ print '%s%s%s' % (v.ljust(varlen), str(bbvars[v]).ljust(6), doctag)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/contrib/build-perf-test.sh b/scripts/contrib/build-perf-test.sh
new file mode 100755
index 0000000..7d99228
--- /dev/null
+++ b/scripts/contrib/build-perf-test.sh
@@ -0,0 +1,400 @@
+#!/bin/bash
+#
+# This script runs a series of tests (with and without sstate) and reports build time (and tmp/ size)
+#
+# Build performance test script
+#
+# Copyright 2013 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# AUTHORS:
+# Stefan Stanacar <stefanx.stanacar@intel.com>
+
+
+ME=$(basename $0)
+
+#
+# usage and setup
+#
+
+usage () {
+cat << EOT
+Usage: $ME [-h]
+ $ME [-c <commit>] [-v] [-m <val>] [-j <val>] [-t <val>] [-i <image-name>] [-d <path>]
+Options:
+ -h
+ Display this help and exit.
+ -c <commit>
+ git checkout <commit> before anything else
+ -v
+ Show bitbake output, don't redirect it to a log.
+ -m <machine>
+ Value for MACHINE. Default is qemux86.
+ -j <val>
+ Value for PARALLEL_MAKE. Default is 8.
+ -t <val>
+ Value for BB_NUMBER_THREADS. Default is 8.
+ -i <image-name>
+ Instead of timing against core-image-sato, use <image-name>
+ -d <path>
+ Use <path> as DL_DIR
+ -p <githash>
+ Cherry pick githash onto the commit
+
+Note: current working directory must be inside a poky git clone.
+
+EOT
+}
+
+
+if clonedir=$(git rev-parse --show-toplevel); then
+ cd $clonedir
+else
+ echo "The current working dir doesn't seem to be a poky git clone. Please cd there before running $ME"
+ exit 1
+fi
+
+IMAGE="core-image-sato"
+verbose=0
+dldir=
+commit=
+pmake=
+cherrypicks=
+while getopts "hvc:m:j:t:i:d:p:" opt; do
+ case $opt in
+ h) usage
+ exit 0
+ ;;
+ v) verbose=1
+ ;;
+ c) commit=$OPTARG
+ ;;
+ m) export MACHINE=$OPTARG
+ ;;
+ j) pmake=$OPTARG
+ ;;
+ t) export BB_NUMBER_THREADS=$OPTARG
+ ;;
+ i) IMAGE=$OPTARG
+ ;;
+ d) dldir=$OPTARG
+ ;;
+ p) cherrypicks="$cherrypicks $OPTARG"
+ ;;
+ *) usage
+ exit 1
+ ;;
+ esac
+done
+
+
+#drop cached credentials and test for sudo access without a password
+sudo -k -n ls > /dev/null 2>&1
+reqpass=$?
+if [ $reqpass -ne 0 ]; then
+ echo "The script requires sudo access to drop caches between builds (echo 3 > /proc/sys/vm/drop_caches)"
+ read -s -p "Please enter your sudo password: " pass
+ echo
+fi
+
+if [ -n "$commit" ]; then
+ echo "git checkout -f $commit"
+ git pull > /dev/null 2>&1
+ git checkout -f $commit || exit 1
+ git pull > /dev/null 2>&1
+fi
+
+if [ -n "$cherrypicks" ]; then
+ for c in $cherrypicks; do
+ git cherry-pick $c
+ done
+fi
+
+rev=$(git rev-parse --short HEAD) || exit 1
+OUTDIR="$clonedir/build-perf-test/results-$rev-`date "+%Y%m%d%H%M%S"`"
+BUILDDIR="$OUTDIR/build"
+resultsfile="$OUTDIR/results.log"
+cmdoutput="$OUTDIR/commands.log"
+myoutput="$OUTDIR/output.log"
+globalres="$clonedir/build-perf-test/globalres.log"
+
+mkdir -p $OUTDIR || exit 1
+
+log () {
+ local msg="$1"
+ echo "`date`: $msg" | tee -a $myoutput
+}
+
+
+#
+# Config stuff
+#
+
+branch=`git branch 2>&1 | grep "^* " | tr -d "* "`
+gitcommit=$(git rev-parse HEAD) || exit 1
+log "Running on $branch:$gitcommit"
+
+source ./oe-init-build-env $OUTDIR/build >/dev/null || exit 1
+cd $OUTDIR/build
+
+[ -n "$MACHINE" ] || export MACHINE="qemux86"
+[ -n "$BB_NUMBER_THREADS" ] || export BB_NUMBER_THREADS="8"
+
+if [ -n "$pmake" ]; then
+ export PARALLEL_MAKE="-j $pmake"
+else
+ export PARALLEL_MAKE="-j 8"
+fi
+
+if [ -n "$dldir" ]; then
+ echo "DL_DIR = \"$dldir\"" >> conf/local.conf
+else
+ echo "DL_DIR = \"$clonedir/build-perf-test/downloads\"" >> conf/local.conf
+fi
+
+# Sometimes I've noticed big differences in timings for the same commit, on the same machine
+# Disabling the network sanity check helps a bit (because of my crappy network connection and/or proxy)
+echo "CONNECTIVITY_CHECK_URIS =\"\"" >> conf/local.conf
+
+
+#
+# Functions
+#
+
+declare -a TIMES
+time_count=0
+declare -a SIZES
+size_count=0
+
+time_cmd () {
+ log " Timing: $*"
+
+ if [ $verbose -eq 0 ]; then
+ /usr/bin/time -v -o $resultsfile "$@" >> $cmdoutput
+ else
+ /usr/bin/time -v -o $resultsfile "$@"
+ fi
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ t=`grep wall $resultsfile | sed 's/.*m:ss): //'`
+ log " TIME: $t"
+ TIMES[(( time_count++ ))]="$t"
+ else
+ log "ERROR: exit status was non-zero, will report time as 0."
+ TIMES[(( time_count++ ))]="0"
+ fi
+
+ #time by default overwrites the output file and we want to keep the results
+ #it has an append option but I don't want to clobber the results in the same file
+ i=`ls $OUTDIR/results.log* |wc -l`
+ mv $resultsfile "${resultsfile}.${i}"
+ log "More stats can be found in ${resultsfile}.${i}"
+}
+
+bbtime () {
+ time_cmd bitbake "$@"
+}
+
+#we don't time bitbake here
+bbnotime () {
+ local arg="$@"
+ log " Running: bitbake ${arg}"
+ if [ $verbose -eq 0 ]; then
+ bitbake ${arg} >> $cmdoutput
+ else
+ bitbake ${arg}
+ fi
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ log " Finished bitbake ${arg}"
+ else
+ log "ERROR: exit status was non-zero. Exit.."
+ exit $ret
+ fi
+
+}
+
+do_rmtmp() {
+ log " Removing tmp"
+ rm -rf bitbake.lock pseudodone conf/sanity_info cache tmp
+}
+do_rmsstate () {
+ log " Removing sstate-cache"
+ rm -rf sstate-cache
+}
+do_sync () {
+ log " Syncing and dropping caches"
+ sync; sync
+ if [ $reqpass -eq 0 ]; then
+ sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
+ else
+ echo "$pass" | sudo -S sh -c "echo 3 > /proc/sys/vm/drop_caches"
+ echo
+ fi
+ sleep 3
+}
+
+write_results() {
+ echo -n "`uname -n`,$branch:$gitcommit,`git describe`," >> $globalres
+ for i in "${TIMES[@]}"; do
+ echo -n "$i," >> $globalres
+ done
+ for i in "${SIZES[@]}"; do
+ echo -n "$i," >> $globalres
+ done
+ echo >> $globalres
+ sed -i '$ s/,$//' $globalres
+}
+
+####
+
+#
+# Test 1
+# Measure: Wall clock of "bitbake core-image-sato" and size of tmp/dir (w/o rm_work and w/ rm_work)
+# Pre: Downloaded sources, no sstate
+# Steps:
+# Part1:
+# - fetchall
+# - clean build dir
+# - time bitbake core-image-sato
+# - collect data
+# Part2:
+# - bitbake virtual/kernel -c cleansstate
+# - time bitbake virtual/kernel
+# Part3:
+# - add INHERIT to local.conf
+# - clean build dir
+# - build
+# - report size, remove INHERIT
+
+test1_p1 () {
+ log "Running Test 1, part 1/3: Measure wall clock of bitbake $IMAGE and size of tmp/ dir"
+ bbnotime $IMAGE -c fetchall
+ do_rmtmp
+ do_rmsstate
+ do_sync
+ bbtime $IMAGE
+ s=`du -s tmp | sed 's/tmp//' | sed 's/[ \t]*$//'`
+ SIZES[(( size_count++ ))]="$s"
+ log "SIZE of tmp dir is: $s"
+ log "Buildstats are saved in $OUTDIR/buildstats-test1"
+ mv tmp/buildstats $OUTDIR/buildstats-test1
+}
+
+
+test1_p2 () {
+ log "Running Test 1, part 2/3: bitbake virtual/kernel -c cleansstate and time bitbake virtual/kernel"
+ bbnotime virtual/kernel -c cleansstate
+ do_sync
+ bbtime virtual/kernel
+}
+
+test1_p3 () {
+ log "Running Test 1, part 3/3: Build $IMAGE w/o sstate and report size of tmp/dir with rm_work enabled"
+ echo "INHERIT += \"rm_work\"" >> conf/local.conf
+ do_rmtmp
+ do_rmsstate
+ do_sync
+ bbtime $IMAGE
+ sed -i 's/INHERIT += \"rm_work\"//' conf/local.conf
+ s=`du -s tmp | sed 's/tmp//' | sed 's/[ \t]*$//'`
+ SIZES[(( size_count++ ))]="$s"
+ log "SIZE of tmp dir is: $s"
+ log "Buildstats are saved in $OUTDIR/buildstats-test13"
+ mv tmp/buildstats $OUTDIR/buildstats-test13
+}
+
+
+#
+# Test 2
+# Measure: Wall clock of "bitbake core-image-sato" and size of tmp/dir
+# Pre: populated sstate cache
+
+test2 () {
+ # Assuming test 1 has run
+ log "Running Test 2: Measure wall clock of bitbake $IMAGE -c rootfs with sstate"
+ do_rmtmp
+ do_sync
+ bbtime $IMAGE -c rootfs
+}
+
+
+# Test 3
+# parsing time metrics
+#
+# Start with
+# i) "rm -rf tmp/cache; time bitbake -p"
+# ii) "rm -rf tmp/cache/default-glibc/; time bitbake -p"
+# iii) "time bitbake -p"
+
+
+test3 () {
+ log "Running Test 3: Parsing time metrics (bitbake -p)"
+ log " Removing tmp/cache && cache"
+ rm -rf tmp/cache cache
+ bbtime -p
+ log " Removing tmp/cache/default-glibc/"
+ rm -rf tmp/cache/default-glibc/
+ bbtime -p
+ bbtime -p
+}
+
+#
+# Test 4 - eSDK
+# Measure: eSDK size and installation time
+test4 () {
+ log "Running Test 4: eSDK size and installation time"
+ bbnotime $IMAGE -c do_populate_sdk_ext
+
+ esdk_installer=(tmp/deploy/sdk/*-toolchain-ext-*.sh)
+
+ if [ ${#esdk_installer[*]} -eq 1 ]; then
+ s=$((`stat -c %s "$esdk_installer"` / 1024))
+ SIZES[(( size_count++ ))]="$s"
+ log "Download SIZE of eSDK is: $s kB"
+
+ do_sync
+ time_cmd "$esdk_installer" -y -d "tmp/esdk-deploy"
+
+ s=$((`du -sb "tmp/esdk-deploy" | cut -f1` / 1024))
+ SIZES[(( size_count++ ))]="$s"
+ log "Install SIZE of eSDK is: $s kB"
+ else
+ log "ERROR: other than one sdk found (${esdk_installer[*]}), reporting size and time as 0."
+ SIZES[(( size_count++ ))]="0"
+ TIMES[(( time_count++ ))]="0"
+ fi
+
+}
+
+
+# RUN!
+
+test1_p1
+test1_p2
+test1_p3
+test2
+test3
+test4
+
+# if we got til here write to global results
+write_results
+
+log "All done, cleaning up..."
+
+do_rmtmp
+do_rmsstate
diff --git a/scripts/contrib/ddimage b/scripts/contrib/ddimage
new file mode 100755
index 0000000..a503f11
--- /dev/null
+++ b/scripts/contrib/ddimage
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+# Default to avoiding the first two disks on typical Linux and Mac OS installs
+# Better safe than sorry :-)
+BLACKLIST_DEVICES="/dev/sda /dev/sdb /dev/disk1 /dev/disk2"
+
+# 1MB blocksize
+BLOCKSIZE=1048576
+
+usage() {
+ echo "Usage: $(basename $0) IMAGE DEVICE"
+}
+
+image_details() {
+ IMG=$1
+ echo "Image details"
+ echo "============="
+ echo " image: $(basename $IMG)"
+ # stat format is different on Mac OS and Linux
+ if [ "$(uname)" = "Darwin" ]; then
+ echo " size: $(stat -L -f '%z bytes' $IMG)"
+ echo " modified: $(stat -L -f '%Sm' $IMG)"
+ else
+ echo " size: $(stat -L -c '%s bytes' $IMG)"
+ echo " modified: $(stat -L -c '%y' $IMG)"
+ fi
+ echo " type: $(file -L -b $IMG)"
+ echo ""
+}
+
+device_details() {
+ DEV=$1
+ BLOCK_SIZE=512
+
+ echo "Device details"
+ echo "=============="
+
+ # Collect disk info using diskutil on Mac OS
+ if [ "$(uname)" = "Darwin" ]; then
+ diskutil info $DEVICE | egrep "(Device Node|Media Name|Total Size)"
+ return
+ fi
+
+ # Default / Linux information collection
+ echo " device: $DEVICE"
+ if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
+ echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)"
+ else
+ echo " vendor: UNKOWN"
+ fi
+ if [ -f "/sys/class/block/$DEV/device/model" ]; then
+ echo " model: $(cat /sys/class/block/$DEV/device/model)"
+ else
+ echo " model: UNKNOWN"
+ fi
+ if [ -f "/sys/class/block/$DEV/size" ]; then
+ echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
+ else
+ echo " size: UNKNOWN"
+ fi
+ echo ""
+}
+
+if [ $# -ne 2 ]; then
+ usage
+ exit 1
+fi
+
+IMAGE=$1
+DEVICE=$2
+
+if [ ! -e "$IMAGE" ]; then
+ echo "ERROR: Image $IMAGE does not exist"
+ usage
+ exit 1
+fi
+
+
+for i in ${BLACKLIST_DEVICES}; do
+ if [ "$i" = "$DEVICE" ]; then
+ echo "ERROR: Device $DEVICE is blacklisted"
+ exit 1
+ fi
+done
+
+if [ ! -w "$DEVICE" ]; then
+ echo "ERROR: Device $DEVICE does not exist or is not writable"
+ usage
+ exit 1
+fi
+
+image_details $IMAGE
+device_details $(basename $DEVICE)
+
+printf "Write $IMAGE to $DEVICE [y/N]? "
+read RESPONSE
+if [ "$RESPONSE" != "y" ]; then
+ echo "Write aborted"
+ exit 0
+fi
+
+echo "Writing image..."
+dd if="$IMAGE" of="$DEVICE" bs="$BLOCKSIZE"
+sync
diff --git a/scripts/contrib/devtool-stress.py b/scripts/contrib/devtool-stress.py
new file mode 100755
index 0000000..8cf92ca
--- /dev/null
+++ b/scripts/contrib/devtool-stress.py
@@ -0,0 +1,242 @@
+#!/usr/bin/env python
+
+# devtool stress tester
+#
+# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
+#
+# Copyright 2015 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import sys
+import os
+import os.path
+import subprocess
+import re
+import argparse
+import logging
+import tempfile
+import shutil
+import signal
+import fnmatch
+
+scripts_lib_path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'lib'))
+sys.path.insert(0, scripts_lib_path)
+import scriptutils
+import argparse_oe
+logger = scriptutils.logger_create('devtool-stress')
+
+def select_recipes(args):
+ import bb.tinfoil
+ tinfoil = bb.tinfoil.Tinfoil()
+ tinfoil.prepare(False)
+
+ pkg_pn = tinfoil.cooker.recipecache.pkg_pn
+ (latest_versions, preferred_versions) = bb.providers.findProviders(tinfoil.config_data, tinfoil.cooker.recipecache, pkg_pn)
+
+ skip_classes = args.skip_classes.split(',')
+
+ recipelist = []
+ for pn in sorted(pkg_pn):
+ pref = preferred_versions[pn]
+ inherits = [os.path.splitext(os.path.basename(f))[0] for f in tinfoil.cooker.recipecache.inherits[pref[1]]]
+ for cls in skip_classes:
+ if cls in inherits:
+ break
+ else:
+ recipelist.append(pn)
+
+ tinfoil.shutdown()
+
+ resume_from = args.resume_from
+ if resume_from:
+ if not resume_from in recipelist:
+ print('%s is not a testable recipe' % resume_from)
+ return 1
+ if args.only:
+ only = args.only.split(',')
+ for onlyitem in only:
+ for pn in recipelist:
+ if fnmatch.fnmatch(pn, onlyitem):
+ break
+ else:
+ print('%s does not match any testable recipe' % onlyitem)
+ return 1
+ else:
+ only = None
+ if args.skip:
+ skip = args.skip.split(',')
+ else:
+ skip = []
+
+ recipes = []
+ for pn in recipelist:
+ if resume_from:
+ if pn == resume_from:
+ resume_from = None
+ else:
+ continue
+
+ if args.only:
+ for item in only:
+ if fnmatch.fnmatch(pn, item):
+ break
+ else:
+ continue
+
+ skipit = False
+ for item in skip:
+ if fnmatch.fnmatch(pn, item):
+ skipit = True
+ if skipit:
+ continue
+
+ recipes.append(pn)
+
+ return recipes
+
+
+def stress_extract(args):
+ import bb.process
+
+ recipes = select_recipes(args)
+
+ failures = 0
+ tmpdir = tempfile.mkdtemp()
+ os.setpgrp()
+ try:
+ for pn in recipes:
+ sys.stdout.write('Testing %s ' % (pn + ' ').ljust(40, '.'))
+ sys.stdout.flush()
+ failed = False
+
+ srctree = os.path.join(tmpdir, pn)
+ try:
+ bb.process.run('devtool extract %s %s' % (pn, srctree))
+ except bb.process.CmdError as exc:
+ failed = True
+ with open('stress_%s_extract.log' % pn, 'w') as f:
+ f.write(str(exc))
+
+ if os.path.exists(srctree):
+ shutil.rmtree(srctree)
+
+ if failed:
+ print('failed')
+ failures += 1
+ else:
+ print('ok')
+ except KeyboardInterrupt:
+ # We want any child processes killed. This is crude, but effective.
+ os.killpg(0, signal.SIGTERM)
+
+ if failures:
+ return 1
+ else:
+ return 0
+
+
+def stress_modify(args):
+ import bb.process
+
+ recipes = select_recipes(args)
+
+ failures = 0
+ tmpdir = tempfile.mkdtemp()
+ os.setpgrp()
+ try:
+ for pn in recipes:
+ sys.stdout.write('Testing %s ' % (pn + ' ').ljust(40, '.'))
+ sys.stdout.flush()
+ failed = False
+ reset = True
+
+ srctree = os.path.join(tmpdir, pn)
+ try:
+ bb.process.run('devtool modify -x %s %s' % (pn, srctree))
+ except bb.process.CmdError as exc:
+ with open('stress_%s_modify.log' % pn, 'w') as f:
+ f.write(str(exc))
+ failed = 'modify'
+ reset = False
+
+ if not failed:
+ try:
+ bb.process.run('bitbake -c install %s' % pn)
+ except bb.process.CmdError as exc:
+ with open('stress_%s_install.log' % pn, 'w') as f:
+ f.write(str(exc))
+ failed = 'build'
+ if reset:
+ try:
+ bb.process.run('devtool reset %s' % pn)
+ except bb.process.CmdError as exc:
+ print('devtool reset failed: %s' % str(exc))
+ break
+
+ if os.path.exists(srctree):
+ shutil.rmtree(srctree)
+
+ if failed:
+ print('failed (%s)' % failed)
+ failures += 1
+ else:
+ print('ok')
+ except KeyboardInterrupt:
+ # We want any child processes killed. This is crude, but effective.
+ os.killpg(0, signal.SIGTERM)
+
+ if failures:
+ return 1
+ else:
+ return 0
+
+
+def main():
+ parser = argparse_oe.ArgumentParser(description="devtool stress tester",
+ epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
+ parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
+ parser.add_argument('-r', '--resume-from', help='Resume from specified recipe', metavar='PN')
+ parser.add_argument('-o', '--only', help='Only test specified recipes (comma-separated without spaces, wildcards allowed)', metavar='PNLIST')
+ parser.add_argument('-s', '--skip', help='Skip specified recipes (comma-separated without spaces, wildcards allowed)', metavar='PNLIST')
+ parser.add_argument('-c', '--skip-classes', help='Skip recipes inheriting specified classes (comma-separated) - default %(default)s', metavar='CLASSLIST', default='native,nativesdk,cross,cross-canadian,image,populate_sdk,meta,packagegroup')
+ subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>')
+
+ parser_modify = subparsers.add_parser('modify',
+ help='Run "devtool modify" followed by a build with bitbake on matching recipes',
+ description='Runs "devtool modify" followed by a build with bitbake on matching recipes')
+ parser_modify.set_defaults(func=stress_modify)
+
+ parser_extract = subparsers.add_parser('extract',
+ help='Run "devtool extract" on matching recipes',
+ description='Runs "devtool extract" on matching recipes')
+ parser_extract.set_defaults(func=stress_extract)
+
+ args = parser.parse_args()
+
+ if args.debug:
+ logger.setLevel(logging.DEBUG)
+
+ import scriptpath
+ bitbakepath = scriptpath.add_bitbake_lib_path()
+ if not bitbakepath:
+ logger.error("Unable to find bitbake by searching parent directory of this script or PATH")
+ return 1
+ logger.debug('Found bitbake path: %s' % bitbakepath)
+
+ ret = args.func(args)
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/contrib/dialog-power-control b/scripts/contrib/dialog-power-control
new file mode 100755
index 0000000..7550ea5
--- /dev/null
+++ b/scripts/contrib/dialog-power-control
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Simple script to show a manual power prompt for when you want to use
+# automated hardware testing with testimage.bbclass but you don't have a
+# web-enabled power strip or similar to do the power on/off/cycle.
+#
+# You can enable it by enabling testimage (see the Yocto Project
+# Development manual "Performing Automated Runtime Testing" section)
+# and setting the following in your local.conf:
+#
+# TEST_POWERCONTROL_CMD = "${COREBASE}/scripts/contrib/dialog-power-control"
+#
+
+PROMPT=""
+while true; do
+ case $1 in
+ on)
+ PROMPT="Please turn device power on";;
+ off)
+ PROMPT="Please turn device power off";;
+ cycle)
+ PROMPT="Please click Done, then turn the device power off then on";;
+ "")
+ break;;
+ esac
+ shift
+done
+
+if [ "$PROMPT" = "" ] ; then
+ echo "ERROR: no power action specified on command line"
+ exit 2
+fi
+
+if [ "`which kdialog 2>/dev/null`" != "" ] ; then
+ DIALOGUTIL="kdialog"
+elif [ "`which zenity 2>/dev/null`" != "" ] ; then
+ DIALOGUTIL="zenity"
+else
+ echo "ERROR: couldn't find program to display a message, install kdialog or zenity"
+ exit 3
+fi
+
+if [ "$DIALOGUTIL" = "kdialog" ] ; then
+ kdialog --yesno "$PROMPT" --title "TestImage Power Control" --yes-label "Done" --no-label "Cancel test"
+elif [ "$DIALOGUTIL" = "zenity" ] ; then
+ zenity --question --text="$PROMPT" --title="TestImage Power Control" --ok-label="Done" --cancel-label="Cancel test"
+fi
+
+if [ "$?" != "0" ] ; then
+ echo "User cancelled test at power prompt"
+ exit 1
+fi
+
diff --git a/scripts/contrib/documentation-audit.sh b/scripts/contrib/documentation-audit.sh
new file mode 100755
index 0000000..2144aac
--- /dev/null
+++ b/scripts/contrib/documentation-audit.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+#
+# Perform an audit of which packages provide documentation and which
+# are missing -doc packages.
+#
+# Setup requirements: be sure to be building for MACHINE=qemux86. Run
+# this script after source'ing the build environment script, so you're
+# running it from build/ directory.
+#
+# Maintainer: Scott Garman <scott.a.garman@intel.com>
+
+REPORT_DOC_SIMPLE="documentation_exists.txt"
+REPORT_DOC_DETAIL="documentation_exists_detail.txt"
+REPORT_MISSING_SIMPLE="documentation_missing.txt"
+REPORT_MISSING_DETAIL="documentation_missing_detail.txt"
+REPORT_BUILD_ERRORS="build_errors.txt"
+
+rm -rf $REPORT_DOC_SIMPLE $REPORT_DOC_DETAIL $REPORT_MISSING_SIMPLE $REPORT_MISSING_DETAIL
+
+BITBAKE=`which bitbake`
+if [ -z "$BITBAKE" ]; then
+ echo "Error: bitbake command not found."
+ echo "Did you forget to source the build environment script?"
+ exit 1
+fi
+
+echo "REMINDER: you need to build for MACHINE=qemux86 or you won't get useful results"
+echo "REMINDER: you need to set LICENSE_FLAGS_WHITELIST appropriately in local.conf or "
+echo " you'll get false positives. For example, LICENSE_FLAGS_WHITELIST = \"Commercial\""
+
+for pkg in `bitbake -s | awk '{ print \$1 }'`; do
+ if [[ "$pkg" == "Loading" || "$pkg" == "Loaded" ||
+ "$pkg" == "Recipe" ||
+ "$pkg" == "Parsing" || "$pkg" == "Package" ||
+ "$pkg" == "NOTE:" || "$pkg" == "WARNING:" ||
+ "$pkg" == "done." || "$pkg" == "===========" ]]
+ then
+ # Skip initial bitbake output
+ continue
+ fi
+ if [[ "$pkg" =~ -native$ || "$pkg" =~ -nativesdk$ ||
+ "$pkg" =~ -cross-canadian ]]; then
+ # Skip native/nativesdk/cross-canadian recipes
+ continue
+ fi
+ if [[ "$pkg" =~ ^meta- || "$pkg" =~ ^packagegroup- || "$pkg" =~ -image ]]; then
+ # Skip meta, task and image recipes
+ continue
+ fi
+ if [[ "$pkg" =~ ^glibc- || "$pkg" =~ ^libiconv$ ||
+ "$pkg" =~ -toolchain$ || "$pkg" =~ ^package-index$ ||
+ "$pkg" =~ ^linux- || "$pkg" =~ ^adt-installer$ ||
+ "$pkg" =~ ^eds-tools$ || "$pkg" =~ ^external-python-tarball$ ||
+ "$pkg" =~ ^qt4-embedded$ || "$pkg" =~ ^qt-mobility ]]; then
+ # Skip glibc, libiconv, -toolchain, and other recipes known
+ # to cause build conflicts or trigger false positives.
+ continue
+ fi
+
+ echo "Building package $pkg..."
+ bitbake $pkg > /dev/null
+ if [ $? -ne 0 ]; then
+ echo "There was an error building package $pkg" >> "$REPORT_MISSING_DETAIL"
+ echo "$pkg" >> $REPORT_BUILD_ERRORS
+
+ # Do not skip the remaining tests, as sometimes the
+ # exit status is 1 due to QA errors, and we can still
+ # perform the -doc checks.
+ fi
+
+ echo "$pkg built successfully, checking for a documentation package..."
+ WORKDIR=`bitbake -e $pkg | grep ^WORKDIR | awk -F '=' '{ print \$2 }' | awk -F '"' '{ print \$2 }'`
+ FIND_DOC_PKG=`find $WORKDIR/packages-split/*-doc -maxdepth 0 -type d`
+ if [ -z "$FIND_DOC_PKG" ]; then
+ # No -doc package was generated:
+ echo "No -doc package: $pkg" >> "$REPORT_MISSING_DETAIL"
+ echo "$pkg" >> $REPORT_MISSING_SIMPLE
+ continue
+ fi
+
+ FIND_DOC_FILES=`find $FIND_DOC_PKG -type f`
+ if [ -z "$FIND_DOC_FILES" ]; then
+ # No files shipped with the -doc package:
+ echo "No files shipped with the -doc package: $pkg" >> "$REPORT_MISSING_DETAIL"
+ echo "$pkg" >> $REPORT_MISSING_SIMPLE
+ continue
+ fi
+
+ echo "Documentation shipped with $pkg:" >> "$REPORT_DOC_DETAIL"
+ echo "$FIND_DOC_FILES" >> "$REPORT_DOC_DETAIL"
+ echo "" >> "$REPORT_DOC_DETAIL"
+
+ echo "$pkg" >> "$REPORT_DOC_SIMPLE"
+done
diff --git a/scripts/contrib/graph-tool b/scripts/contrib/graph-tool
new file mode 100755
index 0000000..6dc7d33
--- /dev/null
+++ b/scripts/contrib/graph-tool
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+# Simple graph query utility
+# useful for getting answers from .dot files produced by bitbake -g
+#
+# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
+#
+# Copyright 2013 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import sys
+
+def get_path_networkx(dotfile, fromnode, tonode):
+ try:
+ import networkx
+ except ImportError:
+ print('ERROR: Please install the networkx python module')
+ sys.exit(1)
+
+ graph = networkx.DiGraph(networkx.read_dot(dotfile))
+
+ def node_missing(node):
+ import difflib
+ close_matches = difflib.get_close_matches(node, graph.nodes(), cutoff=0.7)
+ if close_matches:
+ print('ERROR: no node "%s" in graph. Close matches:\n %s' % (node, '\n '.join(close_matches)))
+ sys.exit(1)
+
+ if not fromnode in graph:
+ node_missing(fromnode)
+ if not tonode in graph:
+ node_missing(tonode)
+ return networkx.all_simple_paths(graph, source=fromnode, target=tonode)
+
+
+def find_paths(args, usage):
+ if len(args) < 3:
+ usage()
+ sys.exit(1)
+
+ fromnode = args[1]
+ tonode = args[2]
+ paths = list(get_path_networkx(args[0], fromnode, tonode))
+ if paths:
+ for path in paths:
+ print ' -> '.join(path)
+ else:
+ print("ERROR: no path from %s to %s in graph" % (fromnode, tonode))
+ sys.exit(1)
+
+def main():
+ import optparse
+ parser = optparse.OptionParser(
+ usage = '''%prog [options] <command> <arguments>
+
+Available commands:
+ find-paths <dotfile> <from> <to>
+ Find all of the paths between two nodes in a dot graph''')
+
+ #parser.add_option("-d", "--debug",
+ # help = "Report all SRCREV values, not just ones where AUTOREV has been used",
+ # action="store_true", dest="debug", default=False)
+
+ options, args = parser.parse_args(sys.argv)
+ args = args[1:]
+
+ if len(args) < 1:
+ parser.print_help()
+ sys.exit(1)
+
+ if args[0] == "find-paths":
+ find_paths(args[1:], parser.print_help)
+ else:
+ parser.print_help()
+ sys.exit(1)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/contrib/list-packageconfig-flags.py b/scripts/contrib/list-packageconfig-flags.py
new file mode 100755
index 0000000..2f3b8b0
--- /dev/null
+++ b/scripts/contrib/list-packageconfig-flags.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation.
+#
+# Copyright (C) 2013 Wind River Systems, Inc.
+# Copyright (C) 2014 Intel Corporation
+#
+# - list available recipes which have PACKAGECONFIG flags
+# - list available PACKAGECONFIG flags and all affected recipes
+# - list all recipes and PACKAGECONFIG information
+
+import sys
+import optparse
+import os
+
+
+scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
+lib_path = os.path.abspath(scripts_path + '/../lib')
+sys.path = sys.path + [lib_path]
+
+import scriptpath
+
+# For importing the following modules
+bitbakepath = scriptpath.add_bitbake_lib_path()
+if not bitbakepath:
+ sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
+ sys.exit(1)
+
+import bb.cache
+import bb.cooker
+import bb.providers
+import bb.tinfoil
+
+def get_fnlist(bbhandler, pkg_pn, preferred):
+ ''' Get all recipe file names '''
+ if preferred:
+ (latest_versions, preferred_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecache, pkg_pn)
+
+ fn_list = []
+ for pn in sorted(pkg_pn):
+ if preferred:
+ fn_list.append(preferred_versions[pn][1])
+ else:
+ fn_list.extend(pkg_pn[pn])
+
+ return fn_list
+
+def get_recipesdata(bbhandler, preferred):
+ ''' Get data of all available recipes which have PACKAGECONFIG flags '''
+ pkg_pn = bbhandler.cooker.recipecache.pkg_pn
+
+ data_dict = {}
+ for fn in get_fnlist(bbhandler, pkg_pn, preferred):
+ data = bb.cache.Cache.loadDataFull(fn, bbhandler.cooker.collection.get_file_appends(fn), bbhandler.config_data)
+ flags = data.getVarFlags("PACKAGECONFIG")
+ flags.pop('doc', None)
+ if flags:
+ data_dict[fn] = data
+
+ return data_dict
+
+def collect_pkgs(data_dict):
+ ''' Collect available pkgs in which have PACKAGECONFIG flags '''
+ # pkg_dict = {'pkg1': ['flag1', 'flag2',...]}
+ pkg_dict = {}
+ for fn in data_dict:
+ pkgconfigflags = data_dict[fn].getVarFlags("PACKAGECONFIG")
+ pkgconfigflags.pop('doc', None)
+ pkgname = data_dict[fn].getVar("P", True)
+ pkg_dict[pkgname] = sorted(pkgconfigflags.keys())
+
+ return pkg_dict
+
+def collect_flags(pkg_dict):
+ ''' Collect available PACKAGECONFIG flags and all affected pkgs '''
+ # flag_dict = {'flag': ['pkg1', 'pkg2',...]}
+ flag_dict = {}
+ for pkgname, flaglist in pkg_dict.iteritems():
+ for flag in flaglist:
+ if flag in flag_dict:
+ flag_dict[flag].append(pkgname)
+ else:
+ flag_dict[flag] = [pkgname]
+
+ return flag_dict
+
+def display_pkgs(pkg_dict):
+ ''' Display available pkgs which have PACKAGECONFIG flags '''
+ pkgname_len = len("RECIPE NAME") + 1
+ for pkgname in pkg_dict:
+ if pkgname_len < len(pkgname):
+ pkgname_len = len(pkgname)
+ pkgname_len += 1
+
+ header = '%-*s%s' % (pkgname_len, str("RECIPE NAME"), str("PACKAGECONFIG FLAGS"))
+ print header
+ print str("").ljust(len(header), '=')
+ for pkgname in sorted(pkg_dict):
+ print('%-*s%s' % (pkgname_len, pkgname, ' '.join(pkg_dict[pkgname])))
+
+
+def display_flags(flag_dict):
+ ''' Display available PACKAGECONFIG flags and all affected pkgs '''
+ flag_len = len("PACKAGECONFIG FLAG") + 5
+
+ header = '%-*s%s' % (flag_len, str("PACKAGECONFIG FLAG"), str("RECIPE NAMES"))
+ print header
+ print str("").ljust(len(header), '=')
+
+ for flag in sorted(flag_dict):
+ print('%-*s%s' % (flag_len, flag, ' '.join(sorted(flag_dict[flag]))))
+
+def display_all(data_dict):
+ ''' Display all pkgs and PACKAGECONFIG information '''
+ print str("").ljust(50, '=')
+ for fn in data_dict:
+ print('%s' % data_dict[fn].getVar("P", True))
+ print fn
+ packageconfig = data_dict[fn].getVar("PACKAGECONFIG", True) or ''
+ if packageconfig.strip() == '':
+ packageconfig = 'None'
+ print('PACKAGECONFIG %s' % packageconfig)
+
+ for flag,flag_val in data_dict[fn].getVarFlags("PACKAGECONFIG").iteritems():
+ if flag == "doc":
+ continue
+ print('PACKAGECONFIG[%s] %s' % (flag, flag_val))
+ print ''
+
+def main():
+ pkg_dict = {}
+ flag_dict = {}
+
+ # Collect and validate input
+ parser = optparse.OptionParser(
+ description = "Lists recipes and PACKAGECONFIG flags. Without -a or -f, recipes and their available PACKAGECONFIG flags are listed.",
+ usage = """
+ %prog [options]""")
+
+ parser.add_option("-f", "--flags",
+ help = "list available PACKAGECONFIG flags and affected recipes",
+ action="store_const", dest="listtype", const="flags", default="recipes")
+ parser.add_option("-a", "--all",
+ help = "list all recipes and PACKAGECONFIG information",
+ action="store_const", dest="listtype", const="all")
+ parser.add_option("-p", "--preferred-only",
+ help = "where multiple recipe versions are available, list only the preferred version",
+ action="store_true", dest="preferred", default=False)
+
+ options, args = parser.parse_args(sys.argv)
+
+ bbhandler = bb.tinfoil.Tinfoil()
+ bbhandler.prepare()
+ print("Gathering recipe data...")
+ data_dict = get_recipesdata(bbhandler, options.preferred)
+
+ if options.listtype == 'flags':
+ pkg_dict = collect_pkgs(data_dict)
+ flag_dict = collect_flags(pkg_dict)
+ display_flags(flag_dict)
+ elif options.listtype == 'recipes':
+ pkg_dict = collect_pkgs(data_dict)
+ display_pkgs(pkg_dict)
+ elif options.listtype == 'all':
+ display_all(data_dict)
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/contrib/mkefidisk.sh b/scripts/contrib/mkefidisk.sh
new file mode 100755
index 0000000..d8db3c0
--- /dev/null
+++ b/scripts/contrib/mkefidisk.sh
@@ -0,0 +1,459 @@
+#!/bin/sh
+#
+# Copyright (c) 2012, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+LANG=C
+
+# Set to 1 to enable additional output
+DEBUG=0
+OUT="/dev/null"
+
+#
+# Defaults
+#
+# 20 Mb for the boot partition
+BOOT_SIZE=20
+# 5% for swap
+SWAP_RATIO=5
+
+# Cleanup after die()
+cleanup() {
+ debug "Syncing and unmounting devices"
+ # Unmount anything we mounted
+ unmount $ROOTFS_MNT || error "Failed to unmount $ROOTFS_MNT"
+ unmount $BOOTFS_MNT || error "Failed to unmount $BOOTFS_MNT"
+ unmount $HDDIMG_ROOTFS_MNT || error "Failed to unmount $HDDIMG_ROOTFS_MNT"
+ unmount $HDDIMG_MNT || error "Failed to unmount $HDDIMG_MNT"
+
+ # Remove the TMPDIR
+ debug "Removing temporary files"
+ if [ -d "$TMPDIR" ]; then
+ rm -rf $TMPDIR || error "Failed to remove $TMPDIR"
+ fi
+}
+
+trap 'die "Signal Received, Aborting..."' HUP INT TERM
+
+# Logging routines
+WARNINGS=0
+ERRORS=0
+CLEAR="$(tput sgr0)"
+INFO="$(tput bold)"
+RED="$(tput setaf 1)$(tput bold)"
+GREEN="$(tput setaf 2)$(tput bold)"
+YELLOW="$(tput setaf 3)$(tput bold)"
+info() {
+ echo "${INFO}$1${CLEAR}"
+}
+error() {
+ ERRORS=$((ERRORS+1))
+ echo "${RED}$1${CLEAR}"
+}
+warn() {
+ WARNINGS=$((WARNINGS+1))
+ echo "${YELLOW}$1${CLEAR}"
+}
+success() {
+ echo "${GREEN}$1${CLEAR}"
+}
+die() {
+ error "$1"
+ cleanup
+ exit 1
+}
+debug() {
+ if [ $DEBUG -eq 1 ]; then
+ echo "$1"
+ fi
+}
+
+usage() {
+ echo "Usage: $(basename $0) [-v] DEVICE HDDIMG TARGET_DEVICE"
+ echo " -v: Verbose debug"
+ echo " DEVICE: The device to write the image to, e.g. /dev/sdh"
+ echo " HDDIMG: The hddimg file to generate the efi disk from"
+ echo " TARGET_DEVICE: The device the target will boot from, e.g. /dev/mmcblk0"
+}
+
+image_details() {
+ IMG=$1
+ info "Image details"
+ echo " image: $(stat --printf '%N\n' $IMG)"
+ echo " size: $(stat -L --printf '%s bytes\n' $IMG)"
+ echo " modified: $(stat -L --printf '%y\n' $IMG)"
+ echo " type: $(file -L -b $IMG)"
+ echo ""
+}
+
+device_details() {
+ DEV=$1
+ BLOCK_SIZE=512
+
+ info "Device details"
+ echo " device: $DEVICE"
+ if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
+ echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)"
+ else
+ echo " vendor: UNKOWN"
+ fi
+ if [ -f "/sys/class/block/$DEV/device/model" ]; then
+ echo " model: $(cat /sys/class/block/$DEV/device/model)"
+ else
+ echo " model: UNKNOWN"
+ fi
+ if [ -f "/sys/class/block/$DEV/size" ]; then
+ echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
+ else
+ echo " size: UNKNOWN"
+ fi
+ echo ""
+}
+
+unmount_device() {
+ grep -q $DEVICE /proc/mounts
+ if [ $? -eq 0 ]; then
+ warn "$DEVICE listed in /proc/mounts, attempting to unmount"
+ umount $DEVICE* 2>/dev/null
+ return $?
+ fi
+ return 0
+}
+
+unmount() {
+ if [ "$1" = "" ] ; then
+ return 0
+ fi
+ grep -q $1 /proc/mounts
+ if [ $? -eq 0 ]; then
+ debug "Unmounting $1"
+ umount $1
+ return $?
+ fi
+ return 0
+}
+
+#
+# Parse and validate arguments
+#
+if [ $# -lt 3 ] || [ $# -gt 4 ]; then
+ if [ $# -eq 1 ]; then
+ AVAILABLE_DISK=`lsblk | grep "disk" | cut -f 1 -d " "`
+ X=0
+ for disk in `echo $AVAILABLE_DISK`; do
+ mounted=`lsblk /dev/$disk | awk {'print $7'} | sed "s/MOUNTPOINT//"`
+ if [ -z "$mounted" ]; then
+ UNMOUNTED_AVAILABLES="$UNMOUNTED_AVAILABLES /dev/$disk"
+ info "$X - /dev/$disk"
+ X=`expr $X + 1`
+ fi
+ done
+ if [ $X -eq 0 ]; then
+ die "No unmounted device found."
+ fi
+ read -p "Choose unmounted device number: " DISK_NUMBER
+ X=0
+ for line in `echo $UNMOUNTED_AVAILABLES`; do
+ if [ $DISK_NUMBER -eq $X ]; then
+ DISK_TO_BE_FLASHED=$line
+ break
+ else
+ X=`expr $X + 1`
+ fi
+ done
+ if [ -z "$DISK_TO_BE_FLASHED" ]; then
+ die "Option \"$DISK_NUMBER\" is invalid. Choose a valid option"
+ else
+ if [ -z `echo $DISK_TO_BE_FLASHED | grep "mmc"` ]; then
+ TARGET_TO_BE_BOOT="/dev/sda"
+ else
+ TARGET_TO_BE_BOOT="/dev/mmcblk0"
+ fi
+ fi
+ echo ""
+ echo "Choose a name of the device that will be boot from"
+ echo -n "Recommended name is: "
+ info "$TARGET_TO_BE_BOOT"
+ read -p "Is target device okay? [y/N]: " RESPONSE
+ if [ "$RESPONSE" != "y" ]; then
+ read -p "Choose target device name: " TARGET_TO_BE_BOOT
+ fi
+ echo ""
+ if [ -z "$TARGET_TO_BE_BOOT" ]; then
+ die "Error: choose a valid target name"
+ fi
+ else
+ usage
+ exit 1
+ fi
+fi
+
+if [ "$1" = "-v" ]; then
+ DEBUG=1
+ OUT="1"
+ shift
+fi
+
+if [ -z "$AVAILABLE_DISK" ]; then
+ DEVICE=$1
+ HDDIMG=$2
+ TARGET_DEVICE=$3
+else
+ DEVICE=$DISK_TO_BE_FLASHED
+ HDDIMG=$1
+ TARGET_DEVICE=$TARGET_TO_BE_BOOT
+fi
+
+LINK=$(readlink $DEVICE)
+if [ $? -eq 0 ]; then
+ DEVICE="$LINK"
+fi
+
+if [ ! -w "$DEVICE" ]; then
+ usage
+ if [ ! -e "${DEVICE}" ] ; then
+ die "Device $DEVICE cannot be found"
+ else
+ die "Device $DEVICE is not writable (need to run under sudo?)"
+ fi
+fi
+
+if [ ! -e "$HDDIMG" ]; then
+ usage
+ die "HDDIMG $HDDIMG does not exist"
+fi
+
+#
+# Ensure the hddimg is not mounted
+#
+unmount "$HDDIMG" || die "Failed to unmount $HDDIMG"
+
+#
+# Check if any $DEVICE partitions are mounted
+#
+unmount_device || die "Failed to unmount $DEVICE"
+
+#
+# Confirm device with user
+#
+image_details $HDDIMG
+device_details $(basename $DEVICE)
+echo -n "${INFO}Prepare EFI image on $DEVICE [y/N]?${CLEAR} "
+read RESPONSE
+if [ "$RESPONSE" != "y" ]; then
+ echo "Image creation aborted"
+ exit 0
+fi
+
+
+#
+# Prepare the temporary working space
+#
+TMPDIR=$(mktemp -d mkefidisk-XXX) || die "Failed to create temporary mounting directory."
+HDDIMG_MNT=$TMPDIR/hddimg
+HDDIMG_ROOTFS_MNT=$TMPDIR/hddimg_rootfs
+ROOTFS_MNT=$TMPDIR/rootfs
+BOOTFS_MNT=$TMPDIR/bootfs
+mkdir $HDDIMG_MNT || die "Failed to create $HDDIMG_MNT"
+mkdir $HDDIMG_ROOTFS_MNT || die "Failed to create $HDDIMG_ROOTFS_MNT"
+mkdir $ROOTFS_MNT || die "Failed to create $ROOTFS_MNT"
+mkdir $BOOTFS_MNT || die "Failed to create $BOOTFS_MNT"
+
+
+#
+# Partition $DEVICE
+#
+DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
+# If the device size is not reported there may not be a valid label
+if [ "$DEVICE_SIZE" = "" ] ; then
+ parted -s $DEVICE mklabel msdos || die "Failed to create MSDOS partition table"
+ DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
+fi
+SWAP_SIZE=$((DEVICE_SIZE*SWAP_RATIO/100))
+ROOTFS_SIZE=$((DEVICE_SIZE-BOOT_SIZE-SWAP_SIZE))
+ROOTFS_START=$((BOOT_SIZE))
+ROOTFS_END=$((ROOTFS_START+ROOTFS_SIZE))
+SWAP_START=$((ROOTFS_END))
+
+# MMC devices use a partition prefix character 'p'
+PART_PREFIX=""
+if [ ! "${DEVICE#/dev/mmcblk}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
+ PART_PREFIX="p"
+fi
+BOOTFS=$DEVICE${PART_PREFIX}1
+ROOTFS=$DEVICE${PART_PREFIX}2
+SWAP=$DEVICE${PART_PREFIX}3
+
+TARGET_PART_PREFIX=""
+if [ ! "${TARGET_DEVICE#/dev/mmcblk}" = "${TARGET_DEVICE}" ]; then
+ TARGET_PART_PREFIX="p"
+fi
+TARGET_ROOTFS=$TARGET_DEVICE${TARGET_PART_PREFIX}2
+TARGET_SWAP=$TARGET_DEVICE${TARGET_PART_PREFIX}3
+
+echo ""
+info "Boot partition size: $BOOT_SIZE MB ($BOOTFS)"
+info "ROOTFS partition size: $ROOTFS_SIZE MB ($ROOTFS)"
+info "Swap partition size: $SWAP_SIZE MB ($SWAP)"
+echo ""
+
+# Use MSDOS by default as GPT cannot be reliably distributed in disk image form
+# as it requires the backup table to be on the last block of the device, which
+# of course varies from device to device.
+
+info "Partitioning installation media ($DEVICE)"
+
+debug "Deleting partition table on $DEVICE"
+dd if=/dev/zero of=$DEVICE bs=512 count=2 >$OUT 2>&1 || die "Failed to zero beginning of $DEVICE"
+
+debug "Creating new partition table (MSDOS) on $DEVICE"
+parted -s $DEVICE mklabel msdos >$OUT 2>&1 || die "Failed to create MSDOS partition table"
+
+debug "Creating boot partition on $BOOTFS"
+parted -s $DEVICE mkpart primary 0% $BOOT_SIZE >$OUT 2>&1 || die "Failed to create BOOT partition"
+
+debug "Enabling boot flag on $BOOTFS"
+parted -s $DEVICE set 1 boot on >$OUT 2>&1 || die "Failed to enable boot flag"
+
+debug "Creating ROOTFS partition on $ROOTFS"
+parted -s $DEVICE mkpart primary $ROOTFS_START $ROOTFS_END >$OUT 2>&1 || die "Failed to create ROOTFS partition"
+
+debug "Creating swap partition on $SWAP"
+parted -s $DEVICE mkpart primary $SWAP_START 100% >$OUT 2>&1 || die "Failed to create SWAP partition"
+
+if [ $DEBUG -eq 1 ]; then
+ parted -s $DEVICE print
+fi
+
+
+#
+# Check if any $DEVICE partitions are mounted after partitioning
+#
+unmount_device || die "Failed to unmount $DEVICE partitions"
+
+
+#
+# Format $DEVICE partitions
+#
+info "Formatting partitions"
+debug "Formatting $BOOTFS as vfat"
+if [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
+ mkfs.vfat -I $BOOTFS -n "EFI" >$OUT 2>&1 || die "Failed to format $BOOTFS"
+else
+ mkfs.vfat $BOOTFS -n "EFI" >$OUT 2>&1 || die "Failed to format $BOOTFS"
+fi
+
+debug "Formatting $ROOTFS as ext3"
+mkfs.ext3 -F $ROOTFS -L "ROOT" >$OUT 2>&1 || die "Failed to format $ROOTFS"
+
+debug "Formatting swap partition ($SWAP)"
+mkswap $SWAP >$OUT 2>&1 || die "Failed to prepare swap"
+
+
+#
+# Installing to $DEVICE
+#
+debug "Mounting images and device in preparation for installation"
+mount -o ro,loop $HDDIMG $HDDIMG_MNT >$OUT 2>&1 || error "Failed to mount $HDDIMG"
+mount -o ro,loop $HDDIMG_MNT/rootfs.img $HDDIMG_ROOTFS_MNT >$OUT 2>&1 || error "Failed to mount rootfs.img"
+mount $ROOTFS $ROOTFS_MNT >$OUT 2>&1 || error "Failed to mount $ROOTFS on $ROOTFS_MNT"
+mount $BOOTFS $BOOTFS_MNT >$OUT 2>&1 || error "Failed to mount $BOOTFS on $BOOTFS_MNT"
+
+info "Preparing boot partition"
+EFIDIR="$BOOTFS_MNT/EFI/BOOT"
+cp $HDDIMG_MNT/vmlinuz $BOOTFS_MNT >$OUT 2>&1 || error "Failed to copy vmlinuz"
+# Copy the efi loader and configs (booti*.efi and grub.cfg if it exists)
+cp -r $HDDIMG_MNT/EFI $BOOTFS_MNT >$OUT 2>&1 || error "Failed to copy EFI dir"
+# Silently ignore a missing gummiboot loader dir (we might just be a GRUB image)
+cp -r $HDDIMG_MNT/loader $BOOTFS_MNT >$OUT 2>&1
+
+# Update the boot loaders configurations for an installed image
+# Remove any existing root= kernel parameters and:
+# o Add a root= parameter with the target rootfs
+# o Specify ro so fsck can be run during boot
+# o Specify rootwait in case the target media is an asyncronous block device
+# such as MMC or USB disks
+# o Specify "quiet" to minimize boot time when using slow serial consoles
+
+# Look for a GRUB installation
+GRUB_CFG="$EFIDIR/grub.cfg"
+if [ -e "$GRUB_CFG" ]; then
+ info "Configuring GRUB"
+ # Delete the install entry
+ sed -i "/menuentry 'install'/,/^}/d" $GRUB_CFG
+ # Delete the initrd lines
+ sed -i "/initrd /d" $GRUB_CFG
+ # Delete any LABEL= strings
+ sed -i "s/ LABEL=[^ ]*/ /" $GRUB_CFG
+
+ sed -i "s@ root=[^ ]*@ @" $GRUB_CFG
+ sed -i "s@vmlinuz @vmlinuz root=$TARGET_ROOTFS ro rootwait console=ttyS0 console=tty0 @" $GRUB_CFG
+fi
+
+# Look for a gummiboot installation
+GUMMI_ENTRIES="$BOOTFS_MNT/loader/entries"
+GUMMI_CFG="$GUMMI_ENTRIES/boot.conf"
+if [ -d "$GUMMI_ENTRIES" ]; then
+ info "Configuring Gummiboot"
+ # remove the install target if it exists
+ rm $GUMMI_ENTRIES/install.conf >$OUT 2>&1
+
+ if [ ! -e "$GUMMI_CFG" ]; then
+ echo "ERROR: $GUMMI_CFG not found"
+ fi
+
+ sed -i "/initrd /d" $GUMMI_CFG
+ sed -i "s@ root=[^ ]*@ @" $GUMMI_CFG
+ sed -i "s@options *LABEL=boot @options LABEL=Boot root=$TARGET_ROOTFS ro rootwait console=ttyS0 console=tty0 @" $GUMMI_CFG
+fi
+
+# Ensure we have at least one EFI bootloader configured
+if [ ! -e $GRUB_CFG ] && [ ! -e $GUMMI_CFG ]; then
+ die "No EFI bootloader configuration found"
+fi
+
+
+info "Copying ROOTFS files (this may take a while)"
+cp -a $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT >$OUT 2>&1 || die "Root FS copy failed"
+
+echo "$TARGET_SWAP swap swap defaults 0 0" >> $ROOTFS_MNT/etc/fstab
+
+# We dont want udev to mount our root device while we're booting...
+if [ -d $ROOTFS_MNT/etc/udev/ ] ; then
+ echo "$TARGET_DEVICE" >> $ROOTFS_MNT/etc/udev/mount.blacklist
+fi
+
+# Add startup.nsh script for automated boot
+echo "fs0:\EFI\BOOT\bootx64.efi" > $BOOTFS_MNT/startup.nsh
+
+
+# Call cleanup to unmount devices and images and remove the TMPDIR
+cleanup
+
+echo ""
+if [ $WARNINGS -ne 0 ] && [ $ERRORS -eq 0 ]; then
+ echo "${YELLOW}Installation completed with warnings${CLEAR}"
+ echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
+elif [ $ERRORS -ne 0 ]; then
+ echo "${RED}Installation encountered errors${CLEAR}"
+ echo "${RED}Errors: $ERRORS${CLEAR}"
+ echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
+else
+ success "Installation completed successfully"
+fi
+echo ""
diff --git a/scripts/contrib/python/generate-manifest-2.7.py b/scripts/contrib/python/generate-manifest-2.7.py
new file mode 100755
index 0000000..d93c943
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-2.7.py
@@ -0,0 +1,397 @@
+#!/usr/bin/env python
+
+# generate Python Manifest for the OpenEmbedded build system
+# (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# (C) 2007 Jeremy Laine
+# licensed under MIT, see COPYING.MIT
+#
+# June 22, 2011 -- Mark Hatle <mark.hatle@windriver.com>
+# * Updated to no longer generate special -dbg package, instead use the
+# single system -dbg
+# * Update version with ".1" to indicate this change
+
+import os
+import sys
+import time
+
+VERSION = "2.7.2"
+
+__author__ = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
+__version__ = "20110222.2"
+
+class MakefileMaker:
+
+ def __init__( self, outfile ):
+ """initialize"""
+ self.packages = {}
+ self.targetPrefix = "${libdir}/python%s/" % VERSION[:3]
+ self.output = outfile
+ self.out( """
+# WARNING: This file is AUTO GENERATED: Manual edits will be lost next time I regenerate the file.
+# Generator: '%s' Version %s (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# Visit the Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy
+""" % ( sys.argv[0], __version__ ) )
+
+ #
+ # helper functions
+ #
+
+ def out( self, data ):
+ """print a line to the output file"""
+ self.output.write( "%s\n" % data )
+
+ def setPrefix( self, targetPrefix ):
+ """set a file prefix for addPackage files"""
+ self.targetPrefix = targetPrefix
+
+ def doProlog( self ):
+ self.out( """ """ )
+ self.out( "" )
+
+ def addPackage( self, name, description, dependencies, filenames ):
+ """add a package to the Makefile"""
+ if type( filenames ) == type( "" ):
+ filenames = filenames.split()
+ fullFilenames = []
+ for filename in filenames:
+ if filename[0] != "$":
+ fullFilenames.append( "%s%s" % ( self.targetPrefix, filename ) )
+ else:
+ fullFilenames.append( filename )
+ self.packages[name] = description, dependencies, fullFilenames
+
+ def doBody( self ):
+ """generate body of Makefile"""
+
+ global VERSION
+
+ #
+ # generate provides line
+ #
+
+ provideLine = 'PROVIDES+="'
+ for name in sorted(self.packages):
+ provideLine += "%s " % name
+ provideLine += '"'
+
+ self.out( provideLine )
+ self.out( "" )
+
+ #
+ # generate package line
+ #
+
+ packageLine = 'PACKAGES="${PN}-dbg '
+ for name in sorted(self.packages):
+ if name.startswith("${PN}-distutils"):
+ if name == "${PN}-distutils":
+ packageLine += "%s-staticdev %s " % (name, name)
+ elif name != '${PN}-dbg':
+ packageLine += "%s " % name
+ packageLine += '${PN}-modules"'
+
+ self.out( packageLine )
+ self.out( "" )
+
+ #
+ # generate package variables
+ #
+
+ for name, data in sorted(self.packages.iteritems()):
+ desc, deps, files = data
+
+ #
+ # write out the description, revision and dependencies
+ #
+ self.out( 'SUMMARY_%s="%s"' % ( name, desc ) )
+ self.out( 'RDEPENDS_%s="%s"' % ( name, deps ) )
+
+ line = 'FILES_%s="' % name
+
+ #
+ # check which directories to make in the temporary directory
+ #
+
+ dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead.
+ for target in files:
+ dirset[os.path.dirname( target )] = True
+
+ #
+ # generate which files to copy for the target (-dfR because whole directories are also allowed)
+ #
+
+ for target in files:
+ line += "%s " % target
+
+ line += '"'
+ self.out( line )
+ self.out( "" )
+
+ self.out( 'SUMMARY_${PN}-modules="All Python modules"' )
+ line = 'RDEPENDS_${PN}-modules="'
+
+ for name, data in sorted(self.packages.iteritems()):
+ if name not in ['${PN}-dev', '${PN}-distutils-staticdev']:
+ line += "%s " % name
+
+ self.out( "%s \"" % line )
+ self.out( 'ALLOW_EMPTY_${PN}-modules = "1"' )
+
+ def doEpilog( self ):
+ self.out( """""" )
+ self.out( "" )
+
+ def make( self ):
+ self.doProlog()
+ self.doBody()
+ self.doEpilog()
+
+if __name__ == "__main__":
+
+ if len( sys.argv ) > 1:
+ try:
+ os.unlink(sys.argv[1])
+ except Exception:
+ sys.exc_clear()
+ outfile = file( sys.argv[1], "w" )
+ else:
+ outfile = sys.stdout
+
+ m = MakefileMaker( outfile )
+
+ # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies!
+ # Parameters: revision, name, description, dependencies, filenames
+ #
+
+ m.addPackage( "${PN}-core", "Python interpreter and core modules", "${PN}-lang ${PN}-re",
+ "__future__.* _abcoll.* abc.* ast.* copy.* copy_reg.* ConfigParser.* " +
+ "genericpath.* getopt.* linecache.* new.* " +
+ "os.* posixpath.* struct.* " +
+ "warnings.* site.* stat.* " +
+ "UserDict.* UserList.* UserString.* " +
+ "lib-dynload/binascii.so lib-dynload/_struct.so lib-dynload/time.so " +
+ "lib-dynload/xreadlines.so types.* platform.* ${bindir}/python* " +
+ "_weakrefset.* sysconfig.* _sysconfigdata.* config/Makefile " +
+ "${includedir}/python${PYTHON_MAJMIN}/pyconfig*.h " +
+ "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py ")
+
+ m.addPackage( "${PN}-dev", "Python development package", "${PN}-core",
+ "${includedir} " +
+ "${libdir}/lib*${SOLIBSDEV} " +
+ "${libdir}/*.la " +
+ "${libdir}/*.a " +
+ "${libdir}/*.o " +
+ "${libdir}/pkgconfig " +
+ "${base_libdir}/*.a " +
+ "${base_libdir}/*.o " +
+ "${datadir}/aclocal " +
+ "${datadir}/pkgconfig " )
+
+ m.addPackage( "${PN}-2to3", "Python automated Python 2 to 3 code translator", "${PN}-core",
+ "${bindir}/2to3 lib2to3" ) # package
+
+ m.addPackage( "${PN}-idle", "Python Integrated Development Environment", "${PN}-core ${PN}-tkinter",
+ "${bindir}/idle idlelib" ) # package
+
+ m.addPackage( "${PN}-pydoc", "Python interactive help support", "${PN}-core ${PN}-lang ${PN}-stringold ${PN}-re",
+ "${bindir}/pydoc pydoc.* pydoc_data" )
+
+ m.addPackage( "${PN}-smtpd", "Python Simple Mail Transport Daemon", "${PN}-core ${PN}-netserver ${PN}-email ${PN}-mime",
+ "${bindir}/smtpd.* smtpd.*" )
+
+ m.addPackage( "${PN}-audio", "Python Audio Handling", "${PN}-core",
+ "wave.* chunk.* sndhdr.* lib-dynload/ossaudiodev.so lib-dynload/audioop.so audiodev.* sunaudio.* sunau.* toaiff.*" )
+
+ m.addPackage( "${PN}-bsddb", "Python bindings for the Berkeley Database", "${PN}-core",
+ "bsddb lib-dynload/_bsddb.so" ) # package
+
+ m.addPackage( "${PN}-codecs", "Python codecs, encodings & i18n support", "${PN}-core ${PN}-lang",
+ "codecs.* encodings gettext.* locale.* lib-dynload/_locale.so lib-dynload/_codecs* lib-dynload/_multibytecodec.so lib-dynload/unicodedata.so stringprep.* xdrlib.*" )
+
+ m.addPackage( "${PN}-compile", "Python bytecode compilation support", "${PN}-core",
+ "py_compile.* compileall.*" )
+
+ m.addPackage( "${PN}-compiler", "Python compiler support", "${PN}-core",
+ "compiler" ) # package
+
+ m.addPackage( "${PN}-compression", "Python high-level compression support", "${PN}-core ${PN}-zlib",
+ "gzip.* zipfile.* tarfile.* lib-dynload/bz2.so" )
+
+ m.addPackage( "${PN}-crypt", "Python basic cryptographic and hashing support", "${PN}-core",
+ "hashlib.* md5.* sha.* lib-dynload/crypt.so lib-dynload/_hashlib.so lib-dynload/_sha256.so lib-dynload/_sha512.so" )
+
+ m.addPackage( "${PN}-textutils", "Python option parsing, text wrapping and CSV support", "${PN}-core ${PN}-io ${PN}-re ${PN}-stringold",
+ "lib-dynload/_csv.so csv.* optparse.* textwrap.*" )
+
+ m.addPackage( "${PN}-curses", "Python curses support", "${PN}-core",
+ "curses lib-dynload/_curses.so lib-dynload/_curses_panel.so" ) # directory + low level module
+
+ m.addPackage( "${PN}-ctypes", "Python C types support", "${PN}-core",
+ "ctypes lib-dynload/_ctypes.so lib-dynload/_ctypes_test.so" ) # directory + low level module
+
+ m.addPackage( "${PN}-datetime", "Python calendar and time support", "${PN}-core ${PN}-codecs",
+ "_strptime.* calendar.* lib-dynload/datetime.so" )
+
+ m.addPackage( "${PN}-db", "Python file-based database support", "${PN}-core",
+ "anydbm.* dumbdbm.* whichdb.* " )
+
+ m.addPackage( "${PN}-debugger", "Python debugger", "${PN}-core ${PN}-io ${PN}-lang ${PN}-re ${PN}-stringold ${PN}-shell ${PN}-pprint",
+ "bdb.* pdb.*" )
+
+ m.addPackage( "${PN}-difflib", "Python helpers for computing deltas between objects", "${PN}-lang ${PN}-re",
+ "difflib.*" )
+
+ m.addPackage( "${PN}-distutils-staticdev", "Python distribution utilities (static libraries)", "${PN}-distutils",
+ "config/lib*.a" ) # package
+
+ m.addPackage( "${PN}-distutils", "Python Distribution Utilities", "${PN}-core ${PN}-email",
+ "config distutils" ) # package
+
+ m.addPackage( "${PN}-doctest", "Python framework for running examples in docstrings", "${PN}-core ${PN}-lang ${PN}-io ${PN}-re ${PN}-unittest ${PN}-debugger ${PN}-difflib",
+ "doctest.*" )
+
+ m.addPackage( "${PN}-email", "Python email support", "${PN}-core ${PN}-io ${PN}-re ${PN}-mime ${PN}-audio ${PN}-image ${PN}-netclient",
+ "imaplib.* email" ) # package
+
+ m.addPackage( "${PN}-fcntl", "Python's fcntl interface", "${PN}-core",
+ "lib-dynload/fcntl.so" )
+
+ m.addPackage( "${PN}-hotshot", "Python hotshot performance profiler", "${PN}-core",
+ "hotshot lib-dynload/_hotshot.so" )
+
+ m.addPackage( "${PN}-html", "Python HTML processing support", "${PN}-core",
+ "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* HTMLParser.* " )
+
+ m.addPackage( "${PN}-importlib", "Python import implementation library", "${PN}-core",
+ "importlib" )
+
+ m.addPackage( "${PN}-gdbm", "Python GNU database support", "${PN}-core",
+ "lib-dynload/gdbm.so" )
+
+ m.addPackage( "${PN}-image", "Python graphical image handling", "${PN}-core",
+ "colorsys.* imghdr.* lib-dynload/imageop.so lib-dynload/rgbimg.so" )
+
+ m.addPackage( "${PN}-io", "Python low-level I/O", "${PN}-core ${PN}-math ${PN}-textutils ${PN}-netclient ${PN}-contextlib",
+ "lib-dynload/_socket.so lib-dynload/_io.so lib-dynload/_ssl.so lib-dynload/select.so lib-dynload/termios.so lib-dynload/cStringIO.so " +
+ "pipes.* socket.* ssl.* tempfile.* StringIO.* io.* _pyio.*" )
+
+ m.addPackage( "${PN}-json", "Python JSON support", "${PN}-core ${PN}-math ${PN}-re ${PN}-codecs",
+ "json lib-dynload/_json.so" ) # package
+
+ m.addPackage( "${PN}-lang", "Python low-level language support", "${PN}-core",
+ "lib-dynload/_bisect.so lib-dynload/_collections.so lib-dynload/_heapq.so lib-dynload/_weakref.so lib-dynload/_functools.so " +
+ "lib-dynload/array.so lib-dynload/itertools.so lib-dynload/operator.so lib-dynload/parser.so " +
+ "atexit.* bisect.* code.* codeop.* collections.* dis.* functools.* heapq.* inspect.* keyword.* opcode.* symbol.* repr.* token.* " +
+ "tokenize.* traceback.* weakref.*" )
+
+ m.addPackage( "${PN}-logging", "Python logging support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-stringold",
+ "logging" ) # package
+
+ m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+ "mailbox.*" )
+
+ m.addPackage( "${PN}-math", "Python math support", "${PN}-core ${PN}-crypt",
+ "lib-dynload/cmath.so lib-dynload/math.so lib-dynload/_random.so random.* sets.*" )
+
+ m.addPackage( "${PN}-mime", "Python MIME handling APIs", "${PN}-core ${PN}-io",
+ "mimetools.* uu.* quopri.* rfc822.* MimeWriter.*" )
+
+ m.addPackage( "${PN}-mmap", "Python memory-mapped file support", "${PN}-core ${PN}-io",
+ "lib-dynload/mmap.so " )
+
+ m.addPackage( "${PN}-multiprocessing", "Python multiprocessing support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-threading ${PN}-ctypes ${PN}-mmap",
+ "lib-dynload/_multiprocessing.so multiprocessing" ) # package
+
+ m.addPackage( "${PN}-netclient", "Python Internet Protocol clients", "${PN}-core ${PN}-crypt ${PN}-datetime ${PN}-io ${PN}-lang ${PN}-logging ${PN}-mime",
+ "*Cookie*.* " +
+ "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.* uuid.* rfc822.* mimetools.*" )
+
+ m.addPackage( "${PN}-netserver", "Python Internet Protocol servers", "${PN}-core ${PN}-netclient ${PN}-shell ${PN}-threading",
+ "cgi.* *HTTPServer.* SocketServer.*" )
+
+ m.addPackage( "${PN}-numbers", "Python number APIs", "${PN}-core ${PN}-lang ${PN}-re",
+ "decimal.* fractions.* numbers.*" )
+
+ m.addPackage( "${PN}-pickle", "Python serialisation/persistence support", "${PN}-core ${PN}-codecs ${PN}-io ${PN}-re",
+ "pickle.* shelve.* lib-dynload/cPickle.so pickletools.*" )
+
+ m.addPackage( "${PN}-pkgutil", "Python package extension utility support", "${PN}-core",
+ "pkgutil.*")
+
+ m.addPackage( "${PN}-plistlib", "Generate and parse Mac OS X .plist files", "${PN}-core ${PN}-datetime ${PN}-io",
+ "plistlib.*")
+
+ m.addPackage( "${PN}-pprint", "Python pretty-print support", "${PN}-core ${PN}-io",
+ "pprint.*" )
+
+ m.addPackage( "${PN}-profile", "Python basic performance profiling support", "${PN}-core ${PN}-textutils",
+ "profile.* pstats.* cProfile.* lib-dynload/_lsprof.so" )
+
+ m.addPackage( "${PN}-re", "Python Regular Expression APIs", "${PN}-core",
+ "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin
+
+ m.addPackage( "${PN}-readline", "Python readline support", "${PN}-core",
+ "lib-dynload/readline.so rlcompleter.*" )
+
+ m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core",
+ "lib-dynload/resource.so" )
+
+ m.addPackage( "${PN}-shell", "Python shell-like functionality", "${PN}-core ${PN}-re",
+ "cmd.* commands.* dircache.* fnmatch.* glob.* popen2.* shlex.* shutil.*" )
+
+ m.addPackage( "${PN}-robotparser", "Python robots.txt parser", "${PN}-core ${PN}-netclient",
+ "robotparser.*")
+
+ m.addPackage( "${PN}-subprocess", "Python subprocess support", "${PN}-core ${PN}-io ${PN}-re ${PN}-fcntl ${PN}-pickle",
+ "subprocess.*" )
+
+ m.addPackage( "${PN}-sqlite3", "Python Sqlite3 database support", "${PN}-core ${PN}-datetime ${PN}-lang ${PN}-crypt ${PN}-io ${PN}-threading ${PN}-zlib",
+ "lib-dynload/_sqlite3.so sqlite3/dbapi2.* sqlite3/__init__.* sqlite3/dump.*" )
+
+ m.addPackage( "${PN}-sqlite3-tests", "Python Sqlite3 database support tests", "${PN}-core ${PN}-sqlite3",
+ "sqlite3/test" )
+
+ m.addPackage( "${PN}-stringold", "Python string APIs [deprecated]", "${PN}-core ${PN}-re",
+ "lib-dynload/strop.so string.* stringold.*" )
+
+ m.addPackage( "${PN}-syslog", "Python syslog interface", "${PN}-core",
+ "lib-dynload/syslog.so" )
+
+ m.addPackage( "${PN}-terminal", "Python terminal controlling support", "${PN}-core ${PN}-io",
+ "pty.* tty.*" )
+
+ m.addPackage( "${PN}-tests", "Python tests", "${PN}-core",
+ "test" ) # package
+
+ m.addPackage( "${PN}-threading", "Python threading & synchronization support", "${PN}-core ${PN}-lang",
+ "_threading_local.* dummy_thread.* dummy_threading.* mutex.* threading.* Queue.*" )
+
+ m.addPackage( "${PN}-tkinter", "Python Tcl/Tk bindings", "${PN}-core",
+ "lib-dynload/_tkinter.so lib-tk" ) # package
+
+ m.addPackage( "${PN}-unittest", "Python unit testing framework", "${PN}-core ${PN}-stringold ${PN}-lang ${PN}-io ${PN}-difflib ${PN}-pprint ${PN}-shell",
+ "unittest/" )
+
+ m.addPackage( "${PN}-unixadmin", "Python Unix administration support", "${PN}-core",
+ "lib-dynload/nis.so lib-dynload/grp.so lib-dynload/pwd.so getpass.*" )
+
+ m.addPackage( "${PN}-xml", "Python basic XML support", "${PN}-core ${PN}-re",
+ "lib-dynload/_elementtree.so lib-dynload/pyexpat.so xml xmllib.*" ) # package
+
+ m.addPackage( "${PN}-xmlrpc", "Python XML-RPC support", "${PN}-core ${PN}-xml ${PN}-netserver ${PN}-lang",
+ "xmlrpclib.* SimpleXMLRPCServer.* DocXMLRPCServer.*" )
+
+ m.addPackage( "${PN}-zlib", "Python zlib compression support", "${PN}-core",
+ "lib-dynload/zlib.so" )
+
+ m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+ "mailbox.*" )
+
+ m.addPackage( "${PN}-argparse", "Python command line argument parser", "${PN}-core ${PN}-codecs ${PN}-textutils",
+ "argparse.*" )
+
+ m.addPackage( "${PN}-contextlib", "Python utilities for with-statement" +
+ "contexts.", "${PN}-core",
+ "${libdir}/python${PYTHON_MAJMIN}/contextlib.*" )
+
+ m.make()
diff --git a/scripts/contrib/python/generate-manifest-3.5.py b/scripts/contrib/python/generate-manifest-3.5.py
new file mode 100755
index 0000000..eac493a
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-3.5.py
@@ -0,0 +1,396 @@
+#!/usr/bin/env python
+
+# generate Python Manifest for the OpenEmbedded build system
+# (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# (C) 2007 Jeremy Laine
+# licensed under MIT, see COPYING.MIT
+#
+# June 22, 2011 -- Mark Hatle <mark.hatle@windriver.com>
+# * Updated to no longer generate special -dbg package, instead use the
+# single system -dbg
+# * Update version with ".1" to indicate this change
+#
+# 2014 Khem Raj <raj.khem@gmail.com>
+# Added python3 support
+#
+import os
+import sys
+import time
+
+VERSION = "3.5.0"
+
+__author__ = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
+__version__ = "20140131"
+
+class MakefileMaker:
+
+ def __init__( self, outfile ):
+ """initialize"""
+ self.packages = {}
+ self.targetPrefix = "${libdir}/python%s/" % VERSION[:3]
+ self.output = outfile
+ self.out( """
+# WARNING: This file is AUTO GENERATED: Manual edits will be lost next time I regenerate the file.
+# Generator: '%s' Version %s (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# Visit the Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy
+""" % ( sys.argv[0], __version__ ) )
+
+ #
+ # helper functions
+ #
+
+ def out( self, data ):
+ """print a line to the output file"""
+ self.output.write( "%s\n" % data )
+
+ def setPrefix( self, targetPrefix ):
+ """set a file prefix for addPackage files"""
+ self.targetPrefix = targetPrefix
+
+ def doProlog( self ):
+ self.out( """ """ )
+ self.out( "" )
+
+ def addPackage( self, name, description, dependencies, filenames ):
+ """add a package to the Makefile"""
+ if type( filenames ) == type( "" ):
+ filenames = filenames.split()
+ fullFilenames = []
+ for filename in filenames:
+ if filename[0] != "$":
+ fullFilenames.append( "%s%s" % ( self.targetPrefix, filename ) )
+ else:
+ fullFilenames.append( filename )
+ self.packages[name] = description, dependencies, fullFilenames
+
+ def doBody( self ):
+ """generate body of Makefile"""
+
+ global VERSION
+
+ #
+ # generate provides line
+ #
+
+ provideLine = 'PROVIDES+="'
+ for name in sorted(self.packages):
+ provideLine += "%s " % name
+ provideLine += '"'
+
+ self.out( provideLine )
+ self.out( "" )
+
+ #
+ # generate package line
+ #
+
+ packageLine = 'PACKAGES="${PN}-dbg '
+ for name in sorted(self.packages):
+ if name.startswith("${PN}-distutils"):
+ if name == "${PN}-distutils":
+ packageLine += "%s-staticdev %s " % (name, name)
+ elif name != '${PN}-dbg':
+ packageLine += "%s " % name
+ packageLine += '${PN}-modules"'
+
+ self.out( packageLine )
+ self.out( "" )
+
+ #
+ # generate package variables
+ #
+
+ for name, data in sorted(self.packages.iteritems()):
+ desc, deps, files = data
+
+ #
+ # write out the description, revision and dependencies
+ #
+ self.out( 'SUMMARY_%s="%s"' % ( name, desc ) )
+ self.out( 'RDEPENDS_%s="%s"' % ( name, deps ) )
+
+ line = 'FILES_%s="' % name
+
+ #
+ # check which directories to make in the temporary directory
+ #
+
+ dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead.
+ for target in files:
+ dirset[os.path.dirname( target )] = True
+
+ #
+ # generate which files to copy for the target (-dfR because whole directories are also allowed)
+ #
+
+ for target in files:
+ line += "%s " % target
+
+ line += '"'
+ self.out( line )
+ self.out( "" )
+
+ self.out( 'SUMMARY_${PN}-modules="All Python modules"' )
+ line = 'RDEPENDS_${PN}-modules="'
+
+ for name, data in sorted(self.packages.iteritems()):
+ if name not in ['${PN}-dev', '${PN}-distutils-staticdev']:
+ line += "%s " % name
+
+ self.out( "%s \"" % line )
+ self.out( 'ALLOW_EMPTY_${PN}-modules = "1"' )
+
+ def doEpilog( self ):
+ self.out( """""" )
+ self.out( "" )
+
+ def make( self ):
+ self.doProlog()
+ self.doBody()
+ self.doEpilog()
+
+if __name__ == "__main__":
+
+ if len( sys.argv ) > 1:
+ try:
+ os.unlink(sys.argv[1])
+ except Exception:
+ sys.exc_clear()
+ outfile = file( sys.argv[1], "w" )
+ else:
+ outfile = sys.stdout
+
+ m = MakefileMaker( outfile )
+
+ # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies!
+ # Parameters: revision, name, description, dependencies, filenames
+ #
+
+ m.addPackage( "${PN}-core", "Python interpreter and core modules", "${PN}-lang ${PN}-re ${PN}-reprlib ${PN}-codecs ${PN}-io ${PN}-math",
+ "__future__.* _abcoll.* abc.* ast.* copy.* copyreg.* ConfigParser.* " +
+ "genericpath.* getopt.* linecache.* new.* " +
+ "os.* posixpath.* struct.* " +
+ "warnings.* site.* stat.* " +
+ "UserDict.* UserList.* UserString.* " +
+ "lib-dynload/binascii.*.so lib-dynload/_struct.*.so lib-dynload/time.*.so " +
+ "lib-dynload/xreadlines.*.so types.* platform.* ${bindir}/python* " +
+ "_weakrefset.* sysconfig.* _sysconfigdata.* config/Makefile " +
+ "${includedir}/python${PYTHON_BINABI}/pyconfig*.h " +
+ "${libdir}/python${PYTHON_MAJMIN}/collections " +
+ "${libdir}/python${PYTHON_MAJMIN}/_collections_abc.* " +
+ "${libdir}/python${PYTHON_MAJMIN}/_sitebuiltins.* " +
+ "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py ")
+
+ m.addPackage( "${PN}-dev", "Python development package", "${PN}-core",
+ "${includedir} " +
+ "${libdir}/lib*${SOLIBSDEV} " +
+ "${libdir}/*.la " +
+ "${libdir}/*.a " +
+ "${libdir}/*.o " +
+ "${libdir}/pkgconfig " +
+ "${base_libdir}/*.a " +
+ "${base_libdir}/*.o " +
+ "${datadir}/aclocal " +
+ "${datadir}/pkgconfig " )
+
+ m.addPackage( "${PN}-2to3", "Python automated Python 2 to 3 code translator", "${PN}-core",
+ "lib2to3" ) # package
+
+ m.addPackage( "${PN}-idle", "Python Integrated Development Environment", "${PN}-core ${PN}-tkinter",
+ "${bindir}/idle idlelib" ) # package
+
+ m.addPackage( "${PN}-pydoc", "Python interactive help support", "${PN}-core ${PN}-lang ${PN}-stringold ${PN}-re",
+ "${bindir}/pydoc pydoc.* pydoc_data" )
+
+ m.addPackage( "${PN}-smtpd", "Python Simple Mail Transport Daemon", "${PN}-core ${PN}-netserver ${PN}-email ${PN}-mime",
+ "${bindir}/smtpd.* smtpd.*" )
+
+ m.addPackage( "${PN}-audio", "Python Audio Handling", "${PN}-core",
+ "wave.* chunk.* sndhdr.* lib-dynload/ossaudiodev.*.so lib-dynload/audioop.*.so audiodev.* sunaudio.* sunau.* toaiff.*" )
+
+ m.addPackage( "${PN}-argparse", "Python command line argument parser", "${PN}-core ${PN}-codecs ${PN}-textutils",
+ "argparse.*" )
+
+ m.addPackage( "${PN}-asyncio", "Python Asynchronous I/O, event loop, coroutines and tasks", "${PN}-core",
+ "asyncio" )
+
+ m.addPackage( "${PN}-codecs", "Python codecs, encodings & i18n support", "${PN}-core ${PN}-lang",
+ "codecs.* encodings gettext.* locale.* lib-dynload/_locale.*.so lib-dynload/_codecs* lib-dynload/_multibytecodec.*.so lib-dynload/unicodedata.*.so stringprep.* xdrlib.*" )
+
+ m.addPackage( "${PN}-compile", "Python bytecode compilation support", "${PN}-core",
+ "py_compile.* compileall.*" )
+
+ m.addPackage( "${PN}-compression", "Python high-level compression support", "${PN}-core ${PN}-codecs ${PN}-importlib ${PN}-threading ${PN}-shell",
+ "gzip.* zipfile.* tarfile.* lib-dynload/bz2.*.so" )
+
+ m.addPackage( "${PN}-crypt", "Python basic cryptographic and hashing support", "${PN}-core",
+ "hashlib.* md5.* sha.* lib-dynload/crypt.*.so lib-dynload/_hashlib.*.so lib-dynload/_sha256.*.so lib-dynload/_sha512.*.so" )
+
+ m.addPackage( "${PN}-textutils", "Python option parsing, text wrapping and CSV support", "${PN}-core ${PN}-io ${PN}-re ${PN}-stringold",
+ "lib-dynload/_csv.*.so csv.* optparse.* textwrap.*" )
+
+ m.addPackage( "${PN}-curses", "Python curses support", "${PN}-core",
+ "curses lib-dynload/_curses.*.so lib-dynload/_curses_panel.*.so" ) # directory + low level module
+
+ m.addPackage( "${PN}-ctypes", "Python C types support", "${PN}-core",
+ "ctypes lib-dynload/_ctypes.*.so lib-dynload/_ctypes_test.*.so" ) # directory + low level module
+
+ m.addPackage( "${PN}-datetime", "Python calendar and time support", "${PN}-core ${PN}-codecs",
+ "_strptime.* calendar.* lib-dynload/datetime.*.so" )
+
+ m.addPackage( "${PN}-db", "Python file-based database support", "${PN}-core",
+ "anydbm.* dumbdbm.* whichdb.* dbm lib-dynload/_dbm.*.so" )
+
+ m.addPackage( "${PN}-debugger", "Python debugger", "${PN}-core ${PN}-io ${PN}-lang ${PN}-re ${PN}-stringold ${PN}-shell ${PN}-pprint ${PN}-importlib ${PN}-pkgutil",
+ "bdb.* pdb.*" )
+
+ m.addPackage( "${PN}-difflib", "Python helpers for computing deltas between objects", "${PN}-lang ${PN}-re",
+ "difflib.*" )
+
+ m.addPackage( "${PN}-distutils-staticdev", "Python distribution utilities (static libraries)", "${PN}-distutils",
+ "config/lib*.a" ) # package
+
+ m.addPackage( "${PN}-distutils", "Python Distribution Utilities", "${PN}-core ${PN}-email",
+ "config distutils" ) # package
+
+ m.addPackage( "${PN}-doctest", "Python framework for running examples in docstrings", "${PN}-core ${PN}-lang ${PN}-io ${PN}-re ${PN}-unittest ${PN}-debugger ${PN}-difflib",
+ "doctest.*" )
+
+ m.addPackage( "${PN}-email", "Python email support", "${PN}-core ${PN}-io ${PN}-re ${PN}-mime ${PN}-audio ${PN}-image ${PN}-netclient",
+ "imaplib.* email" ) # package
+
+ m.addPackage( "${PN}-enum", "Python support for enumerations", "${PN}-core",
+ "enum.*" )
+
+ m.addPackage( "${PN}-fcntl", "Python's fcntl interface", "${PN}-core",
+ "lib-dynload/fcntl.*.so" )
+
+ m.addPackage( "${PN}-html", "Python HTML processing support", "${PN}-core",
+ "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* HTMLParser.* " )
+
+ m.addPackage( "${PN}-importlib", "Python import implementation library", "${PN}-core ${PN}-lang",
+ "importlib" )
+
+ m.addPackage( "${PN}-gdbm", "Python GNU database support", "${PN}-core",
+ "lib-dynload/_gdbm.*.so" )
+
+ m.addPackage( "${PN}-image", "Python graphical image handling", "${PN}-core",
+ "colorsys.* imghdr.* lib-dynload/imageop.*.so lib-dynload/rgbimg.*.so" )
+
+ m.addPackage( "${PN}-io", "Python low-level I/O", "${PN}-core ${PN}-math",
+ "lib-dynload/_socket.*.so lib-dynload/_io.*.so lib-dynload/_ssl.*.so lib-dynload/select.*.so lib-dynload/termios.*.so lib-dynload/cStringIO.*.so " +
+ "pipes.* socket.* ssl.* tempfile.* StringIO.* io.* _pyio.*" )
+
+ m.addPackage( "${PN}-json", "Python JSON support", "${PN}-core ${PN}-math ${PN}-re",
+ "json lib-dynload/_json.*.so" ) # package
+
+ m.addPackage( "${PN}-lang", "Python low-level language support", "${PN}-core",
+ "lib-dynload/_bisect.*.so lib-dynload/_collections.*.so lib-dynload/_heapq.*.so lib-dynload/_weakref.*.so lib-dynload/_functools.*.so " +
+ "lib-dynload/array.*.so lib-dynload/itertools.*.so lib-dynload/operator.*.so lib-dynload/parser.*.so " +
+ "atexit.* bisect.* code.* codeop.* collections.* _collections_abc.* contextlib.* dis.* functools.* heapq.* inspect.* keyword.* opcode.* operator.* symbol.* repr.* token.* " +
+ "tokenize.* traceback.* weakref.*" )
+
+ m.addPackage( "${PN}-logging", "Python logging support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-stringold",
+ "logging" ) # package
+
+ m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+ "mailbox.*" )
+
+ m.addPackage( "${PN}-math", "Python math support", "${PN}-core",
+ "lib-dynload/cmath.*.so lib-dynload/math.*.so lib-dynload/_random.*.so random.* sets.*" )
+
+ m.addPackage( "${PN}-mime", "Python MIME handling APIs", "${PN}-core ${PN}-io",
+ "mimetools.* uu.* quopri.* rfc822.* MimeWriter.*" )
+
+ m.addPackage( "${PN}-mmap", "Python memory-mapped file support", "${PN}-core ${PN}-io",
+ "lib-dynload/mmap.*.so " )
+
+ m.addPackage( "${PN}-multiprocessing", "Python multiprocessing support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-threading ${PN}-ctypes ${PN}-mmap",
+ "lib-dynload/_multiprocessing.*.so multiprocessing" ) # package
+
+ m.addPackage( "${PN}-netclient", "Python Internet Protocol clients", "${PN}-core ${PN}-crypt ${PN}-datetime ${PN}-io ${PN}-lang ${PN}-logging ${PN}-mime",
+ "*Cookie*.* " +
+ "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib uuid.* rfc822.* mimetools.*" )
+
+ m.addPackage( "${PN}-netserver", "Python Internet Protocol servers", "${PN}-core ${PN}-netclient ${PN}-shell ${PN}-threading",
+ "cgi.* *HTTPServer.* SocketServer.*" )
+
+ m.addPackage( "${PN}-numbers", "Python number APIs", "${PN}-core ${PN}-lang ${PN}-re",
+ "decimal.* fractions.* numbers.*" )
+
+ m.addPackage( "${PN}-pickle", "Python serialisation/persistence support", "${PN}-core ${PN}-codecs ${PN}-io ${PN}-re",
+ "pickle.* shelve.* lib-dynload/cPickle.*.so pickletools.*" )
+
+ m.addPackage( "${PN}-pkgutil", "Python package extension utility support", "${PN}-core",
+ "pkgutil.*")
+
+ m.addPackage( "${PN}-pprint", "Python pretty-print support", "${PN}-core ${PN}-io",
+ "pprint.*" )
+
+ m.addPackage( "${PN}-profile", "Python basic performance profiling support", "${PN}-core ${PN}-textutils",
+ "profile.* pstats.* cProfile.* lib-dynload/_lsprof.*.so" )
+
+ m.addPackage( "${PN}-re", "Python Regular Expression APIs", "${PN}-core",
+ "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin
+
+ m.addPackage( "${PN}-readline", "Python readline support", "${PN}-core",
+ "lib-dynload/readline.*.so rlcompleter.*" )
+
+ m.addPackage( "${PN}-reprlib", "Python alternate repr() implementation", "${PN}-core",
+ "reprlib.py" )
+
+ m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core",
+ "lib-dynload/resource.*.so" )
+
+ m.addPackage( "${PN}-selectors", "Python High-level I/O multiplexing", "${PN}-core",
+ "selectors.*" )
+
+ m.addPackage( "${PN}-shell", "Python shell-like functionality", "${PN}-core ${PN}-re",
+ "cmd.* commands.* dircache.* fnmatch.* glob.* popen2.* shlex.* shutil.*" )
+
+ m.addPackage( "${PN}-subprocess", "Python subprocess support", "${PN}-core ${PN}-io ${PN}-re ${PN}-fcntl ${PN}-pickle ${PN}-signal ${PN}-selectors",
+ "subprocess.*" )
+
+ m.addPackage( "${PN}-signal", "Python set handlers for asynchronous events support", "${PN}-core",
+ "signal.*" )
+
+ m.addPackage( "${PN}-sqlite3", "Python Sqlite3 database support", "${PN}-core ${PN}-datetime ${PN}-lang ${PN}-crypt ${PN}-io ${PN}-threading",
+ "lib-dynload/_sqlite3.*.so sqlite3/dbapi2.* sqlite3/__init__.* sqlite3/dump.*" )
+
+ m.addPackage( "${PN}-sqlite3-tests", "Python Sqlite3 database support tests", "${PN}-core ${PN}-sqlite3",
+ "sqlite3/test" )
+
+ m.addPackage( "${PN}-stringold", "Python string APIs [deprecated]", "${PN}-core ${PN}-re",
+ "lib-dynload/strop.*.so string.* stringold.*" )
+
+ m.addPackage( "${PN}-syslog", "Python syslog interface", "${PN}-core",
+ "lib-dynload/syslog.*.so" )
+
+ m.addPackage( "${PN}-terminal", "Python terminal controlling support", "${PN}-core ${PN}-io",
+ "pty.* tty.*" )
+
+ m.addPackage( "${PN}-tests", "Python tests", "${PN}-core",
+ "test" ) # package
+
+ m.addPackage( "${PN}-threading", "Python threading & synchronization support", "${PN}-core ${PN}-lang",
+ "_threading_local.* dummy_thread.* dummy_threading.* mutex.* threading.* queue.*" )
+
+ m.addPackage( "${PN}-tkinter", "Python Tcl/Tk bindings", "${PN}-core",
+ "lib-dynload/_tkinter.*.so lib-tk tkinter" ) # package
+
+ m.addPackage( "${PN}-unittest", "Python unit testing framework", "${PN}-core ${PN}-stringold ${PN}-lang ${PN}-io ${PN}-difflib ${PN}-pprint ${PN}-shell",
+ "unittest/" )
+
+ m.addPackage( "${PN}-unixadmin", "Python Unix administration support", "${PN}-core",
+ "lib-dynload/nis.*.so lib-dynload/grp.*.so lib-dynload/pwd.*.so getpass.*" )
+
+ m.addPackage( "${PN}-xml", "Python basic XML support", "${PN}-core ${PN}-re",
+ "lib-dynload/_elementtree.*.so lib-dynload/pyexpat.*.so xml xmllib.*" ) # package
+
+ m.addPackage( "${PN}-xmlrpc", "Python XML-RPC support", "${PN}-core ${PN}-xml ${PN}-netserver ${PN}-lang",
+ "xmlrpclib.* SimpleXMLRPCServer.* DocXMLRPCServer.* xmlrpc" )
+
+ m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+ "mailbox.*" )
+
+ m.make()
diff --git a/scripts/contrib/serdevtry b/scripts/contrib/serdevtry
new file mode 100755
index 0000000..74bd7b7
--- /dev/null
+++ b/scripts/contrib/serdevtry
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# Copyright (C) 2014 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+if [ "$1" = "" -o "$1" = "--help" ] ; then
+ echo "Usage: $0 <serial terminal command>"
+ echo
+ echo "Simple script to handle maintaining a terminal for serial devices that"
+ echo "disappear when a device is powered down or reset, such as the USB"
+ echo "serial console on the original BeagleBone (white version)."
+ echo
+ echo "e.g. $0 picocom -b 115200 /dev/ttyUSB0"
+ echo
+ exit
+fi
+
+args="$@"
+DEVICE=""
+while [ "$1" != "" ]; do
+ case "$1" in
+ /dev/*)
+ DEVICE=$1
+ break;;
+ esac
+ shift
+done
+
+if [ "$DEVICE" != "" ] ; then
+ while true; do
+ if [ ! -e $DEVICE ] ; then
+ echo "serdevtry: waiting for $DEVICE to exist..."
+ while [ ! -e $DEVICE ]; do
+ sleep 0.1
+ done
+ fi
+ if [ ! -w $DEVICE ] ; then
+ # Sometimes (presumably because of a race with udev) we get to
+ # the device before its permissions have been set up
+ RETRYNUM=0
+ while [ ! -w $DEVICE ]; do
+ if [ "$RETRYNUM" = "2" ] ; then
+ echo "Device $DEVICE exists but is not writable!"
+ exit 1
+ fi
+ RETRYNUM=$((RETRYNUM+1))
+ sleep 0.1
+ done
+ fi
+ $args
+ if [ -e $DEVICE ] ; then
+ break
+ fi
+ done
+else
+ echo "Unable to determine device node from command: $args"
+ exit 1
+fi
+
diff --git a/scripts/contrib/test_build_time.sh b/scripts/contrib/test_build_time.sh
new file mode 100755
index 0000000..9e5725a
--- /dev/null
+++ b/scripts/contrib/test_build_time.sh
@@ -0,0 +1,237 @@
+#!/bin/bash
+
+# Build performance regression test script
+#
+# Copyright 2011 Intel Corporation
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# DESCRIPTION
+# This script is intended to be used in conjunction with "git bisect run"
+# in order to find regressions in build time, however it can also be used
+# independently. It cleans out the build output directories, runs a
+# specified worker script (an example is test_build_time_worker.sh) under
+# TIME(1), logs the results to TEST_LOGDIR (default /tmp) and returns a
+# value telling "git bisect run" whether the build time is good (under
+# the specified threshold) or bad (over it). There is also a tolerance
+# option but it is not particularly useful as it only subtracts the
+# tolerance from the given threshold and uses it as the actual threshold.
+#
+# It is also capable of taking a file listing git revision hashes to be
+# test-applied to the repository in order to get past build failures that
+# would otherwise cause certain revisions to have to be skipped; if a
+# revision does not apply cleanly then the script assumes it does not
+# need to be applied and ignores it.
+#
+# Please see the help output (syntax below) for some important setup
+# instructions.
+#
+# AUTHORS
+# Paul Eggleton <paul.eggleton@linux.intel.com>
+
+
+syntax() {
+ echo "syntax: $0 <script> <time> <tolerance> [patchrevlist]"
+ echo ""
+ echo " script - worker script file (if in current dir, prefix with ./)"
+ echo " time - time threshold (in seconds, suffix m for minutes)"
+ echo " tolerance - tolerance (in seconds, suffix m for minutes or % for"
+ echo " percentage, can be 0)"
+ echo " patchrevlist - optional file listing revisions to apply as patches on top"
+ echo ""
+ echo "You must set TEST_BUILDDIR to point to a previously created build directory,"
+ echo "however please note that this script will wipe out the TMPDIR defined in"
+ echo "TEST_BUILDDIR/conf/local.conf as part of its initial setup (as well as your"
+ echo "~/.ccache)"
+ echo ""
+ echo "To get rid of the sudo prompt, please add the following line to /etc/sudoers"
+ echo "(use 'visudo' to edit this; also it is assumed that the user you are running"
+ echo "as is a member of the 'wheel' group):"
+ echo ""
+ echo "%wheel ALL=(ALL) NOPASSWD: /sbin/sysctl -w vm.drop_caches=[1-3]"
+ echo ""
+ echo "Note: it is recommended that you disable crond and any other process that"
+ echo "may cause significant CPU or I/O usage during build performance tests."
+}
+
+# Note - we exit with 250 here because that will tell git bisect run that
+# something bad happened and stop
+if [ "$1" = "" ] ; then
+ syntax
+ exit 250
+fi
+
+if [ "$2" = "" ] ; then
+ syntax
+ exit 250
+fi
+
+if [ "$3" = "" ] ; then
+ syntax
+ exit 250
+fi
+
+if ! [[ "$2" =~ ^[0-9][0-9m.]*$ ]] ; then
+ echo "'$2' is not a valid number for threshold"
+ exit 250
+fi
+
+if ! [[ "$3" =~ ^[0-9][0-9m.%]*$ ]] ; then
+ echo "'$3' is not a valid number for tolerance"
+ exit 250
+fi
+
+if [ "$TEST_BUILDDIR" = "" ] ; then
+ echo "Please set TEST_BUILDDIR to a previously created build directory"
+ exit 250
+fi
+
+if [ ! -d "$TEST_BUILDDIR" ] ; then
+ echo "TEST_BUILDDIR $TEST_BUILDDIR not found"
+ exit 250
+fi
+
+git diff --quiet
+if [ $? != 0 ] ; then
+ echo "Working tree is dirty, cannot proceed"
+ exit 251
+fi
+
+if [ "$BB_ENV_EXTRAWHITE" != "" ] ; then
+ echo "WARNING: you are running after sourcing the build environment script, this is not recommended"
+fi
+
+runscript=$1
+timethreshold=$2
+tolerance=$3
+
+if [ "$4" != "" ] ; then
+ patchrevlist=`cat $4`
+else
+ patchrevlist=""
+fi
+
+if [[ timethreshold == *m* ]] ; then
+ timethreshold=`echo $timethreshold | sed s/m/*60/ | bc`
+fi
+
+if [[ $tolerance == *m* ]] ; then
+ tolerance=`echo $tolerance | sed s/m/*60/ | bc`
+elif [[ $tolerance == *%* ]] ; then
+ tolerance=`echo $tolerance | sed s/%//`
+ tolerance=`echo "scale = 2; (($tolerance * $timethreshold) / 100)" | bc`
+fi
+
+tmpdir=`grep "^TMPDIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/TMPDIR[ \t]*=[ \t\?]*"//' -e 's/"//'`
+if [ "x$tmpdir" = "x" ]; then
+ echo "Unable to determine TMPDIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
+ exit 250
+fi
+sstatedir=`grep "^SSTATE_DIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/SSTATE_DIR[ \t\?]*=[ \t]*"//' -e 's/"//'`
+if [ "x$sstatedir" = "x" ]; then
+ echo "Unable to determine SSTATE_DIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
+ exit 250
+fi
+
+if [ `expr length $tmpdir` -lt 4 ] ; then
+ echo "TMPDIR $tmpdir is less than 4 characters, bailing out"
+ exit 250
+fi
+
+if [ `expr length $sstatedir` -lt 4 ] ; then
+ echo "SSTATE_DIR $sstatedir is less than 4 characters, bailing out"
+ exit 250
+fi
+
+echo -n "About to wipe out TMPDIR $tmpdir, press Ctrl+C to break out... "
+for i in 9 8 7 6 5 4 3 2 1
+do
+ echo -ne "\x08$i"
+ sleep 1
+done
+echo
+
+pushd . > /dev/null
+
+rm -f pseudodone
+echo "Removing TMPDIR $tmpdir..."
+rm -rf $tmpdir
+echo "Removing TMPDIR $tmpdir-*libc..."
+rm -rf $tmpdir-*libc
+echo "Removing SSTATE_DIR $sstatedir..."
+rm -rf $sstatedir
+echo "Removing ~/.ccache..."
+rm -rf ~/.ccache
+
+echo "Syncing..."
+sync
+sync
+echo "Dropping VM cache..."
+#echo 3 > /proc/sys/vm/drop_caches
+sudo /sbin/sysctl -w vm.drop_caches=3 > /dev/null
+
+if [ "$TEST_LOGDIR" = "" ] ; then
+ logdir="/tmp"
+else
+ logdir="$TEST_LOGDIR"
+fi
+rev=`git rev-parse HEAD`
+logfile="$logdir/timelog_$rev.log"
+echo -n > $logfile
+
+gitroot=`git rev-parse --show-toplevel`
+cd $gitroot
+for patchrev in $patchrevlist ; do
+ echo "Applying $patchrev"
+ patchfile=`mktemp`
+ git show $patchrev > $patchfile
+ git apply --check $patchfile &> /dev/null
+ if [ $? != 0 ] ; then
+ echo " ... patch does not apply without errors, ignoring"
+ else
+ echo "Applied $patchrev" >> $logfile
+ git apply $patchfile &> /dev/null
+ fi
+ rm $patchfile
+done
+
+sync
+echo "Quiescing for 5s..."
+sleep 5
+
+echo "Running $runscript at $rev..."
+timeoutfile=`mktemp`
+/usr/bin/time -o $timeoutfile -f "%e\nreal\t%E\nuser\t%Us\nsys\t%Ss\nmaxm\t%Mk" $runscript 2>&1 | tee -a $logfile
+exitstatus=$PIPESTATUS
+
+git reset --hard HEAD > /dev/null
+popd > /dev/null
+
+timeresult=`head -n1 $timeoutfile`
+cat $timeoutfile | tee -a $logfile
+rm $timeoutfile
+
+if [ $exitstatus != 0 ] ; then
+ # Build failed, exit with 125 to tell git bisect run to skip this rev
+ echo "*** Build failed (exit code $exitstatus), skipping..." | tee -a $logfile
+ exit 125
+fi
+
+ret=`echo "scale = 2; $timeresult > $timethreshold - $tolerance" | bc`
+echo "Returning $ret" | tee -a $logfile
+exit $ret
+
diff --git a/scripts/contrib/test_build_time_worker.sh b/scripts/contrib/test_build_time_worker.sh
new file mode 100755
index 0000000..8e20a9e
--- /dev/null
+++ b/scripts/contrib/test_build_time_worker.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# This is an example script to be used in conjunction with test_build_time.sh
+
+if [ "$TEST_BUILDDIR" = "" ] ; then
+ echo "TEST_BUILDDIR is not set"
+ exit 1
+fi
+
+buildsubdir=`basename $TEST_BUILDDIR`
+if [ ! -d $buildsubdir ] ; then
+ echo "Unable to find build subdir $buildsubdir in current directory"
+ exit 1
+fi
+
+if [ -f oe-init-build-env ] ; then
+ . ./oe-init-build-env $buildsubdir
+elif [ -f poky-init-build-env ] ; then
+ . ./poky-init-build-env $buildsubdir
+else
+ echo "Unable to find build environment setup script"
+ exit 1
+fi
+
+if [ -f ../meta/recipes-sato/images/core-image-sato.bb ] ; then
+ target="core-image-sato"
+else
+ target="poky-image-sato"
+fi
+
+echo "Build started at `date "+%Y-%m-%d %H:%M:%S"`"
+echo "bitbake $target"
+bitbake $target
+ret=$?
+echo "Build finished at `date "+%Y-%m-%d %H:%M:%S"`"
+exit $ret
+
diff --git a/scripts/contrib/verify-homepage.py b/scripts/contrib/verify-homepage.py
new file mode 100755
index 0000000..265ff65
--- /dev/null
+++ b/scripts/contrib/verify-homepage.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+# This script can be used to verify HOMEPAGE values for all recipes in
+# the current configuration.
+# The result is influenced by network environment, since the timeout of connect url is 5 seconds as default.
+
+import sys
+import os
+import subprocess
+import urllib2
+
+
+# Allow importing scripts/lib modules
+scripts_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + '/..')
+lib_path = scripts_path + '/lib'
+sys.path = sys.path + [lib_path]
+import scriptpath
+import scriptutils
+
+# Allow importing bitbake modules
+bitbakepath = scriptpath.add_bitbake_lib_path()
+
+import bb.tinfoil
+
+logger = scriptutils.logger_create('verify_homepage')
+
+def wgetHomepage(pn, homepage):
+ result = subprocess.call('wget ' + '-q -T 5 -t 1 --spider ' + homepage, shell = True)
+ if result:
+ logger.warn("%s: failed to verify HOMEPAGE: %s " % (pn, homepage))
+ return 1
+ else:
+ return 0
+
+def verifyHomepage(bbhandler):
+ pkg_pn = bbhandler.cooker.recipecache.pkg_pn
+ pnlist = sorted(pkg_pn)
+ count = 0
+ checked = []
+ for pn in pnlist:
+ for fn in pkg_pn[pn]:
+ # There's no point checking multiple BBCLASSEXTENDed variants of the same recipe
+ realfn, _ = bb.cache.Cache.virtualfn2realfn(fn)
+ if realfn in checked:
+ continue
+ data = bb.cache.Cache.loadDataFull(realfn, bbhandler.cooker.collection.get_file_appends(realfn), bbhandler.config_data)
+ homepage = data.getVar("HOMEPAGE", True)
+ if homepage:
+ try:
+ urllib2.urlopen(homepage, timeout=5)
+ except Exception:
+ count = count + wgetHomepage(os.path.basename(realfn), homepage)
+ checked.append(realfn)
+ return count
+
+if __name__=='__main__':
+ bbhandler = bb.tinfoil.Tinfoil()
+ bbhandler.prepare()
+ logger.info("Start verifying HOMEPAGE:")
+ failcount = verifyHomepage(bbhandler)
+ logger.info("Finished verifying HOMEPAGE.")
+ logger.info("Summary: %s failed" % failcount)