From c5a2ed20c4e18484e4cb20ad09a2c4189d0c67a1 Mon Sep 17 00:00:00 2001 From: Paul Eggleton Date: Fri, 15 Aug 2014 15:34:13 +0100 Subject: beginnings of new sdk --- meta/classes/populate_sdk_base.bbclass | 2 + meta/recipes-core/meta/meta-newsdk.bb | 202 ++++++++++++++++++++++++++ meta/recipes-core/meta/meta-newsdk/sdktool.py | 113 ++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 meta/recipes-core/meta/meta-newsdk.bb create mode 100644 meta/recipes-core/meta/meta-newsdk/sdktool.py (limited to 'meta') diff --git a/meta/classes/populate_sdk_base.bbclass b/meta/classes/populate_sdk_base.bbclass index 06112dcf81..05440a9134 100644 --- a/meta/classes/populate_sdk_base.bbclass +++ b/meta/classes/populate_sdk_base.bbclass @@ -290,6 +290,8 @@ for perl_script in $($SUDO_EXEC find $native_sysroot -type f -exec grep "^#!.*pe "s: /usr/bin/perl: /usr/bin/env perl:g" $perl_script done +${SDK_POST_INSTALL_COMMAND} + echo done # delete the relocating script, so that user is forced to re-run the installer diff --git a/meta/recipes-core/meta/meta-newsdk.bb b/meta/recipes-core/meta/meta-newsdk.bb new file mode 100644 index 0000000000..f453410447 --- /dev/null +++ b/meta/recipes-core/meta/meta-newsdk.bb @@ -0,0 +1,202 @@ +# Instructions to make this work: +# +# bitbake +# bitbake -S none +# bitbake meta-newsdk +# +# This will produce an installable SDK containing a copy of the build +# system whose output is locked at the point it was generated. +# + +SUMMARY = "New SDK" +LICENSE = "MIT" + +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +inherit populate_sdk + +SRC_URI = "file://sdktool.py" + +# Parts of this borrowed from buildtools-tarball +TOOLCHAIN_HOST_TASK = " \ + nativesdk-qemu \ + nativesdk-qemu-helper \ + nativesdk-pseudo \ + \ + nativesdk-python-core \ + nativesdk-python-textutils \ + nativesdk-python-sqlite3 \ + nativesdk-python-pickle \ + nativesdk-python-logging \ + nativesdk-python-elementtree \ + nativesdk-python-curses \ + nativesdk-python-compile \ + nativesdk-python-compiler \ + nativesdk-python-fcntl \ + nativesdk-python-shell \ + nativesdk-python-misc \ + nativesdk-python-multiprocessing \ + nativesdk-python-subprocess \ + nativesdk-python-xmlrpc \ + nativesdk-python-netclient \ + nativesdk-python-netserver \ + nativesdk-python-distutils \ + nativesdk-python-unixadmin \ + nativesdk-python-compression \ + nativesdk-python-json \ + nativesdk-python-unittest \ + nativesdk-python-mmap \ + nativesdk-python-difflib \ + nativesdk-python-pprint \ + nativesdk-python-git \ + nativesdk-python-pkgutil \ + nativesdk-ncurses-terminfo-base \ + nativesdk-chrpath \ + nativesdk-tar \ + nativesdk-git \ + nativesdk-pigz \ + nativesdk-make \ + nativesdk-wget \ + " + +TOOLCHAIN_TARGET_TASK = "" + +SDK_META_CONF_WHITELIST ?= "MACHINE DISTRO PACKAGE_CLASSES" + +SDK_TARGETS ?= "core-image-minimal" + + +python copy_buildsystem () { + import re + + layerdirs = d.getVar('BBLAYERS', True).split() + + res = re.search('([^:]*/bitbake/bin)', d.getVar('PATH', True)) + if res: + bitbakepath = os.path.dirname(res.group(1)) + layerdirs.append(bitbakepath) + else: + bb.fatal('Unable to find bitbake path!') + + # Copy in all metadata layers + bitbake (as repositories) + baseoutpath = d.getVar('SDK_OUTPUT', True) + '/' + d.getVar('SDKPATH', True) + bb.utils.mkdirhier(baseoutpath + '/layers') + sdkbblayers = [] + for layer in layerdirs: + stdout, stderr = bb.process.run("git rev-parse --show-toplevel", cwd=layer) + toplevel = stdout.strip() + sdkdestpath = baseoutpath + '/layers/' + os.path.basename(toplevel) + if os.path.exists(sdkdestpath): + bb.note("Skipping layer %s, already handled" % layer) + else: + bb.note("Cloning %s for %s..." % (toplevel, layer)) + bb.process.run("git clone %s %s" % (toplevel, sdkdestpath)) + bb.process.run("git gc --auto", cwd=sdkdestpath) + + if layer != bitbakepath: + layerrelpath = os.path.relpath(layer, os.path.dirname(toplevel)) + sdkbblayers.append(layerrelpath) + + # Create a layer for new recipes / appends + bb.utils.mkdirhier(baseoutpath + '/workspace/conf') + with open(baseoutpath + '/workspace/conf/layer.conf', 'w') as f: + f.write('BBPATH =. "$' + '{LAYERDIR}:"\n') + f.write('BBFILES += "$' + '{LAYERDIR}/*/*.bb \\\n') + f.write(' $' + '{LAYERDIR}/*/*.bbappend"\n') + f.write('BBFILE_COLLECTIONS += "sdkworkspace"\n') + f.write('BBFILE_PATTERN_sdkworkspace = "^$' + '{LAYERDIR}/"\n') + f.write('BBFILE_PRIORITY_sdkworkspace = "99"\n') + + # Create bblayers.conf + bb.utils.mkdirhier(baseoutpath + '/conf') + with open(baseoutpath + '/conf/bblayers.conf', 'w') as f: + f.write('LCONF_VERSION = "%s"\n\n' % d.getVar('LCONF_VERSION')) + f.write('BBPATH = "$' + '{TOPDIR}"\n') + f.write('SDKBASEMETAPATH = "$' + '{TOPDIR}"\n') + f.write('BBLAYERS := " \\\n') + for layerrelpath in sdkbblayers: + f.write(' $' + '{SDKBASEMETAPATH}/layers/%s \\\n' % layerrelpath) + f.write(' $' + '{SDKBASEMETAPATH}/workspace \\\n') + f.write(' "\n') + + # Create local.conf + with open(baseoutpath + '/conf/local.conf', 'w') as f: + f.write('CONF_VERSION = "%s"\n\n' % d.getVar('CONF_VERSION')) + + # This is a bit of a hack, but we really don't want these dependencies + # (we're including them in the SDK as nativesdk- versions instead) + f.write('POKYQEMUDEPS_forcevariable = ""\n\n') + + # Another hack, but we want the native part of sstate to be kept the same + # regardless of the host distro + fixedlsbstring = 'SDK-Fixed' + f.write('NATIVELSBSTRING_forcevariable = "%s"\n\n' % fixedlsbstring) + + for varname in d.getVar('SDK_META_CONF_WHITELIST', True).split(): + f.write('%s = "%s"\n' % (varname, d.getVar(varname, True))) + f.write('\nINHERIT += "externalsrc"\n\n') + f.write('require conf/locked-sigs.inc\n') + f.write('require conf/work-config.inc\n') + + # Filter the locked signatures file to just the sstate tasks we are interested in + allowed_tasks = ['do_populate_lic', 'do_populate_sysroot', 'do_packagedata', 'do_package_write', 'do_package_qa', 'do_deploy'] + inputfile = d.getVar('TOPDIR', True) + '/locked-sigs.inc' + with open(inputfile, 'r') as infile: + with open(baseoutpath + '/conf/locked-sigs.inc', 'w') as f: + invalue = False + for line in infile: + if invalue: + if line.endswith('\\\n'): + for task in allowed_tasks: + if task in line: + f.write(line) + break + else: + f.write(line) + break + elif line.startswith('SIGGEN_LOCKEDSIGS'): + invalue = True + f.write(line) + + # Create a dummy config file for additional settings + with open(baseoutpath + '/conf/work-config.inc', 'w') as f: + pass + + # Create a filtered sstate cache containing only the items in the filtered list + bb.utils.mkdirhier(baseoutpath + '/sstate-cache') + bb.note('Generating sstate-cache...') + bb.process.run("gen-lockedsig-cache %s %s %s" % (baseoutpath + '/conf/locked-sigs.inc', d.getVar('SSTATE_DIR', True), baseoutpath + '/sstate-cache')) + os.rename(baseoutpath + '/sstate-cache/' + d.getVar('NATIVELSBSTRING', True), baseoutpath + '/sstate-cache/' + fixedlsbstring) +} + +install_sdktool() { + install -d ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk} + install -m 0755 ${WORKDIR}/sdktool.py ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/sdktool +} + +toolchain_create_sdk_env_script () { + # Create minimal environment setup script + script=${SDK_OUTPUT}/${SDKPATH}/environment-setup-newsdk + rm -f $script + touch $script + EXTRAPATH="" + for i in ${CANADIANEXTRAOS}; do + EXTRAPATH="$EXTRAPATH:${SDKPATHNATIVE}${bindir_nativesdk}/${TARGET_ARCH}${TARGET_VENDOR}-$i" + done + echo 'export PATH=${SDKPATHNATIVE}${bindir_nativesdk}:${SDKPATHNATIVE}${bindir_nativesdk}/${TARGET_SYS}'$EXTRAPATH':$PATH' >> $script + echo 'export OECORE_NATIVE_SYSROOT="${SDKPATHNATIVE}"' >> $script + echo 'export PYTHONHOME=${SDKPATHNATIVE}${prefix_nativesdk}' >> $script +} + +# FIXME this preparation should be done as part of the SDK construction +sdk_postinst() { + echo done + printf "Preparing build system..." + cd $target_sdk_dir + sh -c ". layers/poky/oe-init-build-env . > /dev/null && bitbake ${SDK_TARGETS} > /dev/null" +} + +SDK_POST_INSTALL_COMMAND = "${sdk_postinst}" + +SDK_POSTPROCESS_COMMAND_prepend = "copy_buildsystem; install_sdktool; " diff --git a/meta/recipes-core/meta/meta-newsdk/sdktool.py b/meta/recipes-core/meta/meta-newsdk/sdktool.py new file mode 100644 index 0000000000..8ed48c6346 --- /dev/null +++ b/meta/recipes-core/meta/meta-newsdk/sdktool.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python + +# SDK tool +# +# Copyright (C) 2014 Intel Corporation +# +# Licensed under the MIT license, see COPYING.MIT for details + +import sys +import os +import argparse + +# FIXME these should be written out when producing the SDK +bitbake_subdir = 'layers/poky/bitbake' +init_subdir = 'layers/poky' +init_script = 'oe-init-build-env' + +basepath = os.path.abspath(__file__) +if '/sysroots/' in basepath: + basepath = basepath.split('/sysroots/')[0] + + +def read_workspace(): + workspace = {} + with open(basepath + '/conf/work-config.inc', 'r') as f: + for line in f: + if line.startswith('EXTERNALSRC_'): + splitval = line.split('=', 2) + recipe = splitval[0].split('_pn-', 2)[1].rstrip() + value = splitval[1].strip('" \n\r\t') + workspace[recipe] = value + return workspace + +def create_recipe(pn): + import bb + recipedir = os.path.join(basepath, 'workspace', pn) + bb.utils.mkdirhier(recipedir) + # FIXME: Obviously this is very crude, but we don't have a means of creating a proper recipe automatically yet + with open(os.path.join(recipedir, "%s.bb" % pn), 'w') as f: + f.write('LICENSE = "CLOSED"\n') + f.write('inherit autotools\n') + +def add(args): + workspace = read_workspace() + if args.recipename in workspace: + print("Error: recipe %s is already in your workspace" % args.recipename) + return -1 + + # FIXME we should probably do these as bbappends to avoid reparsing + with open(basepath + '/conf/work-config.inc', 'a') as f: + f.write('EXTERNALSRC_pn-%s = "%s"\n' % (args.recipename, args.srctree)) + + create_recipe(args.recipename) + + return 0 + +def status(args): + workspace = read_workspace() + for recipe, value in workspace.iteritems(): + print("%s: %s" % (recipe, value)) + return 0 + +def build(args): + import bb + stdout, stderr = bb.process.run('. %s %s ; bitbake -c install -b %s.bb' % (os.path.join(basepath, init_subdir, init_script), basepath, args.recipename), cwd=basepath) + print stdout + print stderr + + return 0 + +def main(): + global basepath + + parser = argparse.ArgumentParser(description="SDK tool") + parser.add_argument('--basepath', help='Base directory of SDK') + + subparsers = parser.add_subparsers() + parser_add = subparsers.add_parser('add', help='Add a new recipe') + parser_add.add_argument('recipename', help='Name for new recipe to add') + parser_add.add_argument('srctree', help='Path to external source tree') + parser_add.set_defaults(func=add) + + parser_status = subparsers.add_parser('status', help='Show status') + parser_status.set_defaults(func=status) + + parser_build = subparsers.add_parser('build', help='Build recipe') + parser_build.add_argument('recipename', help='Recipe to build') + parser_build.set_defaults(func=build) + + args = parser.parse_args() + + if args.basepath: + basepath = args.basepath + + if not os.path.exists(basepath + '/conf/work-config.inc'): + print('Error: basepath %s is not valid' % basepath) + return -1 + + sys.path.insert(0, os.path.join(basepath, bitbake_subdir, 'lib')) + + ret = args.func(args) + + return ret + + +if __name__ == "__main__": + try: + ret = main() + except Exception: + ret = 1 + import traceback + traceback.print_exc(5) + sys.exit(ret) -- cgit 1.2.3-korg