buildman: Convert to argparse

Use argparse to parse the arguments, since OptionParser is deprecated now.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2023-07-24 09:34:11 -06:00
parent 6a0c7b4a5e
commit 529957c315
4 changed files with 216 additions and 214 deletions
+135 -131
View File
@@ -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',
help='Adjust the Kconfig settings in .config before building')
parser.add_option('-A', '--print-prefix', action='store_true',
help='Print the tool-chain prefix for a board (CROSS_COMPILE=)')
parser.add_option('-b', '--branch', type='string',
help='Branch name to build, or range of commits to build')
parser.add_option('-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',
help='List of board names to build separated by comma')
parser.add_option('-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',
action='store_true', default=False,
help='Reconfigure for every commit (disable incremental build)')
parser.add_option('-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,
help="Don't build, just configure each commit")
parser.add_option('--debug', action='store_true',
help='Enabling debugging (provides a full traceback on error)')
parser.add_option('-e', '--show_errors', action='store_true',
default=False, help='Show errors and warnings')
parser.add_option('-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',
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',
action='store_true', default=False,
help='Force build of previously-failed build')
parser.add_option('--fetch-arch', type='string',
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',
help='Git repo containing branch to build', default='.')
parser.add_option('-G', '--config-file', type='string',
help='Path to buildman config file', default='')
parser.add_option('-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',
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,
help='Create build output that can be parsed by an IDE')
parser.add_option('-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',
default=False, help='Keep all build output files (e.g. binaries)')
parser.add_option('-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',
default=False, help="Don't convert y to 1 in configs")
parser.add_option('-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',
default=False, help='Disable Link-time Optimisation (LTO) for builds')
parser.add_option('--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',
default=False, help="Run 'make mrproper before reconfiguring")
parser.add_option(
'-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(
'--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',
default=False, help="Do a dry run (describe actions, but do nothing)")
parser.add_option('-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',
help='Directory where all builds happen and buildman has its workspace (default is ../)')
parser.add_option('-O', '--override-toolchain', type='string',
help="Override host toochain to use for sandbox (e.g. 'clang-7')")
parser.add_option('-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',
default=False, help="Use full toolchain path in CROSS_COMPILE")
parser.add_option('-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',
help='Set SOURCE_DATE_EPOCH=0 to suuport a reproducible build')
parser.add_option('-R', '--regen-board-list', type='string',
help='Force regeneration of the list of boards, like the old boards.cfg file')
parser.add_option('-s', '--summary', action='store_true',
default=False, help='Show a build summary')
parser.add_option('-S', '--show-sizes', action='store_true',
default=False, help='Show image size variation in summary')
parser.add_option('--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,
help='Skip tests which need the network')
parser.add_option('-t', '--test', action='store_true', dest='test',
default=False, help='run tests')
parser.add_option('-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',
default=False, help='Show boards with unknown build result')
parser.add_option('-U', '--show-environment', action='store_true',
default=False, help='Show environment changes in summary')
parser.add_option('-v', '--verbose', action='store_true',
default=False, help='Show build results while the build progresses')
parser.add_option('-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',
default=False, help='Use the output directory as the work directory')
parser.add_option('-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',
help='Specify a list of boards to exclude, separated by comma')
parser.add_option('-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',
default=False,
help='Filter out migration warnings from output')
parser.usage += """ [list of target/arch/cpu/board/vendor/soc to build]
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_argument('-A', '--print-prefix', action='store_true',
help='Print the tool-chain prefix for a board (CROSS_COMPILE=)')
parser.add_argument('-b', '--branch', type=str,
help='Branch name to build, or range of commits to build')
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_argument('--boards', type=str, action='append',
help='List of board names to build separated by comma')
parser.add_argument('-c', '--count', dest='count', type=int,
default=-1, help='Run build on the top n commits')
parser.add_argument('-C', '--force-reconfig', dest='force_reconfig',
action='store_true', default=False,
help='Reconfigure for every commit (disable incremental build)')
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_argument('-D', '--config-only', action='store_true',
default=False,
help="Don't build, just configure each commit")
parser.add_argument('--debug', action='store_true',
help='Enabling debugging (provides a full traceback on error)')
parser.add_argument('-e', '--show_errors', action='store_true',
default=False, help='Show errors and warnings')
parser.add_argument('-E', '--warnings-as-errors', action='store_true',
default=False, help='Treat all compiler warnings as errors')
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_argument('-F', '--force-build-failures', dest='force_build_failures',
action='store_true', default=False,
help='Force build of previously-failed build')
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_argument('-g', '--git', type=str,
help='Git repo containing branch to build', default='.')
parser.add_argument('-G', '--config-file', type=str,
help='Path to buildman config file', default='')
parser.add_argument('-H', '--full-help', action='store_true', dest='full_help',
default=False, help='Display the README file')
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_argument('-I', '--ide', action='store_true', default=False,
help='Create build output that can be parsed by an IDE')
parser.add_argument('-j', '--jobs', dest='jobs', type=int,
default=None, help='Number of jobs to run at once (passed to make)')
parser.add_argument('-k', '--keep-outputs', action='store_true',
default=False, help='Keep all build output files (e.g. binaries)')
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_argument('--preserve-config-y', action='store_true',
default=False, help="Don't convert y to 1 in configs")
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_argument('-L', '--no-lto', action='store_true',
default=False, help='Disable Link-time Optimisation (LTO) for builds')
parser.add_argument('--list-tool-chains', action='store_true', default=False,
help='List available tool chains (use -v to see probing detail)')
parser.add_argument('-m', '--mrproper', action='store_true',
default=False, help="Run 'make mrproper before reconfiguring")
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_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_argument('-n', '--dry-run', action='store_true', dest='dry_run',
default=False, help="Do a dry run (describe actions, but do nothing)")
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_argument('-o', '--output-dir', type=str, dest='output_dir',
help='Directory where all builds happen and buildman has its workspace (default is ../)')
parser.add_argument('-O', '--override-toolchain', type=str,
help="Override host toochain to use for sandbox (e.g. 'clang-7')")
parser.add_argument('-Q', '--quick', action='store_true',
default=False, help='Do a rough build, with limited warning resolution')
parser.add_argument('-p', '--full-path', action='store_true',
default=False, help="Use full toolchain path in CROSS_COMPILE")
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_argument('-r', '--reproducible-builds', action='store_true',
help='Set SOURCE_DATE_EPOCH=0 to suuport a reproducible build')
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_argument('-s', '--summary', action='store_true',
default=False, help='Show a build summary')
parser.add_argument('-S', '--show-sizes', action='store_true',
default=False, help='Show image size variation in summary')
parser.add_argument('--step', type=int,
default=1, help='Only build every n commits (0=just first and last)')
if HAS_TESTS:
parser.add_argument('--skip-net-tests', action='store_true', default=False,
help='Skip tests which need the network')
parser.add_argument('-t', '--test', action='store_true', dest='test',
default=False, help='run tests')
parser.add_argument('-T', '--threads', type=int,
default=None,
help='Number of builder threads to use (0=single-thread)')
parser.add_argument('-u', '--show_unknown', action='store_true',
default=False, help='Show boards with unknown build result')
parser.add_argument('-U', '--show-environment', action='store_true',
default=False, help='Show environment changes in summary')
parser.add_argument('-v', '--verbose', action='store_true',
default=False, help='Show build results while the build progresses')
parser.add_argument('-V', '--verbose-build', action='store_true',
default=False, help='Run make with V=1, logging all output')
parser.add_argument('-w', '--work-in-output', action='store_true',
default=False, help='Use the output directory as the work directory')
parser.add_argument('-W', '--ignore-warnings', action='store_true',
default=False, help='Return success even if there are warnings')
parser.add_argument('-x', '--exclude', dest='exclude',
type=str, action='append',
help='Specify a list of boards to exclude, separated by comma')
parser.add_argument('-y', '--filter-dtb-warnings', action='store_true',
default=False,
help='Filter out device-tree-compiler warnings from output')
parser.add_argument('-Y', '--filter-migration-warnings', action='store_true',
default=False,
help='Filter out migration warnings from output')
parser.add_argument('terms', type=str, nargs='*',
help='Board / SoC names to build')
return parser.parse_args()
+70 -71
View File
@@ -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)
+3 -3
View File
@@ -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
+8 -9
View File
@@ -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