2019-01-23 08:31:06 -07:00
|
|
|
# Copyright (c) 2018 Open Source Foundries Limited.
|
2023-01-04 10:36:15 +00:00
|
|
|
# Copyright (c) 2023 Nordic Semiconductor ASA
|
2025-05-06 18:43:59 +05:30
|
|
|
# Copyright (c) 2025 Aerlync Labs Inc.
|
2019-01-23 08:31:06 -07:00
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
'''Common code used by commands which execute runners.
|
|
|
|
'''
|
|
|
|
|
2024-12-19 07:31:22 +01:00
|
|
|
import importlib.util
|
2023-01-04 10:36:15 +00:00
|
|
|
import re
|
2019-01-23 08:31:06 -07:00
|
|
|
import argparse
|
2019-06-02 21:33:41 -06:00
|
|
|
import logging
|
2023-01-04 10:36:15 +00:00
|
|
|
from collections import defaultdict
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
from os import close, getcwd, path, fspath
|
2020-03-17 16:26:51 -07:00
|
|
|
from pathlib import Path
|
2019-01-23 08:31:06 -07:00
|
|
|
from subprocess import CalledProcessError
|
2020-03-17 16:26:51 -07:00
|
|
|
import sys
|
2019-06-03 01:05:26 -06:00
|
|
|
import tempfile
|
2019-01-23 08:31:06 -07:00
|
|
|
import textwrap
|
2019-06-03 01:05:26 -06:00
|
|
|
import traceback
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2023-01-04 10:36:15 +00:00
|
|
|
from dataclasses import dataclass
|
2019-01-23 08:31:06 -07:00
|
|
|
from west import log
|
2021-11-22 10:29:56 +01:00
|
|
|
from build_helpers import find_build_dir, is_zephyr_build, load_domains, \
|
2019-06-05 16:04:29 +02:00
|
|
|
FIND_BUILD_DIR_DESCRIPTION
|
2019-06-03 01:05:26 -06:00
|
|
|
from west.commands import CommandError
|
2019-06-17 11:47:11 +02:00
|
|
|
from west.configuration import config
|
2022-11-16 15:05:29 +01:00
|
|
|
from runners.core import FileType
|
2023-01-04 10:36:15 +00:00
|
|
|
from runners.core import BuildConfiguration
|
2020-02-10 06:40:29 -08:00
|
|
|
import yaml
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2024-12-19 07:31:22 +01:00
|
|
|
import zephyr_module
|
|
|
|
from zephyr_ext_common import ZEPHYR_BASE, ZEPHYR_SCRIPTS
|
2021-02-23 13:40:13 -08:00
|
|
|
|
|
|
|
# Runners depend on edtlib. Make sure the copy in the tree is
|
|
|
|
# available to them before trying to import any.
|
2022-04-30 21:13:52 +10:00
|
|
|
sys.path.insert(0, str(ZEPHYR_SCRIPTS / 'dts' / 'python-devicetree' / 'src'))
|
2021-02-23 13:40:13 -08:00
|
|
|
|
2019-05-25 15:41:36 -06:00
|
|
|
from runners import get_runner_cls, ZephyrBinaryRunner, MissingProgram
|
2020-02-10 06:40:29 -08:00
|
|
|
from runners.core import RunnerConfig
|
|
|
|
import zcmake
|
2019-01-23 08:31:06 -07:00
|
|
|
|
|
|
|
# Context-sensitive help indentation.
|
|
|
|
# Don't change this, or output from argparse won't match up.
|
|
|
|
INDENT = ' ' * 2
|
|
|
|
|
2024-07-01 08:19:25 +01:00
|
|
|
IGNORED_RUN_ONCE_PRIORITY = -1
|
|
|
|
SOC_FILE_RUN_ONCE_DEFAULT_PRIORITY = 0
|
|
|
|
BOARD_FILE_RUN_ONCE_DEFAULT_PRIORITY = 10
|
|
|
|
|
2019-06-02 21:33:41 -06:00
|
|
|
if log.VERBOSE >= log.VERBOSE_NORMAL:
|
|
|
|
# Using level 1 allows sub-DEBUG levels of verbosity. The
|
|
|
|
# west.log module decides whether or not to actually print the
|
|
|
|
# message.
|
|
|
|
#
|
|
|
|
# https://docs.python.org/3.7/library/logging.html#logging-levels.
|
|
|
|
LOG_LEVEL = 1
|
|
|
|
else:
|
|
|
|
LOG_LEVEL = logging.INFO
|
|
|
|
|
2019-06-02 22:46:02 -06:00
|
|
|
def _banner(msg):
|
|
|
|
log.inf('-- ' + msg, colorize=True)
|
2019-06-02 21:33:41 -06:00
|
|
|
|
|
|
|
class WestLogFormatter(logging.Formatter):
|
|
|
|
|
|
|
|
def __init__(self):
|
2019-06-02 22:46:02 -06:00
|
|
|
super().__init__(fmt='%(name)s: %(message)s')
|
2019-06-02 21:33:41 -06:00
|
|
|
|
|
|
|
class WestLogHandler(logging.Handler):
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.setFormatter(WestLogFormatter())
|
|
|
|
self.setLevel(LOG_LEVEL)
|
|
|
|
|
|
|
|
def emit(self, record):
|
|
|
|
fmt = self.format(record)
|
|
|
|
lvl = record.levelno
|
|
|
|
if lvl > logging.CRITICAL:
|
|
|
|
log.die(fmt)
|
|
|
|
elif lvl >= logging.ERROR:
|
|
|
|
log.err(fmt)
|
|
|
|
elif lvl >= logging.WARNING:
|
|
|
|
log.wrn(fmt)
|
|
|
|
elif lvl >= logging.INFO:
|
2019-06-02 22:46:02 -06:00
|
|
|
_banner(fmt)
|
2019-06-02 21:33:41 -06:00
|
|
|
elif lvl >= logging.DEBUG:
|
|
|
|
log.dbg(fmt)
|
|
|
|
else:
|
|
|
|
log.dbg(fmt, level=log.VERBOSE_EXTREME)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2023-01-04 10:36:15 +00:00
|
|
|
@dataclass
|
|
|
|
class UsedFlashCommand:
|
|
|
|
command: str
|
|
|
|
boards: list
|
|
|
|
runners: list
|
|
|
|
first: bool
|
|
|
|
ran: bool = False
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class ImagesFlashed:
|
|
|
|
flashed: int = 0
|
|
|
|
total: int = 0
|
|
|
|
|
2024-07-01 08:19:25 +01:00
|
|
|
@dataclass
|
|
|
|
class SocBoardFilesProcessing:
|
|
|
|
filename: str
|
|
|
|
board: bool = False
|
|
|
|
priority: int = IGNORED_RUN_ONCE_PRIORITY
|
|
|
|
yaml: object = None
|
|
|
|
|
2024-12-19 07:31:22 +01:00
|
|
|
def import_from_path(module_name, file_path):
|
|
|
|
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
|
|
|
module = importlib.util.module_from_spec(spec)
|
|
|
|
sys.modules[module_name] = module
|
|
|
|
spec.loader.exec_module(module)
|
|
|
|
return module
|
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def command_verb(command):
|
|
|
|
return "flash" if command.name == "flash" else "debug"
|
|
|
|
|
|
|
|
def add_parser_common(command, parser_adder=None, parser=None):
|
|
|
|
if parser_adder is not None:
|
|
|
|
parser = parser_adder.add_parser(
|
|
|
|
command.name,
|
|
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
|
|
help=command.help,
|
2020-06-25 12:58:58 -07:00
|
|
|
description=command.description)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
boards/shields: re-work handling in cmake and west
Remove the boards and shields lists from the 'usage' target output.
That might have been readable at some point long ago in Zephyr's
history, when only a few boards were available, but right now it's
obscuring the high level targets we really want 'usage' to print.
Instead, add 'boards' and 'shields' targets which the user can run to
get those lists, and reference them from the 'usage' output. This
makes 'usage' squintable again. We use the new list_boards.py script
from the 'boards' target.
Reference the 'help' target from 'usage' as well, and drop the
recommendation that people run '--target help' from the 'west build
--help' output for the 'west build --target' option. The canonical
place to look is 'usage' now.
Use the new list_boards.py code from 'west boards' as well, which
allows us to add the board's directory as a format string key, in
addition to its name and architecture.
Keep west-completion.bash up to date. While doing that, I noticed that
a bunch of references to this file refer to a stale location, so fix
those too.
Finally, the 'usage' output is what we print for a failed board or
shield lookup, so that needs to be updated also. Handle that by
invoking boards.cmake and a new shields.cmake in CMake script mode to
print the relevant output.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-12-09 15:53:00 -08:00
|
|
|
# Remember to update west-completion.bash if you add or remove
|
2019-01-23 08:31:06 -07:00
|
|
|
# flags
|
|
|
|
|
2020-06-25 12:58:58 -07:00
|
|
|
group = parser.add_argument_group('general options',
|
|
|
|
FIND_BUILD_DIR_DESCRIPTION)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
group.add_argument('-d', '--build-dir', metavar='DIR',
|
2020-06-25 12:58:58 -07:00
|
|
|
help='application build directory')
|
|
|
|
# still supported for backwards compatibility, but questionably
|
|
|
|
# useful now that we do everything with runners.yaml
|
2020-02-10 06:40:29 -08:00
|
|
|
group.add_argument('-c', '--cmake-cache', metavar='FILE',
|
2020-06-25 12:58:58 -07:00
|
|
|
help=argparse.SUPPRESS)
|
2019-01-23 08:31:06 -07:00
|
|
|
group.add_argument('-r', '--runner',
|
2020-06-25 12:58:58 -07:00
|
|
|
help='override default runner from --build-dir')
|
2019-01-23 08:31:06 -07:00
|
|
|
group.add_argument('--skip-rebuild', action='store_true',
|
2020-06-25 12:58:58 -07:00
|
|
|
help='do not refresh cmake dependencies first')
|
2021-11-22 10:29:56 +01:00
|
|
|
group.add_argument('--domain', action='append',
|
|
|
|
help='execute runner only for given domain')
|
2020-06-25 12:58:58 -07:00
|
|
|
|
|
|
|
group = parser.add_argument_group(
|
2020-11-02 08:30:14 -08:00
|
|
|
'runner configuration',
|
2020-06-25 12:58:58 -07:00
|
|
|
textwrap.dedent(f'''\
|
2020-11-02 08:30:14 -08:00
|
|
|
===================================================================
|
|
|
|
IMPORTANT:
|
|
|
|
Individual runners support additional options not printed here.
|
|
|
|
===================================================================
|
|
|
|
|
|
|
|
Run "west {command.name} --context" for runner-specific options.
|
|
|
|
|
|
|
|
If a build directory is found, --context also prints per-runner
|
|
|
|
settings found in that build directory's runners.yaml file.
|
|
|
|
|
|
|
|
Use "west {command.name} --context -r RUNNER" to limit output to a
|
|
|
|
specific RUNNER.
|
2020-06-25 12:58:58 -07:00
|
|
|
|
2020-11-02 08:30:14 -08:00
|
|
|
Some runner settings also can be overridden with options like
|
|
|
|
--hex-file. However, this depends on the runner: not all runners
|
|
|
|
respect --elf-file / --hex-file / --bin-file, nor use gdb or openocd,
|
|
|
|
etc.'''))
|
|
|
|
group.add_argument('-H', '--context', action='store_true',
|
|
|
|
help='print runner- and build-specific help')
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
# Options used to override RunnerConfig values in runners.yaml.
|
2020-06-25 12:58:58 -07:00
|
|
|
# TODO: is this actually useful?
|
|
|
|
group.add_argument('--board-dir', metavar='DIR', help='board directory')
|
|
|
|
# FIXME: these are runner-specific and should be moved to where --context
|
|
|
|
# can find them instead.
|
|
|
|
group.add_argument('--gdb', help='path to GDB')
|
|
|
|
group.add_argument('--openocd', help='path to openocd')
|
2019-01-23 08:31:06 -07:00
|
|
|
group.add_argument(
|
2022-06-16 14:50:37 -06:00
|
|
|
'--openocd-search', metavar='DIR', action='append',
|
2020-06-25 12:58:58 -07:00
|
|
|
help='path to add to openocd search path, if applicable')
|
2019-01-23 08:31:06 -07:00
|
|
|
|
|
|
|
return parser
|
|
|
|
|
2025-05-06 18:43:59 +05:30
|
|
|
def is_sysbuild(build_dir):
|
|
|
|
# Check if the build directory is part of a sysbuild (multi-image build).
|
|
|
|
domains_yaml_path = path.join(build_dir, "domains.yaml")
|
|
|
|
return path.exists(domains_yaml_path)
|
|
|
|
|
|
|
|
def get_domains_to_process(build_dir, args, domain_file, get_all_domain=False):
|
|
|
|
try:
|
|
|
|
domains = load_domains(build_dir)
|
|
|
|
except Exception as e:
|
|
|
|
log.die(f"Failed to load domains: {e}")
|
|
|
|
|
|
|
|
if domain_file is None:
|
|
|
|
if getattr(args, "domain", None) is None and get_all_domain:
|
|
|
|
# This option for getting all available domains in the case of --context
|
|
|
|
# So default domain will be used.
|
|
|
|
return domains.get_domains()
|
|
|
|
if getattr(args, "domain", None) is None:
|
|
|
|
# No domains are passed down and no domains specified by the user.
|
|
|
|
# So default domain will be used.
|
|
|
|
return [domains.get_default_domain()]
|
|
|
|
else:
|
|
|
|
# No domains are passed down, but user has specified domains to use.
|
|
|
|
# Get the user specified domains.
|
|
|
|
return domains.get_domains(args.domain)
|
|
|
|
else:
|
|
|
|
# Use domains from domain file with flash order
|
|
|
|
return domains.get_domains(args.domain, default_flash_order=True)
|
|
|
|
|
2024-06-06 14:28:46 +01:00
|
|
|
def do_run_common(command, user_args, user_runner_args, domain_file=None):
|
2020-02-10 06:40:29 -08:00
|
|
|
# This is the main routine for all the "west flash", "west debug",
|
|
|
|
# etc. commands.
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2023-01-04 10:36:15 +00:00
|
|
|
# Holds a list of run once commands, this is useful for sysbuild images
|
|
|
|
# whereby there are multiple images per board with flash commands that can
|
|
|
|
# interfere with other images if they run one per time an image is flashed.
|
|
|
|
used_cmds = []
|
|
|
|
|
|
|
|
# Holds a set of processed board names for flash running information.
|
|
|
|
processed_boards = set()
|
|
|
|
|
|
|
|
# Holds a dictionary of board image flash counts, the first element is
|
|
|
|
# number of images flashed so far and second element is total number of
|
|
|
|
# images for a given board.
|
|
|
|
board_image_count = defaultdict(ImagesFlashed)
|
|
|
|
|
2024-07-01 08:19:25 +01:00
|
|
|
highest_priority = IGNORED_RUN_ONCE_PRIORITY
|
|
|
|
highest_entry = None
|
|
|
|
check_files = []
|
|
|
|
|
2020-02-28 11:21:59 -08:00
|
|
|
if user_args.context:
|
|
|
|
dump_context(command, user_args, user_runner_args)
|
2020-02-10 06:40:29 -08:00
|
|
|
return
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2024-12-19 07:31:22 +01:00
|
|
|
# Import external module runners
|
|
|
|
for module in zephyr_module.parse_modules(ZEPHYR_BASE, command.manifest):
|
|
|
|
runners_ext = module.meta.get("runners", [])
|
|
|
|
for runner in runners_ext:
|
|
|
|
import_from_path(
|
|
|
|
module.meta.get("name", "runners_ext"), Path(module.project) / runner["file"]
|
|
|
|
)
|
|
|
|
|
2020-02-28 11:21:59 -08:00
|
|
|
build_dir = get_build_dir(user_args)
|
|
|
|
if not user_args.skip_rebuild:
|
|
|
|
rebuild(command, build_dir, user_args)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2025-05-06 18:43:59 +05:30
|
|
|
domains = get_domains_to_process(build_dir, user_args, domain_file)
|
2021-11-22 10:29:56 +01:00
|
|
|
|
2023-01-04 10:36:15 +00:00
|
|
|
if len(domains) > 1:
|
|
|
|
if len(user_runner_args) > 0:
|
|
|
|
log.wrn("Specifying runner options for multiple domains is experimental.\n"
|
|
|
|
"If problems are experienced, please specify a single domain "
|
|
|
|
"using '--domain <domain>'")
|
|
|
|
|
|
|
|
# Process all domains to load board names and populate flash runner
|
|
|
|
# parameters.
|
|
|
|
board_names = set()
|
|
|
|
for d in domains:
|
|
|
|
if d.build_dir is None:
|
|
|
|
build_dir = get_build_dir(user_args)
|
|
|
|
else:
|
|
|
|
build_dir = d.build_dir
|
|
|
|
|
|
|
|
cache = load_cmake_cache(build_dir, user_args)
|
|
|
|
build_conf = BuildConfiguration(build_dir)
|
|
|
|
board = build_conf.get('CONFIG_BOARD_TARGET')
|
|
|
|
board_names.add(board)
|
|
|
|
board_image_count[board].total += 1
|
|
|
|
|
|
|
|
# Load board flash runner configuration (if it exists) and store
|
|
|
|
# single-use commands in a dictionary so that they get executed
|
|
|
|
# once per unique board name.
|
2024-07-01 08:19:25 +01:00
|
|
|
for directory in cache.get_list('SOC_DIRECTORIES'):
|
|
|
|
if directory not in processed_boards:
|
|
|
|
check_files.append(SocBoardFilesProcessing(Path(directory) / 'soc.yml'))
|
|
|
|
processed_boards.add(directory)
|
|
|
|
|
|
|
|
for directory in cache.get_list('BOARD_DIRECTORIES'):
|
|
|
|
if directory not in processed_boards:
|
|
|
|
check_files.append(SocBoardFilesProcessing(Path(directory) / 'board.yml', True))
|
|
|
|
processed_boards.add(directory)
|
|
|
|
|
|
|
|
for check in check_files:
|
|
|
|
try:
|
|
|
|
with open(check.filename, 'r') as f:
|
|
|
|
check.yaml = yaml.safe_load(f.read())
|
|
|
|
|
|
|
|
if 'runners' not in check.yaml:
|
|
|
|
continue
|
|
|
|
elif check.board is False and 'run_once' not in check.yaml['runners']:
|
2023-01-04 10:36:15 +00:00
|
|
|
continue
|
|
|
|
|
2024-07-01 08:19:25 +01:00
|
|
|
if 'priority' in check.yaml['runners']:
|
|
|
|
check.priority = check.yaml['runners']['priority']
|
|
|
|
else:
|
|
|
|
check.priority = BOARD_FILE_RUN_ONCE_DEFAULT_PRIORITY if check.board is True else SOC_FILE_RUN_ONCE_DEFAULT_PRIORITY
|
|
|
|
|
|
|
|
if check.priority == highest_priority:
|
|
|
|
log.die("Duplicate flash run once configuration found with equal priorities")
|
|
|
|
|
|
|
|
elif check.priority > highest_priority:
|
|
|
|
highest_priority = check.priority
|
|
|
|
highest_entry = check
|
|
|
|
|
|
|
|
except FileNotFoundError:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if highest_entry is not None:
|
|
|
|
group_type = 'boards' if highest_entry.board is True else 'qualifiers'
|
|
|
|
|
|
|
|
for cmd in highest_entry.yaml['runners']['run_once']:
|
|
|
|
for data in highest_entry.yaml['runners']['run_once'][cmd]:
|
|
|
|
for group in data['groups']:
|
|
|
|
run_first = bool(data['run'] == 'first')
|
|
|
|
if group_type == 'qualifiers':
|
|
|
|
targets = []
|
|
|
|
for target in group[group_type]:
|
|
|
|
# For SoC-based qualifiers, prepend to the beginning of the
|
|
|
|
# match to allow for matching any board name
|
|
|
|
targets.append('([^/]+)/' + target)
|
|
|
|
else:
|
|
|
|
targets = group[group_type]
|
|
|
|
|
|
|
|
used_cmds.append(UsedFlashCommand(cmd, targets, data['runners'], run_first))
|
2023-01-04 10:36:15 +00:00
|
|
|
|
|
|
|
# Reduce entries to only those having matching board names (either exact or with regex) and
|
|
|
|
# remove any entries with empty board lists
|
|
|
|
for i, entry in enumerate(used_cmds):
|
|
|
|
for l, match in enumerate(entry.boards):
|
|
|
|
match_found = False
|
|
|
|
|
|
|
|
# Check if there is a matching board for this regex
|
|
|
|
for check in board_names:
|
|
|
|
if re.match(fr'^{match}$', check) is not None:
|
|
|
|
match_found = True
|
|
|
|
break
|
|
|
|
|
|
|
|
if not match_found:
|
|
|
|
del entry.boards[l]
|
|
|
|
|
|
|
|
if len(entry.boards) == 0:
|
|
|
|
del used_cmds[i]
|
2022-08-11 10:33:38 +02:00
|
|
|
|
2024-07-20 19:56:10 +10:00
|
|
|
prev_runner = None
|
2021-11-22 10:29:56 +01:00
|
|
|
for d in domains:
|
2024-07-20 19:56:10 +10:00
|
|
|
prev_runner = do_run_common_image(command, user_args, user_runner_args, used_cmds,
|
|
|
|
board_image_count, d.build_dir, prev_runner)
|
2023-01-04 10:36:15 +00:00
|
|
|
|
2021-11-22 10:29:56 +01:00
|
|
|
|
2023-01-04 10:36:15 +00:00
|
|
|
def do_run_common_image(command, user_args, user_runner_args, used_cmds,
|
2024-07-20 19:56:10 +10:00
|
|
|
board_image_count, build_dir=None, prev_runner=None):
|
2023-01-04 10:36:15 +00:00
|
|
|
global re
|
2021-11-22 10:29:56 +01:00
|
|
|
command_name = command.name
|
|
|
|
if build_dir is None:
|
|
|
|
build_dir = get_build_dir(user_args)
|
|
|
|
cache = load_cmake_cache(build_dir, user_args)
|
2023-01-04 10:36:15 +00:00
|
|
|
build_conf = BuildConfiguration(build_dir)
|
|
|
|
board = build_conf.get('CONFIG_BOARD_TARGET')
|
|
|
|
|
|
|
|
if board_image_count is not None and board in board_image_count:
|
|
|
|
board_image_count[board].flashed += 1
|
2021-11-22 10:29:56 +01:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
# Load runners.yaml.
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
yaml_path = runners_yaml_path(build_dir, board)
|
|
|
|
runners_yaml = load_runners_yaml(yaml_path)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
# Get a concrete ZephyrBinaryRunner subclass to use based on
|
|
|
|
# runners.yaml and command line arguments.
|
2020-08-26 11:10:27 -07:00
|
|
|
runner_cls = use_runner_cls(command, board, user_args, runners_yaml,
|
2020-03-17 16:26:51 -07:00
|
|
|
cache)
|
2020-02-10 06:40:29 -08:00
|
|
|
runner_name = runner_cls.name()
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
# Set up runner logging to delegate to west.log commands.
|
|
|
|
logger = logging.getLogger('runners')
|
|
|
|
logger.setLevel(LOG_LEVEL)
|
2021-11-22 10:29:56 +01:00
|
|
|
if not logger.hasHandlers():
|
|
|
|
# Only add a runners log handler if none has been added already.
|
|
|
|
logger.addHandler(WestLogHandler())
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
# If the user passed -- to force the parent argument parser to stop
|
|
|
|
# parsing, it will show up here, and needs to be filtered out.
|
2020-02-28 11:13:37 -08:00
|
|
|
runner_args = [arg for arg in user_runner_args if arg != '--']
|
2020-02-10 06:40:29 -08:00
|
|
|
|
2023-01-04 10:36:15 +00:00
|
|
|
# Check if there are any commands that should only be ran once per board
|
|
|
|
# and if so, remove them for all but the first iteration of the flash
|
|
|
|
# runner per unique board name.
|
|
|
|
if len(used_cmds) > 0 and len(runner_args) > 0:
|
|
|
|
i = len(runner_args) - 1
|
|
|
|
while i >= 0:
|
|
|
|
for cmd in used_cmds:
|
|
|
|
if cmd.command == runner_args[i] and (runner_name in cmd.runners or 'all' in cmd.runners):
|
|
|
|
# Check if board is here
|
|
|
|
match_found = False
|
|
|
|
|
|
|
|
for match in cmd.boards:
|
|
|
|
# Check if there is a matching board for this regex
|
|
|
|
if re.match(fr'^{match}$', board) is not None:
|
|
|
|
match_found = True
|
|
|
|
break
|
|
|
|
|
|
|
|
if not match_found:
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Check if this is a first or last run
|
|
|
|
if not cmd.first:
|
|
|
|
# For last run instances, we need to check that this really is the last
|
|
|
|
# image of all boards being flashed
|
|
|
|
for check in cmd.boards:
|
|
|
|
can_continue = False
|
|
|
|
|
|
|
|
for match in board_image_count:
|
|
|
|
if re.match(fr'^{check}$', match) is not None:
|
|
|
|
if board_image_count[match].flashed == board_image_count[match].total:
|
|
|
|
can_continue = True
|
|
|
|
break
|
|
|
|
|
|
|
|
if not can_continue:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if not cmd.ran:
|
|
|
|
cmd.ran = True
|
|
|
|
else:
|
|
|
|
runner_args.pop(i)
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
i = i - 1
|
|
|
|
|
2025-03-14 20:07:15 +01:00
|
|
|
# Arguments in this order to allow specific to override general:
|
|
|
|
#
|
|
|
|
# - runner-specific runners.yaml arguments
|
|
|
|
# - user-provided command line arguments
|
|
|
|
final_argv = runners_yaml['args'][runner_name] + runner_args
|
|
|
|
|
2023-01-04 10:36:15 +00:00
|
|
|
# If flashing multiple images, the runner supports reset after flashing and
|
|
|
|
# the board has enabled this functionality, check if the board should be
|
|
|
|
# reset or not. If this is not specified in the board/soc file, leave it up to
|
|
|
|
# the runner's default configuration to decide if a reset should occur.
|
2025-03-14 20:07:15 +01:00
|
|
|
if runner_cls.capabilities().reset and '--no-reset' not in final_argv:
|
2023-01-04 10:36:15 +00:00
|
|
|
if board_image_count is not None:
|
|
|
|
reset = True
|
|
|
|
|
|
|
|
for cmd in used_cmds:
|
|
|
|
if cmd.command == '--reset' and (runner_name in cmd.runners or 'all' in cmd.runners):
|
|
|
|
# Check if board is here
|
|
|
|
match_found = False
|
|
|
|
|
|
|
|
for match in cmd.boards:
|
|
|
|
if re.match(fr'^{match}$', board) is not None:
|
|
|
|
match_found = True
|
|
|
|
break
|
|
|
|
|
|
|
|
if not match_found:
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Check if this is a first or last run
|
|
|
|
if cmd.first and cmd.ran:
|
|
|
|
reset = False
|
|
|
|
break
|
|
|
|
elif not cmd.first and not cmd.ran:
|
|
|
|
# For last run instances, we need to check that this really is the last
|
|
|
|
# image of all boards being flashed
|
|
|
|
for check in cmd.boards:
|
|
|
|
can_continue = False
|
|
|
|
|
|
|
|
for match in board_image_count:
|
|
|
|
if re.match(fr'^{check}$', match) is not None:
|
|
|
|
if board_image_count[match].flashed != board_image_count[match].total:
|
|
|
|
reset = False
|
|
|
|
break
|
|
|
|
|
|
|
|
if reset:
|
2025-03-14 20:07:15 +01:00
|
|
|
final_argv.append('--reset')
|
2023-01-04 10:36:15 +00:00
|
|
|
else:
|
2025-03-14 20:07:15 +01:00
|
|
|
final_argv.append('--no-reset')
|
2020-02-10 06:40:29 -08:00
|
|
|
|
2020-02-28 11:21:59 -08:00
|
|
|
# 'user_args' contains parsed arguments which are:
|
2020-02-10 06:40:29 -08:00
|
|
|
#
|
2020-02-28 11:21:59 -08:00
|
|
|
# 1. provided on the command line, and
|
|
|
|
# 2. handled by add_parser_common(), and
|
|
|
|
# 3. *not* runner-specific
|
2020-02-10 06:40:29 -08:00
|
|
|
#
|
2020-02-28 11:21:59 -08:00
|
|
|
# 'final_argv' contains unparsed arguments from either:
|
2020-02-10 06:40:29 -08:00
|
|
|
#
|
2020-02-28 11:21:59 -08:00
|
|
|
# 1. runners.yaml, or
|
|
|
|
# 2. the command line
|
|
|
|
#
|
|
|
|
# We next have to:
|
|
|
|
#
|
|
|
|
# - parse 'final_argv' now that we have all the command line
|
|
|
|
# arguments
|
|
|
|
# - create a RunnerConfig using 'user_args' and the result
|
|
|
|
# of parsing 'final_argv'
|
2023-01-04 16:08:36 +00:00
|
|
|
parser = argparse.ArgumentParser(prog=runner_name, allow_abbrev=False)
|
2020-02-10 06:40:29 -08:00
|
|
|
add_parser_common(command, parser=parser)
|
|
|
|
runner_cls.add_parser(parser)
|
2020-02-28 11:31:28 -08:00
|
|
|
args, unknown = parser.parse_known_args(args=final_argv)
|
2020-02-10 06:40:29 -08:00
|
|
|
if unknown:
|
|
|
|
log.die(f'runner {runner_name} received unknown arguments: {unknown}')
|
|
|
|
|
2024-07-20 19:56:10 +10:00
|
|
|
# Propagate useful args from previous domain invocations
|
|
|
|
if prev_runner is not None:
|
|
|
|
runner_cls.args_from_previous_runner(prev_runner, args)
|
|
|
|
|
2020-02-28 11:31:28 -08:00
|
|
|
# Override args with any user_args. The latter must take
|
|
|
|
# precedence, or e.g. --hex-file on the command line would be
|
|
|
|
# ignored in favor of a board.cmake setting.
|
|
|
|
for a, v in vars(user_args).items():
|
|
|
|
if v is not None:
|
|
|
|
setattr(args, a, v)
|
|
|
|
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
# Create the RunnerConfig from runners.yaml and any command line
|
|
|
|
# overrides.
|
|
|
|
runner_config = get_runner_config(build_dir, yaml_path, runners_yaml, args)
|
|
|
|
log.dbg(f'runner_config: {runner_config}', level=log.VERBOSE_VERY)
|
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
# Use that RunnerConfig to create the ZephyrBinaryRunner instance
|
|
|
|
# and call its run().
|
|
|
|
try:
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
runner = runner_cls.create(runner_config, args)
|
2020-02-10 06:40:29 -08:00
|
|
|
runner.run(command_name)
|
|
|
|
except ValueError as ve:
|
|
|
|
log.err(str(ve), fatal=True)
|
|
|
|
dump_traceback()
|
|
|
|
raise CommandError(1)
|
|
|
|
except MissingProgram as e:
|
|
|
|
log.die('required program', e.filename,
|
|
|
|
'not found; install it or add its location to PATH')
|
|
|
|
except RuntimeError as re:
|
2020-02-28 11:21:59 -08:00
|
|
|
if not user_args.verbose:
|
2020-02-10 06:40:29 -08:00
|
|
|
log.die(re)
|
|
|
|
else:
|
|
|
|
log.err('verbose mode enabled, dumping stack:', fatal=True)
|
|
|
|
raise
|
2024-07-20 19:56:10 +10:00
|
|
|
return runner
|
2020-02-10 06:40:29 -08:00
|
|
|
|
|
|
|
def get_build_dir(args, die_if_none=True):
|
2019-01-23 08:31:06 -07:00
|
|
|
# Get the build directory for the given argument list and environment.
|
|
|
|
if args.build_dir:
|
|
|
|
return args.build_dir
|
|
|
|
|
2019-06-17 11:47:11 +02:00
|
|
|
guess = config.get('build', 'guess-dir', fallback='never')
|
2019-09-05 20:10:53 +02:00
|
|
|
guess = guess == 'runners'
|
2019-06-17 11:47:11 +02:00
|
|
|
dir = find_build_dir(None, guess)
|
2019-06-03 12:43:38 +02:00
|
|
|
|
2019-06-05 16:04:29 +02:00
|
|
|
if dir and is_zephyr_build(dir):
|
2019-06-03 12:43:38 +02:00
|
|
|
return dir
|
2019-01-23 08:31:06 -07:00
|
|
|
elif die_if_none:
|
2019-06-05 16:04:29 +02:00
|
|
|
msg = '--build-dir was not given, '
|
|
|
|
if dir:
|
|
|
|
msg = msg + 'and neither {} nor {} are zephyr build directories.'
|
|
|
|
else:
|
|
|
|
msg = msg + ('{} is not a build directory and the default build '
|
|
|
|
'directory cannot be determined. Check your '
|
|
|
|
'build.dir-fmt configuration option')
|
|
|
|
log.die(msg.format(getcwd(), dir))
|
2019-01-23 08:31:06 -07:00
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def load_cmake_cache(build_dir, args):
|
|
|
|
cache_file = path.join(build_dir, args.cmake_cache or zcmake.DEFAULT_CACHE)
|
|
|
|
try:
|
|
|
|
return zcmake.CMakeCache(cache_file)
|
|
|
|
except FileNotFoundError:
|
|
|
|
log.die(f'no CMake cache found (expected one at {cache_file})')
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def rebuild(command, build_dir, args):
|
|
|
|
_banner(f'west {command.name}: rebuilding')
|
|
|
|
try:
|
runners: remove dependencies from runners
Today, there is a build target is added for each runner: flash, debug,
debugserver, attach.
And those runners will have a dependency to Zephyr logical target that
is built before invoking `west <runner>`.
This design has some flaws, mainly that additional dependencies directly
on the target will not be built when running `west <runner>` directly.
That generator expressions cannot be used for the DEPENDS argument.
Instead, the build target `<runner>` will not have any dependencies, and
will raise a build error if a dependency is added to the target.
Due to how `add_dependencies()` work, this must be done as a build time
check, and not configure time check.
`west <runner>` will invoke a build before executing the runner, and
this way ensure the build target is up-to-date, which again removes the
need for a dedicated `west_<runner>_target`.
It also minimizes the risk of developer errors, as developers no longer
need to consider the need for adding additional dependencies.
If a custom target is part of the default `all` build, then it's ensured
to be up-to-date.
Fixes: Issue reported on slack.
Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2021-03-17 14:09:37 +01:00
|
|
|
zcmake.run_build(build_dir)
|
2020-02-10 06:40:29 -08:00
|
|
|
except CalledProcessError:
|
|
|
|
if args.build_dir:
|
|
|
|
log.die(f're-build in {args.build_dir} failed')
|
|
|
|
else:
|
|
|
|
log.die(f're-build in {build_dir} failed (no --build-dir given)')
|
2019-01-23 08:31:06 -07:00
|
|
|
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
def runners_yaml_path(build_dir, board):
|
|
|
|
ret = Path(build_dir) / 'zephyr' / 'runners.yaml'
|
|
|
|
if not ret.is_file():
|
2024-05-02 15:26:05 +02:00
|
|
|
log.die(f'no runners.yaml found in {build_dir}/zephyr. '
|
|
|
|
f"Either board {board} doesn't support west flash/debug/simulate,"
|
|
|
|
' or a pristine build is needed.')
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
return ret
|
2019-01-23 08:31:06 -07:00
|
|
|
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
def load_runners_yaml(path):
|
|
|
|
# Load runners.yaml and convert to Python object.
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2019-06-10 14:11:27 -06:00
|
|
|
try:
|
2020-02-10 06:40:29 -08:00
|
|
|
with open(path, 'r') as f:
|
2020-08-26 11:10:27 -07:00
|
|
|
content = yaml.safe_load(f.read())
|
2019-06-10 14:11:27 -06:00
|
|
|
except FileNotFoundError:
|
2020-02-10 06:40:29 -08:00
|
|
|
log.die(f'runners.yaml file not found: {path}')
|
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
if not content.get('runners'):
|
2020-02-10 06:40:29 -08:00
|
|
|
log.wrn(f'no pre-configured runners in {path}; '
|
|
|
|
"this probably won't work")
|
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
return content
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
def use_runner_cls(command, board, args, runners_yaml, cache):
|
2020-02-10 06:40:29 -08:00
|
|
|
# Get the ZephyrBinaryRunner class from its name, and make sure it
|
|
|
|
# supports the command. Print a message about the choice, and
|
|
|
|
# return the class.
|
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
runner = args.runner or runners_yaml.get(command.runner_key)
|
2019-01-23 08:31:06 -07:00
|
|
|
if runner is None:
|
2020-02-10 06:40:29 -08:00
|
|
|
log.die(f'no {command.name} runner available for board {board}. '
|
|
|
|
"Check the board's documentation for instructions.")
|
|
|
|
|
|
|
|
_banner(f'west {command.name}: using runner {runner}')
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
available = runners_yaml.get('runners', [])
|
2019-01-23 08:31:06 -07:00
|
|
|
if runner not in available:
|
2020-03-17 16:26:51 -07:00
|
|
|
if 'BOARD_DIR' in cache:
|
|
|
|
board_cmake = Path(cache['BOARD_DIR']) / 'board.cmake'
|
|
|
|
else:
|
|
|
|
board_cmake = 'board.cmake'
|
|
|
|
log.err(f'board {board} does not support runner {runner}',
|
|
|
|
fatal=True)
|
|
|
|
log.inf(f'To fix, configure this runner in {board_cmake} and rebuild.')
|
|
|
|
sys.exit(1)
|
2021-02-23 14:00:18 -08:00
|
|
|
try:
|
|
|
|
runner_cls = get_runner_cls(runner)
|
|
|
|
except ValueError as e:
|
|
|
|
log.die(e)
|
2020-02-10 06:40:29 -08:00
|
|
|
if command.name not in runner_cls.capabilities().commands:
|
|
|
|
log.die(f'runner {runner} does not support command {command.name}')
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
return runner_cls
|
2019-01-23 08:31:06 -07:00
|
|
|
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
def get_runner_config(build_dir, yaml_path, runners_yaml, args=None):
|
|
|
|
# Get a RunnerConfig object for the current run. yaml_config is
|
|
|
|
# runners.yaml's config: map, and args are the command line arguments.
|
|
|
|
yaml_config = runners_yaml['config']
|
|
|
|
yaml_dir = yaml_path.parent
|
|
|
|
if args is None:
|
|
|
|
args = argparse.Namespace()
|
|
|
|
|
|
|
|
def output_file(filetype):
|
|
|
|
|
|
|
|
from_args = getattr(args, f'{filetype}_file', None)
|
|
|
|
if from_args is not None:
|
|
|
|
return from_args
|
|
|
|
|
|
|
|
from_yaml = yaml_config.get(f'{filetype}_file')
|
|
|
|
if from_yaml is not None:
|
|
|
|
# Output paths in runners.yaml are relative to the
|
|
|
|
# directory containing the runners.yaml file.
|
|
|
|
return fspath(yaml_dir / from_yaml)
|
|
|
|
|
2021-02-02 08:55:16 -08:00
|
|
|
return None
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
|
2021-08-25 22:07:54 -03:00
|
|
|
def config(attr, default=None):
|
|
|
|
return getattr(args, attr, None) or yaml_config.get(attr, default)
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
|
2022-11-16 15:05:29 +01:00
|
|
|
def filetype(attr):
|
|
|
|
ftype = str(getattr(args, attr, None)).lower()
|
|
|
|
if ftype == "hex":
|
|
|
|
return FileType.HEX
|
|
|
|
elif ftype == "bin":
|
|
|
|
return FileType.BIN
|
|
|
|
elif ftype == "elf":
|
|
|
|
return FileType.ELF
|
|
|
|
elif getattr(args, attr, None) is not None:
|
|
|
|
err = 'unknown --file-type ({}). Please use hex, bin or elf'
|
|
|
|
raise ValueError(err.format(ftype))
|
|
|
|
|
|
|
|
# file-type not provided, try to get from filename
|
|
|
|
file = getattr(args, "file", None)
|
|
|
|
if file is not None:
|
|
|
|
ext = Path(file).suffix
|
|
|
|
if ext == ".hex":
|
|
|
|
return FileType.HEX
|
|
|
|
if ext == ".bin":
|
|
|
|
return FileType.BIN
|
|
|
|
if ext == ".elf":
|
|
|
|
return FileType.ELF
|
|
|
|
|
|
|
|
# we couldn't get the file-type, set to
|
|
|
|
# OTHER and let the runner deal with it
|
|
|
|
return FileType.OTHER
|
|
|
|
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
return RunnerConfig(build_dir,
|
|
|
|
yaml_config['board_dir'],
|
|
|
|
output_file('elf'),
|
2023-10-03 13:15:59 +02:00
|
|
|
output_file('exe'),
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
output_file('hex'),
|
|
|
|
output_file('bin'),
|
2023-01-30 00:50:57 -05:00
|
|
|
output_file('uf2'),
|
2024-09-13 15:32:09 +07:00
|
|
|
output_file('mot'),
|
2022-11-16 15:05:29 +01:00
|
|
|
config('file'),
|
|
|
|
filetype('file_type'),
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
config('gdb'),
|
|
|
|
config('openocd'),
|
2024-07-05 12:42:12 +02:00
|
|
|
config('openocd_search', []),
|
|
|
|
config('rtt_address'))
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def dump_traceback():
|
|
|
|
# Save the current exception to a file and return its path.
|
|
|
|
fd, name = tempfile.mkstemp(prefix='west-exc-', suffix='.txt')
|
|
|
|
close(fd) # traceback has no use for the fd
|
|
|
|
with open(name, 'w') as f:
|
|
|
|
traceback.print_exc(file=f)
|
|
|
|
log.inf("An exception trace has been saved in", name)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
|
|
|
#
|
2020-02-10 06:40:29 -08:00
|
|
|
# west {command} --context
|
2019-01-23 08:31:06 -07:00
|
|
|
#
|
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def dump_context(command, args, unknown_args):
|
|
|
|
build_dir = get_build_dir(args, die_if_none=False)
|
2025-05-06 18:43:59 +05:30
|
|
|
get_all_domain = False
|
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
if build_dir is None:
|
|
|
|
log.wrn('no --build-dir given or found; output will be limited')
|
2025-05-06 18:43:59 +05:30
|
|
|
dump_context_no_config(command, None)
|
|
|
|
return
|
|
|
|
|
|
|
|
if is_sysbuild(build_dir):
|
|
|
|
get_all_domain = True
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
# Re-build unless asked not to, to make sure the output is up to date.
|
2019-01-23 08:31:06 -07:00
|
|
|
if build_dir and not args.skip_rebuild:
|
2020-02-10 06:40:29 -08:00
|
|
|
rebuild(command, build_dir, args)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2025-05-06 18:43:59 +05:30
|
|
|
domains = get_domains_to_process(build_dir, args, None, get_all_domain)
|
|
|
|
|
|
|
|
if len(domains) > 1 and not getattr(args, "domain", None):
|
|
|
|
log.inf("Multiple domains available:")
|
|
|
|
for i, domain in enumerate(domains, 1):
|
|
|
|
log.inf(f"{INDENT}{i}. {domain.name} (build_dir: {domain.build_dir})")
|
|
|
|
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
choice = input(f"Select domain (1-{len(domains)}): ")
|
|
|
|
choice = int(choice)
|
|
|
|
if 1 <= choice <= len(domains):
|
|
|
|
domains = [domains[choice-1]]
|
|
|
|
break
|
|
|
|
log.wrn(f"Please enter a number between 1 and {len(domains)}")
|
|
|
|
except ValueError:
|
|
|
|
log.wrn("Please enter a valid number")
|
|
|
|
except EOFError:
|
|
|
|
log.die("Input cancelled, exiting")
|
|
|
|
|
|
|
|
selected_build_dir = domains[0].build_dir
|
|
|
|
|
|
|
|
if not path.exists(selected_build_dir):
|
|
|
|
log.die(f"Build directory does not exist: {selected_build_dir}")
|
|
|
|
|
|
|
|
build_conf = BuildConfiguration(selected_build_dir)
|
|
|
|
|
|
|
|
board = build_conf.get('CONFIG_BOARD_TARGET')
|
|
|
|
if not board:
|
|
|
|
log.die("CONFIG_BOARD_TARGET not found in build configuration.")
|
|
|
|
|
|
|
|
yaml_path = runners_yaml_path(selected_build_dir, board)
|
|
|
|
if not path.exists(yaml_path):
|
|
|
|
log.die(f"runners.yaml not found in: {yaml_path}")
|
|
|
|
|
|
|
|
runners_yaml = load_runners_yaml(yaml_path)
|
|
|
|
|
|
|
|
# Dump runner info
|
|
|
|
log.inf(f'build configuration:', colorize=True)
|
|
|
|
log.inf(f'{INDENT}build directory: {build_dir}')
|
|
|
|
log.inf(f'{INDENT}board: {board}')
|
|
|
|
log.inf(f'{INDENT}runners.yaml: {yaml_path}')
|
2019-01-23 08:31:06 -07:00
|
|
|
if args.runner:
|
2020-02-10 06:40:29 -08:00
|
|
|
try:
|
|
|
|
cls = get_runner_cls(args.runner)
|
2025-05-06 18:43:59 +05:30
|
|
|
dump_runner_context(command, cls, runners_yaml)
|
2020-02-10 06:40:29 -08:00
|
|
|
except ValueError:
|
2025-05-06 18:43:59 +05:30
|
|
|
available_runners = ", ".join(cls.name() for cls in ZephyrBinaryRunner.get_runners())
|
|
|
|
log.die(f"Invalid runner name {args.runner}; choices: {available_runners}")
|
2020-02-10 06:40:29 -08:00
|
|
|
else:
|
2025-05-06 18:43:59 +05:30
|
|
|
dump_all_runner_context(command, runners_yaml, board, selected_build_dir)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def dump_context_no_config(command, cls):
|
|
|
|
if not cls:
|
|
|
|
all_cls = {cls.name(): cls for cls in ZephyrBinaryRunner.get_runners()
|
|
|
|
if command.name in cls.capabilities().commands}
|
|
|
|
log.inf('all Zephyr runners which support {}:'.format(command.name),
|
2019-01-23 08:31:06 -07:00
|
|
|
colorize=True)
|
2020-02-10 06:40:29 -08:00
|
|
|
dump_wrapped_lines(', '.join(all_cls.keys()), INDENT)
|
|
|
|
log.inf()
|
|
|
|
log.inf('Note: use -r RUNNER to limit information to one runner.')
|
|
|
|
else:
|
2020-08-26 11:10:27 -07:00
|
|
|
# This does the right thing with a None argument.
|
2020-02-10 06:40:29 -08:00
|
|
|
dump_runner_context(command, cls, None)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
def dump_runner_context(command, cls, runners_yaml, indent=''):
|
2020-02-10 06:40:29 -08:00
|
|
|
dump_runner_caps(cls, indent)
|
|
|
|
dump_runner_option_help(cls, indent)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
if runners_yaml is None:
|
2019-01-23 08:31:06 -07:00
|
|
|
return
|
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
if cls.name() in runners_yaml['runners']:
|
|
|
|
dump_runner_args(cls.name(), runners_yaml, indent)
|
2020-02-10 06:40:29 -08:00
|
|
|
else:
|
|
|
|
log.wrn(f'support for runner {cls.name()} is not configured '
|
|
|
|
f'in this build directory')
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def dump_runner_caps(cls, indent=''):
|
|
|
|
# Print RunnerCaps for the given runner class.
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
log.inf(f'{indent}{cls.name()} capabilities:', colorize=True)
|
|
|
|
log.inf(f'{indent}{INDENT}{cls.capabilities()}')
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
def dump_runner_option_help(cls, indent=''):
|
|
|
|
# Print help text for class-specific command line options for the
|
|
|
|
# given runner class.
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2023-01-04 16:08:36 +00:00
|
|
|
dummy_parser = argparse.ArgumentParser(prog='', add_help=False, allow_abbrev=False)
|
2019-01-23 08:31:06 -07:00
|
|
|
cls.add_parser(dummy_parser)
|
|
|
|
formatter = dummy_parser._get_formatter()
|
|
|
|
for group in dummy_parser._action_groups:
|
|
|
|
# Break the abstraction to filter out the 'flash', 'debug', etc.
|
|
|
|
# TODO: come up with something cleaner (may require changes
|
|
|
|
# in the runner core).
|
|
|
|
actions = group._group_actions
|
|
|
|
if len(actions) == 1 and actions[0].dest == 'command':
|
|
|
|
# This is the lone positional argument. Skip it.
|
|
|
|
continue
|
|
|
|
formatter.start_section('REMOVE ME')
|
|
|
|
formatter.add_text(group.description)
|
|
|
|
formatter.add_arguments(actions)
|
|
|
|
formatter.end_section()
|
|
|
|
# Get the runner help, with the "REMOVE ME" string gone
|
2020-02-10 06:40:29 -08:00
|
|
|
runner_help = f'\n{indent}'.join(formatter.format_help().splitlines()[1:])
|
|
|
|
|
|
|
|
log.inf(f'{indent}{cls.name()} options:', colorize=True)
|
|
|
|
log.inf(indent + runner_help)
|
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
def dump_runner_args(group, runners_yaml, indent=''):
|
2020-02-10 06:40:29 -08:00
|
|
|
msg = f'{indent}{group} arguments from runners.yaml:'
|
2020-08-26 11:10:27 -07:00
|
|
|
args = runners_yaml['args'][group]
|
2020-02-10 06:40:29 -08:00
|
|
|
if args:
|
|
|
|
log.inf(msg, colorize=True)
|
|
|
|
for arg in args:
|
|
|
|
log.inf(f'{indent}{INDENT}{arg}')
|
|
|
|
else:
|
|
|
|
log.inf(f'{msg} (none)', colorize=True)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-08-26 11:10:27 -07:00
|
|
|
def dump_all_runner_context(command, runners_yaml, board, build_dir):
|
2020-02-10 06:40:29 -08:00
|
|
|
all_cls = {cls.name(): cls for cls in ZephyrBinaryRunner.get_runners() if
|
|
|
|
command.name in cls.capabilities().commands}
|
2020-08-26 11:10:27 -07:00
|
|
|
available = runners_yaml['runners']
|
2020-02-10 06:40:29 -08:00
|
|
|
available_cls = {r: all_cls[r] for r in available if r in all_cls}
|
2020-08-26 11:10:27 -07:00
|
|
|
default_runner = runners_yaml[command.runner_key]
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
yaml_path = runners_yaml_path(build_dir, board)
|
|
|
|
runners_yaml = load_runners_yaml(yaml_path)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
log.inf(f'zephyr runners which support "west {command.name}":',
|
2019-01-23 08:31:06 -07:00
|
|
|
colorize=True)
|
2020-02-10 06:40:29 -08:00
|
|
|
dump_wrapped_lines(', '.join(all_cls.keys()), INDENT)
|
|
|
|
log.inf()
|
|
|
|
dump_wrapped_lines('Note: not all may work with this board and build '
|
|
|
|
'directory. Available runners are listed below.',
|
|
|
|
INDENT)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
log.inf(f'available runners in runners.yaml:',
|
2019-01-23 08:31:06 -07:00
|
|
|
colorize=True)
|
2020-02-10 06:40:29 -08:00
|
|
|
dump_wrapped_lines(', '.join(available), INDENT)
|
|
|
|
log.inf(f'default runner in runners.yaml:', colorize=True)
|
|
|
|
log.inf(INDENT + default_runner)
|
cmake: flash/debug: refactor runner configuration
This commit message is a bit of a novel mostly:
- because the issues involved are longstanding
- as evidence this is not a capricious refactoring
The runners.core.RunnerConfig Python class holds common configuration
values used by multiple runners, such as the location of the build
outputs and board directory.
The runners code, first written in 2017-ish, replaced various shell
scripts that got this information from the environment. Avoiding
environment variables was a requirement, however. It's ghastly to set
environment variables for a single command invocation on Windows, and
the whole thing was part of a larger push to make Zephyr development
on Windows better.
I had a hammer (the argparse module). Finding a replacement naturally
looked like a nail, so the information that ends up in RunnerConfig
got shunted from the build system to Python in the form of 'west
flash' / 'west debug' command line options like '--board-dir',
'--elf-file', etc.
I initially stored the options and their values in the CMake cache.
This was chosen in hopes the build system maintainer would like
the strategy (which worked).
I knew the command line arguments approach was a bit hacky (this
wasn't a nail), but I also honestly didn't have a better idea at the
time.
It did indeed cause issues:
- users don't know that just because they specify --bin-file on the
command line doesn't mean that their runner respects the option, and
have gotten confused trying to flash alternate files, usually for
chain-loading by MCUboot (for example, see #15961)
- common options weren't possible to pass via board.cmake files
(#22563, fixed partly via introduction of runners.yaml and the west
flash/debug commands no longer relying on the cache)
- it is confusing that "west flash --help" prints information about
openocd related options even when the user's board has no openocd
support. The same could be said about gdb in potential future use
cases where debugging occurs via some other tool.
Over time, they've caused enough users enough problems that
improvements are a priority.
To work towards this, put these values into runners.yaml using a new
'config: ...' key/value instead of command line options.
For example, instead of this in the generated runners.yaml file:
args:
common:
- --hex-file=.../zephyr.hex
we now have:
config:
hex_file: zephyr.hex
and similarly for other values.
In Python, we still support the command line options, but they are not
generated by the build system for any in-tree boards. Further work is
needed to deprecate the confusing ones (like --hex-file) and move the
runner-specific host tool related options (like --openocd) to the
runners that need them.
Individual board.cmake files should now influence these values by
overriding the relevant target properties of the
runners_yaml_props_target.
For example, instead of:
board_runner_args(foo "--hex-file=bar.hex")
Do this:
set_target_properties(runners_yaml_props_target PROPERTIES
hex_file bar.hex)
This change additionally allows us to stitch cmake/mcuboot.cmake and
the runners together easily by having mcuboot.cmake override the
properties that set the hex or bin file to flash. (The command line
arguments are still supported as-is.)
Combined with 98e0c95d91ae16f14e4997fb64ccdf0956595712 ("build:
auto-generate signed mcuboot binaries"), this will allow users to
build and flash images to be chain loaded by mcuboot in a way that
avoids calling 'west sign' and passing 'west flash' its output files
entirely.
While we are here, rename runner_yml_write to runners_yaml_append().
This function doesn't actually write anything, and we're here
refactoring this file anyway, so we might as well improve the
situation while we're at it.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2020-08-24 15:21:15 -07:00
|
|
|
log.inf('common runner configuration:', colorize=True)
|
|
|
|
runner_config = get_runner_config(build_dir, yaml_path, runners_yaml)
|
|
|
|
for field, value in zip(runner_config._fields, runner_config):
|
|
|
|
log.inf(f'{INDENT}- {field}: {value}')
|
2020-02-10 06:40:29 -08:00
|
|
|
log.inf('runner-specific context:', colorize=True)
|
|
|
|
for cls in available_cls.values():
|
2020-08-26 11:10:27 -07:00
|
|
|
dump_runner_context(command, cls, runners_yaml, INDENT)
|
2019-01-23 08:31:06 -07:00
|
|
|
|
2020-02-10 06:40:29 -08:00
|
|
|
if len(available) > 1:
|
|
|
|
log.inf()
|
|
|
|
log.inf('Note: use -r RUNNER to limit information to one runner.')
|
|
|
|
|
|
|
|
def dump_wrapped_lines(text, indent):
|
|
|
|
for line in textwrap.wrap(text, initial_indent=indent,
|
|
|
|
subsequent_indent=indent,
|
|
|
|
break_on_hyphens=False,
|
|
|
|
break_long_words=False):
|
|
|
|
log.inf(line)
|