From: Simon Glass <simon.glass@canonical.com> Introduce a RunRequest named tuple to group the parameters that don't change during a job's for loop in run_job() This includes: - brd: Board to build - work_dir: Directory for source checkout - work_in_output: Whether to use output directory as work directory - adjust_cfg: Config adjustments - fragments: Config fragments This reduces the run_commit() signature from 11 parameters to 7, and simplifies passing these values through to _decide_dirs() and _config_and_build() Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/builderthread.py | 158 ++++++++++++++++---------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index c480f4888a1..eda2b0083d4 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -8,6 +8,7 @@ This module provides the BuilderThread class, which handles calling the builder based on the jobs provided. """ +from collections import namedtuple import errno import glob import io @@ -20,6 +21,23 @@ from u_boot_pylib import command from u_boot_pylib import gitutil from u_boot_pylib import tools +# Named tuple for run_commit() options that don't change during a job +# +# Members: +# brd (Board): Board to build +# work_dir (str): Directory to which the source will be checked out +# work_in_output (bool): Use the output directory as the work directory and +# don't write to a separate output directory +# adjust_cfg (list of str): List of changes to make to .config file before +# building. Each is one of (where C is either CONFIG_xxx or just xxx): +# C to enable C +# ~C to disable C +# C=val to set the value of C (val must have quotes if C is a +# string Kconfig +# fragments (str): Config fragments added to defconfig +RunRequest = namedtuple('RunRequest', ['brd', 'work_dir', 'work_in_output', + 'adjust_cfg', 'fragments']) + RETURN_CODE_RETRY = -1 BASE_ELF_FILENAMES = ['u-boot', 'spl/u-boot-spl', 'tpl/u-boot-tpl'] @@ -384,28 +402,26 @@ class BuilderThread(threading.Thread): return will_build, result - def _decide_dirs(self, brd, work_dir, work_in_output): + def _decide_dirs(self, req): """Decide the output directory to use Args: - work_dir (str): Directory to which the source will be checked out - work_in_output (bool): Use the output directory as the work - directory and don't write to a separate output directory. + req (RunRequest): Run request (see RunRequest for details) Returns: tuple: out_dir (str): Output directory for the build - out_rel_dir (str): Output directory relatie to the current dir + out_rel_dir (str): Output directory relative to the current dir """ - if work_in_output or self.builder.in_tree: + if req.work_in_output or self.builder.in_tree: out_rel_dir = None - out_dir = work_dir + out_dir = req.work_dir else: if self.per_board_out_dir: - out_rel_dir = os.path.join('..', brd.target) + out_rel_dir = os.path.join('..', req.brd.target) else: out_rel_dir = 'build' - out_dir = os.path.join(work_dir, out_rel_dir) + out_dir = os.path.join(req.work_dir, out_rel_dir) return out_dir, out_rel_dir def _checkout(self, commit_upto, work_dir): @@ -427,24 +443,20 @@ class BuilderThread(threading.Thread): commit = 'current' return commit - def _config_and_build(self, commit_upto, brd, work_dir, do_config, mrproper, - config_only, adjust_cfg, commit, out_dir, out_rel_dir, - fragments, result): + def _config_and_build(self, req, commit_upto, do_config, mrproper, + config_only, commit, out_dir, out_rel_dir, result): """Do the build, configuring first if necessary Args: + req (RunRequest): Run request (see RunRequest for details) commit_upto (int): Commit number to build (0...n-1) - brd (Board): Board to create arguments for - work_dir (str): Directory to which the source will be checked out do_config (bool): True to run a make <board>_defconfig on the source mrproper (bool): True to run mrproper first config_only (bool): Only configure the source, do not build it - adjust_cfg (list of str): See the cfgutil module and run_commit() - commit (Commit): Commit only being built + commit (Commit): Commit being built out_dir (str): Output directory for the build, or None to use current - out_rel_dir (str): Output directory relatie to the current dir - fragments (str): config fragments added to defconfig + out_rel_dir (str): Output directory relative to the current dir result (CommandResult): Previous result Returns: @@ -458,17 +470,17 @@ class BuilderThread(threading.Thread): if out_dir and not os.path.exists(out_dir): mkdir(out_dir) - args, cwd, src_dir = self._build_args(brd, out_dir, out_rel_dir, - work_dir, commit_upto) - if brd.extended: - config_args = [f'{brd.orig_target}_defconfig'] - for frag in brd.extended.fragments: + args, cwd, src_dir = self._build_args(req.brd, out_dir, out_rel_dir, + req.work_dir, commit_upto) + if req.brd.extended: + config_args = [f'{req.brd.orig_target}_defconfig'] + for frag in req.brd.extended.fragments: fname = os.path.join(f'{frag}.config') config_args.append(fname) else: - config_args = [f'{brd.target}_defconfig'] - if fragments is not None: - config_args.extend(fragments.split(',')) + config_args = [f'{req.brd.target}_defconfig'] + if req.fragments is not None: + config_args.extend(req.fragments.split(',')) config_out = io.StringIO() _remove_old_outputs(out_dir) @@ -476,26 +488,26 @@ class BuilderThread(threading.Thread): # If we need to reconfigure, do that now cfg_file = os.path.join(out_dir or '', '.config') cmd_list = [] - if do_config or adjust_cfg: + if do_config or req.adjust_cfg: result = self._reconfigure( - commit, brd, cwd, args, env, config_args, config_out, cmd_list, - mrproper) + commit, req.brd, cwd, args, env, config_args, config_out, + cmd_list, mrproper) do_config = False # No need to configure next time - if adjust_cfg: - cfgutil.adjust_cfg_file(cfg_file, adjust_cfg) + if req.adjust_cfg: + cfgutil.adjust_cfg_file(cfg_file, req.adjust_cfg) # Now do the build, if everything looks OK if result.return_code == 0: - if adjust_cfg: + if req.adjust_cfg: oldc_args = list(args) + ['oldconfig'] - oldc_result = self.make(commit, brd, 'oldconfig', cwd, + oldc_result = self.make(commit, req.brd, 'oldconfig', cwd, *oldc_args, env=env) if oldc_result.return_code: return oldc_result - result = self._build(commit, brd, cwd, args, env, cmd_list, + result = self._build(commit, req.brd, cwd, args, env, cmd_list, config_only) - if adjust_cfg: - errs = cfgutil.check_cfg_file(cfg_file, adjust_cfg) + if req.adjust_cfg: + errs = cfgutil.check_cfg_file(cfg_file, req.adjust_cfg) if errs: result.stderr += errs result.return_code = 1 @@ -505,34 +517,22 @@ class BuilderThread(threading.Thread): result.cmd_list = cmd_list return result, do_config - def run_commit(self, commit_upto, brd, work_dir, do_config, mrproper, - config_only, force_build, force_build_failures, - work_in_output, adjust_cfg, fragments): + def run_commit(self, req, commit_upto, do_config, mrproper, config_only, + force_build, force_build_failures): """Build a particular commit. If the build is already done, and we are not forcing a build, we skip the build and just return the previously-saved results. Args: + req (RunRequest): Run request (see RunRequest for details) commit_upto (int): Commit number to build (0...n-1) - brd (Board): Board to build - work_dir (str): Directory to which the source will be checked out do_config (bool): True to run a make <board>_defconfig on the source mrproper (bool): True to run mrproper first config_only (bool): Only configure the source, do not build it force_build (bool): Force a build even if one was previously done - force_build_failures (bool): Force a bulid if the previous result + force_build_failures (bool): Force a build if the previous result showed failure - work_in_output (bool) : Use the output directory as the work - directory and don't write to a separate output directory. - adjust_cfg (list of str): List of changes to make to .config file - before building. Each is one of (where C is either CONFIG_xxx - or just xxx): - C to enable C - ~C to disable C - C=val to set the value of C (val must have quotes if C is - a string Kconfig - fragments (str): config fragments added to defconfig Returns: tuple containing: @@ -541,10 +541,11 @@ class BuilderThread(threading.Thread): """ # Create a default result - it will be overwritte by the call to # self.make() below, in the event that we do a build. - out_dir, out_rel_dir = self._decide_dirs(brd, work_dir, work_in_output) + out_dir, out_rel_dir = self._decide_dirs(req) # Check if the job was already completed last time - will_build, result = self._read_done_file(commit_upto, brd, force_build, + will_build, result = self._read_done_file(commit_upto, req.brd, + force_build, force_build_failures) kconfig_reconfig = False @@ -552,33 +553,33 @@ class BuilderThread(threading.Thread): # We are going to have to build it. First, get a toolchain if not self.toolchain: try: - self.toolchain = self.builder.toolchains.select(brd.arch) + self.toolchain = self.builder.toolchains.select( + req.brd.arch) except ValueError as err: result.return_code = 10 result.stdout = '' - result.stderr = (f'Tool chain error for {brd.arch}: ' + result.stderr = (f'Tool chain error for {req.brd.arch}: ' f'{str(err)}') if self.toolchain: - commit = self._checkout(commit_upto, work_dir) + commit = self._checkout(commit_upto, req.work_dir) # Check if Kconfig files have changed since last config if self.builder.kconfig_check: config_file = os.path.join(out_dir, '.config') - if kconfig_changed_since(config_file, work_dir, - brd.target): + if kconfig_changed_since(config_file, req.work_dir, + req.brd.target): kconfig_reconfig = True do_config = True result, do_config = self._config_and_build( - commit_upto, brd, work_dir, do_config, mrproper, - config_only, adjust_cfg, commit, out_dir, out_rel_dir, - fragments, result) + req, commit_upto, do_config, mrproper, config_only, + commit, out_dir, out_rel_dir, result) result.already_done = False result.kconfig_reconfig = kconfig_reconfig result.toolchain = self.toolchain - result.brd = brd + result.brd = req.brd result.commit_upto = commit_upto result.out_dir = out_dir return result, do_config @@ -761,29 +762,29 @@ class BuilderThread(threading.Thread): brd = job.brd work_dir = self.builder.get_thread_dir(self.thread_num) self.toolchain = None + req = RunRequest(brd, work_dir, job.work_in_output, job.adjust_cfg, + job.fragments) if job.commits: # Run 'make board_defconfig' on the first commit do_config = True commit_upto = 0 force_build = False for commit_upto in range(0, len(job.commits), job.step): - result, request_config = self.run_commit(commit_upto, brd, - work_dir, do_config, self.mrproper, + result, request_config = self.run_commit( + req, commit_upto, do_config, self.mrproper, self.builder.config_only, force_build or self.builder.force_build, - self.builder.force_build_failures, - job.work_in_output, job.adjust_cfg, job.fragments) + self.builder.force_build_failures) failed = result.return_code did_config = do_config if failed and not do_config and not self.mrproper: # If our incremental build failed, try building again # with a reconfig. if self.builder.force_config_on_failure: - result, request_config = self.run_commit(commit_upto, - brd, work_dir, True, + result, request_config = self.run_commit( + req, commit_upto, True, self.mrproper or self.builder.fallback_mrproper, - False, True, False, job.work_in_output, - job.adjust_cfg, job.fragments) + False, True, False) did_config = True if not self.builder.force_reconfig: do_config = request_config @@ -826,17 +827,16 @@ class BuilderThread(threading.Thread): self._send_result(result) else: # Just build the currently checked-out build - result, request_config = self.run_commit(None, brd, work_dir, True, - self.mrproper, self.builder.config_only, True, - self.builder.force_build_failures, job.work_in_output, - job.adjust_cfg, job.fragments) + result, request_config = self.run_commit( + req, None, True, self.mrproper, + self.builder.config_only, True, + self.builder.force_build_failures) failed = result.return_code if failed and not self.mrproper: - result, request_config = self.run_commit(None, brd, work_dir, - True, self.builder.fallback_mrproper, + result, request_config = self.run_commit( + req, None, True, self.builder.fallback_mrproper, self.builder.config_only, True, - self.builder.force_build_failures, - job.work_in_output, job.adjust_cfg, job.fragments) + self.builder.force_build_failures) result.commit_upto = 0 self._write_result(result, job.keep_outputs, job.work_in_output) -- 2.43.0