From patchwork Mon Jan 5 18:30:23 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1278 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767637884; bh=1exaOO1SCKvQRmUWr0E6TxZD5OZwpW16aJH8czXhx/g=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=po9HPBemmGLphKdKjS//7MKwDht/7dxxV0gvmhI+R+dZE2edFVbcblEyMAYZbJyA5 o8TMVy/7IkcpiUUoMSXZf5p2w8whAMFPG5mX6HpUC8aKDV+WNRPBpvBIa4FuhkkrLh PbekRpzFQ0p5f2NFNgLWzzvnwjgI/PsIYpisCqFxGLXyMP+B2c0Gz1D37a58p/lxx7 GDIpNcdyO2WW6QicoZJqrcd4YqZIHIcneNOAjN1Zt4+N37CUVV/Zst6zVN9we+ykzB i/kzHufiQ4wx94bJx3LS+IYR5AUZEiU3NQt3c5R8tMdCSrw1vSIqPLIXfDhug0+q1h s2JBQnzfE05MA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id A60A269125 for ; Mon, 5 Jan 2026 11:31:24 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 01ttL1IKRsKm for ; Mon, 5 Jan 2026 11:31:24 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767637884; bh=1exaOO1SCKvQRmUWr0E6TxZD5OZwpW16aJH8czXhx/g=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=po9HPBemmGLphKdKjS//7MKwDht/7dxxV0gvmhI+R+dZE2edFVbcblEyMAYZbJyA5 o8TMVy/7IkcpiUUoMSXZf5p2w8whAMFPG5mX6HpUC8aKDV+WNRPBpvBIa4FuhkkrLh PbekRpzFQ0p5f2NFNgLWzzvnwjgI/PsIYpisCqFxGLXyMP+B2c0Gz1D37a58p/lxx7 GDIpNcdyO2WW6QicoZJqrcd4YqZIHIcneNOAjN1Zt4+N37CUVV/Zst6zVN9we+ykzB i/kzHufiQ4wx94bJx3LS+IYR5AUZEiU3NQt3c5R8tMdCSrw1vSIqPLIXfDhug0+q1h s2JBQnzfE05MA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9459A6911C for ; Mon, 5 Jan 2026 11:31:24 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767637881; bh=qWrS+cX7z7acKB/+Lq+Lt6syAWr4VcxyeR4d9nzWIoI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tEU86fwNWrh6iTjnfriVwQ345uOVbb9BX7jiNHarH9HgAcdzw4+D8dzukOBb8SLNe S+qT9gPXkoBNVnzMdeJy//Mjj6YiUIbixVHVmUd7UqEe+h7v/i4nfo8uWUgHb8WEmI CO92PiqwxWb8xClkB3iBcSF4r7IEdFedAnsmuQAxZsGc6qGBimH4sstM0hClb/p3bw IcioZuYOvvw5b9QJp2YWSttfObcKljjZ4jIdab1Wd1i7dclta28QWJWC4alaV/b/Pw BaRwpF2x5OdSdWiciy5zGUGkz62MXsukDkAFlBFNSc67SgpZrKRTkWwSh2YtA9zsgT gi+eoipfR6lzA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D1FB869045; Mon, 5 Jan 2026 11:31:21 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id P8IG8x-gGMBm; Mon, 5 Jan 2026 11:31:21 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767637880; bh=uHXK0s72cDWj8IZa+ldb1gpDjd2j6Lu2OWyA2C2TMsA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JJClfvdOmKJGPztejtPhOn3AkULjJbA4N1sKVkH9TeyIxhXvoJ9SSepj8OyVWd+Z/ sycTiDWlu2Nk6/OgBIxSfWFuskktnGqiA7lfatk0uZgCJhyxD678BS/7GyBWzpa6em myZrLLtb27DGwlFSUW6r6Jw0Dl7fCJi85Pa2bKzv6mTu0dH5b+1kAcd+f2eUWwW/Ta UkcrqtJi1hsffz/580MBdfRy5xHiR4ix2/qivdNWV0fZyr4onNLl5ftHsQRdjMHc6X q2Ed2v2W16w2tOvwKpl2NCcFHNcYS63lw+jcB5bcCT4NpahW8lOqwqBzSb9Raem+LL a+qz2O0voARcg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 32B2969103; Mon, 5 Jan 2026 11:31:20 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Mon, 5 Jan 2026 11:30:23 -0700 Message-ID: <20260105183030.1487468-9-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260105183030.1487468-1-sjg@u-boot.org> References: <20260105183030.1487468-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: YNQNI76KTAMNQSKLF4O7IFBW2S4Z2KPF X-Message-ID-Hash: YNQNI76KTAMNQSKLF4O7IFBW2S4Z2KPF X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 08/11] buildman: Extract _write_toolchain_result() from _write_result() List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Move the toolchain-result-writing logic from the 'if result.toolchain:' block in _write_result() into a separate _write_toolchain_result() method. This improves readability and reduces the complexity of _write_result() The new method handles: - Writing the done file with the return code - Writing toolchain information (gcc, path, cross, arch) - Writing environment and command list files - Running nm, objdump, and size on ELF files - Extracting and copying the U-Boot environment - Writing image sizes file Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- tools/buildman/builderthread.py | 179 +++++++++++++++++--------------- 1 file changed, 97 insertions(+), 82 deletions(-) diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index 8420698023a..1855e2cc2cb 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -684,6 +684,101 @@ class BuilderThread(threading.Thread): result.out_dir = out_dir return result, do_config + def _write_toolchain_result(self, result, done_file, build_dir, + maybe_aborted, work_in_output): + """Write build result and toolchain information + + Args: + result (CommandResult): Result to write + done_file (str): Path to the 'done' file + build_dir (str): Build directory path + maybe_aborted (bool): True if the build may have been aborted + work_in_output (bool): Use the output directory as the work + directory and don't write to a separate output directory + """ + # Write the build result and toolchain information. + with open(done_file, 'w', encoding='utf-8') as outf: + if maybe_aborted: + # Special code to indicate we need to retry + outf.write(f'{RETURN_CODE_RETRY}') + else: + outf.write(f'{result.return_code}') + with open(os.path.join(build_dir, 'toolchain'), 'w', + encoding='utf-8') as outf: + print('gcc', result.toolchain.gcc, file=outf) + print('path', result.toolchain.path, file=outf) + print('cross', result.toolchain.cross, file=outf) + print('arch', result.toolchain.arch, file=outf) + outf.write(f'{result.return_code}') + + # Write out the image and function size information and an objdump + env = self.builder.make_environment(self.toolchain) + with open(os.path.join(build_dir, 'out-env'), 'wb') as outf: + for var in sorted(env.keys()): + outf.write(b'%s="%s"' % (var, env[var])) + + with open(os.path.join(build_dir, 'out-cmd'), 'w', + encoding='utf-8') as outf: + for cmd in result.cmd_list: + print(' '.join(cmd), file=outf) + + lines = [] + for fname in BASE_ELF_FILENAMES: + cmd = [f'{self.toolchain.cross}nm', '--size-sort', fname] + nm_result = command.run_one(*cmd, capture=True, + capture_stderr=True, + cwd=result.out_dir, + raise_on_error=False, env=env) + if nm_result.stdout: + nm_fname = self.builder.get_func_sizes_file( + result.commit_upto, result.brd.target, fname) + with open(nm_fname, 'w', encoding='utf-8') as outf: + print(nm_result.stdout, end=' ', file=outf) + + cmd = [f'{self.toolchain.cross}objdump', '-h', fname] + dump_result = command.run_one(*cmd, capture=True, + capture_stderr=True, + cwd=result.out_dir, + raise_on_error=False, env=env) + rodata_size = '' + if dump_result.stdout: + objdump = self.builder.get_objdump_file(result.commit_upto, + result.brd.target, fname) + with open(objdump, 'w', encoding='utf-8') as outf: + print(dump_result.stdout, end=' ', file=outf) + for line in dump_result.stdout.splitlines(): + fields = line.split() + if len(fields) > 5 and fields[1] == '.rodata': + rodata_size = fields[2] + + cmd = [f'{self.toolchain.cross}size', fname] + size_result = command.run_one(*cmd, capture=True, + capture_stderr=True, + cwd=result.out_dir, + raise_on_error=False, env=env) + if size_result.stdout: + lines.append(size_result.stdout.splitlines()[1] + ' ' + + rodata_size) + + # Extract the environment from U-Boot and dump it out + cmd = [f'{self.toolchain.cross}objcopy', '-O', 'binary', + '-j', '.rodata.default_environment', + 'env/built-in.o', 'uboot.env'] + command.run_one(*cmd, capture=True, capture_stderr=True, + cwd=result.out_dir, raise_on_error=False, env=env) + if not work_in_output: + copy_files(result.out_dir, build_dir, '', ['uboot.env']) + + # Write out the image sizes file. This is similar to the output + # of binutil's 'size' utility, but it omits the header line and + # adds an additional hex value at the end of each line for the + # rodata size + if lines: + sizes = self.builder.get_sizes_file(result.commit_upto, + result.brd.target) + with open(sizes, 'w', encoding='utf-8') as outf: + print('\n'.join(lines), file=outf) + def _write_result(self, result, keep_outputs, work_in_output): """Write a built result to the output directory. @@ -729,88 +824,8 @@ class BuilderThread(threading.Thread): done_file = self.builder.get_done_file(result.commit_upto, result.brd.target) if result.toolchain: - # Write the build result and toolchain information. - with open(done_file, 'w', encoding='utf-8') as outf: - if maybe_aborted: - # Special code to indicate we need to retry - outf.write(f'{RETURN_CODE_RETRY}') - else: - outf.write(f'{result.return_code}') - with open(os.path.join(build_dir, 'toolchain'), 'w', - encoding='utf-8') as outf: - print('gcc', result.toolchain.gcc, file=outf) - print('path', result.toolchain.path, file=outf) - print('cross', result.toolchain.cross, file=outf) - print('arch', result.toolchain.arch, file=outf) - outf.write(f'{result.return_code}') - - # Write out the image and function size information and an objdump - env = self.builder.make_environment(self.toolchain) - with open(os.path.join(build_dir, 'out-env'), 'wb') as outf: - for var in sorted(env.keys()): - outf.write(b'%s="%s"' % (var, env[var])) - - with open(os.path.join(build_dir, 'out-cmd'), 'w', - encoding='utf-8') as outf: - for cmd in result.cmd_list: - print(' '.join(cmd), file=outf) - - lines = [] - for fname in BASE_ELF_FILENAMES: - cmd = [f'{self.toolchain.cross}nm', '--size-sort', fname] - nm_result = command.run_one(*cmd, capture=True, - capture_stderr=True, - cwd=result.out_dir, - raise_on_error=False, env=env) - if nm_result.stdout: - nm_fname = self.builder.get_func_sizes_file( - result.commit_upto, result.brd.target, fname) - with open(nm_fname, 'w', encoding='utf-8') as outf: - print(nm_result.stdout, end=' ', file=outf) - - cmd = [f'{self.toolchain.cross}objdump', '-h', fname] - dump_result = command.run_one(*cmd, capture=True, - capture_stderr=True, - cwd=result.out_dir, - raise_on_error=False, env=env) - rodata_size = '' - if dump_result.stdout: - objdump = self.builder.get_objdump_file(result.commit_upto, - result.brd.target, fname) - with open(objdump, 'w', encoding='utf-8') as outf: - print(dump_result.stdout, end=' ', file=outf) - for line in dump_result.stdout.splitlines(): - fields = line.split() - if len(fields) > 5 and fields[1] == '.rodata': - rodata_size = fields[2] - - cmd = [f'{self.toolchain.cross}size', fname] - size_result = command.run_one(*cmd, capture=True, - capture_stderr=True, - cwd=result.out_dir, - raise_on_error=False, env=env) - if size_result.stdout: - lines.append(size_result.stdout.splitlines()[1] + ' ' + - rodata_size) - - # Extract the environment from U-Boot and dump it out - cmd = [f'{self.toolchain.cross}objcopy', '-O', 'binary', - '-j', '.rodata.default_environment', - 'env/built-in.o', 'uboot.env'] - command.run_one(*cmd, capture=True, capture_stderr=True, - cwd=result.out_dir, raise_on_error=False, env=env) - if not work_in_output: - copy_files(result.out_dir, build_dir, '', ['uboot.env']) - - # Write out the image sizes file. This is similar to the output - # of binutil's 'size' utility, but it omits the header line and - # adds an additional hex value at the end of each line for the - # rodata size - if lines: - sizes = self.builder.get_sizes_file(result.commit_upto, - result.brd.target) - with open(sizes, 'w', encoding='utf-8') as outf: - print('\n'.join(lines), file=outf) + self._write_toolchain_result(result, done_file, build_dir, + maybe_aborted, work_in_output) else: # Indicate that the build failure due to lack of toolchain tools.write_file(done_file, '2\n', binary=False)