1# Development tool - build command plugin 2# 3# Copyright (C) 2014-2015 Intel Corporation 4# 5# SPDX-License-Identifier: GPL-2.0-only 6# 7"""Devtool build plugin""" 8 9import os 10import bb 11import logging 12import argparse 13import tempfile 14from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, DevtoolError 15from devtool import parse_recipe 16 17logger = logging.getLogger('devtool') 18 19 20def _set_file_values(fn, values): 21 remaining = list(values.keys()) 22 23 def varfunc(varname, origvalue, op, newlines): 24 newvalue = values.get(varname, origvalue) 25 remaining.remove(varname) 26 return (newvalue, '=', 0, True) 27 28 with open(fn, 'r') as f: 29 (updated, newlines) = bb.utils.edit_metadata(f, values, varfunc) 30 31 for item in remaining: 32 updated = True 33 newlines.append('%s = "%s"' % (item, values[item])) 34 35 if updated: 36 with open(fn, 'w') as f: 37 f.writelines(newlines) 38 return updated 39 40def _get_build_tasks(config): 41 tasks = config.get('Build', 'build_task', 'populate_sysroot,packagedata').split(',') 42 return ['do_%s' % task.strip() for task in tasks] 43 44def build(args, config, basepath, workspace): 45 """Entry point for the devtool 'build' subcommand""" 46 workspacepn = check_workspace_recipe(workspace, args.recipename, bbclassextend=True) 47 tinfoil = setup_tinfoil(config_only=False, basepath=basepath) 48 try: 49 rd = parse_recipe(config, tinfoil, args.recipename, appends=True, filter_workspace=False) 50 if not rd: 51 return 1 52 deploytask = 'do_deploy' in rd.getVar('__BBTASKS') 53 finally: 54 tinfoil.shutdown() 55 56 if args.clean: 57 # use clean instead of cleansstate to avoid messing things up in eSDK 58 build_tasks = ['do_clean'] 59 else: 60 build_tasks = _get_build_tasks(config) 61 if deploytask: 62 build_tasks.append('do_deploy') 63 64 bbappend = workspace[workspacepn]['bbappend'] 65 if args.disable_parallel_make: 66 logger.info("Disabling 'make' parallelism") 67 _set_file_values(bbappend, {'PARALLEL_MAKE': ''}) 68 try: 69 bbargs = [] 70 for task in build_tasks: 71 if args.recipename.endswith('-native') and 'package' in task: 72 continue 73 bbargs.append('%s:%s' % (args.recipename, task)) 74 exec_build_env_command(config.init_path, basepath, 'bitbake %s' % ' '.join(bbargs), watch=True) 75 except bb.process.ExecutionError as e: 76 # We've already seen the output since watch=True, so just ensure we return something to the user 77 return e.exitcode 78 finally: 79 if args.disable_parallel_make: 80 _set_file_values(bbappend, {'PARALLEL_MAKE': None}) 81 82 return 0 83 84def register_commands(subparsers, context): 85 """Register devtool subcommands from this plugin""" 86 parser_build = subparsers.add_parser('build', help='Build a recipe', 87 description='Builds the specified recipe using bitbake (up to and including %s)' % ', '.join(_get_build_tasks(context.config)), 88 group='working', order=50) 89 parser_build.add_argument('recipename', help='Recipe to build') 90 parser_build.add_argument('-s', '--disable-parallel-make', action="store_true", help='Disable make parallelism') 91 parser_build.add_argument('-c', '--clean', action='store_true', help='clean up recipe building results') 92 parser_build.set_defaults(func=build) 93