This is redundant information. The command is already known from the top-level west command line. We can just feed it to run without inserting it on the command line as well, which is safe to do now that zephyr_flash_debug.py is gone. Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
125 lines
4.9 KiB
Python
125 lines
4.9 KiB
Python
# Copyright (c) 2018 Open Source Foundries Limited.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
'''Common code used by commands which execute runners.
|
|
'''
|
|
|
|
import argparse
|
|
from os import getcwd, chdir
|
|
from subprocess import CalledProcessError
|
|
from textwrap import dedent
|
|
|
|
from .. import cmake
|
|
from .. import log
|
|
from ..runner import get_runner_cls
|
|
from . import CommandContextError
|
|
|
|
|
|
def add_parser_common(parser_adder, command):
|
|
parser = parser_adder.add_parser(
|
|
command.name,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
description=command.description)
|
|
|
|
parser.add_argument('-d', '--build-dir',
|
|
help='''Build directory to obtain runner information
|
|
from; default is the current working directory.''')
|
|
parser.add_argument('-c', '--cmake-cache', default=cmake.DEFAULT_CACHE,
|
|
help='''Path to CMake cache file containing runner
|
|
configuration (this is generated by the Zephyr
|
|
build system when compiling binaries);
|
|
default: {}.
|
|
|
|
If this is a relative path, it is assumed relative to
|
|
the build directory. An absolute path can also be
|
|
given instead.'''.format(cmake.DEFAULT_CACHE))
|
|
parser.add_argument('-r', '--runner',
|
|
help='''If given, overrides any cached {}
|
|
runner.'''.format(command.name))
|
|
parser.add_argument('--skip-rebuild', action='store_true',
|
|
help='''If given, do not rebuild the application
|
|
before running {} commands.'''.format(command.name))
|
|
|
|
return parser
|
|
|
|
|
|
def desc_common(command_name):
|
|
return dedent('''\
|
|
Any options not recognized by this command are passed to the
|
|
back-end {command} runner.
|
|
|
|
If you need to pass an option to a runner which has the
|
|
same name as one recognized by this command, you can
|
|
end argument parsing with a '--', like so:
|
|
|
|
west {command} --{command}-arg=value -- --runner-arg=value2
|
|
'''.format(**{'command': command_name}))
|
|
|
|
|
|
def do_run_common(command, args, runner_args, cached_runner_var):
|
|
command_name = command.name
|
|
build_dir = args.build_dir or getcwd()
|
|
|
|
if not args.skip_rebuild:
|
|
try:
|
|
cmake.run_build(build_dir)
|
|
except CalledProcessError:
|
|
if args.build_dir:
|
|
log.die('cannot run {}, build in {} failed'.format(
|
|
command_name, args.build_dir))
|
|
else:
|
|
log.die('cannot run {}; no --build-dir given and build in '
|
|
'current directory {} failed'.format(command_name,
|
|
build_dir))
|
|
|
|
# Temporary hack: we need to ensure we're running from the build
|
|
# directory for now. Otherwise, the BuildConfiguration objects
|
|
# that get created by the runners look for .config in the wrong
|
|
# places.
|
|
chdir(build_dir)
|
|
|
|
# TODO: build this by joining with build_dir once the above chdir
|
|
# goes away.
|
|
cache_file = args.cmake_cache
|
|
cache = cmake.CMakeCache(cache_file)
|
|
board = cache['CACHED_BOARD']
|
|
available = cache.get_list('ZEPHYR_RUNNERS')
|
|
if not available:
|
|
log.wrn('No cached runners are available in', cache_file)
|
|
runner = args.runner or cache.get(cached_runner_var)
|
|
|
|
if runner is None:
|
|
raise CommandContextError(dedent("""
|
|
No {} runner available for {}. Please either specify one
|
|
manually, or check your board's documentation for
|
|
alternative instructions.""".format(command_name, board)))
|
|
|
|
log.inf('Using runner:', runner)
|
|
if runner not in available:
|
|
log.wrn('Runner {} is not configured for use with {}, '
|
|
'this may not work'.format(runner, board))
|
|
runner_cls = get_runner_cls(runner)
|
|
if command_name not in runner_cls.capabilities().commands:
|
|
log.die('Runner {} does not support command {}'.format(
|
|
runner, command_name))
|
|
|
|
cached_common_args = cache.get_list('ZEPHYR_RUNNER_ARGS_COMMON')
|
|
cached_runner_args = cache.get_list(
|
|
'ZEPHYR_RUNNER_ARGS_{}'.format(cmake.make_c_identifier(runner)))
|
|
# Construct the final command line arguments, create a
|
|
# runner-specific parser to handle them, and run the command.
|
|
assert isinstance(runner_args, list), runner_args
|
|
final_runner_args = cached_common_args + cached_runner_args + runner_args
|
|
|
|
# Having the runners themselves be the place where their argument
|
|
# parsing is handled is hackish; it's an artifact of the time
|
|
# before the runner package was part of west.
|
|
#
|
|
# TODO: refactor runner argument parsing higher up into west.
|
|
parser = argparse.ArgumentParser(prog=runner)
|
|
runner_cls.add_parser(parser)
|
|
parsed_args = parser.parse_args(args=final_runner_args)
|
|
parsed_args.verbose = args.verbose
|
|
runner = runner_cls.create_from_args(parsed_args)
|
|
runner.run(command_name)
|