Ejemplo n.º 1
0
def configure(args, config, basepath, workspace):
    """Entry point for the devtool 'configure' subcommand"""

    if args.component not in workspace:
        raise DevtoolError(
            "recipe %s is not in your workspace, run devtool modify command first"
            % args.component)

    rd = ""
    tinfoil = setup_tinfoil(basepath=basepath)
    try:
        rd = parse_recipe(config,
                          tinfoil,
                          args.component,
                          appends=True,
                          filter_workspace=False)
        if not rd:
            return 1

        pn = rd.getVar('PN', True)
        if pn not in workspace:
            raise DevtoolError(
                "Run devtool modify before calling configure for %s" % pn)

    finally:
        tinfoil.shutdown()

    exec_build_env_command(config.init_path,
                           basepath,
                           'bitbake -c configure %s' % pn,
                           watch=True)

    return 0
Ejemplo n.º 2
0
def edit_recipe(args, config, basepath, workspace):
    """Entry point for the devtool 'edit-recipe' subcommand"""
    if args.any_recipe:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                return 1
            recipefile = rd.getVar('FILE', True)
        finally:
            tinfoil.shutdown()
    else:
        check_workspace_recipe(workspace, args.recipename)
        recipefile = workspace[args.recipename]['recipefile']
        if not recipefile:
            raise DevtoolError(
                "Recipe file for %s is not under the workspace" %
                args.recipename)

    editor = os.environ.get('EDITOR', None)
    if not editor:
        raise DevtoolError("EDITOR environment variable not set")

    import subprocess
    try:
        subprocess.check_call('%s "%s"' % (editor, recipefile), shell=True)
    except subprocess.CalledProcessError as e:
        return e.returncode

    return 0
Ejemplo n.º 3
0
def edit_recipe(args, config, basepath, workspace):
    """Entry point for the devtool 'edit-recipe' subcommand"""
    if args.any_recipe:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                return 1
            recipefile = rd.getVar('FILE', True)
        finally:
            tinfoil.shutdown()
    else:
        check_workspace_recipe(workspace, args.recipename)
        recipefile = workspace[args.recipename]['recipefile']
        if not recipefile:
            raise DevtoolError("Recipe file for %s is not under the workspace" %
                               args.recipename)

    editor = os.environ.get('EDITOR', None)
    if not editor:
        raise DevtoolError("EDITOR environment variable not set")

    import subprocess
    try:
        subprocess.check_call('%s "%s"' % (editor, recipefile), shell=True)
    except subprocess.CalledProcessError as e:
        return e.returncode

    return 0
Ejemplo n.º 4
0
def sdk_install(args, config, basepath, workspace):
    """Entry point for the devtool sdk-install command"""

    import oe.recipeutils
    import bb.process

    for recipe in args.recipename:
        if recipe in workspace:
            raise DevtoolError('recipe %s is a recipe in your workspace' % recipe)

    tasks = ['do_populate_sysroot', 'do_packagedata']
    stampprefixes = {}
    def checkstamp(recipe):
        stampprefix = stampprefixes[recipe]
        stamps = glob.glob(stampprefix + '*')
        for stamp in stamps:
            if '.sigdata.' not in stamp and stamp.startswith((stampprefix + '.', stampprefix + '_setscene.')):
                return True
        else:
            return False

    install_recipes = []
    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        for recipe in args.recipename:
            rd = parse_recipe(config, tinfoil, recipe, True)
            if not rd:
                return 1
            stampprefixes[recipe] = '%s.%s' % (rd.getVar('STAMP', True), tasks[0])
            if checkstamp(recipe):
                logger.info('%s is already installed' % recipe)
            else:
                install_recipes.append(recipe)
    finally:
        tinfoil.shutdown()

    if install_recipes:
        logger.info('Installing %s...' % ', '.join(install_recipes))
        install_tasks = []
        for recipe in install_recipes:
            for task in tasks:
                if recipe.endswith('-native') and 'package' in task:
                    continue
                install_tasks.append('%s:%s' % (recipe, task))
        options = ''
        if not args.allow_build:
            options += ' --setscene-only'
        try:
            exec_build_env_command(config.init_path, basepath, 'bitbake %s %s' % (options, ' '.join(install_tasks)), watch=True)
        except bb.process.ExecutionError as e:
            raise DevtoolError('Failed to install %s:\n%s' % (recipe, str(e)))
        failed = False
        for recipe in install_recipes:
            if checkstamp(recipe):
                logger.info('Successfully installed %s' % recipe)
            else:
                raise DevtoolError('Failed to install %s - unavailable' % recipe)
                failed = True
        if failed:
            return 2
Ejemplo n.º 5
0
def upgrade(args, config, basepath, workspace):
    """Entry point for the devtool 'upgrade' subcommand"""

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" %
                           args.recipename)
    if not args.version and not args.srcrev:
        raise DevtoolError(
            "You must provide a version using the --version/-V option, or for recipes that fetch from an SCM such as git, the --srcrev/-S option"
        )
    if args.srcbranch and not args.srcrev:
        raise DevtoolError(
            "If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision"
            % args.recipename)

    reason = oe.recipeutils.validate_pn(args.recipename)
    if reason:
        raise DevtoolError(reason)

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1

    pn = rd.getVar('PN', True)
    if pn != args.recipename:
        logger.info('Mapping %s to %s' % (args.recipename, pn))
    if pn in workspace:
        raise DevtoolError("recipe %s is already in your workspace" % pn)

    standard._check_compatible_recipe(pn, rd)
    if rd.getVar('PV', True) == args.version and rd.getVar(
            'SRCREV', True) == args.srcrev:
        raise DevtoolError(
            "Current and upgrade versions are the same version" % version)

    rf = None
    try:
        rev1 = standard._extract_source(args.srctree, False, 'devtool-orig',
                                        False, rd)
        rev2, md5, sha256 = _extract_new_source(args.version, args.srctree,
                                                args.no_patch, args.srcrev,
                                                args.branch, args.keep_temp,
                                                tinfoil, rd)
        rf = _create_new_recipe(args.version, md5, sha256, args.srcrev,
                                args.srcbranch, config.workspace_path, tinfoil,
                                rd)
    except bb.process.CmdError as e:
        _upgrade_error(e, rf, args.srctree)
    except DevtoolError as e:
        _upgrade_error(e, rf, args.srctree)
    standard._add_md5(config, pn, os.path.dirname(rf))

    af = _write_append(rf, args.srctree, args.same_dir, args.no_same_dir, rev2,
                       config.workspace_path, rd)
    standard._add_md5(config, pn, af)
    logger.info('Upgraded source extracted to %s' % args.srctree)
    return 0
Ejemplo n.º 6
0
 def print_match(pn):
     rd = parse_recipe(config, tinfoil, pn, True)
     if not rd:
         return
     summary = rd.getVar('SUMMARY')
     if summary == rd.expand(defsummary):
         summary = ''
     print("%s  %s" % (pn.ljust(20), summary))
 def print_match(pn):
     rd = parse_recipe(config, tinfoil, pn, True)
     if not rd:
         return
     summary = rd.getVar('SUMMARY')
     if summary == rd.expand(defsummary):
         summary = ''
     print("%s  %s" % (pn.ljust(20), summary))
Ejemplo n.º 8
0
def search(args, config, basepath, workspace):
    """Entry point for the devtool 'search' subcommand"""

    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR')
        defsummary = tinfoil.config_data.getVar('SUMMARY', False) or ''

        keyword_rc = re.compile(args.keyword)

        for fn in os.listdir(pkgdata_dir):
            pfn = os.path.join(pkgdata_dir, fn)
            if not os.path.isfile(pfn):
                continue

            packages = []
            match = False
            if keyword_rc.search(fn):
                match = True

            if not match:
                with open(pfn, 'r') as f:
                    for line in f:
                        if line.startswith('PACKAGES:'):
                            packages = line.split(':', 1)[1].strip().split()

                for pkg in packages:
                    if keyword_rc.search(pkg):
                        match = True
                        break
                    if os.path.exists(
                            os.path.join(pkgdata_dir, 'runtime',
                                         pkg + '.packaged')):
                        with open(os.path.join(pkgdata_dir, 'runtime', pkg),
                                  'r') as f:
                            for line in f:
                                if ': ' in line:
                                    splitline = line.split(':', 1)
                                    key = splitline[0]
                                    value = splitline[1].strip()
                                if key in [
                                        'PKG_%s' % pkg, 'DESCRIPTION',
                                        'FILES_INFO'
                                ] or key.startswith('FILERPROVIDES_'):
                                    if keyword_rc.search(value):
                                        match = True
                                        break

            if match:
                rd = parse_recipe(config, tinfoil, fn, True)
                summary = rd.getVar('SUMMARY')
                if summary == rd.expand(defsummary):
                    summary = ''
                print("%s  %s" % (fn.ljust(20), summary))
    finally:
        tinfoil.shutdown()

    return 0
Ejemplo n.º 9
0
Archivo: upgrade.py Proyecto: kacf/poky
def upgrade(args, config, basepath, workspace):
    """Entry point for the devtool 'upgrade' subcommand"""

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" % args.recipename)
    if not args.version and not args.srcrev:
        raise DevtoolError("You must provide a version using the --version/-V option, or for recipes that fetch from an SCM such as git, the --srcrev/-S option")
    if args.srcbranch and not args.srcrev:
        raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename)

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        pn = rd.getVar('PN')
        if pn != args.recipename:
            logger.info('Mapping %s to %s' % (args.recipename, pn))
        if pn in workspace:
            raise DevtoolError("recipe %s is already in your workspace" % pn)

        if args.srctree:
            srctree = os.path.abspath(args.srctree)
        else:
            srctree = standard.get_default_srctree(config, pn)

        standard._check_compatible_recipe(pn, rd)
        old_srcrev = rd.getVar('SRCREV')
        if old_srcrev == 'INVALID':
            old_srcrev = None
        if old_srcrev and not args.srcrev:
            raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading")
        if rd.getVar('PV') == args.version and old_srcrev == args.srcrev:
            raise DevtoolError("Current and upgrade versions are the same version")

        rf = None
        try:
            rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, rd, tinfoil)
            rev2, md5, sha256 = _extract_new_source(args.version, srctree, args.no_patch,
                                                    args.srcrev, args.branch, args.keep_temp,
                                                    tinfoil, rd)
            rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, args.srcbranch, config.workspace_path, tinfoil, rd)
        except bb.process.CmdError as e:
            _upgrade_error(e, rf, srctree)
        except DevtoolError as e:
            _upgrade_error(e, rf, srctree)
        standard._add_md5(config, pn, os.path.dirname(rf))

        af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2,
                        copied, config.workspace_path, rd)
        standard._add_md5(config, pn, af)
        logger.info('Upgraded source extracted to %s' % srctree)
        logger.info('New recipe is %s' % rf)
    finally:
        tinfoil.shutdown()
    return 0
Ejemplo n.º 10
0
def upgrade(args, config, basepath, workspace):
    """Entry point for the devtool 'upgrade' subcommand"""

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" % args.recipename)
    if not args.version and not args.srcrev:
        raise DevtoolError("You must provide a version using the --version/-V option, or for recipes that fetch from an SCM such as git, the --srcrev/-S option")
    if args.srcbranch and not args.srcrev:
        raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename)

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        pn = rd.getVar('PN')
        if pn != args.recipename:
            logger.info('Mapping %s to %s' % (args.recipename, pn))
        if pn in workspace:
            raise DevtoolError("recipe %s is already in your workspace" % pn)

        if args.srctree:
            srctree = os.path.abspath(args.srctree)
        else:
            srctree = standard.get_default_srctree(config, pn)

        standard._check_compatible_recipe(pn, rd)
        old_srcrev = rd.getVar('SRCREV')
        if old_srcrev == 'INVALID':
            old_srcrev = None
        if old_srcrev and not args.srcrev:
            raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading")
        if rd.getVar('PV') == args.version and old_srcrev == args.srcrev:
            raise DevtoolError("Current and upgrade versions are the same version")

        rf = None
        try:
            rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, rd, tinfoil)
            rev2, md5, sha256 = _extract_new_source(args.version, srctree, args.no_patch,
                                                    args.srcrev, args.branch, args.keep_temp,
                                                    tinfoil, rd)
            rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, args.srcbranch, config.workspace_path, tinfoil, rd)
        except bb.process.CmdError as e:
            _upgrade_error(e, rf, srctree)
        except DevtoolError as e:
            _upgrade_error(e, rf, srctree)
        standard._add_md5(config, pn, os.path.dirname(rf))

        af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2,
                        copied, config.workspace_path, rd)
        standard._add_md5(config, pn, af)
        logger.info('Upgraded source extracted to %s' % srctree)
        logger.info('New recipe is %s' % rf)
    finally:
        tinfoil.shutdown()
    return 0
Ejemplo n.º 11
0
def _get_packages(tinfoil, workspace, config):
    """Get list of packages from recipes in the workspace."""
    result = []
    for recipe in workspace:
        data = parse_recipe(config, tinfoil, recipe, True)
        if "class-target" in data.getVar("OVERRIDES", True).split(":"):
            if recipe in data.getVar("PACKAGES", True):
                result.append(recipe)
            else:
                logger.warning("Skipping recipe %s as it doesn't produce a " "package with the same name", recipe)
    return result
Ejemplo n.º 12
0
def menuconfig(args, config, basepath, workspace):
    """Entry point for the devtool 'menuconfig' subcommand"""

    rd = ""
    kconfigpath = ""
    pn_src = ""
    localfilesdir = ""
    workspace_dir = ""
    tinfoil = setup_tinfoil(basepath=basepath)
    try:
        rd = parse_recipe(config,
                          tinfoil,
                          args.component,
                          appends=True,
                          filter_workspace=False)
        if not rd:
            return 1

        check_workspace_recipe(workspace, args.component)
        pn = rd.getVar('PN', True)

        if not rd.getVarFlag('do_menuconfig', 'task'):
            raise DevtoolError(
                "This recipe does not support menuconfig option")

        workspace_dir = os.path.join(config.workspace_path, 'sources')
        kconfigpath = rd.getVar('B')
        pn_src = os.path.join(workspace_dir, pn)

        # add check to see if oe_local_files exists or not
        localfilesdir = os.path.join(pn_src, 'oe-local-files')
        if not os.path.exists(localfilesdir):
            bb.utils.mkdirhier(localfilesdir)
            # Add gitignore to ensure source tree is clean
            gitignorefile = os.path.join(localfilesdir, '.gitignore')
            with open(gitignorefile, 'w') as f:
                f.write(
                    '# Ignore local files, by default. Remove this file if you want to commit the directory to Git\n'
                )
                f.write('*\n')

    finally:
        tinfoil.shutdown()

    logger.info('Launching menuconfig')
    exec_build_env_command(config.init_path,
                           basepath,
                           'bitbake -c menuconfig %s' % pn,
                           watch=True)
    fragment = os.path.join(localfilesdir, 'devtool-fragment.cfg')
    res = standard._create_kconfig_diff(pn_src, rd, fragment)

    return 0
def _get_packages(tinfoil, workspace, config):
    """Get list of packages from recipes in the workspace."""
    result = []
    for recipe in workspace:
        data = parse_recipe(config, tinfoil, recipe, True)
        if 'class-target' in data.getVar('OVERRIDES').split(':'):
            if recipe in data.getVar('PACKAGES').split():
                result.append(recipe)
            else:
                logger.warning("Skipping recipe %s as it doesn't produce a "
                               "package with the same name", recipe)
    return result
Ejemplo n.º 14
0
def search(args, config, basepath, workspace):
    """Entry point for the devtool 'search' subcommand"""

    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR', True)
        defsummary = tinfoil.config_data.getVar('SUMMARY', False) or ''

        keyword_rc = re.compile(args.keyword)

        for fn in os.listdir(pkgdata_dir):
            pfn = os.path.join(pkgdata_dir, fn)
            if not os.path.isfile(pfn):
                continue

            packages = []
            match = False
            if keyword_rc.search(fn):
                match = True

            if not match:
                with open(pfn, 'r') as f:
                    for line in f:
                        if line.startswith('PACKAGES:'):
                            packages = line.split(':', 1)[1].strip().split()

                for pkg in packages:
                    if keyword_rc.search(pkg):
                        match = True
                        break
                    if os.path.exists(os.path.join(pkgdata_dir, 'runtime', pkg + '.packaged')):
                        with open(os.path.join(pkgdata_dir, 'runtime', pkg), 'r') as f:
                            for line in f:
                                if ': ' in line:
                                    splitline = line.split(':', 1)
                                    key = splitline[0]
                                    value = splitline[1].strip()
                                if key in ['PKG_%s' % pkg, 'DESCRIPTION', 'FILES_INFO'] or key.startswith('FILERPROVIDES_'):
                                    if keyword_rc.search(value):
                                        match = True
                                        break

            if match:
                rd = parse_recipe(config, tinfoil, fn, True)
                summary = rd.getVar('SUMMARY', True)
                if summary == rd.expand(defsummary):
                    summary = ''
                print("%s  %s" % (fn.ljust(20), summary))
    finally:
        tinfoil.shutdown()

    return 0
Ejemplo n.º 15
0
def _get_recipes(workspace, config):
    """Get list of target recipes from the workspace."""
    result = []
    tinfoil = setup_tinfoil()
    for recipe in workspace:
        data = parse_recipe(config, tinfoil, recipe, True)
        if 'class-target' in data.getVar('OVERRIDES', True).split(':'):
            if recipe in data.getVar('PACKAGES', True):
                result.append(recipe)
            else:
                logger.warning("Skipping recipe %s as it doesn't produce "
                               "package with the same name", recipe)
    tinfoil.shutdown()
    return result
Ejemplo n.º 16
0
def build(args, config, basepath, workspace):
    """Entry point for the devtool 'build' subcommand"""
    workspacepn = check_workspace_recipe(workspace,
                                         args.recipename,
                                         bbclassextend=True)
    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        rd = parse_recipe(config,
                          tinfoil,
                          args.recipename,
                          appends=True,
                          filter_workspace=False)
        if not rd:
            return 1
        deploytask = 'do_deploy' in rd.getVar('__BBTASKS')
    finally:
        tinfoil.shutdown()

    if args.clean:
        # use clean instead of cleansstate to avoid messing things up in eSDK
        build_tasks = ['do_clean']
    else:
        build_tasks = _get_build_tasks(config)
        if deploytask:
            build_tasks.append('do_deploy')

    bbappend = workspace[workspacepn]['bbappend']
    if args.disable_parallel_make:
        logger.info("Disabling 'make' parallelism")
        _set_file_values(bbappend, {'PARALLEL_MAKE': ''})
    try:
        bbargs = []
        for task in build_tasks:
            if args.recipename.endswith('-native') and 'package' in task:
                continue
            bbargs.append('%s:%s' % (args.recipename, task))
        exec_build_env_command(config.init_path,
                               basepath,
                               'bitbake %s' % ' '.join(bbargs),
                               watch=True)
    except bb.process.ExecutionError as e:
        # We've already seen the output since watch=True, so just ensure we return something to the user
        return e.exitcode
    finally:
        if args.disable_parallel_make:
            _set_file_values(bbappend, {'PARALLEL_MAKE': None})

    return 0
Ejemplo n.º 17
0
def upgrade(args, config, basepath, workspace):
    """Entry point for the devtool 'upgrade' subcommand"""

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" % args.recipename)
    if not args.version and not args.srcrev:
        raise DevtoolError("You must provide a version using the --version/-V option, or for recipes that fetch from an SCM such as git, the --srcrev/-S option")
    if args.srcbranch and not args.srcrev:
        raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename)

    reason = oe.recipeutils.validate_pn(args.recipename)
    if reason:
        raise DevtoolError(reason)

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1

    pn = rd.getVar('PN', True)
    if pn != args.recipename:
        logger.info('Mapping %s to %s' % (args.recipename, pn))
    if pn in workspace:
        raise DevtoolError("recipe %s is already in your workspace" % pn)

    standard._check_compatible_recipe(pn, rd)
    if rd.getVar('PV', True) == args.version and rd.getVar('SRCREV', True) == args.srcrev:
        raise DevtoolError("Current and upgrade versions are the same version" % version)

    rf = None
    try:
        rev1 = standard._extract_source(args.srctree, False, 'devtool-orig', False, rd)
        rev2, md5, sha256 = _extract_new_source(args.version, args.srctree, args.no_patch,
                                                args.srcrev, args.branch, args.keep_temp,
                                                tinfoil, rd)
        rf = _create_new_recipe(args.version, md5, sha256, args.srcrev, args.srcbranch, config.workspace_path, tinfoil, rd)
    except bb.process.CmdError as e:
        _upgrade_error(e, rf, args.srctree)
    except DevtoolError as e:
        _upgrade_error(e, rf, args.srctree)
    standard._add_md5(config, pn, os.path.dirname(rf))

    af = _write_append(rf, args.srctree, args.same_dir, args.no_same_dir, rev2,
                       config.workspace_path, rd)
    standard._add_md5(config, pn, af)
    logger.info('Upgraded source extracted to %s' % args.srctree)
    return 0
Ejemplo n.º 18
0
def _prep_extract_operation(config, basepath, recipename):
    """HACK: Ugly workaround for making sure that requirements are met when
       trying to extract a package. Returns the tinfoil instance to be used."""
    tinfoil = setup_tinfoil()
    rd = parse_recipe(config, tinfoil, recipename, True)

    if bb.data.inherits_class('kernel-yocto', rd):
        tinfoil.shutdown()
        try:
            stdout, _ = exec_build_env_command(config.init_path, basepath,
                                               'bitbake kern-tools-native')
            tinfoil = setup_tinfoil()
        except bb.process.ExecutionError as err:
            raise DevtoolError("Failed to build kern-tools-native:\n%s" %
                               err.stdout)
    return tinfoil
Ejemplo n.º 19
0
def _prep_extract_operation(config, basepath, recipename):
    """HACK: Ugly workaround for making sure that requirements are met when
       trying to extract a package. Returns the tinfoil instance to be used."""
    tinfoil = setup_tinfoil(basepath=basepath)
    rd = parse_recipe(config, tinfoil, recipename, True)

    if bb.data.inherits_class('kernel-yocto', rd):
        tinfoil.shutdown()
        try:
            stdout, _ = exec_build_env_command(config.init_path, basepath,
                                               'bitbake kern-tools-native')
            tinfoil = setup_tinfoil(basepath=basepath)
        except bb.process.ExecutionError as err:
            raise DevtoolError("Failed to build kern-tools-native:\n%s" %
                               err.stdout)
    return tinfoil
Ejemplo n.º 20
0
def _find_recipe_path(args, config, basepath, workspace):
    if args.any_recipe:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                raise DevtoolError("Failed to find specified recipe")
            recipefile = rd.getVar('FILE')
        finally:
            tinfoil.shutdown()
    else:
        check_workspace_recipe(workspace, args.recipename)
        recipefile = workspace[args.recipename]['recipefile']
        if not recipefile:
            raise DevtoolError("Recipe file for %s is not under the workspace" %
                               args.recipename)
    return recipefile
Ejemplo n.º 21
0
def find_recipe(args, config, basepath, workspace):
    """Entry point for the devtool 'find-recipe' subcommand"""
    if args.any_recipe:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                return 1
            recipefile = rd.getVar('FILE')
        finally:
            tinfoil.shutdown()
    else:
        check_workspace_recipe(workspace, args.recipename)
        recipefile = workspace[args.recipename]['recipefile']
        if not recipefile:
            raise DevtoolError("Recipe file for %s is not under the workspace" %
                               args.recipename)
Ejemplo n.º 22
0
def _find_recipe_path(args, config, basepath, workspace):
    if args.any_recipe:
        logger.warning('-a/--any-recipe option is now always active, and thus the option will be removed in a future release')
    if args.recipename in workspace:
        recipefile = workspace[args.recipename]['recipefile']
    else:
        recipefile = None
    if not recipefile:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                raise DevtoolError("Failed to find specified recipe")
            recipefile = rd.getVar('FILE')
        finally:
            tinfoil.shutdown()
    return recipefile
Ejemplo n.º 23
0
def _find_recipe_path(args, config, basepath, workspace):
    if args.any_recipe:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                raise DevtoolError("Failed to find specified recipe")
            recipefile = rd.getVar('FILE')
        finally:
            tinfoil.shutdown()
    else:
        check_workspace_recipe(workspace, args.recipename)
        recipefile = workspace[args.recipename]['recipefile']
        if not recipefile:
            raise DevtoolError(
                "Recipe file for %s is not under the workspace" %
                args.recipename)
    return recipefile
Ejemplo n.º 24
0
def extract(args, config, basepath, workspace):
    """Entry point for the devtool 'extract' subcommand"""
    import bb

    tinfoil = _prep_extract_operation(config, basepath, args.recipename)

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1

    srctree = os.path.abspath(args.srctree)
    initial_rev = _extract_source(srctree, args.keep_temp, args.branch, rd)
    logger.info('Source tree extracted to %s' % srctree)

    if initial_rev:
        return 0
    else:
        return 1
Ejemplo n.º 25
0
def extract(args, config, basepath, workspace):
    """Entry point for the devtool 'extract' subcommand"""
    import bb

    tinfoil = _prep_extract_operation(config, basepath, args.recipename)

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1

    srctree = os.path.abspath(args.srctree)
    initial_rev = _extract_source(srctree, args.keep_temp, args.branch, rd)
    logger.info('Source tree extracted to %s' % srctree)

    if initial_rev:
        return 0
    else:
        return 1
Ejemplo n.º 26
0
def kernel_menuconfig(args, config, basepath, workspace):
    """Entry point for the devtool 'kernel-menuconfig' subcommand"""

    # FIXME we end up with a triple parse here which is ugly (one for
    # the initial tinfoil instantiation, one for the modify, and then
    # finally one for the call to bitbake). Unfortunately it's
    # unavoidable without significant refactoring though so that will
    # have to wait until next release.

    tinfoil = setup_tinfoil(basepath=basepath)
    try:
        tinfoil.prepare(config_only=False)

        rd = parse_recipe(config, tinfoil, 'virtual/kernel', appends=True, filter_workspace=False)
        if not rd:
            return 1
        pn = rd.getVar('PN', True)
        # We need to do this carefully as the version will change as a result of running devtool modify
        ver = rd.expand('${EXTENDPE}${PV}-${PR}')
        taintfn = (rd.getVar('STAMP', True) + '.do_compile.taint').replace(ver, '*')
    finally:
        tinfoil.shutdown()

    if not pn in workspace:
        # FIXME this will break if any options are added to the modify
        # subcommand.
        margs = argparse.Namespace()
        margs.recipename = pn
        margs.srctree = None
        margs.wildcard = False
        margs.extract = True
        margs.no_extract = False
        margs.same_dir = False
        margs.no_same_dir = False
        margs.branch = 'devtool'
        standard.modify(margs, config, basepath, workspace)

    exec_build_env_command(config.init_path, basepath, 'bitbake -c menuconfig %s' % pn, watch=True)

    # Remove taint created by do_menuconfig, if any
    for fn in glob.glob(taintfn):
        os.remove(fn)

    return 0
Ejemplo n.º 27
0
def edit_recipe(args, config, basepath, workspace):
    """Entry point for the devtool 'edit-recipe' subcommand"""
    if args.any_recipe:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                return 1
            recipefile = rd.getVar('FILE')
        finally:
            tinfoil.shutdown()
    else:
        check_workspace_recipe(workspace, args.recipename)
        recipefile = workspace[args.recipename]['recipefile']
        if not recipefile:
            raise DevtoolError("Recipe file for %s is not under the workspace" %
                               args.recipename)

    return scriptutils.run_editor(recipefile)
Ejemplo n.º 28
0
def _find_recipe_path(args, config, basepath, workspace):
    if args.any_recipe:
        logger.warning(
            '-a/--any-recipe option is now always active, and thus the option will be removed in a future release'
        )
    if args.recipename in workspace:
        recipefile = workspace[args.recipename]['recipefile']
    else:
        recipefile = None
    if not recipefile:
        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
        try:
            rd = parse_recipe(config, tinfoil, args.recipename, True)
            if not rd:
                raise DevtoolError("Failed to find specified recipe")
            recipefile = rd.getVar('FILE')
        finally:
            tinfoil.shutdown()
    return recipefile
Ejemplo n.º 29
0
def latest_version(args, config, basepath, workspace):
    """Entry point for the devtool 'latest_version' subcommand"""
    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1
        version_info = oe.recipeutils.get_recipe_upstream_version(rd)
        # "new-commits-available" is an indication that upstream never issues version tags
        if not version_info['version'].endswith("new-commits-available"):
            logger.info("Current version: {}".format(version_info['current_version']))
            logger.info("Latest version: {}".format(version_info['version']))
            if version_info['revision']:
                logger.info("Latest version's commit: {}".format(version_info['revision']))
        else:
            logger.info("Latest commit: {}".format(version_info['revision']))
    finally:
        tinfoil.shutdown()
    return 0
Ejemplo n.º 30
0
def latest_version(args, config, basepath, workspace):
    """Entry point for the devtool 'latest_version' subcommand"""
    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1
        version_info = oe.recipeutils.get_recipe_upstream_version(rd)
        # "new-commits-available" is an indication that upstream never issues version tags
        if not version_info['version'].endswith("new-commits-available"):
            logger.info("Current version: {}".format(version_info['current_version']))
            logger.info("Latest version: {}".format(version_info['version']))
            if version_info['revision']:
                logger.info("Latest version's commit: {}".format(version_info['revision']))
        else:
            logger.info("Latest commit: {}".format(version_info['revision']))
    finally:
        tinfoil.shutdown()
    return 0
Ejemplo n.º 31
0
def update_recipe(args, config, basepath, workspace):
    """Entry point for the devtool 'update-recipe' subcommand"""
    if not args.recipename in workspace:
        raise DevtoolError("no recipe named %s in your workspace" %
                           args.recipename)

    if args.append:
        if not os.path.exists(args.append):
            raise DevtoolError('bbappend destination layer directory "%s" '
                               'does not exist' % args.append)
        if not os.path.exists(os.path.join(args.append, 'conf', 'layer.conf')):
            raise DevtoolError('conf/layer.conf not found in bbappend '
                               'destination layer "%s"' % args.append)

    tinfoil = setup_tinfoil()

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1

    srctree = workspace[args.recipename]['srctree']
    if args.mode == 'auto':
        mode = _guess_recipe_update_mode(srctree, rd)
    else:
        mode = args.mode

    if mode == 'srcrev':
        _update_recipe_srcrev(args, srctree, rd, tinfoil.config_data)
    elif mode == 'patch':
        _update_recipe_patch(args, config, srctree, rd, tinfoil.config_data)
    else:
        raise DevtoolError('update_recipe: invalid mode %s' % mode)

    rf = rd.getVar('FILE', True)
    if rf.startswith(config.workspace_path):
        logger.warn(
            'Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes'
            % rf)

    return 0
Ejemplo n.º 32
0
def update_recipe(args, config, basepath, workspace):
    """Entry point for the devtool 'update-recipe' subcommand"""
    if not args.recipename in workspace:
        raise DevtoolError("no recipe named %s in your workspace" %
                           args.recipename)

    if args.append:
        if not os.path.exists(args.append):
            raise DevtoolError('bbappend destination layer directory "%s" '
                               'does not exist' % args.append)
        if not os.path.exists(os.path.join(args.append, 'conf', 'layer.conf')):
            raise DevtoolError('conf/layer.conf not found in bbappend '
                               'destination layer "%s"' % args.append)

    tinfoil = setup_tinfoil()

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1

    srctree = workspace[args.recipename]['srctree']
    if args.mode == 'auto':
        mode = _guess_recipe_update_mode(srctree, rd)
    else:
        mode = args.mode

    if mode == 'srcrev':
        _update_recipe_srcrev(args, srctree, rd, tinfoil.config_data)
    elif mode == 'patch':
        _update_recipe_patch(args, config, srctree, rd, tinfoil.config_data)
    else:
        raise DevtoolError('update_recipe: invalid mode %s' % mode)

    rf = rd.getVar('FILE', True)
    if rf.startswith(config.workspace_path):
        logger.warn('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf)

    return 0
Ejemplo n.º 33
0
def build_image(args, config, basepath, workspace):
    """Entry point for the devtool 'build-image' subcommand."""

    image = args.imagename
    auto_image = False
    if not image:
        sdk_targets = config.get('SDK', 'sdk_targets', '').split()
        if sdk_targets:
            image = sdk_targets[0]
            auto_image = True
    if not image:
        raise DevtoolError('Unable to determine image to build, please specify one')

    appendfile = os.path.join(config.workspace_path, 'appends',
                              '%s.bbappend' % image)

    # remove <image>.bbappend to make sure setup_tinfoil doesn't
    # break because of it
    if os.path.isfile(appendfile):
        os.unlink(appendfile)

    tinfoil = setup_tinfoil(basepath=basepath)
    rd = parse_recipe(config, tinfoil, image, True)
    if not rd:
        # Error already shown
        return 1
    if not bb.data.inherits_class('image', rd):
        if auto_image:
            raise DevtoolError('Unable to determine image to build, please specify one')
        else:
            raise DevtoolError('Specified recipe %s is not an image recipe' % image)

    try:
        if workspace:
            packages = _get_packages(tinfoil, workspace, config)
            if packages:
                with open(appendfile, 'w') as afile:
                    # include packages from workspace recipes into the image
                    afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages))
                    logger.info('Building image %s with the following '
                                'additional packages: %s', image, ' '.join(packages))
            else:
                logger.warning('No packages to add, building image %s unmodified', image)
        else:
            logger.warning('No recipes in workspace, building image %s unmodified', image)

        deploy_dir_image = tinfoil.config_data.getVar('DEPLOY_DIR_IMAGE', True)

        tinfoil.shutdown()

        # run bitbake to build image
        try:
            exec_build_env_command(config.init_path, basepath,
                                'bitbake %s' % image, watch=True)
        except ExecutionError as err:
            return err.exitcode
    finally:
        if os.path.isfile(appendfile):
            os.unlink(appendfile)

    logger.info('Successfully built %s. You can find output files in %s'
                % (image, deploy_dir_image))
Ejemplo n.º 34
0
def upgrade(args, config, basepath, workspace):
    """Entry point for the devtool 'upgrade' subcommand"""

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" %
                           args.recipename)
    if args.srcbranch and not args.srcrev:
        raise DevtoolError(
            "If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision"
            % args.recipename)

    _check_git_config()

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        pn = rd.getVar('PN')
        if pn != args.recipename:
            logger.info('Mapping %s to %s' % (args.recipename, pn))
        if pn in workspace:
            raise DevtoolError("recipe %s is already in your workspace" % pn)

        if args.srctree:
            srctree = os.path.abspath(args.srctree)
        else:
            srctree = standard.get_default_srctree(config, pn)

        # try to automatically discover latest version and revision if not provided on command line
        if not args.version and not args.srcrev:
            version_info = oe.recipeutils.get_recipe_upstream_version(rd)
            if version_info['version'] and not version_info[
                    'version'].endswith("new-commits-available"):
                args.version = version_info['version']
            if version_info['revision']:
                args.srcrev = version_info['revision']
        if not args.version and not args.srcrev:
            raise DevtoolError(
                "Automatic discovery of latest version/revision failed - you must provide a version using the --version/-V option, or for recipes that fetch from an SCM such as git, the --srcrev/-S option."
            )

        standard._check_compatible_recipe(pn, rd)
        old_srcrev = rd.getVar('SRCREV')
        if old_srcrev == 'INVALID':
            old_srcrev = None
        if old_srcrev and not args.srcrev:
            raise DevtoolError(
                "Recipe specifies a SRCREV value; you must specify a new one when upgrading"
            )
        old_ver = rd.getVar('PV')
        if old_ver == args.version and old_srcrev == args.srcrev:
            raise DevtoolError(
                "Current and upgrade versions are the same version")
        if args.version:
            if bb.utils.vercmp_string(args.version, old_ver) < 0:
                logger.warning(
                    'Upgrade version %s compares as less than the current version %s. If you are using a package feed for on-target upgrades or providing this recipe for general consumption, then you should increment PE in the recipe (or if there is no current PE value set, set it to "1")'
                    % (args.version, old_ver))
            check_prerelease_version(args.version, 'devtool upgrade')

        rf = None
        license_diff = None
        try:
            logger.info('Extracting current version source...')
            rev1, srcsubdir1 = standard._extract_source(
                srctree,
                False,
                'devtool-orig',
                False,
                config,
                basepath,
                workspace,
                args.fixed_setup,
                rd,
                tinfoil,
                no_overrides=args.no_overrides)
            old_licenses = _extract_licenses(srctree,
                                             rd.getVar('LIC_FILES_CHKSUM'))
            logger.info('Extracting upgraded version source...')
            rev2, md5, sha256, srcbranch, srcsubdir2 = _extract_new_source(
                args.version, srctree, args.no_patch, args.srcrev,
                args.srcbranch, args.branch, args.keep_temp, tinfoil, rd)
            new_licenses = _extract_licenses(srctree,
                                             rd.getVar('LIC_FILES_CHKSUM'))
            license_diff = _generate_license_diff(old_licenses, new_licenses)
            rf, copied = _create_new_recipe(args.version, md5, sha256,
                                            args.srcrev, srcbranch, srcsubdir1,
                                            srcsubdir2, config.workspace_path,
                                            tinfoil, rd, license_diff,
                                            new_licenses)
        except bb.process.CmdError as e:
            _upgrade_error(e, rf, srctree)
        except DevtoolError as e:
            _upgrade_error(e, rf, srctree)
        standard._add_md5(config, pn, os.path.dirname(rf))

        af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2,
                           copied, config.workspace_path, rd)
        standard._add_md5(config, pn, af)

        update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn])

        logger.info('Upgraded source extracted to %s' % srctree)
        logger.info('New recipe is %s' % rf)
        if license_diff:
            logger.info(
                'License checksums have been updated in the new recipe; please refer to it for the difference between the old and the new license texts.'
            )
    finally:
        tinfoil.shutdown()
    return 0
Ejemplo n.º 35
0
def build_image_task(config, basepath, workspace, image, add_packages=None, task=None, extra_append=None):
    # remove <image>.bbappend to make sure setup_tinfoil doesn't
    # break because of it
    target_basename = config.get('SDK', 'target_basename', '')
    if target_basename:
        appendfile = os.path.join(config.workspace_path, 'appends',
                                  '%s.bbappend' % target_basename)
        try:
            os.unlink(appendfile)
        except OSError as exc:
            if exc.errno != errno.ENOENT:
                raise

    tinfoil = setup_tinfoil(basepath=basepath)
    rd = parse_recipe(config, tinfoil, image, True)
    if not rd:
        # Error already shown
        return (1, None)
    if not bb.data.inherits_class('image', rd):
        raise TargetNotImageError()

    # Get the actual filename used and strip the .bb and full path
    target_basename = rd.getVar('FILE', True)
    target_basename = os.path.splitext(os.path.basename(target_basename))[0]
    config.set('SDK', 'target_basename', target_basename)
    config.write()

    appendfile = os.path.join(config.workspace_path, 'appends',
                              '%s.bbappend' % target_basename)

    outputdir = None
    try:
        if workspace or add_packages:
            if add_packages:
                packages = add_packages
            else:
                packages = _get_packages(tinfoil, workspace, config)
        else:
            packages = None
        if not task:
            if not packages and not add_packages and workspace:
                logger.warning('No recipes in workspace, building image %s unmodified', image)
            elif not packages:
                logger.warning('No packages to add, building image %s unmodified', image)

        if packages or extra_append:
            bb.utils.mkdirhier(os.path.dirname(appendfile))
            with open(appendfile, 'w') as afile:
                if packages:
                    # include packages from workspace recipes into the image
                    afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages))
                    if not task:
                        logger.info('Building image %s with the following '
                                    'additional packages: %s', image, ' '.join(packages))
                if extra_append:
                    for line in extra_append:
                        afile.write('%s\n' % line)

        if task in ['populate_sdk', 'populate_sdk_ext']:
            outputdir = rd.getVar('SDK_DEPLOY', True)
        else:
            outputdir = rd.getVar('DEPLOY_DIR_IMAGE', True)

        tinfoil.shutdown()

        options = ''
        if task:
            options += '-c %s' % task

        # run bitbake to build image (or specified task)
        try:
            exec_build_env_command(config.init_path, basepath,
                                   'bitbake %s %s' % (options, image), watch=True)
        except ExecutionError as err:
            return (err.exitcode, None)
    finally:
        if os.path.isfile(appendfile):
            os.unlink(appendfile)
    return (0, outputdir)
Ejemplo n.º 36
0
def configure_help(args, config, basepath, workspace):
    """Entry point for the devtool 'configure-help' subcommand"""
    import oe.utils

    check_workspace_recipe(workspace, args.recipename)
    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        rd = parse_recipe(config,
                          tinfoil,
                          args.recipename,
                          appends=True,
                          filter_workspace=False)
        if not rd:
            return 1
        b = rd.getVar('B', True)
        s = rd.getVar('S', True)
        configurescript = os.path.join(s, 'configure')
        confdisabled = 'noexec' in rd.getVarFlags(
            'do_configure') or 'do_configure' not in (rd.getVar(
                '__BBTASKS', False) or [])
        configureopts = oe.utils.squashspaces(
            rd.getVar('CONFIGUREOPTS', True) or '')
        extra_oeconf = oe.utils.squashspaces(
            rd.getVar('EXTRA_OECONF', True) or '')
        extra_oecmake = oe.utils.squashspaces(
            rd.getVar('EXTRA_OECMAKE', True) or '')
        do_configure = rd.getVar('do_configure', True) or ''
        do_configure_noexpand = rd.getVar('do_configure', False) or ''
        packageconfig = rd.getVarFlags('PACKAGECONFIG') or []
        autotools = bb.data.inherits_class(
            'autotools', rd) and ('oe_runconf' in do_configure
                                  or 'autotools_do_configure' in do_configure)
        cmake = bb.data.inherits_class('cmake', rd) and ('cmake_do_configure'
                                                         in do_configure)
        cmake_do_configure = rd.getVar('cmake_do_configure', True)
        pn = rd.getVar('PN', True)
    finally:
        tinfoil.shutdown()

    if 'doc' in packageconfig:
        del packageconfig['doc']

    if autotools and not os.path.exists(configurescript):
        logger.info('Running do_configure to generate configure script')
        try:
            stdout, _ = exec_build_env_command(config.init_path,
                                               basepath,
                                               'bitbake -c configure %s' % msg,
                                               args.recipename,
                                               stderr=subprocess.STDOUT)
        except bb.process.ExecutionError:
            pass

    if confdisabled or do_configure.strip() in ('', ':'):
        raise DevtoolError(
            "do_configure task has been disabled for this recipe")
    elif args.no_pager and not os.path.exists(configurescript):
        raise DevtoolError(
            "No configure script found and no other information to display")
    else:
        configopttext = ''
        if autotools and configureopts:
            configopttext = '''
Arguments currently passed to the configure script:

%s

Some of those are fixed.''' % (configureopts + ' ' + extra_oeconf)
            if extra_oeconf:
                configopttext += ''' The ones that are specified through EXTRA_OECONF (which you can change or add to easily):

%s''' % extra_oeconf

        elif cmake:
            in_cmake = False
            cmake_cmd = ''
            for line in cmake_do_configure.splitlines():
                if in_cmake:
                    cmake_cmd = cmake_cmd + ' ' + line.strip().rstrip('\\')
                    if not line.endswith('\\'):
                        break
                if line.lstrip().startswith('cmake '):
                    cmake_cmd = line.strip().rstrip('\\')
                    if line.endswith('\\'):
                        in_cmake = True
                    else:
                        break
            if cmake_cmd:
                configopttext = '''
The current cmake command line:

%s

Arguments specified through EXTRA_OECMAKE (which you can change or add to easily)

%s''' % (oe.utils.squashspaces(cmake_cmd), extra_oecmake)
            else:
                configopttext = '''
The current implementation of cmake_do_configure:

cmake_do_configure() {
%s
}

Arguments specified through EXTRA_OECMAKE (which you can change or add to easily)

%s''' % (cmake_do_configure.rstrip(), extra_oecmake)

        elif do_configure:
            configopttext = '''
The current implementation of do_configure:

do_configure() {
%s
}''' % do_configure.rstrip()
            if '${EXTRA_OECONF}' in do_configure_noexpand:
                configopttext += '''

Arguments specified through EXTRA_OECONF (which you can change or add to easily):

%s''' % extra_oeconf

        if packageconfig:
            configopttext += '''

Some of these options may be controlled through PACKAGECONFIG; for more details please see the recipe.'''

        if args.arg:
            helpargs = ' '.join(args.arg)
        elif cmake:
            helpargs = '-LH'
        else:
            helpargs = '--help'

        msg = '''configure information for %s
------------------------------------------
%s''' % (pn, configopttext)

        if cmake:
            msg += '''

The cmake %s output for %s follows. After "-- Cache values" you should see a list of variables you can add to EXTRA_OECMAKE (prefixed with -D and suffixed with = followed by the desired value, without any spaces).
------------------------------------------''' % (helpargs, pn)
        elif os.path.exists(configurescript):
            msg += '''

The ./configure %s output for %s follows.
------------------------------------------''' % (helpargs, pn)

        olddir = os.getcwd()
        tmppath = tempfile.mkdtemp()
        with tempfile.NamedTemporaryFile('w', delete=False) as tf:
            if not args.no_header:
                tf.write(msg + '\n')
            tf.close()
            try:
                try:
                    cmd = 'cat %s' % tf.name
                    if cmake:
                        cmd += '; cmake %s %s 2>&1' % (helpargs, s)
                        os.chdir(b)
                    elif os.path.exists(configurescript):
                        cmd += '; %s %s' % (configurescript, helpargs)
                    if sys.stdout.isatty() and not args.no_pager:
                        pager = os.environ.get('PAGER', 'less')
                        cmd = '(%s) | %s' % (cmd, pager)
                    subprocess.check_call(cmd, shell=True)
                except subprocess.CalledProcessError as e:
                    return e.returncode
            finally:
                os.chdir(olddir)
                shutil.rmtree(tmppath)
                os.remove(tf.name)
Ejemplo n.º 37
0
def configure_help(args, config, basepath, workspace):
    """Entry point for the devtool 'configure-help' subcommand"""
    import oe.utils

    check_workspace_recipe(workspace, args.recipename)
    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, appends=True, filter_workspace=False)
        if not rd:
            return 1
        b = rd.getVar('B')
        s = rd.getVar('S')
        configurescript = os.path.join(s, 'configure')
        confdisabled = 'noexec' in rd.getVarFlags('do_configure') or 'do_configure' not in (rd.getVar('__BBTASKS', False) or [])
        configureopts = oe.utils.squashspaces(rd.getVar('CONFIGUREOPTS') or '')
        extra_oeconf = oe.utils.squashspaces(rd.getVar('EXTRA_OECONF') or '')
        extra_oecmake = oe.utils.squashspaces(rd.getVar('EXTRA_OECMAKE') or '')
        do_configure = rd.getVar('do_configure') or ''
        do_configure_noexpand = rd.getVar('do_configure', False) or ''
        packageconfig = rd.getVarFlags('PACKAGECONFIG') or []
        autotools = bb.data.inherits_class('autotools', rd) and ('oe_runconf' in do_configure or 'autotools_do_configure' in do_configure)
        cmake = bb.data.inherits_class('cmake', rd) and ('cmake_do_configure' in do_configure)
        cmake_do_configure = rd.getVar('cmake_do_configure')
        pn = rd.getVar('PN')
    finally:
        tinfoil.shutdown()

    if 'doc' in packageconfig:
        del packageconfig['doc']

    if autotools and not os.path.exists(configurescript):
        logger.info('Running do_configure to generate configure script')
        try:
            stdout, _ = exec_build_env_command(config.init_path, basepath,
                                               'bitbake -c configure %s' % args.recipename,
                                               stderr=subprocess.STDOUT)
        except bb.process.ExecutionError:
            pass

    if confdisabled or do_configure.strip() in ('', ':'):
        raise DevtoolError("do_configure task has been disabled for this recipe")
    elif args.no_pager and not os.path.exists(configurescript):
        raise DevtoolError("No configure script found and no other information to display")
    else:
        configopttext = ''
        if autotools and configureopts:
            configopttext = '''
Arguments currently passed to the configure script:

%s

Some of those are fixed.''' % (configureopts + ' ' + extra_oeconf)
            if extra_oeconf:
                configopttext += ''' The ones that are specified through EXTRA_OECONF (which you can change or add to easily):

%s''' % extra_oeconf

        elif cmake:
            in_cmake = False
            cmake_cmd = ''
            for line in cmake_do_configure.splitlines():
                if in_cmake:
                    cmake_cmd = cmake_cmd + ' ' + line.strip().rstrip('\\')
                    if not line.endswith('\\'):
                        break
                if line.lstrip().startswith('cmake '):
                    cmake_cmd = line.strip().rstrip('\\')
                    if line.endswith('\\'):
                        in_cmake = True
                    else:
                        break
            if cmake_cmd:
                configopttext = '''
The current cmake command line:

%s

Arguments specified through EXTRA_OECMAKE (which you can change or add to easily)

%s''' % (oe.utils.squashspaces(cmake_cmd), extra_oecmake)
            else:
                configopttext = '''
The current implementation of cmake_do_configure:

cmake_do_configure() {
%s
}

Arguments specified through EXTRA_OECMAKE (which you can change or add to easily)

%s''' % (cmake_do_configure.rstrip(), extra_oecmake)

        elif do_configure:
            configopttext = '''
The current implementation of do_configure:

do_configure() {
%s
}''' % do_configure.rstrip()
            if '${EXTRA_OECONF}' in do_configure_noexpand:
                configopttext += '''

Arguments specified through EXTRA_OECONF (which you can change or add to easily):

%s''' % extra_oeconf

        if packageconfig:
            configopttext += '''

Some of these options may be controlled through PACKAGECONFIG; for more details please see the recipe.'''

        if args.arg:
            helpargs = ' '.join(args.arg)
        elif cmake:
            helpargs = '-LH'
        else:
            helpargs = '--help'

        msg = '''configure information for %s
------------------------------------------
%s''' % (pn, configopttext)

        if cmake:
            msg += '''

The cmake %s output for %s follows. After "-- Cache values" you should see a list of variables you can add to EXTRA_OECMAKE (prefixed with -D and suffixed with = followed by the desired value, without any spaces).
------------------------------------------''' % (helpargs, pn)
        elif os.path.exists(configurescript):
            msg += '''

The ./configure %s output for %s follows.
------------------------------------------''' % (helpargs, pn)

        olddir = os.getcwd()
        tmppath = tempfile.mkdtemp()
        with tempfile.NamedTemporaryFile('w', delete=False) as tf:
            if not args.no_header:
                tf.write(msg + '\n')
            tf.close()
            try:
                try:
                    cmd = 'cat %s' % tf.name
                    if cmake:
                        cmd += '; cmake %s %s 2>&1' % (helpargs, s)
                        os.chdir(b)
                    elif os.path.exists(configurescript):
                        cmd += '; %s %s' % (configurescript, helpargs)
                    if sys.stdout.isatty() and not args.no_pager:
                        pager = os.environ.get('PAGER', 'less')
                        cmd = '(%s) | %s' % (cmd, pager)
                    subprocess.check_call(cmd, shell=True)
                except subprocess.CalledProcessError as e:
                    return e.returncode
            finally:
                os.chdir(olddir)
                shutil.rmtree(tmppath)
                os.remove(tf.name)
Ejemplo n.º 38
0
def modify(args, config, basepath, workspace):
    """Entry point for the devtool 'modify' subcommand"""
    import bb
    import oe.recipeutils

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" %
                           args.recipename)

    if not args.extract and not os.path.isdir(args.srctree):
        raise DevtoolError("directory %s does not exist or not a directory "
                           "(specify -x to extract source from recipe)" %
                           args.srctree)
    if args.extract:
        tinfoil = _prep_extract_operation(config, basepath, args.recipename)
    else:
        tinfoil = setup_tinfoil(basepath=basepath)

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1
    recipefile = rd.getVar('FILE', True)
    appendname = os.path.splitext(os.path.basename(recipefile))[0]
    if args.wildcard:
        appendname = re.sub(r'_.*', '_%', appendname)
    appendpath = os.path.join(config.workspace_path, 'appends')
    appendfile = os.path.join(appendpath, appendname + '.bbappend')
    if os.path.exists(appendfile):
        raise DevtoolError("Another variant of recipe %s is already in your "
                           "workspace (only one variant of a recipe can "
                           "currently be worked on at once)"
                           % args.recipename)

    _check_compatible_recipe(args.recipename, rd)

    initial_rev = None
    commits = []
    srctree = os.path.abspath(args.srctree)
    if args.extract:
        initial_rev = _extract_source(args.srctree, False, args.branch, rd)
        if not initial_rev:
            return 1
        logger.info('Source tree extracted to %s' % srctree)
        # Get list of commits since this revision
        (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=args.srctree)
        commits = stdout.split()
    else:
        if os.path.exists(os.path.join(args.srctree, '.git')):
            # Check if it's a tree previously extracted by us
            try:
                (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=args.srctree)
            except bb.process.ExecutionError:
                stdout = ''
            for line in stdout.splitlines():
                if line.startswith('*'):
                    (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=args.srctree)
                    initial_rev = stdout.rstrip()
            if not initial_rev:
                # Otherwise, just grab the head revision
                (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=args.srctree)
                initial_rev = stdout.rstrip()

    # Check that recipe isn't using a shared workdir
    s = os.path.abspath(rd.getVar('S', True))
    workdir = os.path.abspath(rd.getVar('WORKDIR', True))
    if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir:
        # Handle if S is set to a subdirectory of the source
        srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1]
        srctree = os.path.join(srctree, srcsubdir)

    if not os.path.exists(appendpath):
        os.makedirs(appendpath)
    with open(appendfile, 'w') as f:
        f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n')
        # Local files can be modified/tracked in separate subdir under srctree
        # Mostly useful for packages with S != WORKDIR
        f.write('FILESPATH_prepend := "%s:"\n' %
                os.path.join(srctree, 'oe-local-files'))

        f.write('\ninherit externalsrc\n')
        f.write('# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n')
        f.write('EXTERNALSRC_pn-%s = "%s"\n' % (args.recipename, srctree))

        b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
        if b_is_s:
            f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (args.recipename, srctree))

        if bb.data.inherits_class('kernel', rd):
            f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout do_fetch do_unpack"\n')
        if initial_rev:
            f.write('\n# initial_rev: %s\n' % initial_rev)
            for commit in commits:
                f.write('# commit: %s\n' % commit)

    _add_md5(config, args.recipename, appendfile)

    logger.info('Recipe %s now set up to build from %s' % (args.recipename, srctree))

    return 0
Ejemplo n.º 39
0
def sdk_install(args, config, basepath, workspace):
    """Entry point for the devtool sdk-install command"""

    import oe.recipeutils
    import bb.process

    for recipe in args.recipename:
        if recipe in workspace:
            raise DevtoolError("recipe %s is a recipe in your workspace" % recipe)

    tasks = ["do_populate_sysroot", "do_packagedata"]
    stampprefixes = {}

    def checkstamp(recipe):
        stampprefix = stampprefixes[recipe]
        stamps = glob.glob(stampprefix + "*")
        for stamp in stamps:
            if ".sigdata." not in stamp and stamp.startswith((stampprefix + ".", stampprefix + "_setscene.")):
                return True
        else:
            return False

    install_recipes = []
    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
    try:
        for recipe in args.recipename:
            rd = parse_recipe(config, tinfoil, recipe, True)
            if not rd:
                return 1
            stampprefixes[recipe] = "%s.%s" % (rd.getVar("STAMP", True), tasks[0])
            if checkstamp(recipe):
                logger.info("%s is already installed" % recipe)
            else:
                install_recipes.append(recipe)
    finally:
        tinfoil.shutdown()

    if install_recipes:
        logger.info("Installing %s..." % ", ".join(install_recipes))
        install_tasks = []
        for recipe in install_recipes:
            for task in tasks:
                if recipe.endswith("-native") and "package" in task:
                    continue
                install_tasks.append("%s:%s" % (recipe, task))
        options = ""
        if not args.allow_build:
            options += " --setscene-only"
        try:
            exec_build_env_command(
                config.init_path, basepath, "bitbake %s %s" % (options, " ".join(install_tasks)), watch=True
            )
        except bb.process.ExecutionError as e:
            raise DevtoolError("Failed to install %s:\n%s" % (recipe, str(e)))
        failed = False
        for recipe in install_recipes:
            if checkstamp(recipe):
                logger.info("Successfully installed %s" % recipe)
            else:
                raise DevtoolError("Failed to install %s - unavailable" % recipe)
                failed = True
        if failed:
            return 2
Ejemplo n.º 40
0
def upgrade(args, config, basepath, workspace):
    """Entry point for the devtool 'upgrade' subcommand"""

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" % args.recipename)
    if args.srcbranch and not args.srcrev:
        raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename)

    _check_git_config()

    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
    try:
        rd = parse_recipe(config, tinfoil, args.recipename, True)
        if not rd:
            return 1

        pn = rd.getVar('PN')
        if pn != args.recipename:
            logger.info('Mapping %s to %s' % (args.recipename, pn))
        if pn in workspace:
            raise DevtoolError("recipe %s is already in your workspace" % pn)

        if args.srctree:
            srctree = os.path.abspath(args.srctree)
        else:
            srctree = standard.get_default_srctree(config, pn)

        # try to automatically discover latest version and revision if not provided on command line
        if not args.version and not args.srcrev:
            version_info = oe.recipeutils.get_recipe_upstream_version(rd)
            if version_info['version'] and not version_info['version'].endswith("new-commits-available"):
                args.version = version_info['version']
            if version_info['revision']:
                args.srcrev = version_info['revision']
        if not args.version and not args.srcrev:
            raise DevtoolError("Automatic discovery of latest version/revision failed - you must provide a version using the --version/-V option, or for recipes that fetch from an SCM such as git, the --srcrev/-S option.")

        standard._check_compatible_recipe(pn, rd)
        old_srcrev = rd.getVar('SRCREV')
        if old_srcrev == 'INVALID':
            old_srcrev = None
        if old_srcrev and not args.srcrev:
            raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading")
        old_ver = rd.getVar('PV')
        if old_ver == args.version and old_srcrev == args.srcrev:
            raise DevtoolError("Current and upgrade versions are the same version")
        if args.version:
            if bb.utils.vercmp_string(args.version, old_ver) < 0:
                logger.warning('Upgrade version %s compares as less than the current version %s. If you are using a package feed for on-target upgrades or providing this recipe for general consumption, then you should increment PE in the recipe (or if there is no current PE value set, set it to "1")' % (args.version, old_ver))
            check_prerelease_version(args.version, 'devtool upgrade')

        rf = None
        license_diff = None
        try:
            logger.info('Extracting current version source...')
            rev1, srcsubdir1 = standard._extract_source(srctree, False, 'devtool-orig', False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides)
            old_licenses = _extract_licenses(srctree, rd.getVar('LIC_FILES_CHKSUM'))
            logger.info('Extracting upgraded version source...')
            rev2, md5, sha256, srcbranch, srcsubdir2 = _extract_new_source(args.version, srctree, args.no_patch,
                                                    args.srcrev, args.srcbranch, args.branch, args.keep_temp,
                                                    tinfoil, rd)
            new_licenses = _extract_licenses(srctree, rd.getVar('LIC_FILES_CHKSUM'))
            license_diff = _generate_license_diff(old_licenses, new_licenses)
            rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, srcbranch, srcsubdir1, srcsubdir2, config.workspace_path, tinfoil, rd, license_diff, new_licenses)
        except bb.process.CmdError as e:
            _upgrade_error(e, rf, srctree)
        except DevtoolError as e:
            _upgrade_error(e, rf, srctree)
        standard._add_md5(config, pn, os.path.dirname(rf))

        af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2,
                        copied, config.workspace_path, rd)
        standard._add_md5(config, pn, af)

        update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn])

        logger.info('Upgraded source extracted to %s' % srctree)
        logger.info('New recipe is %s' % rf)
        if license_diff:
            logger.info('License checksums have been updated in the new recipe; please refer to it for the difference between the old and the new license texts.')
    finally:
        tinfoil.shutdown()
    return 0
Ejemplo n.º 41
0
def modify(args, config, basepath, workspace):
    """Entry point for the devtool 'modify' subcommand"""
    import bb
    import oe.recipeutils

    if args.recipename in workspace:
        raise DevtoolError("recipe %s is already in your workspace" %
                           args.recipename)

    if not args.extract and not os.path.isdir(args.srctree):
        raise DevtoolError("directory %s does not exist or not a directory "
                           "(specify -x to extract source from recipe)" %
                           args.srctree)
    if args.extract:
        tinfoil = _prep_extract_operation(config, basepath, args.recipename)
    else:
        tinfoil = setup_tinfoil()

    rd = parse_recipe(config, tinfoil, args.recipename, True)
    if not rd:
        return 1
    recipefile = rd.getVar('FILE', True)
    appendname = os.path.splitext(os.path.basename(recipefile))[0]
    if args.wildcard:
        appendname = re.sub(r'_.*', '_%', appendname)
    appendpath = os.path.join(config.workspace_path, 'appends')
    appendfile = os.path.join(appendpath, appendname + '.bbappend')
    if os.path.exists(appendfile):
        raise DevtoolError("Another variant of recipe %s is already in your "
                           "workspace (only one variant of a recipe can "
                           "currently be worked on at once)" % args.recipename)

    _check_compatible_recipe(args.recipename, rd)

    initial_rev = None
    commits = []
    srctree = os.path.abspath(args.srctree)
    if args.extract:
        initial_rev = _extract_source(args.srctree, False, args.branch, rd)
        if not initial_rev:
            return 1
        logger.info('Source tree extracted to %s' % srctree)
        # Get list of commits since this revision
        (stdout,
         _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev,
                             cwd=args.srctree)
        commits = stdout.split()
    else:
        if os.path.exists(os.path.join(args.srctree, '.git')):
            # Check if it's a tree previously extracted by us
            try:
                (stdout,
                 _) = bb.process.run('git branch --contains devtool-base',
                                     cwd=args.srctree)
            except bb.process.ExecutionError:
                stdout = ''
            for line in stdout.splitlines():
                if line.startswith('*'):
                    (stdout, _) = bb.process.run('git rev-parse devtool-base',
                                                 cwd=args.srctree)
                    initial_rev = stdout.rstrip()
            if not initial_rev:
                # Otherwise, just grab the head revision
                (stdout, _) = bb.process.run('git rev-parse HEAD',
                                             cwd=args.srctree)
                initial_rev = stdout.rstrip()

    # Check that recipe isn't using a shared workdir
    s = os.path.abspath(rd.getVar('S', True))
    workdir = os.path.abspath(rd.getVar('WORKDIR', True))
    if s.startswith(
            workdir) and s != workdir and os.path.dirname(s) != workdir:
        # Handle if S is set to a subdirectory of the source
        srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1]
        srctree = os.path.join(srctree, srcsubdir)

    if not os.path.exists(appendpath):
        os.makedirs(appendpath)
    with open(appendfile, 'w') as f:
        f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n\n')
        f.write('inherit externalsrc\n')
        f.write(
            '# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n'
        )
        f.write('EXTERNALSRC_pn-%s = "%s"\n' % (args.recipename, srctree))

        b_is_s = True
        if args.no_same_dir:
            logger.info(
                'using separate build directory since --no-same-dir specified')
            b_is_s = False
        elif args.same_dir:
            logger.info(
                'using source tree as build directory since --same-dir specified'
            )
        elif bb.data.inherits_class('autotools-brokensep', rd):
            logger.info(
                'using source tree as build directory since original recipe inherits autotools-brokensep'
            )
        elif rd.getVar('B', True) == s:
            logger.info(
                'using source tree as build directory since that is the default for this recipe'
            )
        else:
            b_is_s = False
        if b_is_s:
            f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' %
                    (args.recipename, srctree))

        if bb.data.inherits_class('kernel', rd):
            f.write(
                'SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout do_fetch do_unpack"\n'
            )
        if initial_rev:
            f.write('\n# initial_rev: %s\n' % initial_rev)
            for commit in commits:
                f.write('# commit: %s\n' % commit)

    _add_md5(config, args.recipename, appendfile)

    logger.info('Recipe %s now set up to build from %s' %
                (args.recipename, srctree))

    return 0
def build_image_task(config, basepath, workspace, image, add_packages=None, task=None, extra_append=None):
    # remove <image>.bbappend to make sure setup_tinfoil doesn't
    # break because of it
    target_basename = config.get('SDK', 'target_basename', '')
    if target_basename:
        appendfile = os.path.join(config.workspace_path, 'appends',
                                  '%s.bbappend' % target_basename)
        try:
            os.unlink(appendfile)
        except OSError as exc:
            if exc.errno != errno.ENOENT:
                raise

    tinfoil = setup_tinfoil(basepath=basepath)
    try:
        rd = parse_recipe(config, tinfoil, image, True)
        if not rd:
            # Error already shown
            return (1, None)
        if not bb.data.inherits_class('image', rd):
            raise TargetNotImageError()

        # Get the actual filename used and strip the .bb and full path
        target_basename = rd.getVar('FILE')
        target_basename = os.path.splitext(os.path.basename(target_basename))[0]
        config.set('SDK', 'target_basename', target_basename)
        config.write()

        appendfile = os.path.join(config.workspace_path, 'appends',
                                '%s.bbappend' % target_basename)

        outputdir = None
        try:
            if workspace or add_packages:
                if add_packages:
                    packages = add_packages
                else:
                    packages = _get_packages(tinfoil, workspace, config)
            else:
                packages = None
            if not task:
                if not packages and not add_packages and workspace:
                    logger.warning('No recipes in workspace, building image %s unmodified', image)
                elif not packages:
                    logger.warning('No packages to add, building image %s unmodified', image)

            if packages or extra_append:
                bb.utils.mkdirhier(os.path.dirname(appendfile))
                with open(appendfile, 'w') as afile:
                    if packages:
                        # include packages from workspace recipes into the image
                        afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages))
                        if not task:
                            logger.info('Building image %s with the following '
                                        'additional packages: %s', image, ' '.join(packages))
                    if extra_append:
                        for line in extra_append:
                            afile.write('%s\n' % line)

            if task in ['populate_sdk', 'populate_sdk_ext']:
                outputdir = rd.getVar('SDK_DEPLOY')
            else:
                outputdir = rd.getVar('DEPLOY_DIR_IMAGE')

            tmp_tinfoil = tinfoil
            tinfoil = None
            tmp_tinfoil.shutdown()

            options = ''
            if task:
                options += '-c %s' % task

            # run bitbake to build image (or specified task)
            try:
                exec_build_env_command(config.init_path, basepath,
                                    'bitbake %s %s' % (options, image), watch=True)
            except ExecutionError as err:
                return (err.exitcode, None)
        finally:
            if os.path.isfile(appendfile):
                os.unlink(appendfile)
    finally:
        if tinfoil:
            tinfoil.shutdown()
    return (0, outputdir)
Ejemplo n.º 43
0
def build_image(args, config, basepath, workspace):
    """Entry point for the devtool 'build-image' subcommand."""

    image = args.imagename
    auto_image = False
    if not image:
        sdk_targets = config.get('SDK', 'sdk_targets', '').split()
        if sdk_targets:
            image = sdk_targets[0]
            auto_image = True
    if not image:
        raise DevtoolError(
            'Unable to determine image to build, please specify one')

    appendfile = os.path.join(config.workspace_path, 'appends',
                              '%s.bbappend' % image)

    # remove <image>.bbappend to make sure setup_tinfoil doesn't
    # break because of it
    if os.path.isfile(appendfile):
        os.unlink(appendfile)

    tinfoil = setup_tinfoil(basepath=basepath)
    rd = parse_recipe(config, tinfoil, image, True)
    if not rd:
        # Error already shown
        return 1
    if not bb.data.inherits_class('image', rd):
        if auto_image:
            raise DevtoolError(
                'Unable to determine image to build, please specify one')
        else:
            raise DevtoolError('Specified recipe %s is not an image recipe' %
                               image)

    try:
        if workspace:
            packages = _get_packages(tinfoil, workspace, config)
            if packages:
                with open(appendfile, 'w') as afile:
                    # include packages from workspace recipes into the image
                    afile.write('IMAGE_INSTALL_append = " %s"\n' %
                                ' '.join(packages))
                    logger.info(
                        'Building image %s with the following '
                        'additional packages: %s', image, ' '.join(packages))
            else:
                logger.warning(
                    'No packages to add, building image %s unmodified', image)
        else:
            logger.warning(
                'No recipes in workspace, building image %s unmodified', image)

        deploy_dir_image = tinfoil.config_data.getVar('DEPLOY_DIR_IMAGE', True)

        tinfoil.shutdown()

        # run bitbake to build image
        try:
            exec_build_env_command(config.init_path,
                                   basepath,
                                   'bitbake %s' % image,
                                   watch=True)
        except ExecutionError as err:
            return err.exitcode
    finally:
        if os.path.isfile(appendfile):
            os.unlink(appendfile)

    logger.info('Successfully built %s. You can find output files in %s' %
                (image, deploy_dir_image))