From 529957c3157c7667d9ccfbf539ccad7316a37f83 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 19 Jul 2023 17:49:04 -0600 Subject: buildman: Convert to argparse Use argparse to parse the arguments, since OptionParser is deprecated now. Signed-off-by: Simon Glass --- tools/buildman/cmdline.py | 130 ++++++++++++++++++++-------------------- tools/buildman/control.py | 141 ++++++++++++++++++++++---------------------- tools/buildman/func_test.py | 6 +- tools/buildman/main.py | 17 +++--- 4 files changed, 148 insertions(+), 146 deletions(-) (limited to 'tools') diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py index 660a83b..a5febe9 100644 --- a/tools/buildman/cmdline.py +++ b/tools/buildman/cmdline.py @@ -7,7 +7,7 @@ This creates the argument parser and uses it to parse the arguments passed in """ -from optparse import OptionParser +import argparse import os import pathlib @@ -22,137 +22,141 @@ def parse_args(): options: command line options args: command lin arguments """ - parser = OptionParser() - parser.add_option('-a', '--adjust-cfg', type=str, action='append', + epilog = """ [list of target/arch/cpu/board/vendor/soc to build] + + Build U-Boot for all commits in a branch. Use -n to do a dry run""" + + parser = argparse.ArgumentParser(epilog=epilog) + parser.add_argument('-a', '--adjust-cfg', type=str, action='append', help='Adjust the Kconfig settings in .config before building') - parser.add_option('-A', '--print-prefix', action='store_true', + parser.add_argument('-A', '--print-prefix', action='store_true', help='Print the tool-chain prefix for a board (CROSS_COMPILE=)') - parser.add_option('-b', '--branch', type='string', + parser.add_argument('-b', '--branch', type=str, help='Branch name to build, or range of commits to build') - parser.add_option('-B', '--bloat', dest='show_bloat', + parser.add_argument('-B', '--bloat', dest='show_bloat', action='store_true', default=False, help='Show changes in function code size for each board') - parser.add_option('--boards', type='string', action='append', + parser.add_argument('--boards', type=str, action='append', help='List of board names to build separated by comma') - parser.add_option('-c', '--count', dest='count', type='int', + parser.add_argument('-c', '--count', dest='count', type=int, default=-1, help='Run build on the top n commits') - parser.add_option('-C', '--force-reconfig', dest='force_reconfig', + parser.add_argument('-C', '--force-reconfig', dest='force_reconfig', action='store_true', default=False, help='Reconfigure for every commit (disable incremental build)') - parser.add_option('-d', '--detail', dest='show_detail', + parser.add_argument('-d', '--detail', dest='show_detail', action='store_true', default=False, help='Show detailed size delta for each board in the -S summary') - parser.add_option('-D', '--config-only', action='store_true', default=False, + parser.add_argument('-D', '--config-only', action='store_true', + default=False, help="Don't build, just configure each commit") - parser.add_option('--debug', action='store_true', + parser.add_argument('--debug', action='store_true', help='Enabling debugging (provides a full traceback on error)') - parser.add_option('-e', '--show_errors', action='store_true', + parser.add_argument('-e', '--show_errors', action='store_true', default=False, help='Show errors and warnings') - parser.add_option('-E', '--warnings-as-errors', action='store_true', + parser.add_argument('-E', '--warnings-as-errors', action='store_true', default=False, help='Treat all compiler warnings as errors') - parser.add_option('-f', '--force-build', dest='force_build', + parser.add_argument('-f', '--force-build', dest='force_build', action='store_true', default=False, help='Force build of boards even if already built') - parser.add_option('-F', '--force-build-failures', dest='force_build_failures', + parser.add_argument('-F', '--force-build-failures', dest='force_build_failures', action='store_true', default=False, help='Force build of previously-failed build') - parser.add_option('--fetch-arch', type='string', + parser.add_argument('--fetch-arch', type=str, help="Fetch a toolchain for architecture FETCH_ARCH ('list' to list)." ' You can also fetch several toolchains separate by comma, or' " 'all' to download all") - parser.add_option('-g', '--git', type='string', + parser.add_argument('-g', '--git', type=str, help='Git repo containing branch to build', default='.') - parser.add_option('-G', '--config-file', type='string', + parser.add_argument('-G', '--config-file', type=str, help='Path to buildman config file', default='') - parser.add_option('-H', '--full-help', action='store_true', dest='full_help', + parser.add_argument('-H', '--full-help', action='store_true', dest='full_help', default=False, help='Display the README file') - parser.add_option('-i', '--in-tree', dest='in_tree', + parser.add_argument('-i', '--in-tree', dest='in_tree', action='store_true', default=False, help='Build in the source tree instead of a separate directory') - parser.add_option('-I', '--ide', action='store_true', default=False, + parser.add_argument('-I', '--ide', action='store_true', default=False, help='Create build output that can be parsed by an IDE') - parser.add_option('-j', '--jobs', dest='jobs', type='int', + parser.add_argument('-j', '--jobs', dest='jobs', type=int, default=None, help='Number of jobs to run at once (passed to make)') - parser.add_option('-k', '--keep-outputs', action='store_true', + parser.add_argument('-k', '--keep-outputs', action='store_true', default=False, help='Keep all build output files (e.g. binaries)') - parser.add_option('-K', '--show-config', action='store_true', + parser.add_argument('-K', '--show-config', action='store_true', default=False, help='Show configuration changes in summary (both board config files and Kconfig)') - parser.add_option('--preserve-config-y', action='store_true', + parser.add_argument('--preserve-config-y', action='store_true', default=False, help="Don't convert y to 1 in configs") - parser.add_option('-l', '--list-error-boards', action='store_true', + parser.add_argument('-l', '--list-error-boards', action='store_true', default=False, help='Show a list of boards next to each error/warning') - parser.add_option('-L', '--no-lto', action='store_true', + parser.add_argument('-L', '--no-lto', action='store_true', default=False, help='Disable Link-time Optimisation (LTO) for builds') - parser.add_option('--list-tool-chains', action='store_true', default=False, + parser.add_argument('--list-tool-chains', action='store_true', default=False, help='List available tool chains (use -v to see probing detail)') - parser.add_option('-m', '--mrproper', action='store_true', + parser.add_argument('-m', '--mrproper', action='store_true', default=False, help="Run 'make mrproper before reconfiguring") - parser.add_option( + parser.add_argument( '-M', '--allow-missing', action='store_true', default=False, help='Tell binman to allow missing blobs and generate fake ones as needed') - parser.add_option('--maintainer-check', action='store_true', - help='Check that maintainer entries exist for each board') - parser.add_option( + parser.add_argument( + '--maintainer-check', action='store_true', + help='Check that maintainer entries exist for each board') + parser.add_argument( '--no-allow-missing', action='store_true', default=False, help='Disable telling binman to allow missing blobs') - parser.add_option('-n', '--dry-run', action='store_true', dest='dry_run', + parser.add_argument('-n', '--dry-run', action='store_true', dest='dry_run', default=False, help="Do a dry run (describe actions, but do nothing)") - parser.add_option('-N', '--no-subdirs', action='store_true', dest='no_subdirs', + parser.add_argument('-N', '--no-subdirs', action='store_true', dest='no_subdirs', default=False, help="Don't create subdirectories when building current source for a single board") - parser.add_option('-o', '--output-dir', type='string', dest='output_dir', + parser.add_argument('-o', '--output-dir', type=str, dest='output_dir', help='Directory where all builds happen and buildman has its workspace (default is ../)') - parser.add_option('-O', '--override-toolchain', type='string', + parser.add_argument('-O', '--override-toolchain', type=str, help="Override host toochain to use for sandbox (e.g. 'clang-7')") - parser.add_option('-Q', '--quick', action='store_true', + parser.add_argument('-Q', '--quick', action='store_true', default=False, help='Do a rough build, with limited warning resolution') - parser.add_option('-p', '--full-path', action='store_true', + parser.add_argument('-p', '--full-path', action='store_true', default=False, help="Use full toolchain path in CROSS_COMPILE") - parser.add_option('-P', '--per-board-out-dir', action='store_true', + parser.add_argument('-P', '--per-board-out-dir', action='store_true', default=False, help="Use an O= (output) directory per board rather than per thread") - parser.add_option('-r', '--reproducible-builds', action='store_true', + parser.add_argument('-r', '--reproducible-builds', action='store_true', help='Set SOURCE_DATE_EPOCH=0 to suuport a reproducible build') - parser.add_option('-R', '--regen-board-list', type='string', + parser.add_argument('-R', '--regen-board-list', type=str, help='Force regeneration of the list of boards, like the old boards.cfg file') - parser.add_option('-s', '--summary', action='store_true', + parser.add_argument('-s', '--summary', action='store_true', default=False, help='Show a build summary') - parser.add_option('-S', '--show-sizes', action='store_true', + parser.add_argument('-S', '--show-sizes', action='store_true', default=False, help='Show image size variation in summary') - parser.add_option('--step', type='int', + parser.add_argument('--step', type=int, default=1, help='Only build every n commits (0=just first and last)') if HAS_TESTS: - parser.add_option('--skip-net-tests', action='store_true', default=False, + parser.add_argument('--skip-net-tests', action='store_true', default=False, help='Skip tests which need the network') - parser.add_option('-t', '--test', action='store_true', dest='test', + parser.add_argument('-t', '--test', action='store_true', dest='test', default=False, help='run tests') - parser.add_option('-T', '--threads', type='int', + parser.add_argument('-T', '--threads', type=int, default=None, help='Number of builder threads to use (0=single-thread)') - parser.add_option('-u', '--show_unknown', action='store_true', + parser.add_argument('-u', '--show_unknown', action='store_true', default=False, help='Show boards with unknown build result') - parser.add_option('-U', '--show-environment', action='store_true', + parser.add_argument('-U', '--show-environment', action='store_true', default=False, help='Show environment changes in summary') - parser.add_option('-v', '--verbose', action='store_true', + parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Show build results while the build progresses') - parser.add_option('-V', '--verbose-build', action='store_true', + parser.add_argument('-V', '--verbose-build', action='store_true', default=False, help='Run make with V=1, logging all output') - parser.add_option('-w', '--work-in-output', action='store_true', + parser.add_argument('-w', '--work-in-output', action='store_true', default=False, help='Use the output directory as the work directory') - parser.add_option('-W', '--ignore-warnings', action='store_true', + parser.add_argument('-W', '--ignore-warnings', action='store_true', default=False, help='Return success even if there are warnings') - parser.add_option('-x', '--exclude', dest='exclude', - type='string', action='append', + parser.add_argument('-x', '--exclude', dest='exclude', + type=str, action='append', help='Specify a list of boards to exclude, separated by comma') - parser.add_option('-y', '--filter-dtb-warnings', action='store_true', + parser.add_argument('-y', '--filter-dtb-warnings', action='store_true', default=False, help='Filter out device-tree-compiler warnings from output') - parser.add_option('-Y', '--filter-migration-warnings', action='store_true', + parser.add_argument('-Y', '--filter-migration-warnings', action='store_true', default=False, help='Filter out migration warnings from output') - - parser.usage += """ [list of target/arch/cpu/board/vendor/soc to build] - - Build U-Boot for all commits in a branch. Use -n to do a dry run""" + parser.add_argument('terms', type=str, nargs='*', + help='Board / SoC names to build') return parser.parse_args() diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 3a9454c..cda2d40 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -429,35 +429,35 @@ def determine_boards(brds, args, col, opt_boards, exclude_list): return selected, why_selected, board_warnings -def adjust_options(options, series, selected): - """Adjust options according to various constraints +def adjust_args(args, series, selected): + """Adjust arguments according to various constraints Updates verbose, show_errors, threads, jobs and step Args: - options (Options): Options object to adjust + args (Namespace): Namespace object to adjust series (Series): Series being built / summarised selected (list of Board): List of Board objects that are marked """ - if not series and not options.dry_run: - options.verbose = True - if not options.summary: - options.show_errors = True + if not series and not args.dry_run: + args.verbose = True + if not args.summary: + args.show_errors = True # By default we have one thread per CPU. But if there are not enough jobs # we can have fewer threads and use a high '-j' value for make. - if options.threads is None: - options.threads = min(multiprocessing.cpu_count(), len(selected)) - if not options.jobs: - options.jobs = max(1, (multiprocessing.cpu_count() + + if args.threads is None: + args.threads = min(multiprocessing.cpu_count(), len(selected)) + if not args.jobs: + args.jobs = max(1, (multiprocessing.cpu_count() + len(selected) - 1) // len(selected)) - if not options.step: - options.step = len(series.commits) - 1 + if not args.step: + args.step = len(series.commits) - 1 # We can't show function sizes without board details at present - if options.show_bloat: - options.show_detail = True + if args.show_bloat: + args.show_detail = True def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col, @@ -489,7 +489,7 @@ def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col, return output_dir -def run_builder(builder, commits, board_selected, options): +def run_builder(builder, commits, board_selected, args): """Run the builder or show the summary Args: @@ -497,37 +497,37 @@ def run_builder(builder, commits, board_selected, options): boards_selected (dict): Dict of selected boards: key: target name value: Board object - options (Options): Options to use + args (Namespace): Namespace to use Returns: int: Return code for buildman """ - gnu_make = command.output(os.path.join(options.git, + gnu_make = command.output(os.path.join(args.git, 'scripts/show-gnu-make'), raise_on_error=False).rstrip() if not gnu_make: sys.exit('GNU Make not found') builder.gnu_make = gnu_make - if not options.ide: - commit_count = count_build_commits(commits, options.step) - tprint(get_action_summary(options.summary, commit_count, board_selected, - options.threads, options.jobs)) + if not args.ide: + commit_count = count_build_commits(commits, args.step) + tprint(get_action_summary(args.summary, commit_count, board_selected, + args.threads, args.jobs)) builder.SetDisplayOptions( - options.show_errors, options.show_sizes, options.show_detail, - options.show_bloat, options.list_error_boards, options.show_config, - options.show_environment, options.filter_dtb_warnings, - options.filter_migration_warnings, options.ide) - if options.summary: + args.show_errors, args.show_sizes, args.show_detail, + args.show_bloat, args.list_error_boards, args.show_config, + args.show_environment, args.filter_dtb_warnings, + args.filter_migration_warnings, args.ide) + if args.summary: builder.ShowSummary(commits, board_selected) else: fail, warned, excs = builder.BuildBoards( - commits, board_selected, options.keep_outputs, options.verbose) + commits, board_selected, args.keep_outputs, args.verbose) if excs: return 102 if fail: return 100 - if warned and not options.ignore_warnings: + if warned and not args.ignore_warnings: return 101 return 0 @@ -556,12 +556,12 @@ def calc_adjust_cfg(adjust_cfg, reproducible_builds): return adjust_cfg -def do_buildman(options, args, toolchains=None, make_func=None, brds=None, +def do_buildman(args, toolchains=None, make_func=None, brds=None, clean_dir=False, test_thread_exceptions=False): """The main control code for buildman Args: - options: Command line options object + args: ArgumentParser object args: Command line arguments (list of strings) toolchains: Toolchains to use - this should be a Toolchains() object. If None, then it will be created and scanned @@ -583,68 +583,67 @@ def do_buildman(options, args, toolchains=None, make_func=None, brds=None, gitutil.setup() col = terminal.Color() - git_dir = os.path.join(options.git, '.git') + git_dir = os.path.join(args.git, '.git') - toolchains = get_toolchains(toolchains, col, options.override_toolchain, - options.fetch_arch, options.list_tool_chains, - options.verbose) + toolchains = get_toolchains(toolchains, col, args.override_toolchain, + args.fetch_arch, args.list_tool_chains, + args.verbose) output_dir = setup_output_dir( - options.output_dir, options.work_in_output, options.branch, - options.no_subdirs, col, clean_dir) + args.output_dir, args.work_in_output, args.branch, + args.no_subdirs, col, clean_dir) # Work out what subset of the boards we are building if not brds: - brds = get_boards_obj(output_dir, options.regen_board_list, - options.maintainer_check, options.threads, - options.verbose) + brds = get_boards_obj(output_dir, args.regen_board_list, + args.maintainer_check, args.threads, args.verbose) if isinstance(brds, int): return brds selected, why_selected, board_warnings = determine_boards( - brds, args, col, options.boards, options.exclude) + brds, args.terms, col, args.boards, args.exclude) - if options.print_prefix: + if args.print_prefix: show_toolchain_prefix(brds, toolchains) return 0 - series = determine_series(selected, col, git_dir, options.count, - options.branch, options.work_in_output) + series = determine_series(selected, col, git_dir, args.count, + args.branch, args.work_in_output) - adjust_options(options, series, selected) + adjust_args(args, series, selected) # For a dry run, just show our actions as a sanity check - if options.dry_run: + if args.dry_run: show_actions(series, why_selected, selected, output_dir, board_warnings, - options.step, options.threads, options.jobs, - options.verbose) + args.step, args.threads, args.jobs, + args.verbose) return 0 - # Create a new builder with the selected options + # Create a new builder with the selected args builder = Builder(toolchains, output_dir, git_dir, - options.threads, options.jobs, checkout=True, - show_unknown=options.show_unknown, step=options.step, - no_subdirs=options.no_subdirs, full_path=options.full_path, - verbose_build=options.verbose_build, - mrproper=options.mrproper, - per_board_out_dir=options.per_board_out_dir, - config_only=options.config_only, - squash_config_y=not options.preserve_config_y, - warnings_as_errors=options.warnings_as_errors, - work_in_output=options.work_in_output, + args.threads, args.jobs, checkout=True, + show_unknown=args.show_unknown, step=args.step, + no_subdirs=args.no_subdirs, full_path=args.full_path, + verbose_build=args.verbose_build, + mrproper=args.mrproper, + per_board_out_dir=args.per_board_out_dir, + config_only=args.config_only, + squash_config_y=not args.preserve_config_y, + warnings_as_errors=args.warnings_as_errors, + work_in_output=args.work_in_output, test_thread_exceptions=test_thread_exceptions, - adjust_cfg=calc_adjust_cfg(options.adjust_cfg, - options.reproducible_builds), - allow_missing=get_allow_missing(options.allow_missing, - options.no_allow_missing, - len(selected), options.branch), - no_lto=options.no_lto, - reproducible_builds=options.reproducible_builds, - force_build = options.force_build, - force_build_failures = options.force_build_failures, - force_reconfig = options.force_reconfig, in_tree = options.in_tree, - force_config_on_failure=not options.quick, make_func=make_func) + adjust_cfg=calc_adjust_cfg(args.adjust_cfg, + args.reproducible_builds), + allow_missing=get_allow_missing(args.allow_missing, + args.no_allow_missing, + len(selected), args.branch), + no_lto=args.no_lto, + reproducible_builds=args.reproducible_builds, + force_build = args.force_build, + force_build_failures = args.force_build_failures, + force_reconfig = args.force_reconfig, in_tree = args.in_tree, + force_config_on_failure=not args.quick, make_func=make_func) TEST_BUILDER = builder return run_builder(builder, series.commits if series else None, - brds.get_selected_dict(), options) + brds.get_selected_dict(), args) diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index aaf4cde..fe11917 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -252,12 +252,12 @@ class TestFunctional(unittest.TestCase): result code from buildman """ sys.argv = [sys.argv[0]] + list(args) - options, args = cmdline.parse_args() + args = cmdline.parse_args() if brds == False: brds = self._boards result = control.do_buildman( - options, args, toolchains=self._toolchains, - make_func=self._HandleMake, brds=brds, clean_dir=clean_dir, + args, toolchains=self._toolchains, make_func=self._HandleMake, + brds=brds, clean_dir=clean_dir, test_thread_exceptions=test_thread_exceptions) if get_builder: self._builder = control.TEST_BUILDER diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 70ab9a4..097e059 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -41,7 +41,7 @@ def run_tests(skip_net_tests, debug, verbose, args): from buildman import func_test from buildman import test - test_name = args and args[0] or None + test_name = args.terms and args.terms[0] or None if skip_net_tests: test.use_network = False @@ -60,23 +60,22 @@ def run_buildman(): This is the main program. It collects arguments and runs either the tests or the control module. """ - options, args = cmdline.parse_args() + args = cmdline.parse_args() - if not options.debug: + if not args.debug: sys.tracebacklimit = 0 # Run our meagre tests - if cmdline.HAS_TESTS and options.test: - return run_tests(options.skip_net_tests, options.debug, options.verbose, - args) + if cmdline.HAS_TESTS and args.test: + return run_tests(args.skip_net_tests, args.debug, args.verbose, args) - elif options.full_help: + elif args.full_help: tools.print_full_help(str(files('buildman').joinpath('README.rst'))) # Build selected commits for selected boards else: - bsettings.Setup(options.config_file) - ret_code = control.do_buildman(options, args) + bsettings.Setup(args.config_file) + ret_code = control.do_buildman(args) return ret_code -- cgit v1.1