Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
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..cdd7885
--- /dev/null
+++ b/scripts/contrib/build-perf-test.sh
@@ -0,0 +1,369 @@
+#!/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"
+bboutput="$OUTDIR/bitbake.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
+
+bbtime () {
+    local arg="$@"
+    log "   Timing: bitbake ${arg}"
+
+    if [ $verbose -eq 0 ]; then 
+        /usr/bin/time -v -o $resultsfile bitbake ${arg} >> $bboutput
+    else
+        /usr/bin/time -v -o $resultsfile bitbake ${arg}
+    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}"    
+}
+
+#we don't time bitbake here
+bbnotime () {
+    local arg="$@"
+    log "   Running: bitbake ${arg}"
+    if [ $verbose -eq 0 ]; then
+        bitbake ${arg} >> $bboutput
+    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
+}
+
+
+
+# RUN!
+
+test1_p1
+test1_p2
+test1_p3
+test2
+test3
+
+# 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/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..55f72b0
--- /dev/null
+++ b/scripts/contrib/mkefidisk.sh
@@ -0,0 +1,403 @@
+#!/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
+	usage
+	exit 1
+fi
+
+if [ "$1" = "-v" ]; then
+	DEBUG=1
+	OUT="1"
+	shift
+fi
+
+DEVICE=$1
+HDDIMG=$2
+TARGET_DEVICE=$3
+
+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 loop $HDDIMG $HDDIMG_MNT >$OUT 2>&1 || error "Failed to mount $HDDIMG"
+mount -o 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 quiet @" $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 quiet @" $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
+
+
+# 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..936522e
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-2.7.py
@@ -0,0 +1,398 @@
+#!/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.* 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",
+    "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.*" )
+
+    # FIXME consider adding to some higher level package
+    m.addPackage( "${PN}-elementtree", "Python elementree", "${PN}-core",
+    "lib-dynload/_elementtree.so" )
+
+    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}-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}-elementtree ${PN}-re",
+    "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.4.py b/scripts/contrib/python/generate-manifest-3.4.py
new file mode 100755
index 0000000..06eecdc
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-3.4.py
@@ -0,0 +1,388 @@
+#!/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.4.2"
+
+__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.* 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}-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",
+    "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",
+    "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",
+    "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.*" )
+
+    # FIXME consider adding to some higher level package
+    m.addPackage( "${PN}-elementtree", "Python elementree", "${PN}-core",
+    "lib-dynload/_elementtree.*.so" )
+
+    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}-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",
+    "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.* 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",
+    "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}-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",
+    "subprocess.*" )
+
+    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}-elementtree ${PN}-re",
+    "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..86cc82b
--- /dev/null
+++ b/scripts/contrib/verify-homepage.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+# This script is used for verify HOMEPAGE.
+# 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
+
+def search_bitbakepath():
+    bitbakepath = ""
+
+    # Search path to bitbake lib dir in order to load bb modules
+    if os.path.exists(os.path.join(os.path.dirname(sys.argv[0]), '../../bitbake/lib/bb')):
+        bitbakepath = os.path.join(os.path.dirname(sys.argv[0]), '../../bitbake/lib')
+        bitbakepath = os.path.abspath(bitbakepath)
+    else:
+        # Look for bitbake/bin dir in PATH
+        for pth in os.environ['PATH'].split(':'):
+            if os.path.exists(os.path.join(pth, '../lib/bb')):
+                bitbakepath = os.path.abspath(os.path.join(pth, '../lib'))
+                break
+        if not bitbakepath:
+            sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
+            sys.exit(1)
+    return bitbakepath
+
+# For importing the following modules
+sys.path.insert(0, search_bitbakepath())
+import bb.tinfoil
+
+def wgetHomepage(pn, homepage):
+    result = subprocess.call('wget ' + '-q -T 5 -t 1 --spider ' + homepage, shell = True)
+    if result:
+        bb.warn("Failed to verify HOMEPAGE (%s) of %s" % (homepage, pn))
+        return 1
+    else:
+        return 0
+
+def verifyHomepage(bbhandler):
+    pkg_pn = bbhandler.cooker.recipecache.pkg_pn
+    pnlist = sorted(pkg_pn)
+    count = 0
+    for pn in pnlist:
+        fn = pkg_pn[pn].pop()
+        data = bb.cache.Cache.loadDataFull(fn, bbhandler.cooker.collection.get_file_appends(fn), bbhandler.config_data)
+        homepage = data.getVar("HOMEPAGE")
+        if homepage:
+            try:
+                urllib2.urlopen(homepage, timeout=5)
+            except Exception:
+                count = count + wgetHomepage(pn, homepage)
+    return count
+
+if __name__=='__main__':
+    failcount = 0
+    bbhandler = bb.tinfoil.Tinfoil()
+    bbhandler.prepare()
+    print "Start to verify HOMEPAGE:"
+    failcount = verifyHomepage(bbhandler)
+    print "finish to verify HOMEPAGE."
+    print "Summary: %s failed" % failcount