diff --git a/scripts/lib/recipetool/__init__.py b/scripts/lib/recipetool/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/recipetool/__init__.py
diff --git a/scripts/lib/recipetool/append.py b/scripts/lib/recipetool/append.py
new file mode 100644
index 0000000..7fe4115
--- /dev/null
+++ b/scripts/lib/recipetool/append.py
@@ -0,0 +1,469 @@
+# Recipe creation tool - append plugin
+#
+# Copyright (C) 2015 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os
+import argparse
+import glob
+import fnmatch
+import re
+import subprocess
+import logging
+import stat
+import shutil
+import scriptutils
+import errno
+from collections import defaultdict
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+# FIXME guessing when we don't have pkgdata?
+# FIXME mode to create patch rather than directly substitute
+
+class InvalidTargetFileError(Exception):
+    pass
+
+def find_target_file(targetpath, d, pkglist=None):
+    """Find the recipe installing the specified target path, optionally limited to a select list of packages"""
+    import json
+
+    pkgdata_dir = d.getVar('PKGDATA_DIR', True)
+
+    # The mix between /etc and ${sysconfdir} here may look odd, but it is just
+    # being consistent with usage elsewhere
+    invalidtargets = {'${sysconfdir}/version': '${sysconfdir}/version is written out at image creation time',
+                      '/etc/timestamp': '/etc/timestamp is written out at image creation time',
+                      '/dev/*': '/dev is handled by udev (or equivalent) and the kernel (devtmpfs)',
+                      '/etc/passwd': '/etc/passwd should be managed through the useradd and extrausers classes',
+                      '/etc/group': '/etc/group should be managed through the useradd and extrausers classes',
+                      '/etc/shadow': '/etc/shadow should be managed through the useradd and extrausers classes',
+                      '/etc/gshadow': '/etc/gshadow should be managed through the useradd and extrausers classes',
+                      '${sysconfdir}/hostname': '${sysconfdir}/hostname contents should be set by setting hostname_pn-base-files = "value" in configuration',}
+
+    for pthspec, message in invalidtargets.iteritems():
+        if fnmatch.fnmatchcase(targetpath, d.expand(pthspec)):
+            raise InvalidTargetFileError(d.expand(message))
+
+    targetpath_re = re.compile(r'\s+(\$D)?%s(\s|$)' % targetpath)
+
+    recipes = defaultdict(list)
+    for root, dirs, files in os.walk(os.path.join(pkgdata_dir, 'runtime')):
+        if pkglist:
+            filelist = pkglist
+        else:
+            filelist = files
+        for fn in filelist:
+            pkgdatafile = os.path.join(root, fn)
+            if pkglist and not os.path.exists(pkgdatafile):
+                continue
+            with open(pkgdatafile, 'r') as f:
+                pn = ''
+                # This does assume that PN comes before other values, but that's a fairly safe assumption
+                for line in f:
+                    if line.startswith('PN:'):
+                        pn = line.split(':', 1)[1].strip()
+                    elif line.startswith('FILES_INFO:'):
+                        val = line.split(':', 1)[1].strip()
+                        dictval = json.loads(val)
+                        for fullpth in dictval.keys():
+                            if fnmatch.fnmatchcase(fullpth, targetpath):
+                                recipes[targetpath].append(pn)
+                    elif line.startswith('pkg_preinst_') or line.startswith('pkg_postinst_'):
+                        scriptval = line.split(':', 1)[1].strip().decode('string_escape')
+                        if 'update-alternatives --install %s ' % targetpath in scriptval:
+                            recipes[targetpath].append('?%s' % pn)
+                        elif targetpath_re.search(scriptval):
+                            recipes[targetpath].append('!%s' % pn)
+    return recipes
+
+def _get_recipe_file(cooker, pn):
+    import oe.recipeutils
+    recipefile = oe.recipeutils.pn_to_recipe(cooker, pn)
+    if not recipefile:
+        skipreasons = oe.recipeutils.get_unavailable_reasons(cooker, pn)
+        if skipreasons:
+            logger.error('\n'.join(skipreasons))
+        else:
+            logger.error("Unable to find any recipe file matching %s" % pn)
+    return recipefile
+
+def _parse_recipe(pn, tinfoil):
+    import oe.recipeutils
+    recipefile = _get_recipe_file(tinfoil.cooker, pn)
+    if not recipefile:
+        # Error already logged
+        return None
+    append_files = tinfoil.cooker.collection.get_file_appends(recipefile)
+    rd = oe.recipeutils.parse_recipe(recipefile, append_files,
+                                    tinfoil.config_data)
+    return rd
+
+def determine_file_source(targetpath, rd):
+    """Assuming we know a file came from a specific recipe, figure out exactly where it came from"""
+    import oe.recipeutils
+
+    # See if it's in do_install for the recipe
+    workdir = rd.getVar('WORKDIR', True)
+    src_uri = rd.getVar('SRC_URI', True)
+    srcfile = ''
+    modpatches = []
+    elements = check_do_install(rd, targetpath)
+    if elements:
+        logger.debug('do_install line:\n%s' % ' '.join(elements))
+        srcpath = get_source_path(elements)
+        logger.debug('source path: %s' % srcpath)
+        if not srcpath.startswith('/'):
+            # Handle non-absolute path
+            srcpath = os.path.abspath(os.path.join(rd.getVarFlag('do_install', 'dirs', True).split()[-1], srcpath))
+        if srcpath.startswith(workdir):
+            # OK, now we have the source file name, look for it in SRC_URI
+            workdirfile = os.path.relpath(srcpath, workdir)
+            # FIXME this is where we ought to have some code in the fetcher, because this is naive
+            for item in src_uri.split():
+                localpath = bb.fetch2.localpath(item, rd)
+                # Source path specified in do_install might be a glob
+                if fnmatch.fnmatch(os.path.basename(localpath), workdirfile):
+                    srcfile = 'file://%s' % localpath
+                elif '/' in workdirfile:
+                    if item == 'file://%s' % workdirfile:
+                        srcfile = 'file://%s' % localpath
+
+        # Check patches
+        srcpatches = []
+        patchedfiles = oe.recipeutils.get_recipe_patched_files(rd)
+        for patch, filelist in patchedfiles.iteritems():
+            for fileitem in filelist:
+                if fileitem[0] == srcpath:
+                    srcpatches.append((patch, fileitem[1]))
+        if srcpatches:
+            addpatch = None
+            for patch in srcpatches:
+                if patch[1] == 'A':
+                    addpatch = patch[0]
+                else:
+                    modpatches.append(patch[0])
+            if addpatch:
+                srcfile = 'patch://%s' % addpatch
+
+    return (srcfile, elements, modpatches)
+
+def get_source_path(cmdelements):
+    """Find the source path specified within a command"""
+    command = cmdelements[0]
+    if command in ['install', 'cp']:
+        helptext = subprocess.check_output('LC_ALL=C %s --help' % command, shell=True)
+        argopts = ''
+        argopt_line_re = re.compile('^-([a-zA-Z0-9]), --[a-z-]+=')
+        for line in helptext.splitlines():
+            line = line.lstrip()
+            res = argopt_line_re.search(line)
+            if res:
+                argopts += res.group(1)
+        if not argopts:
+            # Fallback
+            if command == 'install':
+                argopts = 'gmoSt'
+            elif command == 'cp':
+                argopts = 't'
+            else:
+                raise Exception('No fallback arguments for command %s' % command)
+
+        skipnext = False
+        for elem in cmdelements[1:-1]:
+            if elem.startswith('-'):
+                if len(elem) > 1 and elem[1] in argopts:
+                    skipnext = True
+                continue
+            if skipnext:
+                skipnext = False
+                continue
+            return elem
+    else:
+        raise Exception('get_source_path: no handling for command "%s"')
+
+def get_func_deps(func, d):
+    """Find the function dependencies of a shell function"""
+    deps = bb.codeparser.ShellParser(func, logger).parse_shell(d.getVar(func, True))
+    deps |= set((d.getVarFlag(func, "vardeps", True) or "").split())
+    funcdeps = []
+    for dep in deps:
+        if d.getVarFlag(dep, 'func', True):
+            funcdeps.append(dep)
+    return funcdeps
+
+def check_do_install(rd, targetpath):
+    """Look at do_install for a command that installs/copies the specified target path"""
+    instpath = os.path.abspath(os.path.join(rd.getVar('D', True), targetpath.lstrip('/')))
+    do_install = rd.getVar('do_install', True)
+    # Handle where do_install calls other functions (somewhat crudely, but good enough for this purpose)
+    deps = get_func_deps('do_install', rd)
+    for dep in deps:
+        do_install = do_install.replace(dep, rd.getVar(dep, True))
+
+    # Look backwards through do_install as we want to catch where a later line (perhaps
+    # from a bbappend) is writing over the top
+    for line in reversed(do_install.splitlines()):
+        line = line.strip()
+        if (line.startswith('install ') and ' -m' in line) or line.startswith('cp '):
+            elements = line.split()
+            destpath = os.path.abspath(elements[-1])
+            if destpath == instpath:
+                return elements
+            elif destpath.rstrip('/') == os.path.dirname(instpath):
+                # FIXME this doesn't take recursive copy into account; unsure if it's practical to do so
+                srcpath = get_source_path(elements)
+                if fnmatch.fnmatchcase(os.path.basename(instpath), os.path.basename(srcpath)):
+                    return elements
+    return None
+
+
+def appendfile(args):
+    import oe.recipeutils
+
+    stdout = ''
+    try:
+        (stdout, _) = bb.process.run('LANG=C file -b %s' % args.newfile, shell=True)
+        if 'cannot open' in stdout:
+            raise bb.process.ExecutionError(stdout)
+    except bb.process.ExecutionError as err:
+        logger.debug('file command returned error: %s' % err)
+        stdout = ''
+    if stdout:
+        logger.debug('file command output: %s' % stdout.rstrip())
+        if ('executable' in stdout and not 'shell script' in stdout) or 'shared object' in stdout:
+            logger.warn('This file looks like it is a binary or otherwise the output of compilation. If it is, you should consider building it properly instead of substituting a binary file directly.')
+
+    if args.recipe:
+        recipes = {args.targetpath: [args.recipe],}
+    else:
+        try:
+            recipes = find_target_file(args.targetpath, tinfoil.config_data)
+        except InvalidTargetFileError as e:
+            logger.error('%s cannot be handled by this tool: %s' % (args.targetpath, e))
+            return 1
+        if not recipes:
+            logger.error('Unable to find any package producing path %s - this may be because the recipe packaging it has not been built yet' % args.targetpath)
+            return 1
+
+    alternative_pns = []
+    postinst_pns = []
+
+    selectpn = None
+    for targetpath, pnlist in recipes.iteritems():
+        for pn in pnlist:
+            if pn.startswith('?'):
+                alternative_pns.append(pn[1:])
+            elif pn.startswith('!'):
+                postinst_pns.append(pn[1:])
+            elif selectpn:
+                # hit here with multilibs
+                continue
+            else:
+                selectpn = pn
+
+    if not selectpn and len(alternative_pns) == 1:
+        selectpn = alternative_pns[0]
+        logger.error('File %s is an alternative possibly provided by recipe %s but seemingly no other, selecting it by default - you should double check other recipes' % (args.targetpath, selectpn))
+
+    if selectpn:
+        logger.debug('Selecting recipe %s for file %s' % (selectpn, args.targetpath))
+        if postinst_pns:
+            logger.warn('%s be modified by postinstall scripts for the following recipes:\n  %s\nThis may or may not be an issue depending on what modifications these postinstall scripts make.' % (args.targetpath, '\n  '.join(postinst_pns)))
+        rd = _parse_recipe(selectpn, tinfoil)
+        if not rd:
+            # Error message already shown
+            return 1
+        sourcefile, instelements, modpatches = determine_file_source(args.targetpath, rd)
+        sourcepath = None
+        if sourcefile:
+            sourcetype, sourcepath = sourcefile.split('://', 1)
+            logger.debug('Original source file is %s (%s)' % (sourcepath, sourcetype))
+            if sourcetype == 'patch':
+                logger.warn('File %s is added by the patch %s - you may need to remove or replace this patch in order to replace the file.' % (args.targetpath, sourcepath))
+                sourcepath = None
+        else:
+            logger.debug('Unable to determine source file, proceeding anyway')
+        if modpatches:
+            logger.warn('File %s is modified by the following patches:\n  %s' % (args.targetpath, '\n  '.join(modpatches)))
+
+        if instelements and sourcepath:
+            install = None
+        else:
+            # Auto-determine permissions
+            # Check destination
+            binpaths = '${bindir}:${sbindir}:${base_bindir}:${base_sbindir}:${libexecdir}:${sysconfdir}/init.d'
+            perms = '0644'
+            if os.path.abspath(os.path.dirname(args.targetpath)) in rd.expand(binpaths).split(':'):
+                # File is going into a directory normally reserved for executables, so it should be executable
+                perms = '0755'
+            else:
+                # Check source
+                st = os.stat(args.newfile)
+                if st.st_mode & stat.S_IXUSR:
+                    perms = '0755'
+            install = {args.newfile: (args.targetpath, perms)}
+        oe.recipeutils.bbappend_recipe(rd, args.destlayer, {args.newfile: sourcepath}, install, wildcardver=args.wildcard_version, machine=args.machine)
+        return 0
+    else:
+        if alternative_pns:
+            logger.error('File %s is an alternative possibly provided by the following recipes:\n  %s\nPlease select recipe with -r/--recipe' % (targetpath, '\n  '.join(alternative_pns)))
+        elif postinst_pns:
+            logger.error('File %s may be written out in a pre/postinstall script of the following recipes:\n  %s\nPlease select recipe with -r/--recipe' % (targetpath, '\n  '.join(postinst_pns)))
+        return 3
+
+
+def appendsrc(args, files, rd, extralines=None):
+    import oe.recipeutils
+
+    srcdir = rd.getVar('S', True)
+    workdir = rd.getVar('WORKDIR', True)
+
+    import bb.fetch
+    simplified = {}
+    src_uri = rd.getVar('SRC_URI', True).split()
+    for uri in src_uri:
+        simple_uri = bb.fetch.URI(uri)
+        simple_uri.params = {}
+        simplified[str(simple_uri)] = uri
+
+    copyfiles = {}
+    extralines = extralines or []
+    for newfile, srcfile in files.iteritems():
+        src_destdir = os.path.dirname(srcfile)
+        if not args.use_workdir:
+            if rd.getVar('S', True) == rd.getVar('STAGING_KERNEL_DIR', True):
+                srcdir = os.path.join(workdir, 'git')
+                if not bb.data.inherits_class('kernel-yocto', rd):
+                    logger.warn('S == STAGING_KERNEL_DIR and non-kernel-yocto, unable to determine path to srcdir, defaulting to ${WORKDIR}/git')
+            src_destdir = os.path.join(os.path.relpath(srcdir, workdir), src_destdir)
+        src_destdir = os.path.normpath(src_destdir)
+
+        source_uri = 'file://{0}'.format(os.path.basename(srcfile))
+        if src_destdir and src_destdir != '.':
+            source_uri += ';subdir={0}'.format(src_destdir)
+
+        simple = bb.fetch.URI(source_uri)
+        simple.params = {}
+        simple_str = str(simple)
+        if simple_str in simplified:
+            existing = simplified[simple_str]
+            if source_uri != existing:
+                logger.warn('{0!r} is already in SRC_URI, with different parameters: {1!r}, not adding'.format(source_uri, existing))
+            else:
+                logger.warn('{0!r} is already in SRC_URI, not adding'.format(source_uri))
+        else:
+            extralines.append('SRC_URI += {0}'.format(source_uri))
+        copyfiles[newfile] = srcfile
+
+    oe.recipeutils.bbappend_recipe(rd, args.destlayer, copyfiles, None, wildcardver=args.wildcard_version, machine=args.machine, extralines=extralines)
+
+
+def appendsrcfiles(parser, args):
+    recipedata = _parse_recipe(args.recipe, tinfoil)
+    if not recipedata:
+        parser.error('RECIPE must be a valid recipe name')
+
+    files = dict((f, os.path.join(args.destdir, os.path.basename(f)))
+                 for f in args.files)
+    return appendsrc(args, files, recipedata)
+
+
+def appendsrcfile(parser, args):
+    recipedata = _parse_recipe(args.recipe, tinfoil)
+    if not recipedata:
+        parser.error('RECIPE must be a valid recipe name')
+
+    if not args.destfile:
+        args.destfile = os.path.basename(args.file)
+    elif args.destfile.endswith('/'):
+        args.destfile = os.path.join(args.destfile, os.path.basename(args.file))
+
+    return appendsrc(args, {args.file: args.destfile}, recipedata)
+
+
+def layer(layerpath):
+    if not os.path.exists(os.path.join(layerpath, 'conf', 'layer.conf')):
+        raise argparse.ArgumentTypeError('{0!r} must be a path to a valid layer'.format(layerpath))
+    return layerpath
+
+
+def existing_path(filepath):
+    if not os.path.exists(filepath):
+        raise argparse.ArgumentTypeError('{0!r} must be an existing path'.format(filepath))
+    return filepath
+
+
+def existing_file(filepath):
+    filepath = existing_path(filepath)
+    if os.path.isdir(filepath):
+        raise argparse.ArgumentTypeError('{0!r} must be a file, not a directory'.format(filepath))
+    return filepath
+
+
+def destination_path(destpath):
+    if os.path.isabs(destpath):
+        raise argparse.ArgumentTypeError('{0!r} must be a relative path, not absolute'.format(destpath))
+    return destpath
+
+
+def target_path(targetpath):
+    if not os.path.isabs(targetpath):
+        raise argparse.ArgumentTypeError('{0!r} must be an absolute path, not relative'.format(targetpath))
+    return targetpath
+
+
+def register_command(subparsers):
+    common = argparse.ArgumentParser(add_help=False)
+    common.add_argument('-m', '--machine', help='Make bbappend changes specific to a machine only', metavar='MACHINE')
+    common.add_argument('-w', '--wildcard-version', help='Use wildcard to make the bbappend apply to any recipe version', action='store_true')
+    common.add_argument('destlayer', metavar='DESTLAYER', help='Base directory of the destination layer to write the bbappend to', type=layer)
+
+    parser_appendfile = subparsers.add_parser('appendfile',
+                                              parents=[common],
+                                              help='Create/update a bbappend to replace a target file',
+                                              description='Creates a bbappend (or updates an existing one) to replace the specified file that appears in the target system, determining the recipe that packages the file and the required path and name for the bbappend automatically. Note that the ability to determine the recipe packaging a particular file depends upon the recipe\'s do_packagedata task having already run prior to running this command (which it will have when the recipe has been built successfully, which in turn will have happened if one or more of the recipe\'s packages is included in an image that has been built successfully).')
+    parser_appendfile.add_argument('targetpath', help='Path to the file to be replaced (as it would appear within the target image, e.g. /etc/motd)', type=target_path)
+    parser_appendfile.add_argument('newfile', help='Custom file to replace the target file with', type=existing_file)
+    parser_appendfile.add_argument('-r', '--recipe', help='Override recipe to apply to (default is to find which recipe already packages the file)')
+    parser_appendfile.set_defaults(func=appendfile, parserecipes=True)
+
+    common_src = argparse.ArgumentParser(add_help=False, parents=[common])
+    common_src.add_argument('-W', '--workdir', help='Unpack file into WORKDIR rather than S', dest='use_workdir', action='store_true')
+    common_src.add_argument('recipe', metavar='RECIPE', help='Override recipe to apply to')
+
+    parser = subparsers.add_parser('appendsrcfiles',
+                                   parents=[common_src],
+                                   help='Create/update a bbappend to add or replace source files',
+                                   description='Creates a bbappend (or updates an existing one) to add or replace the specified file in the recipe sources, either those in WORKDIR or those in the source tree. This command lets you specify multiple files with a destination directory, so cannot specify the destination filename. See the `appendsrcfile` command for the other behavior.')
+    parser.add_argument('-D', '--destdir', help='Destination directory (relative to S or WORKDIR, defaults to ".")', default='', type=destination_path)
+    parser.add_argument('files', nargs='+', metavar='FILE', help='File(s) to be added to the recipe sources (WORKDIR or S)', type=existing_path)
+    parser.set_defaults(func=lambda a: appendsrcfiles(parser, a), parserecipes=True)
+
+    parser = subparsers.add_parser('appendsrcfile',
+                                   parents=[common_src],
+                                   help='Create/update a bbappend to add or replace a source file',
+                                   description='Creates a bbappend (or updates an existing one) to add or replace the specified files in the recipe sources, either those in WORKDIR or those in the source tree. This command lets you specify the destination filename, not just destination directory, but only works for one file. See the `appendsrcfiles` command for the other behavior.')
+    parser.add_argument('file', metavar='FILE', help='File to be added to the recipe sources (WORKDIR or S)', type=existing_path)
+    parser.add_argument('destfile', metavar='DESTFILE', nargs='?', help='Destination path (relative to S or WORKDIR, optional)', type=destination_path)
+    parser.set_defaults(func=lambda a: appendsrcfile(parser, a), parserecipes=True)
diff --git a/scripts/lib/recipetool/create.py b/scripts/lib/recipetool/create.py
new file mode 100644
index 0000000..c4754db
--- /dev/null
+++ b/scripts/lib/recipetool/create.py
@@ -0,0 +1,412 @@
+# Recipe creation tool - create command plugin
+#
+# Copyright (C) 2014-2015 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os
+import argparse
+import glob
+import fnmatch
+import re
+import logging
+import scriptutils
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+plugins = None
+
+def plugin_init(pluginlist):
+    # Take a reference to the list so we can use it later
+    global plugins
+    plugins = pluginlist
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+class RecipeHandler():
+    @staticmethod
+    def checkfiles(path, speclist):
+        results = []
+        for spec in speclist:
+            results.extend(glob.glob(os.path.join(path, spec)))
+        return results
+
+    def genfunction(self, outlines, funcname, content):
+        outlines.append('%s () {' % funcname)
+        for line in content:
+            outlines.append('\t%s' % line)
+        outlines.append('}')
+        outlines.append('')
+
+    def process(self, srctree, classes, lines_before, lines_after, handled):
+        return False
+
+
+
+def supports_srcrev(uri):
+    localdata = bb.data.createCopy(tinfoil.config_data)
+    # This is a bit sad, but if you don't have this set there can be some
+    # odd interactions with the urldata cache which lead to errors
+    localdata.setVar('SRCREV', '${AUTOREV}')
+    bb.data.update_data(localdata)
+    fetcher = bb.fetch2.Fetch([uri], localdata)
+    urldata = fetcher.ud
+    for u in urldata:
+        if urldata[u].method.supports_srcrev():
+            return True
+    return False
+
+def create_recipe(args):
+    import bb.process
+    import tempfile
+    import shutil
+
+    pkgarch = ""
+    if args.machine:
+        pkgarch = "${MACHINE_ARCH}"
+
+    checksums = (None, None)
+    tempsrc = ''
+    srcsubdir = ''
+    srcrev = '${AUTOREV}'
+    if '://' in args.source:
+        # Fetch a URL
+        srcuri = args.source
+        rev_re = re.compile(';rev=([^;]+)')
+        res = rev_re.search(srcuri)
+        if res:
+            srcrev = res.group(1)
+            srcuri = rev_re.sub('', srcuri)
+        tempsrc = tempfile.mkdtemp(prefix='recipetool-')
+        srctree = tempsrc
+        logger.info('Fetching %s...' % srcuri)
+        checksums = scriptutils.fetch_uri(tinfoil.config_data, args.source, srctree, srcrev)
+        dirlist = os.listdir(srctree)
+        if 'git.indirectionsymlink' in dirlist:
+            dirlist.remove('git.indirectionsymlink')
+        if len(dirlist) == 1 and os.path.isdir(os.path.join(srctree, dirlist[0])):
+            # We unpacked a single directory, so we should use that
+            srcsubdir = dirlist[0]
+            srctree = os.path.join(srctree, srcsubdir)
+    else:
+        # Assume we're pointing to an existing source tree
+        if args.extract_to:
+            logger.error('--extract-to cannot be specified if source is a directory')
+            sys.exit(1)
+        if not os.path.isdir(args.source):
+            logger.error('Invalid source directory %s' % args.source)
+            sys.exit(1)
+        srcuri = ''
+        srctree = args.source
+
+    outfile = args.outfile
+    if outfile and outfile != '-':
+        if os.path.exists(outfile):
+            logger.error('Output file %s already exists' % outfile)
+            sys.exit(1)
+
+    lines_before = []
+    lines_after = []
+
+    lines_before.append('# Recipe created by %s' % os.path.basename(sys.argv[0]))
+    lines_before.append('# This is the basis of a recipe and may need further editing in order to be fully functional.')
+    lines_before.append('# (Feel free to remove these comments when editing.)')
+    lines_before.append('#')
+
+    licvalues = guess_license(srctree)
+    lic_files_chksum = []
+    if licvalues:
+        licenses = []
+        for licvalue in licvalues:
+            if not licvalue[0] in licenses:
+                licenses.append(licvalue[0])
+            lic_files_chksum.append('file://%s;md5=%s' % (licvalue[1], licvalue[2]))
+        lines_before.append('# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is')
+        lines_before.append('# your responsibility to verify that the values are complete and correct.')
+        if len(licvalues) > 1:
+            lines_before.append('#')
+            lines_before.append('# NOTE: multiple licenses have been detected; if that is correct you should separate')
+            lines_before.append('# these in the LICENSE value using & if the multiple licenses all apply, or | if there')
+            lines_before.append('# is a choice between the multiple licenses. If in doubt, check the accompanying')
+            lines_before.append('# documentation to determine which situation is applicable.')
+    else:
+        lines_before.append('# Unable to find any files that looked like license statements. Check the accompanying')
+        lines_before.append('# documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.')
+        lines_before.append('#')
+        lines_before.append('# NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if')
+        lines_before.append('# this is not accurate with respect to the licensing of the software being built (it')
+        lines_before.append('# will not be in most cases) you must specify the correct value before using this')
+        lines_before.append('# recipe for anything other than initial testing/development!')
+        licenses = ['CLOSED']
+    lines_before.append('LICENSE = "%s"' % ' '.join(licenses))
+    lines_before.append('LIC_FILES_CHKSUM = "%s"' % ' \\\n                    '.join(lic_files_chksum))
+    lines_before.append('')
+
+    # FIXME This is kind of a hack, we probably ought to be using bitbake to do this
+    # we'd also want a way to automatically set outfile based upon auto-detecting these values from the source if possible
+    recipefn = os.path.splitext(os.path.basename(outfile))[0]
+    fnsplit = recipefn.split('_')
+    if len(fnsplit) > 1:
+        pn = fnsplit[0]
+        pv = fnsplit[1]
+    else:
+        pn = recipefn
+        pv = None
+
+    if args.version:
+        pv = args.version
+
+    if pv and pv not in 'git svn hg'.split():
+        realpv = pv
+    else:
+        realpv = None
+
+    if srcuri:
+        if realpv:
+            srcuri = srcuri.replace(realpv, '${PV}')
+    else:
+        lines_before.append('# No information for SRC_URI yet (only an external source tree was specified)')
+    lines_before.append('SRC_URI = "%s"' % srcuri)
+    (md5value, sha256value) = checksums
+    if md5value:
+        lines_before.append('SRC_URI[md5sum] = "%s"' % md5value)
+    if sha256value:
+        lines_before.append('SRC_URI[sha256sum] = "%s"' % sha256value)
+    if srcuri and supports_srcrev(srcuri):
+        lines_before.append('')
+        lines_before.append('# Modify these as desired')
+        lines_before.append('PV = "%s+git${SRCPV}"' % (realpv or '1.0'))
+        lines_before.append('SRCREV = "%s"' % srcrev)
+    lines_before.append('')
+
+    if srcsubdir and pv:
+        if srcsubdir == "%s-%s" % (pn, pv):
+            # This would be the default, so we don't need to set S in the recipe
+            srcsubdir = ''
+    if srcsubdir:
+        if pv and pv not in 'git svn hg'.split():
+            srcsubdir = srcsubdir.replace(pv, '${PV}')
+        lines_before.append('S = "${WORKDIR}/%s"' % srcsubdir)
+        lines_before.append('')
+
+    if pkgarch:
+        lines_after.append('PACKAGE_ARCH = "%s"' % pkgarch)
+        lines_after.append('')
+
+    # Find all plugins that want to register handlers
+    handlers = []
+    for plugin in plugins:
+        if hasattr(plugin, 'register_recipe_handlers'):
+            plugin.register_recipe_handlers(handlers)
+
+    # Apply the handlers
+    classes = []
+    handled = []
+    for handler in handlers:
+        handler.process(srctree, classes, lines_before, lines_after, handled)
+
+    outlines = []
+    outlines.extend(lines_before)
+    if classes:
+        outlines.append('inherit %s' % ' '.join(classes))
+        outlines.append('')
+    outlines.extend(lines_after)
+
+    if args.extract_to:
+        scriptutils.git_convert_standalone_clone(srctree)
+        shutil.move(srctree, args.extract_to)
+        logger.info('Source extracted to %s' % args.extract_to)
+
+    if outfile == '-':
+        sys.stdout.write('\n'.join(outlines) + '\n')
+    else:
+        with open(outfile, 'w') as f:
+            f.write('\n'.join(outlines) + '\n')
+        logger.info('Recipe %s has been created; further editing may be required to make it fully functional' % outfile)
+
+    if tempsrc:
+        shutil.rmtree(tempsrc)
+
+    return 0
+
+def get_license_md5sums(d, static_only=False):
+    import bb.utils
+    md5sums = {}
+    if not static_only:
+        # Gather md5sums of license files in common license dir
+        commonlicdir = d.getVar('COMMON_LICENSE_DIR', True)
+        for fn in os.listdir(commonlicdir):
+            md5value = bb.utils.md5_file(os.path.join(commonlicdir, fn))
+            md5sums[md5value] = fn
+    # The following were extracted from common values in various recipes
+    # (double checking the license against the license file itself, not just
+    # the LICENSE value in the recipe)
+    md5sums['94d55d512a9ba36caa9b7df079bae19f'] = 'GPLv2'
+    md5sums['b234ee4d69f5fce4486a80fdaf4a4263'] = 'GPLv2'
+    md5sums['59530bdf33659b29e73d4adb9f9f6552'] = 'GPLv2'
+    md5sums['0636e73ff0215e8d672dc4c32c317bb3'] = 'GPLv2'
+    md5sums['eb723b61539feef013de476e68b5c50a'] = 'GPLv2'
+    md5sums['751419260aa954499f7abaabaa882bbe'] = 'GPLv2'
+    md5sums['393a5ca445f6965873eca0259a17f833'] = 'GPLv2'
+    md5sums['12f884d2ae1ff87c09e5b7ccc2c4ca7e'] = 'GPLv2'
+    md5sums['8ca43cbc842c2336e835926c2166c28b'] = 'GPLv2'
+    md5sums['ebb5c50ab7cab4baeffba14977030c07'] = 'GPLv2'
+    md5sums['c93c0550bd3173f4504b2cbd8991e50b'] = 'GPLv2'
+    md5sums['9ac2e7cff1ddaf48b6eab6028f23ef88'] = 'GPLv2'
+    md5sums['4325afd396febcb659c36b49533135d4'] = 'GPLv2'
+    md5sums['18810669f13b87348459e611d31ab760'] = 'GPLv2'
+    md5sums['d7810fab7487fb0aad327b76f1be7cd7'] = 'GPLv2' # the Linux kernel's COPYING file
+    md5sums['bbb461211a33b134d42ed5ee802b37ff'] = 'LGPLv2.1'
+    md5sums['7fbc338309ac38fefcd64b04bb903e34'] = 'LGPLv2.1'
+    md5sums['4fbd65380cdd255951079008b364516c'] = 'LGPLv2.1'
+    md5sums['2d5025d4aa3495befef8f17206a5b0a1'] = 'LGPLv2.1'
+    md5sums['fbc093901857fcd118f065f900982c24'] = 'LGPLv2.1'
+    md5sums['a6f89e2100d9b6cdffcea4f398e37343'] = 'LGPLv2.1'
+    md5sums['d8045f3b8f929c1cb29a1e3fd737b499'] = 'LGPLv2.1'
+    md5sums['fad9b3332be894bab9bc501572864b29'] = 'LGPLv2.1'
+    md5sums['3bf50002aefd002f49e7bb854063f7e7'] = 'LGPLv2'
+    md5sums['9f604d8a4f8e74f4f5140845a21b6674'] = 'LGPLv2'
+    md5sums['5f30f0716dfdd0d91eb439ebec522ec2'] = 'LGPLv2'
+    md5sums['55ca817ccb7d5b5b66355690e9abc605'] = 'LGPLv2'
+    md5sums['252890d9eee26aab7b432e8b8a616475'] = 'LGPLv2'
+    md5sums['d32239bcb673463ab874e80d47fae504'] = 'GPLv3'
+    md5sums['f27defe1e96c2e1ecd4e0c9be8967949'] = 'GPLv3'
+    md5sums['6a6a8e020838b23406c81b19c1d46df6'] = 'LGPLv3'
+    md5sums['3b83ef96387f14655fc854ddc3c6bd57'] = 'Apache-2.0'
+    md5sums['385c55653886acac3821999a3ccd17b3'] = 'Artistic-1.0 | GPL-2.0' # some perl modules
+    return md5sums
+
+def guess_license(srctree):
+    import bb
+    md5sums = get_license_md5sums(tinfoil.config_data)
+
+    licenses = []
+    licspecs = ['LICENSE*', 'COPYING*', '*[Ll]icense*', 'LICENCE*', 'LEGAL*', '[Ll]egal*', '*GPL*', 'README.lic*', 'COPYRIGHT*', '[Cc]opyright*']
+    licfiles = []
+    for root, dirs, files in os.walk(srctree):
+        for fn in files:
+            for spec in licspecs:
+                if fnmatch.fnmatch(fn, spec):
+                    fullpath = os.path.join(root, fn)
+                    if not fullpath in licfiles:
+                        licfiles.append(fullpath)
+    for licfile in licfiles:
+        md5value = bb.utils.md5_file(licfile)
+        license = md5sums.get(md5value, 'Unknown')
+        licenses.append((license, os.path.relpath(licfile, srctree), md5value))
+
+    # FIXME should we grab at least one source file with a license header and add that too?
+
+    return licenses
+
+def read_pkgconfig_provides(d):
+    pkgdatadir = d.getVar('PKGDATA_DIR', True)
+    pkgmap = {}
+    for fn in glob.glob(os.path.join(pkgdatadir, 'shlibs2', '*.pclist')):
+        with open(fn, 'r') as f:
+            for line in f:
+                pkgmap[os.path.basename(line.rstrip())] = os.path.splitext(os.path.basename(fn))[0]
+    recipemap = {}
+    for pc, pkg in pkgmap.iteritems():
+        pkgdatafile = os.path.join(pkgdatadir, 'runtime', pkg)
+        if os.path.exists(pkgdatafile):
+            with open(pkgdatafile, 'r') as f:
+                for line in f:
+                    if line.startswith('PN: '):
+                        recipemap[pc] = line.split(':', 1)[1].strip()
+    return recipemap
+
+def convert_pkginfo(pkginfofile):
+    values = {}
+    with open(pkginfofile, 'r') as f:
+        indesc = False
+        for line in f:
+            if indesc:
+                if line.strip():
+                    values['DESCRIPTION'] += ' ' + line.strip()
+                else:
+                    indesc = False
+            else:
+                splitline = line.split(': ', 1)
+                key = line[0]
+                value = line[1]
+                if key == 'LICENSE':
+                    for dep in value.split(','):
+                        dep = dep.split()[0]
+                        mapped = depmap.get(dep, '')
+                        if mapped:
+                            depends.append(mapped)
+                elif key == 'License':
+                    values['LICENSE'] = value
+                elif key == 'Summary':
+                    values['SUMMARY'] = value
+                elif key == 'Description':
+                    values['DESCRIPTION'] = value
+                    indesc = True
+    return values
+
+def convert_debian(debpath):
+    # FIXME extend this mapping - perhaps use distro_alias.inc?
+    depmap = {'libz-dev': 'zlib'}
+
+    values = {}
+    depends = []
+    with open(os.path.join(debpath, 'control')) as f:
+        indesc = False
+        for line in f:
+            if indesc:
+                if line.strip():
+                    if line.startswith(' This package contains'):
+                        indesc = False
+                    else:
+                        values['DESCRIPTION'] += ' ' + line.strip()
+                else:
+                    indesc = False
+            else:
+                splitline = line.split(':', 1)
+                key = line[0]
+                value = line[1]
+                if key == 'Build-Depends':
+                    for dep in value.split(','):
+                        dep = dep.split()[0]
+                        mapped = depmap.get(dep, '')
+                        if mapped:
+                            depends.append(mapped)
+                elif key == 'Section':
+                    values['SECTION'] = value
+                elif key == 'Description':
+                    values['SUMMARY'] = value
+                    indesc = True
+
+    if depends:
+        values['DEPENDS'] = ' '.join(depends)
+
+    return values
+
+
+def register_command(subparsers):
+    parser_create = subparsers.add_parser('create',
+                                          help='Create a new recipe',
+                                          description='Creates a new recipe from a source tree')
+    parser_create.add_argument('source', help='Path or URL to source')
+    parser_create.add_argument('-o', '--outfile', help='Specify filename for recipe to create', required=True)
+    parser_create.add_argument('-m', '--machine', help='Make recipe machine-specific as opposed to architecture-specific', action='store_true')
+    parser_create.add_argument('-x', '--extract-to', metavar='EXTRACTPATH', help='Assuming source is a URL, fetch it and extract it to the directory specified as %(metavar)s')
+    parser_create.add_argument('-V', '--version', help='Version to use within recipe (PV)')
+    parser_create.set_defaults(func=create_recipe)
+
diff --git a/scripts/lib/recipetool/create_buildsys.py b/scripts/lib/recipetool/create_buildsys.py
new file mode 100644
index 0000000..ed14a53
--- /dev/null
+++ b/scripts/lib/recipetool/create_buildsys.py
@@ -0,0 +1,316 @@
+# Recipe creation tool - create command build system handlers
+#
+# Copyright (C) 2014 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 re
+import logging
+from recipetool.create import RecipeHandler, read_pkgconfig_provides
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+class CmakeRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled):
+        if 'buildsystem' in handled:
+            return False
+
+        if RecipeHandler.checkfiles(srctree, ['CMakeLists.txt']):
+            classes.append('cmake')
+            lines_after.append('# Specify any options you want to pass to cmake using EXTRA_OECMAKE:')
+            lines_after.append('EXTRA_OECMAKE = ""')
+            lines_after.append('')
+            handled.append('buildsystem')
+            return True
+        return False
+
+class SconsRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled):
+        if 'buildsystem' in handled:
+            return False
+
+        if RecipeHandler.checkfiles(srctree, ['SConstruct', 'Sconstruct', 'sconstruct']):
+            classes.append('scons')
+            lines_after.append('# Specify any options you want to pass to scons using EXTRA_OESCONS:')
+            lines_after.append('EXTRA_OESCONS = ""')
+            lines_after.append('')
+            handled.append('buildsystem')
+            return True
+        return False
+
+class QmakeRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled):
+        if 'buildsystem' in handled:
+            return False
+
+        if RecipeHandler.checkfiles(srctree, ['*.pro']):
+            classes.append('qmake2')
+            handled.append('buildsystem')
+            return True
+        return False
+
+class AutotoolsRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled):
+        if 'buildsystem' in handled:
+            return False
+
+        autoconf = False
+        if RecipeHandler.checkfiles(srctree, ['configure.ac', 'configure.in']):
+            autoconf = True
+            values = AutotoolsRecipeHandler.extract_autotools_deps(lines_before, srctree)
+            classes.extend(values.pop('inherit', '').split())
+            for var, value in values.iteritems():
+                lines_before.append('%s = "%s"' % (var, value))
+        else:
+            conffile = RecipeHandler.checkfiles(srctree, ['configure'])
+            if conffile:
+                # Check if this is just a pre-generated autoconf configure script
+                with open(conffile[0], 'r') as f:
+                    for i in range(1, 10):
+                        if 'Generated by GNU Autoconf' in f.readline():
+                            autoconf = True
+                            break
+
+        if autoconf:
+            lines_before.append('# NOTE: if this software is not capable of being built in a separate build directory')
+            lines_before.append('# from the source, you should replace autotools with autotools-brokensep in the')
+            lines_before.append('# inherit line')
+            classes.append('autotools')
+            lines_after.append('# Specify any options you want to pass to the configure script using EXTRA_OECONF:')
+            lines_after.append('EXTRA_OECONF = ""')
+            lines_after.append('')
+            handled.append('buildsystem')
+            return True
+
+        return False
+
+    @staticmethod
+    def extract_autotools_deps(outlines, srctree, acfile=None):
+        import shlex
+        import oe.package
+
+        values = {}
+        inherits = []
+
+        # FIXME this mapping is very thin
+        progmap = {'flex': 'flex-native',
+                'bison': 'bison-native',
+                'm4': 'm4-native'}
+        progclassmap = {'gconftool-2': 'gconf',
+                'pkg-config': 'pkgconfig'}
+
+        ignoredeps = ['gcc-runtime', 'glibc', 'uclibc']
+
+        pkg_re = re.compile('PKG_CHECK_MODULES\(\[?[a-zA-Z0-9]*\]?, \[?([^,\]]*)[),].*')
+        lib_re = re.compile('AC_CHECK_LIB\(\[?([a-zA-Z0-9]*)\]?, .*')
+        progs_re = re.compile('_PROGS?\(\[?[a-zA-Z0-9]*\]?, \[?([^,\]]*)\]?[),].*')
+        dep_re = re.compile('([^ ><=]+)( [<>=]+ [^ ><=]+)?')
+
+        # Build up lib library->package mapping
+        shlib_providers = oe.package.read_shlib_providers(tinfoil.config_data)
+        libdir = tinfoil.config_data.getVar('libdir', True)
+        base_libdir = tinfoil.config_data.getVar('base_libdir', True)
+        libpaths = list(set([base_libdir, libdir]))
+        libname_re = re.compile('^lib(.+)\.so.*$')
+        pkglibmap = {}
+        for lib, item in shlib_providers.iteritems():
+            for path, pkg in item.iteritems():
+                if path in libpaths:
+                    res = libname_re.match(lib)
+                    if res:
+                        libname = res.group(1)
+                        if not libname in pkglibmap:
+                            pkglibmap[libname] = pkg[0]
+                    else:
+                        logger.debug('unable to extract library name from %s' % lib)
+
+        # Now turn it into a library->recipe mapping
+        recipelibmap = {}
+        pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR', True)
+        for libname, pkg in pkglibmap.iteritems():
+            try:
+                with open(os.path.join(pkgdata_dir, 'runtime', pkg)) as f:
+                    for line in f:
+                        if line.startswith('PN:'):
+                            recipelibmap[libname] = line.split(':', 1)[-1].strip()
+                            break
+            except IOError as ioe:
+                if ioe.errno == 2:
+                    logger.warn('unable to find a pkgdata file for package %s' % pkg)
+                else:
+                    raise
+
+        # Since a configure.ac file is essentially a program, this is only ever going to be
+        # a hack unfortunately; but it ought to be enough of an approximation
+        if acfile:
+            srcfiles = [acfile]
+        else:
+            srcfiles = RecipeHandler.checkfiles(srctree, ['configure.ac', 'configure.in'])
+        pcdeps = []
+        deps = []
+        unmapped = []
+        unmappedlibs = []
+        with open(srcfiles[0], 'r') as f:
+            for line in f:
+                if 'PKG_CHECK_MODULES' in line:
+                    res = pkg_re.search(line)
+                    if res:
+                        res = dep_re.findall(res.group(1))
+                        if res:
+                            pcdeps.extend([x[0] for x in res])
+                    inherits.append('pkgconfig')
+                if line.lstrip().startswith('AM_GNU_GETTEXT'):
+                    inherits.append('gettext')
+                elif 'AC_CHECK_PROG' in line or 'AC_PATH_PROG' in line:
+                    res = progs_re.search(line)
+                    if res:
+                        for prog in shlex.split(res.group(1)):
+                            prog = prog.split()[0]
+                            progclass = progclassmap.get(prog, None)
+                            if progclass:
+                                inherits.append(progclass)
+                            else:
+                                progdep = progmap.get(prog, None)
+                                if progdep:
+                                    deps.append(progdep)
+                                else:
+                                    if not prog.startswith('$'):
+                                        unmapped.append(prog)
+                elif 'AC_CHECK_LIB' in line:
+                    res = lib_re.search(line)
+                    if res:
+                        lib = res.group(1)
+                        libdep = recipelibmap.get(lib, None)
+                        if libdep:
+                            deps.append(libdep)
+                        else:
+                            if libdep is None:
+                                if not lib.startswith('$'):
+                                    unmappedlibs.append(lib)
+                elif 'AC_PATH_X' in line:
+                    deps.append('libx11')
+
+        if unmapped:
+            outlines.append('# NOTE: the following prog dependencies are unknown, ignoring: %s' % ' '.join(unmapped))
+
+        if unmappedlibs:
+            outlines.append('# NOTE: the following library dependencies are unknown, ignoring: %s' % ' '.join(unmappedlibs))
+            outlines.append('#       (this is based on recipes that have previously been built and packaged)')
+
+        recipemap = read_pkgconfig_provides(tinfoil.config_data)
+        unmapped = []
+        for pcdep in pcdeps:
+            recipe = recipemap.get(pcdep, None)
+            if recipe:
+                deps.append(recipe)
+            else:
+                if not pcdep.startswith('$'):
+                    unmapped.append(pcdep)
+
+        deps = set(deps).difference(set(ignoredeps))
+
+        if unmapped:
+            outlines.append('# NOTE: unable to map the following pkg-config dependencies: %s' % ' '.join(unmapped))
+            outlines.append('#       (this is based on recipes that have previously been built and packaged)')
+
+        if deps:
+            values['DEPENDS'] = ' '.join(deps)
+
+        if inherits:
+            values['inherit'] = ' '.join(list(set(inherits)))
+
+        return values
+
+
+class MakefileRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled):
+        if 'buildsystem' in handled:
+            return False
+
+        makefile = RecipeHandler.checkfiles(srctree, ['Makefile'])
+        if makefile:
+            lines_after.append('# NOTE: this is a Makefile-only piece of software, so we cannot generate much of the')
+            lines_after.append('# recipe automatically - you will need to examine the Makefile yourself and ensure')
+            lines_after.append('# that the appropriate arguments are passed in.')
+            lines_after.append('')
+
+            scanfile = os.path.join(srctree, 'configure.scan')
+            skipscan = False
+            try:
+                stdout, stderr = bb.process.run('autoscan', cwd=srctree, shell=True)
+            except bb.process.ExecutionError as e:
+                skipscan = True
+            if scanfile and os.path.exists(scanfile):
+                values = AutotoolsRecipeHandler.extract_autotools_deps(lines_before, srctree, acfile=scanfile)
+                classes.extend(values.pop('inherit', '').split())
+                for var, value in values.iteritems():
+                    if var == 'DEPENDS':
+                        lines_before.append('# NOTE: some of these dependencies may be optional, check the Makefile and/or upstream documentation')
+                    lines_before.append('%s = "%s"' % (var, value))
+                lines_before.append('')
+                for f in ['configure.scan', 'autoscan.log']:
+                    fp = os.path.join(srctree, f)
+                    if os.path.exists(fp):
+                        os.remove(fp)
+
+            self.genfunction(lines_after, 'do_configure', ['# Specify any needed configure commands here'])
+
+            func = []
+            func.append('# You will almost certainly need to add additional arguments here')
+            func.append('oe_runmake')
+            self.genfunction(lines_after, 'do_compile', func)
+
+            installtarget = True
+            try:
+                stdout, stderr = bb.process.run('make -qn install', cwd=srctree, shell=True)
+            except bb.process.ExecutionError as e:
+                if e.exitcode != 1:
+                    installtarget = False
+            func = []
+            if installtarget:
+                func.append('# This is a guess; additional arguments may be required')
+                makeargs = ''
+                with open(makefile[0], 'r') as f:
+                    for i in range(1, 100):
+                        if 'DESTDIR' in f.readline():
+                            makeargs += " 'DESTDIR=${D}'"
+                            break
+                func.append('oe_runmake install%s' % makeargs)
+            else:
+                func.append('# NOTE: unable to determine what to put here - there is a Makefile but no')
+                func.append('# target named "install", so you will need to define this yourself')
+            self.genfunction(lines_after, 'do_install', func)
+
+            handled.append('buildsystem')
+        else:
+            lines_after.append('# NOTE: no Makefile found, unable to determine what needs to be done')
+            lines_after.append('')
+            self.genfunction(lines_after, 'do_configure', ['# Specify any needed configure commands here'])
+            self.genfunction(lines_after, 'do_compile', ['# Specify compilation commands here'])
+            self.genfunction(lines_after, 'do_install', ['# Specify install commands here'])
+
+
+def register_recipe_handlers(handlers):
+    # These are in a specific order so that the right one is detected first
+    handlers.append(CmakeRecipeHandler())
+    handlers.append(AutotoolsRecipeHandler())
+    handlers.append(SconsRecipeHandler())
+    handlers.append(QmakeRecipeHandler())
+    handlers.append(MakefileRecipeHandler())
diff --git a/scripts/lib/recipetool/create_buildsys_python.py b/scripts/lib/recipetool/create_buildsys_python.py
new file mode 100644
index 0000000..e0af2a0
--- /dev/null
+++ b/scripts/lib/recipetool/create_buildsys_python.py
@@ -0,0 +1,716 @@
+# Recipe creation tool - create build system handler for python
+#
+# Copyright (C) 2015 Mentor Graphics 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 ast
+import codecs
+import collections
+import distutils.command.build_py
+import email
+import imp
+import glob
+import itertools
+import logging
+import os
+import re
+import sys
+import subprocess
+from recipetool.create import RecipeHandler
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+class PythonRecipeHandler(RecipeHandler):
+    base_pkgdeps = ['python-core']
+    excluded_pkgdeps = ['python-dbg']
+    # os.path is provided by python-core
+    assume_provided = ['builtins', 'os.path']
+    # Assumes that the host python builtin_module_names is sane for target too
+    assume_provided = assume_provided + list(sys.builtin_module_names)
+
+    bbvar_map = {
+        'Name': 'PN',
+        'Version': 'PV',
+        'Home-page': 'HOMEPAGE',
+        'Summary': 'SUMMARY',
+        'Description': 'DESCRIPTION',
+        'License': 'LICENSE',
+        'Requires': 'RDEPENDS_${PN}',
+        'Provides': 'RPROVIDES_${PN}',
+        'Obsoletes': 'RREPLACES_${PN}',
+    }
+    # PN/PV are already set by recipetool core & desc can be extremely long
+    excluded_fields = [
+        'Name',
+        'Version',
+        'Description',
+    ]
+    setup_parse_map = {
+        'Url': 'Home-page',
+        'Classifiers': 'Classifier',
+        'Description': 'Summary',
+    }
+    setuparg_map = {
+        'Home-page': 'url',
+        'Classifier': 'classifiers',
+        'Summary': 'description',
+        'Description': 'long-description',
+    }
+    # Values which are lists, used by the setup.py argument based metadata
+    # extraction method, to determine how to process the setup.py output.
+    setuparg_list_fields = [
+        'Classifier',
+        'Requires',
+        'Provides',
+        'Obsoletes',
+        'Platform',
+        'Supported-Platform',
+    ]
+    setuparg_multi_line_values = ['Description']
+    replacements = [
+        ('License', r' ', '-'),
+        ('License', r'-License$', ''),
+        ('License', r'^UNKNOWN$', ''),
+
+        # Remove currently unhandled version numbers from these variables
+        ('Requires', r' *\([^)]*\)', ''),
+        ('Provides', r' *\([^)]*\)', ''),
+        ('Obsoletes', r' *\([^)]*\)', ''),
+        ('Install-requires', r'^([^><= ]+).*', r'\1'),
+        ('Extras-require', r'^([^><= ]+).*', r'\1'),
+        ('Tests-require', r'^([^><= ]+).*', r'\1'),
+
+        # Remove unhandled dependency on particular features (e.g. foo[PDF])
+        ('Install-requires', r'\[[^\]]+\]$', ''),
+    ]
+
+    classifier_license_map = {
+        'License :: OSI Approved :: Academic Free License (AFL)': 'AFL',
+        'License :: OSI Approved :: Apache Software License': 'Apache',
+        'License :: OSI Approved :: Apple Public Source License': 'APSL',
+        'License :: OSI Approved :: Artistic License': 'Artistic',
+        'License :: OSI Approved :: Attribution Assurance License': 'AAL',
+        'License :: OSI Approved :: BSD License': 'BSD',
+        'License :: OSI Approved :: Common Public License': 'CPL',
+        'License :: OSI Approved :: Eiffel Forum License': 'EFL',
+        'License :: OSI Approved :: European Union Public Licence 1.0 (EUPL 1.0)': 'EUPL-1.0',
+        'License :: OSI Approved :: European Union Public Licence 1.1 (EUPL 1.1)': 'EUPL-1.1',
+        'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)': 'AGPL-3.0+',
+        'License :: OSI Approved :: GNU Affero General Public License v3': 'AGPL-3.0',
+        'License :: OSI Approved :: GNU Free Documentation License (FDL)': 'GFDL',
+        'License :: OSI Approved :: GNU General Public License (GPL)': 'GPL',
+        'License :: OSI Approved :: GNU General Public License v2 (GPLv2)': 'GPL-2.0',
+        'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)': 'GPL-2.0+',
+        'License :: OSI Approved :: GNU General Public License v3 (GPLv3)': 'GPL-3.0',
+        'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)': 'GPL-3.0+',
+        'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)': 'LGPL-2.0',
+        'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)': 'LGPL-2.0+',
+        'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)': 'LGPL-3.0',
+        'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)': 'LGPL-3.0+',
+        'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)': 'LGPL',
+        'License :: OSI Approved :: IBM Public License': 'IPL',
+        'License :: OSI Approved :: ISC License (ISCL)': 'ISC',
+        'License :: OSI Approved :: Intel Open Source License': 'Intel',
+        'License :: OSI Approved :: Jabber Open Source License': 'Jabber',
+        'License :: OSI Approved :: MIT License': 'MIT',
+        'License :: OSI Approved :: MITRE Collaborative Virtual Workspace License (CVW)': 'CVWL',
+        'License :: OSI Approved :: Motosoto License': 'Motosoto',
+        'License :: OSI Approved :: Mozilla Public License 1.0 (MPL)': 'MPL-1.0',
+        'License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)': 'MPL-1.1',
+        'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)': 'MPL-2.0',
+        'License :: OSI Approved :: Nethack General Public License': 'NGPL',
+        'License :: OSI Approved :: Nokia Open Source License': 'Nokia',
+        'License :: OSI Approved :: Open Group Test Suite License': 'OGTSL',
+        'License :: OSI Approved :: Python License (CNRI Python License)': 'CNRI-Python',
+        'License :: OSI Approved :: Python Software Foundation License': 'PSF',
+        'License :: OSI Approved :: Qt Public License (QPL)': 'QPL',
+        'License :: OSI Approved :: Ricoh Source Code Public License': 'RSCPL',
+        'License :: OSI Approved :: Sleepycat License': 'Sleepycat',
+        'License :: OSI Approved :: Sun Industry Standards Source License (SISSL)': '--  Sun Industry Standards Source License (SISSL)',
+        'License :: OSI Approved :: Sun Public License': 'SPL',
+        'License :: OSI Approved :: University of Illinois/NCSA Open Source License': 'NCSA',
+        'License :: OSI Approved :: Vovida Software License 1.0': 'VSL-1.0',
+        'License :: OSI Approved :: W3C License': 'W3C',
+        'License :: OSI Approved :: X.Net License': 'Xnet',
+        'License :: OSI Approved :: Zope Public License': 'ZPL',
+        'License :: OSI Approved :: zlib/libpng License': 'Zlib',
+    }
+
+    def __init__(self):
+        pass
+
+    def process(self, srctree, classes, lines_before, lines_after, handled):
+        if 'buildsystem' in handled:
+            return False
+
+        if not RecipeHandler.checkfiles(srctree, ['setup.py']):
+            return
+
+        # setup.py is always parsed to get at certain required information, such as
+        # distutils vs setuptools
+        #
+        # If egg info is available, we use it for both its PKG-INFO metadata
+        # and for its requires.txt for install_requires.
+        # If PKG-INFO is available but no egg info is, we use that for metadata in preference to
+        # the parsed setup.py, but use the install_requires info from the
+        # parsed setup.py.
+
+        setupscript = os.path.join(srctree, 'setup.py')
+        try:
+            setup_info, uses_setuptools, setup_non_literals, extensions = self.parse_setup_py(setupscript)
+        except Exception:
+            logger.exception("Failed to parse setup.py")
+            setup_info, uses_setuptools, setup_non_literals, extensions = {}, True, [], []
+
+        egginfo = glob.glob(os.path.join(srctree, '*.egg-info'))
+        if egginfo:
+            info = self.get_pkginfo(os.path.join(egginfo[0], 'PKG-INFO'))
+            requires_txt = os.path.join(egginfo[0], 'requires.txt')
+            if os.path.exists(requires_txt):
+                with codecs.open(requires_txt) as f:
+                    inst_req = []
+                    extras_req = collections.defaultdict(list)
+                    current_feature = None
+                    for line in f.readlines():
+                        line = line.rstrip()
+                        if not line:
+                            continue
+
+                        if line.startswith('['):
+                            current_feature = line[1:-1]
+                        elif current_feature:
+                            extras_req[current_feature].append(line)
+                        else:
+                            inst_req.append(line)
+                    info['Install-requires'] = inst_req
+                    info['Extras-require'] = extras_req
+        elif RecipeHandler.checkfiles(srctree, ['PKG-INFO']):
+            info = self.get_pkginfo(os.path.join(srctree, 'PKG-INFO'))
+
+            if setup_info:
+                if 'Install-requires' in setup_info:
+                    info['Install-requires'] = setup_info['Install-requires']
+                if 'Extras-require' in setup_info:
+                    info['Extras-require'] = setup_info['Extras-require']
+        else:
+            if setup_info:
+                info = setup_info
+            else:
+                info = self.get_setup_args_info(setupscript)
+
+        self.apply_info_replacements(info)
+
+        if uses_setuptools:
+            classes.append('setuptools')
+        else:
+            classes.append('distutils')
+
+        if 'Classifier' in info:
+            licenses = []
+            for classifier in info['Classifier']:
+                if classifier in self.classifier_license_map:
+                    license = self.classifier_license_map[classifier]
+                    licenses.append(license)
+
+            if licenses:
+                info['License'] = ' & '.join(licenses)
+
+
+        # Map PKG-INFO & setup.py fields to bitbake variables
+        bbinfo = {}
+        for field, values in info.iteritems():
+            if field in self.excluded_fields:
+                continue
+
+            if field not in self.bbvar_map:
+                continue
+
+            if isinstance(values, basestring):
+                value = values
+            else:
+                value = ' '.join(str(v) for v in values if v)
+
+            bbvar = self.bbvar_map[field]
+            if bbvar not in bbinfo and value:
+                bbinfo[bbvar] = value
+
+        comment_lic_line = None
+        for pos, line in enumerate(list(lines_before)):
+            if line.startswith('#') and 'LICENSE' in line:
+                comment_lic_line = pos
+            elif line.startswith('LICENSE =') and 'LICENSE' in bbinfo:
+                if line in ('LICENSE = "Unknown"', 'LICENSE = "CLOSED"'):
+                    lines_before[pos] = 'LICENSE = "{}"'.format(bbinfo['LICENSE'])
+                    if line == 'LICENSE = "CLOSED"' and comment_lic_line:
+                        lines_before[comment_lic_line:pos] = [
+                            '# WARNING: the following LICENSE value is a best guess - it is your',
+                            '# responsibility to verify that the value is complete and correct.'
+                        ]
+                del bbinfo['LICENSE']
+
+        src_uri_line = None
+        for pos, line in enumerate(lines_before):
+            if line.startswith('SRC_URI ='):
+                src_uri_line = pos
+
+        if bbinfo:
+            mdinfo = ['']
+            for k in sorted(bbinfo):
+                v = bbinfo[k]
+                mdinfo.append('{} = "{}"'.format(k, v))
+            lines_before[src_uri_line-1:src_uri_line-1] = mdinfo
+
+        mapped_deps, unmapped_deps = self.scan_setup_python_deps(srctree, setup_info, setup_non_literals)
+
+        extras_req = set()
+        if 'Extras-require' in info:
+            extras_req = info['Extras-require']
+            if extras_req:
+                lines_after.append('# The following configs & dependencies are from setuptools extras_require.')
+                lines_after.append('# These dependencies are optional, hence can be controlled via PACKAGECONFIG.')
+                lines_after.append('# The upstream names may not correspond exactly to bitbake package names.')
+                lines_after.append('#')
+                lines_after.append('# Uncomment this line to enable all the optional features.')
+                lines_after.append('#PACKAGECONFIG ?= "{}"'.format(' '.join(k.lower() for k in extras_req.iterkeys())))
+                for feature, feature_reqs in extras_req.iteritems():
+                    unmapped_deps.difference_update(feature_reqs)
+
+                    feature_req_deps = ('python-' + r.replace('.', '-').lower() for r in sorted(feature_reqs))
+                    lines_after.append('PACKAGECONFIG[{}] = ",,,{}"'.format(feature.lower(), ' '.join(feature_req_deps)))
+
+        inst_reqs = set()
+        if 'Install-requires' in info:
+            if extras_req:
+                lines_after.append('')
+            inst_reqs = info['Install-requires']
+            if inst_reqs:
+                unmapped_deps.difference_update(inst_reqs)
+
+                inst_req_deps = ('python-' + r.replace('.', '-').lower() for r in sorted(inst_reqs))
+                lines_after.append('# WARNING: the following rdepends are from setuptools install_requires. These')
+                lines_after.append('# upstream names may not correspond exactly to bitbake package names.')
+                lines_after.append('RDEPENDS_${{PN}} += "{}"'.format(' '.join(inst_req_deps)))
+
+        if mapped_deps:
+            name = info.get('Name')
+            if name and name[0] in mapped_deps:
+                # Attempt to avoid self-reference
+                mapped_deps.remove(name[0])
+            mapped_deps -= set(self.excluded_pkgdeps)
+            if inst_reqs or extras_req:
+                lines_after.append('')
+            lines_after.append('# WARNING: the following rdepends are determined through basic analysis of the')
+            lines_after.append('# python sources, and might not be 100% accurate.')
+            lines_after.append('RDEPENDS_${{PN}} += "{}"'.format(' '.join(sorted(mapped_deps))))
+
+        unmapped_deps -= set(extensions)
+        unmapped_deps -= set(self.assume_provided)
+        if unmapped_deps:
+            if mapped_deps:
+                lines_after.append('')
+            lines_after.append('# WARNING: We were unable to map the following python package/module')
+            lines_after.append('# dependencies to the bitbake packages which include them:')
+            lines_after.extend('#    {}'.format(d) for d in sorted(unmapped_deps))
+
+        handled.append('buildsystem')
+
+    def get_pkginfo(self, pkginfo_fn):
+        msg = email.message_from_file(open(pkginfo_fn, 'r'))
+        msginfo = {}
+        for field in msg.keys():
+            values = msg.get_all(field)
+            if len(values) == 1:
+                msginfo[field] = values[0]
+            else:
+                msginfo[field] = values
+        return msginfo
+
+    def parse_setup_py(self, setupscript='./setup.py'):
+        with codecs.open(setupscript) as f:
+            info, imported_modules, non_literals, extensions = gather_setup_info(f)
+
+        def _map(key):
+            key = key.replace('_', '-')
+            key = key[0].upper() + key[1:]
+            if key in self.setup_parse_map:
+                key = self.setup_parse_map[key]
+            return key
+
+        # Naive mapping of setup() arguments to PKG-INFO field names
+        for d in [info, non_literals]:
+            for key, value in d.items():
+                new_key = _map(key)
+                if new_key != key:
+                    del d[key]
+                    d[new_key] = value
+
+        return info, 'setuptools' in imported_modules, non_literals, extensions
+
+    def get_setup_args_info(self, setupscript='./setup.py'):
+        cmd = ['python', setupscript]
+        info = {}
+        keys = set(self.bbvar_map.keys())
+        keys |= set(self.setuparg_list_fields)
+        keys |= set(self.setuparg_multi_line_values)
+        grouped_keys = itertools.groupby(keys, lambda k: (k in self.setuparg_list_fields, k in self.setuparg_multi_line_values))
+        for index, keys in grouped_keys:
+            if index == (True, False):
+                # Splitlines output for each arg as a list value
+                for key in keys:
+                    arg = self.setuparg_map.get(key, key.lower())
+                    try:
+                        arg_info = self.run_command(cmd + ['--' + arg], cwd=os.path.dirname(setupscript))
+                    except (OSError, subprocess.CalledProcessError):
+                        pass
+                    else:
+                        info[key] = [l.rstrip() for l in arg_info.splitlines()]
+            elif index == (False, True):
+                # Entire output for each arg
+                for key in keys:
+                    arg = self.setuparg_map.get(key, key.lower())
+                    try:
+                        arg_info = self.run_command(cmd + ['--' + arg], cwd=os.path.dirname(setupscript))
+                    except (OSError, subprocess.CalledProcessError):
+                        pass
+                    else:
+                        info[key] = arg_info
+            else:
+                info.update(self.get_setup_byline(list(keys), setupscript))
+        return info
+
+    def get_setup_byline(self, fields, setupscript='./setup.py'):
+        info = {}
+
+        cmd = ['python', setupscript]
+        cmd.extend('--' + self.setuparg_map.get(f, f.lower()) for f in fields)
+        try:
+            info_lines = self.run_command(cmd, cwd=os.path.dirname(setupscript)).splitlines()
+        except (OSError, subprocess.CalledProcessError):
+            pass
+        else:
+            if len(fields) != len(info_lines):
+                logger.error('Mismatch between setup.py output lines and number of fields')
+                sys.exit(1)
+
+            for lineno, line in enumerate(info_lines):
+                line = line.rstrip()
+                info[fields[lineno]] = line
+        return info
+
+    def apply_info_replacements(self, info):
+        for variable, search, replace in self.replacements:
+            if variable not in info:
+                continue
+
+            def replace_value(search, replace, value):
+                if replace is None:
+                    if re.search(search, value):
+                        return None
+                else:
+                    new_value = re.sub(search, replace, value)
+                    if value != new_value:
+                        return new_value
+                return value
+
+            value = info[variable]
+            if isinstance(value, basestring):
+                new_value = replace_value(search, replace, value)
+                if new_value is None:
+                    del info[variable]
+                elif new_value != value:
+                    info[variable] = new_value
+            elif hasattr(value, 'iteritems'):
+                for dkey, dvalue in value.iteritems():
+                    new_list = []
+                    for pos, a_value in enumerate(dvalue):
+                        new_value = replace_value(search, replace, a_value)
+                        if new_value is not None and new_value != value:
+                            new_list.append(new_value)
+
+                    if value != new_list:
+                        value[dkey] = new_list
+            else:
+                new_list = []
+                for pos, a_value in enumerate(value):
+                    new_value = replace_value(search, replace, a_value)
+                    if new_value is not None and new_value != value:
+                        new_list.append(new_value)
+
+                if value != new_list:
+                    info[variable] = new_list
+
+    def scan_setup_python_deps(self, srctree, setup_info, setup_non_literals):
+        if 'Package-dir' in setup_info:
+            package_dir = setup_info['Package-dir']
+        else:
+            package_dir = {}
+
+        class PackageDir(distutils.command.build_py.build_py):
+            def __init__(self, package_dir):
+                self.package_dir = package_dir
+
+        pd = PackageDir(package_dir)
+        to_scan = []
+        if not any(v in setup_non_literals for v in ['Py-modules', 'Scripts', 'Packages']):
+            if 'Py-modules' in setup_info:
+                for module in setup_info['Py-modules']:
+                    try:
+                        package, module = module.rsplit('.', 1)
+                    except ValueError:
+                        package, module = '.', module
+                    module_path = os.path.join(pd.get_package_dir(package), module + '.py')
+                    to_scan.append(module_path)
+
+            if 'Packages' in setup_info:
+                for package in setup_info['Packages']:
+                    to_scan.append(pd.get_package_dir(package))
+
+            if 'Scripts' in setup_info:
+                to_scan.extend(setup_info['Scripts'])
+        else:
+            logger.info("Scanning the entire source tree, as one or more of the following setup keywords are non-literal: py_modules, scripts, packages.")
+
+        if not to_scan:
+            to_scan = ['.']
+
+        logger.info("Scanning paths for packages & dependencies: %s", ', '.join(to_scan))
+
+        provided_packages = self.parse_pkgdata_for_python_packages()
+        scanned_deps = self.scan_python_dependencies([os.path.join(srctree, p) for p in to_scan])
+        mapped_deps, unmapped_deps = set(self.base_pkgdeps), set()
+        for dep in scanned_deps:
+            mapped = provided_packages.get(dep)
+            if mapped:
+                mapped_deps.add(mapped)
+            else:
+                unmapped_deps.add(dep)
+        return mapped_deps, unmapped_deps
+
+    def scan_python_dependencies(self, paths):
+        deps = set()
+        try:
+            dep_output = self.run_command(['pythondeps', '-d'] + paths)
+        except (OSError, subprocess.CalledProcessError):
+            pass
+        else:
+            for line in dep_output.splitlines():
+                line = line.rstrip()
+                dep, filename = line.split('\t', 1)
+                if filename.endswith('/setup.py'):
+                    continue
+                deps.add(dep)
+
+        try:
+            provides_output = self.run_command(['pythondeps', '-p'] + paths)
+        except (OSError, subprocess.CalledProcessError):
+            pass
+        else:
+            provides_lines = (l.rstrip() for l in provides_output.splitlines())
+            provides = set(l for l in provides_lines if l and l != 'setup')
+            deps -= provides
+
+        return deps
+
+    def parse_pkgdata_for_python_packages(self):
+        suffixes = [t[0] for t in imp.get_suffixes()]
+        pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR', True)
+
+        ldata = tinfoil.config_data.createCopy()
+        bb.parse.handle('classes/python-dir.bbclass', ldata, True)
+        python_sitedir = ldata.getVar('PYTHON_SITEPACKAGES_DIR', True)
+
+        dynload_dir = os.path.join(os.path.dirname(python_sitedir), 'lib-dynload')
+        python_dirs = [python_sitedir + os.sep,
+                       os.path.join(os.path.dirname(python_sitedir), 'dist-packages') + os.sep,
+                       os.path.dirname(python_sitedir) + os.sep]
+        packages = {}
+        for pkgdatafile in glob.glob('{}/runtime/*'.format(pkgdata_dir)):
+            files_info = None
+            with open(pkgdatafile, 'r') as f:
+                for line in f.readlines():
+                    field, value = line.split(': ', 1)
+                    if field == 'FILES_INFO':
+                        files_info = ast.literal_eval(value)
+                        break
+                else:
+                    continue
+
+            for fn in files_info.iterkeys():
+                for suffix in suffixes:
+                    if fn.endswith(suffix):
+                        break
+                else:
+                    continue
+
+                if fn.startswith(dynload_dir + os.sep):
+                    base = os.path.basename(fn)
+                    provided = base.split('.', 1)[0]
+                    packages[provided] = os.path.basename(pkgdatafile)
+                    continue
+
+                for python_dir in python_dirs:
+                    if fn.startswith(python_dir):
+                        relpath = fn[len(python_dir):]
+                        relstart, _, relremaining = relpath.partition(os.sep)
+                        if relstart.endswith('.egg'):
+                            relpath = relremaining
+                        base, _ = os.path.splitext(relpath)
+
+                        if '/.debug/' in base:
+                            continue
+                        if os.path.basename(base) == '__init__':
+                            base = os.path.dirname(base)
+                        base = base.replace(os.sep + os.sep, os.sep)
+                        provided = base.replace(os.sep, '.')
+                        packages[provided] = os.path.basename(pkgdatafile)
+        return packages
+
+    @classmethod
+    def run_command(cls, cmd, **popenargs):
+        if 'stderr' not in popenargs:
+            popenargs['stderr'] = subprocess.STDOUT
+        try:
+            return subprocess.check_output(cmd, **popenargs)
+        except OSError as exc:
+            logger.error('Unable to run `{}`: {}', ' '.join(cmd), exc)
+            raise
+        except subprocess.CalledProcessError as exc:
+            logger.error('Unable to run `{}`: {}', ' '.join(cmd), exc.output)
+            raise
+
+
+def gather_setup_info(fileobj):
+    parsed = ast.parse(fileobj.read(), fileobj.name)
+    visitor = SetupScriptVisitor()
+    visitor.visit(parsed)
+
+    non_literals, extensions = {}, []
+    for key, value in visitor.keywords.items():
+        if key == 'ext_modules':
+            if isinstance(value, list):
+                for ext in value:
+                    if  (isinstance(ext, ast.Call) and
+                         isinstance(ext.func, ast.Name) and
+                         ext.func.id == 'Extension' and
+                         not has_non_literals(ext.args)):
+                        extensions.append(ext.args[0])
+        elif has_non_literals(value):
+            non_literals[key] = value
+            del visitor.keywords[key]
+
+    return visitor.keywords, visitor.imported_modules, non_literals, extensions
+
+
+class SetupScriptVisitor(ast.NodeVisitor):
+    def __init__(self):
+        ast.NodeVisitor.__init__(self)
+        self.keywords = {}
+        self.non_literals = []
+        self.imported_modules = set()
+
+    def visit_Expr(self, node):
+        if isinstance(node.value, ast.Call) and \
+           isinstance(node.value.func, ast.Name) and \
+           node.value.func.id == 'setup':
+            self.visit_setup(node.value)
+
+    def visit_setup(self, node):
+        call = LiteralAstTransform().visit(node)
+        self.keywords = call.keywords
+        for k, v in self.keywords.iteritems():
+            if has_non_literals(v):
+               self.non_literals.append(k)
+
+    def visit_Import(self, node):
+        for alias in node.names:
+            self.imported_modules.add(alias.name)
+
+    def visit_ImportFrom(self, node):
+        self.imported_modules.add(node.module)
+
+
+class LiteralAstTransform(ast.NodeTransformer):
+    """Simplify the ast through evaluation of literals."""
+    excluded_fields = ['ctx']
+
+    def visit(self, node):
+        if not isinstance(node, ast.AST):
+            return node
+        else:
+            return ast.NodeTransformer.visit(self, node)
+
+    def generic_visit(self, node):
+        try:
+            return ast.literal_eval(node)
+        except ValueError:
+            for field, value in ast.iter_fields(node):
+                if field in self.excluded_fields:
+                    delattr(node, field)
+                if value is None:
+                    continue
+
+                if isinstance(value, list):
+                    if field in ('keywords', 'kwargs'):
+                        new_value = dict((kw.arg, self.visit(kw.value)) for kw in value)
+                    else:
+                        new_value = [self.visit(i) for i in value]
+                else:
+                    new_value = self.visit(value)
+                setattr(node, field, new_value)
+            return node
+
+    def visit_Name(self, node):
+        if hasattr('__builtins__', node.id):
+            return getattr(__builtins__, node.id)
+        else:
+            return self.generic_visit(node)
+
+    def visit_Tuple(self, node):
+        return tuple(self.visit(v) for v in node.elts)
+
+    def visit_List(self, node):
+        return [self.visit(v) for v in node.elts]
+
+    def visit_Set(self, node):
+        return set(self.visit(v) for v in node.elts)
+
+    def visit_Dict(self, node):
+        keys = (self.visit(k) for k in node.keys)
+        values = (self.visit(v) for v in node.values)
+        return dict(zip(keys, values))
+
+
+def has_non_literals(value):
+    if isinstance(value, ast.AST):
+        return True
+    elif isinstance(value, basestring):
+        return False
+    elif hasattr(value, 'itervalues'):
+        return any(has_non_literals(v) for v in value.itervalues())
+    elif hasattr(value, '__iter__'):
+        return any(has_non_literals(v) for v in value)
+
+
+def register_recipe_handlers(handlers):
+    # We need to make sure this is ahead of the makefile fallback handler
+    handlers.insert(0, PythonRecipeHandler())
