Browse Source

boards: extend list_boards.py and update boards CMake module

Extend list_boards.py and update boards CMake module to handle HWMv2.

list_boards.py is extended to support board.yml file in each board
folder with various information related to the board, such as vendor,
soc, cpucluster, variants, revisions.

The HWMv2 removes the requirement for a _defconfig file.
It also unifies how board revisions, cpusets, etc is defined which again
provides an option for cleaner build system implementation for handling
of boards and their integration to the build system.

The CMake boards.cmake module is updated to take advantage of the
improved design.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
pull/69687/head
Torsten Rasmussen 2 years ago committed by Jamie McCrae
parent
commit
1f026f70eb
  1. 179
      cmake/modules/boards.cmake
  2. 2
      scripts/ci/test_plan.py
  3. 240
      scripts/list_boards.py
  4. 82
      scripts/schemas/board-schema.yml
  5. 10
      scripts/west_commands/boards.py
  6. 1
      scripts/west_commands/completion/west-completion.bash
  7. 1
      scripts/west_commands/completion/west-completion.fish
  8. 1
      scripts/west_commands/completion/west-completion.zsh
  9. 4
      share/sysbuild/cmake/modules/sysbuild_extensions.cmake

179
cmake/modules/boards.cmake

@ -62,6 +62,21 @@ if(NOT unittest IN_LIST Zephyr_FIND_COMPONENTS) @@ -62,6 +62,21 @@ if(NOT unittest IN_LIST Zephyr_FIND_COMPONENTS)
endif()
string(FIND "${BOARD}" "@" REVISION_SEPARATOR_INDEX)
string(FIND "${BOARD}" "/" IDENTIFIER_SEPARATOR_INDEX)
if(NOT (REVISION_SEPARATOR_INDEX EQUAL -1 OR IDENTIFIER_SEPARATOR_INDEX EQUAL -1))
if(REVISION_SEPARATOR_INDEX GREATER IDENTIFIER_SEPARATOR_INDEX)
message(FATAL_ERROR "Invalid revision / identifier format, format is: "
"<board>@<revision>/<identifier>"
)
endif()
endif()
if(NOT (IDENTIFIER_SEPARATOR_INDEX EQUAL -1))
string(SUBSTRING ${BOARD} ${IDENTIFIER_SEPARATOR_INDEX} -1 BOARD_IDENTIFIER)
string(SUBSTRING ${BOARD} 0 ${IDENTIFIER_SEPARATOR_INDEX} BOARD)
endif()
if(NOT (REVISION_SEPARATOR_INDEX EQUAL -1))
math(EXPR BOARD_REVISION_INDEX "${REVISION_SEPARATOR_INDEX} + 1")
string(SUBSTRING ${BOARD} ${BOARD_REVISION_INDEX} -1 BOARD_REVISION)
@ -95,41 +110,125 @@ Hints: @@ -95,41 +110,125 @@ Hints:
- if your board directory is '/foo/bar/boards/<ARCH>/my_board' then add '/foo/bar' to BOARD_ROOT, not the entire board directory
- if in doubt, use absolute paths")
endif()
endforeach()
if((HWMv1 AND NOT EXISTS ${BOARD_DIR}/${BOARD}_defconfig)
OR (HWMv2 AND NOT EXISTS ${BOARD_DIR}))
message(WARNING "BOARD_DIR: ${BOARD_DIR} has been moved or deleted. "
"Trying to find new location."
)
set(BOARD_DIR BOARD_DIR-NOTFOUND CACHE PATH "Path to a file." FORCE)
endif()
# Prepare list boards command.
# This command is used for locating the board dir as well as printing all boards
# in the system in the following cases:
# - User specifies an invalid BOARD
# - User invokes '<build-command> boards' target
list(TRANSFORM ARCH_ROOT PREPEND "--arch-root=" OUTPUT_VARIABLE arch_root_args)
list(TRANSFORM BOARD_ROOT PREPEND "--board-root=" OUTPUT_VARIABLE board_root_args)
list(TRANSFORM SOC_ROOT PREPEND "--soc-root=" OUTPUT_VARIABLE soc_root_args)
set(list_boards_commands
COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/list_boards.py
${arch_root_args} ${board_root_args} --arch-root=${ZEPHYR_BASE}
${soc_root_args} --soc-root=${ZEPHYR_BASE}
)
if(NOT BOARD_DIR)
if(BOARD_ALIAS)
execute_process(${list_boards_commands} --board=${BOARD_ALIAS} --format={name}\;{dir}\;{hwm}
OUTPUT_VARIABLE ret_board
ERROR_VARIABLE err_board
RESULT_VARIABLE ret_val
)
list(GET ret_board 1 BOARD_HIDDEN_DIR)
string(STRIP "${BOARD_HIDDEN_DIR}" BOARD_HIDDEN_DIR)
set(BOARD_HIDDEN_DIR ${BOARD_HIDDEN_DIR} CACHE PATH "Path to a folder." FORCE)
# NB: find_path will return immediately if the output variable is
# already set
if (BOARD_ALIAS)
find_path(BOARD_HIDDEN_DIR
NAMES ${BOARD_ALIAS}_defconfig
PATHS ${root}/boards/*/*
NO_DEFAULT_PATH
)
if(BOARD_HIDDEN_DIR)
message("Board alias ${BOARD_ALIAS} is hiding the real board of same name")
endif()
endif()
if(BOARD_DIR AND NOT EXISTS ${BOARD_DIR}/${BOARD}_defconfig)
message(WARNING "BOARD_DIR: ${BOARD_DIR} has been moved or deleted. "
"Trying to find new location."
)
set(BOARD_DIR BOARD_DIR-NOTFOUND CACHE PATH "Path to a file." FORCE)
set(format_str "{NAME}\;{DIR}\;{HWM}\;")
set(format_str "${format_str}{REVISION_FORMAT}\;{REVISION_DEFAULT}\;{REVISION_EXACT}\;")
set(format_str "${format_str}{REVISIONS}\;{IDENTIFIERS}")
execute_process(${list_boards_commands} --board=${BOARD}
--cmakeformat=${format_str}
OUTPUT_VARIABLE ret_board
ERROR_VARIABLE err_board
RESULT_VARIABLE ret_val
)
if(ret_val)
message(FATAL_ERROR "Error finding board: ${BOARD}\nError message: ${err_board}")
endif()
find_path(BOARD_DIR
NAMES ${BOARD}_defconfig
PATHS ${root}/boards/*/*
NO_DEFAULT_PATH
)
if(BOARD_DIR AND NOT (${root} STREQUAL ${ZEPHYR_BASE}))
set(USING_OUT_OF_TREE_BOARD 1)
string(STRIP "${ret_board}" ret_board)
set(single_val "NAME;DIR;HWM;REVISION_FORMAT;REVISION_DEFAULT;REVISION_EXACT")
set(multi_val "REVISIONS;IDENTIFIERS")
cmake_parse_arguments(BOARD "" "${single_val}" "${multi_val}" ${ret_board})
set(BOARD_DIR ${BOARD_DIR} CACHE PATH "Board directory for board (${BOARD})" FORCE)
# Create two CMake variables identifying the hw model.
# CMake variable: HWM=[v1,v2]
# CMake variable: HWMv1=True, when HWMv1 is in use.
# CMake variable: HWMv2=True, when HWMv2 is in use.
set(HWM ${BOARD_HWM} CACHE INTERNAL "Zephyr hardware model version")
set(HWM${HWM} True CACHE INTERNAL "Zephyr hardware model")
endif()
if(NOT BOARD_DIR)
message("No board named '${BOARD}' found.\n\n"
"Please choose one of the following boards:\n"
)
execute_process(${list_boards_commands})
unset(CACHED_BOARD CACHE)
message(FATAL_ERROR "Invalid BOARD; see above.")
endif()
cmake_path(IS_PREFIX ZEPHYR_BASE "${BOARD_DIR}" NORMALIZE in_zephyr_tree)
if(NOT in_zephyr_tree)
set(USING_OUT_OF_TREE_BOARD 1)
endif()
if(HWMv1)
if(EXISTS ${BOARD_DIR}/revision.cmake)
# Board provides revision handling.
include(${BOARD_DIR}/revision.cmake)
elseif(BOARD_REVISION)
message(WARNING "Board revision ${BOARD_REVISION} specified for ${BOARD}, \
but board has no revision so revision will be ignored.")
endif()
endforeach()
elseif(HWMv2)
if(BOARD_REVISION_FORMAT)
if(BOARD_REVISION_FORMAT STREQUAL "custom")
include(${BOARD_DIR}/revision.cmake)
else()
string(TOUPPER "${BOARD_REVISION_FORMAT}" rev_format)
if(BOARD_REVISION_EXACT)
set(rev_exact EXACT)
endif()
if(EXISTS ${BOARD_DIR}/revision.cmake)
# Board provides revision handling.
include(${BOARD_DIR}/revision.cmake)
elseif(BOARD_REVISION)
message(WARNING "Board revision ${BOARD_REVISION} specified for ${BOARD}, \
but board has no revision so revision will be ignored.")
board_check_revision(
FORMAT ${rev_format}
DEFAULT_REVISION ${BOARD_REVISION_DEFAULT}
VALID_REVISIONS ${BOARD_REVISIONS}
${rev_exact}
)
endif()
endif()
if(BOARD_IDENTIFIERS)
if(NOT ("${BOARD}${BOARD_IDENTIFIER}" IN_LIST BOARD_IDENTIFIERS))
string(REPLACE ";" "\n" BOARD_IDENTIFIERS "${BOARD_IDENTIFIERS}")
message(FATAL_ERROR "Board identifier `${BOARD_IDENTIFIER}` for board \
`${BOARD}` not found. Please specify a valid board.\n"
"Valid board identifiers for ${BOARD_NAME} are:\n${BOARD_IDENTIFIERS}\n")
endif()
endif()
else()
message(FATAL_ERROR "Unknown hw model (${HWM}) for board: ${BOARD}.")
endif()
set(board_message "Board: ${BOARD}")
@ -144,29 +243,13 @@ if(DEFINED BOARD_REVISION) @@ -144,29 +243,13 @@ if(DEFINED BOARD_REVISION)
string(REPLACE "." "_" BOARD_REVISION_STRING ${BOARD_REVISION})
endif()
message(STATUS "${board_message}")
# Prepare boards usage command printing.
# This command prints all boards in the system in the following cases:
# - User specifies an invalid BOARD
# - User invokes '<build-command> boards' target
list(TRANSFORM ARCH_ROOT PREPEND "--arch-root=" OUTPUT_VARIABLE arch_root_args)
list(TRANSFORM BOARD_ROOT PREPEND "--board-root=" OUTPUT_VARIABLE board_root_args)
set(list_boards_commands
COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/list_boards.py
${arch_root_args} ${board_root_args} --arch-root=${ZEPHYR_BASE}
)
if(NOT BOARD_DIR)
message("No board named '${BOARD}' found.\n\n"
"Please choose one of the following boards:\n"
)
execute_process(${list_boards_commands})
unset(CACHED_BOARD CACHE)
message(FATAL_ERROR "Invalid BOARD; see above.")
if(DEFINED BOARD_IDENTIFIER)
string(REGEX REPLACE "^/" "variant: " board_message_identifier "${BOARD_IDENTIFIER}")
set(board_message "${board_message}, ${board_message_identifier}")
endif()
message(STATUS "${board_message}")
add_custom_target(boards ${list_boards_commands} USES_TERMINAL)
# Board extensions are enabled by default

2
scripts/ci/test_plan.py

@ -226,7 +226,7 @@ class Filters: @@ -226,7 +226,7 @@ class Filters:
roots.append(repository_path)
# Look for boards in monitored repositories
lb_args = argparse.Namespace(**{ 'arch_roots': roots, 'board_roots': roots})
lb_args = argparse.Namespace(**{ 'arch_roots': roots, 'board_roots': roots, 'board': None})
known_boards = list_boards.find_boards(lb_args)
for b in boards:
name_re = re.compile(b)

240
scripts/list_boards.py

@ -5,9 +5,20 @@ @@ -5,9 +5,20 @@
import argparse
from collections import defaultdict
from dataclasses import dataclass, field
import itertools
from pathlib import Path
from typing import NamedTuple
import pykwalify.core
import sys
from typing import List
import yaml
import list_hardware
BOARD_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'board-schema.yml')
with open(BOARD_SCHEMA_PATH, 'r') as f:
board_schema = yaml.safe_load(f.read())
BOARD_YML = 'board.yml'
#
# This is shared code between the build system's 'boards' target
@ -18,10 +29,73 @@ from typing import NamedTuple @@ -18,10 +29,73 @@ from typing import NamedTuple
# 'ninja boards' in a build directory without west installed.)
#
class Board(NamedTuple):
@dataclass
class Revision:
name: str
variants: List[str] = field(default_factory=list)
@staticmethod
def from_dict(revision):
revisions = []
for r in revision.get('revisions', []):
revisions.append(Revision.from_dict(r))
return Revision(revision['name'], revisions)
@dataclass
class Variant:
name: str
variants: List[str] = field(default_factory=list)
@staticmethod
def from_dict(variant):
variants = []
for v in variant.get('variants', []):
variants.append(Variant.from_dict(v))
return Variant(variant['name'], variants)
@dataclass
class Cpucluster:
name: str
variants: List[str] = field(default_factory=list)
@dataclass
class Soc:
name: str
cpuclusters: List[str] = field(default_factory=list)
variants: List[str] = field(default_factory=list)
@staticmethod
def from_soc(soc, variants):
if soc is None:
return None
if soc.cpuclusters:
cpus = []
for c in soc.cpuclusters:
cpus.append(Cpucluster(c,
[Variant.from_dict(v) for v in variants if c == v['cpucluster']]
))
return Soc(soc.name, cpuclusters=cpus)
return Soc(soc.name, variants=[Variant.from_dict(v) for v in variants])
@dataclass(frozen=True)
class Board:
name: str
arch: str
dir: Path
hwm: str
arch: str = None
vendor: str = None
revision_format: str = None
revision_default: str = None
revision_exact: bool = False
revisions: List[str] = field(default_factory=list, compare=False)
socs: List[Soc] = field(default_factory=list, compare=False)
variants: List[str] = field(default_factory=list, compare=False)
def board_key(board):
return board.name
@ -41,7 +115,10 @@ def find_arch2board_set(args): @@ -41,7 +115,10 @@ def find_arch2board_set(args):
for root in args.board_roots:
for arch, boards in find_arch2board_set_in(root, arches).items():
ret[arch] |= boards
if args.board is not None:
ret[arch] |= {b for b in boards if b.name == args.board}
else:
ret[arch] |= boards
return ret
@ -83,15 +160,74 @@ def find_arch2board_set_in(root, arches): @@ -83,15 +160,74 @@ def find_arch2board_set_in(root, arches):
file_name = maybe_defconfig.name
if file_name.endswith('_defconfig'):
board_name = file_name[:-len('_defconfig')]
ret[arch].add(Board(board_name, arch, maybe_board))
ret[arch].add(Board(board_name, maybe_board, 'v1', arch=arch))
return ret
def find_v2_boards(args):
root_args = argparse.Namespace(**{'soc_roots': args.soc_roots})
systems = list_hardware.find_v2_systems(root_args)
boards = []
board_files = []
for root in args.board_roots:
board_files.extend((root / 'boards').rglob(BOARD_YML))
for board_yml in board_files:
if board_yml.is_file():
with board_yml.open('r') as f:
b = yaml.safe_load(f.read())
try:
pykwalify.core.Core(source_data=b, schema_data=board_schema).validate()
except pykwalify.errors.SchemaError as e:
sys.exit('ERROR: Malformed "build" section in file: {}\n{}'
.format(board_yml.as_posix(), e))
mutual_exclusive = {'board', 'boards'}
if len(mutual_exclusive - b.keys()) < 1:
sys.exit(f'ERROR: Malformed content in file: {board_yml.as_posix()}\n'
f'{mutual_exclusive} are mutual exclusive at this level.')
board_array = b.get('boards', [ b.get('board', None) ])
for board in board_array:
if args.board is not None:
if board['name'] != args.board:
# Not the board we're looking for, ignore.
continue
mutual_exclusive = {'socs', 'variants'}
if len(mutual_exclusive - board.keys()) < 1:
sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n'
f'{mutual_exclusive} are mutual exclusive at this level.')
socs = [Soc.from_soc(systems.get_soc(s['name']), s.get('variants', []))
for s in board.get('socs', {})]
board = Board(
name=board['name'],
dir=board_yml.parent,
vendor=board.get('vendor'),
revision_format=board.get('revision', {}).get('format'),
revision_default=board.get('revision', {}).get('default'),
revision_exact=board.get('revision', {}).get('exact', False),
revisions=[Revision.from_dict(v) for v in
board.get('revision', {}).get('revisions', [])],
socs=socs,
variants=[Variant.from_dict(v) for v in board.get('variants', [])],
hwm='v2',
)
boards.append(board)
return boards
def parse_args():
parser = argparse.ArgumentParser(allow_abbrev=False)
add_args(parser)
add_args_formatting(parser)
return parser.parse_args()
def add_args(parser):
# Remember to update west-completion.bash if you add or remove
# flags
@ -101,12 +237,98 @@ def add_args(parser): @@ -101,12 +237,98 @@ def add_args(parser):
parser.add_argument("--board-root", dest='board_roots', default=[],
type=Path, action='append',
help='add a board root, may be given more than once')
parser.add_argument("--soc-root", dest='soc_roots', default=[],
type=Path, action='append',
help='add a soc root, may be given more than once')
parser.add_argument("--board", dest='board', default=None,
help='lookup the specific board, fail if not found')
def add_args_formatting(parser):
parser.add_argument("--cmakeformat", default=None,
help='''CMake Format string to use to list each board''')
def dump_boards(arch2boards):
def variant_v2_identifiers(variant, identifier):
identifiers = [identifier + '/' + variant.name]
for v in variant.variants:
identifiers.append(variant_v2_identifiers(v, identifier + '/' + variant.name))
return identifiers
def board_v2_identifiers(board):
identifiers = []
for s in board.socs:
if s.cpuclusters:
for c in s.cpuclusters:
id_str = board.name + '/' + s.name + '/' + c.name
identifiers.append(id_str)
for v in c.variants:
identifiers.extend(variant_v2_identifiers(v, id_str))
else:
id_str = board.name + '/' + s.name
identifiers.append(id_str)
for v in s.variants:
identifiers.extend(variant_v2_identifiers(v, id_str))
if not board.socs:
identifiers.append(board.name)
for v in board.variants:
identifiers.extend(variant_v2_identifiers(v, board.name))
return identifiers
def dump_v2_boards(args):
boards = find_v2_boards(args)
for b in boards:
identifiers = board_v2_identifiers(b)
if args.cmakeformat is not None:
notfound = lambda x: x or 'NOTFOUND'
info = args.cmakeformat.format(
NAME='NAME;' + b.name,
DIR='DIR;' + str(b.dir),
VENDOR='VENDOR;' + notfound(b.vendor),
HWM='HWM;' + b.hwm,
REVISION_DEFAULT='REVISION_DEFAULT;' + notfound(b.revision_default),
REVISION_FORMAT='REVISION_FORMAT;' + notfound(b.revision_format),
REVISION_EXACT='REVISION_EXACT;' + str(b.revision_exact),
REVISIONS='REVISIONS;' + ';'.join(
[x.name for x in b.revisions]),
IDENTIFIERS='IDENTIFIERS;' + ';'.join(identifiers)
)
print(info)
else:
print(f'{b.name}')
def dump_boards(args):
arch2boards = find_arch2boards(args)
for arch, boards in arch2boards.items():
print(f'{arch}:')
if args.cmakeformat is None:
print(f'{arch}:')
for board in boards:
print(f' {board.name}')
if args.cmakeformat is not None:
info = args.cmakeformat.format(
NAME='NAME;' + board.name,
DIR='DIR;' + str(board.dir),
HWM='HWM;' + board.hwm,
VENDOR='VENDOR;NOTFOUND',
REVISION_DEFAULT='REVISION_DEFAULT;NOTFOUND',
REVISION_FORMAT='REVISION_FORMAT;NOTFOUND',
REVISION_EXACT='REVISION_EXACT;NOTFOUND',
REVISIONS='REVISIONS;NOTFOUND',
VARIANT_DEFAULT='VARIANT_DEFAULT;NOTFOUND',
IDENTIFIERS='IDENTIFIERS;'
)
print(info)
else:
print(f' {board.name}')
if __name__ == '__main__':
dump_boards(find_arch2boards(parse_args()))
args = parse_args()
dump_boards(args)
dump_v2_boards(args)

82
scripts/schemas/board-schema.yml

@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023, Nordic Semiconductor ASA
## A pykwalify schema for basic validation of the structure of a
## board metadata YAML file.
##
# The board.yml file is a simple list of key value pairs containing board
# information like: name, vendor, socs, variants.
schema;variant-schema:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
cpucluster:
required: false
type: str
variants:
required: false
include: variant-schema
schema;board-schema:
type: map
mapping:
name:
required: true
type: str
desc: Name of the board
vendor:
required: false
type: str
desc: SoC family of the SoC on the board.
revision:
required: false
type: map
mapping:
format:
required: true
type: str
enum:
["major.minor.patch", "letter", "number", "custom"]
default:
required: true
type: str
exact:
required: false
type: bool
revisions:
required: true
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
socs:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
variants:
include: variant-schema
variants:
include: variant-schema
type: map
mapping:
board:
include: board-schema
boards:
type: seq
sequence:
- include: board-schema

10
scripts/west_commands/boards.py

@ -49,6 +49,7 @@ class Boards(WestCommand): @@ -49,6 +49,7 @@ class Boards(WestCommand):
The following arguments are available:
- name: board name
- identifiers: board identifiers
- arch: board architecture
- dir: directory that contains the board definition
'''))
@ -72,6 +73,7 @@ class Boards(WestCommand): @@ -72,6 +73,7 @@ class Boards(WestCommand):
name_re = None
args.arch_roots = [ZEPHYR_BASE]
args.soc_roots = [ZEPHYR_BASE]
modules_board_roots = [ZEPHYR_BASE]
for module in zephyr_module.parse_modules(ZEPHYR_BASE, self.manifest):
@ -85,4 +87,10 @@ class Boards(WestCommand): @@ -85,4 +87,10 @@ class Boards(WestCommand):
if name_re is not None and not name_re.search(board.name):
continue
log.inf(args.format.format(name=board.name, arch=board.arch,
dir=board.dir))
dir=board.dir, hwm=board.hwm, identifiers=''))
for board in list_boards.find_v2_boards(args):
if name_re is not None and not name_re.search(board.name):
continue
log.inf(args.format.format(name=board.name, dir=board.dir, hwm=board.hwm,
identifiers=list_boards.board_v2_identifiers(board)))

1
scripts/west_commands/completion/west-completion.bash

@ -660,6 +660,7 @@ __comp_west_boards() @@ -660,6 +660,7 @@ __comp_west_boards()
local dir_opts="
--arch-root
--board-root
--soc-root
"
all_opts="$dir_opts $other_opts"

1
scripts/west_commands/completion/west-completion.fish

@ -292,6 +292,7 @@ complete -c west -n "__zephyr_west_seen_subcommand_from boards" -o f -l format - @@ -292,6 +292,7 @@ complete -c west -n "__zephyr_west_seen_subcommand_from boards" -o f -l format -
complete -c west -n "__zephyr_west_seen_subcommand_from boards" -o n -l name -d "name regex"
complete -c west -n "__zephyr_west_seen_subcommand_from boards" -l arch-root -xa "(__zephyr_west_complete_directories)" -d "add an arch root"
complete -c west -n "__zephyr_west_seen_subcommand_from boards" -l board-root -xa "(__zephyr_west_complete_directories)" -d "add a board root"
complete -c west -n "__zephyr_west_seen_subcommand_from boards" -l soc-root -xa "(__zephyr_west_complete_directories)" -d "add a soc root"
# build
complete -c west -n "__zephyr_west_use_subcommand; and __zephyr_west_check_if_in_workspace" -ra build -d "compile a Zephyr application"

1
scripts/west_commands/completion/west-completion.zsh

@ -214,6 +214,7 @@ _west_boards() { @@ -214,6 +214,7 @@ _west_boards() {
{-n,--name}'[name regex]:regex:'
'*--arch-root[Add an arch root]:arch root:_directories'
'*--board-root[Add a board root]:board root:_directories'
'*--soc-root[Add a soc root]:soc root:_directories'
)
_arguments -S $opts

4
share/sysbuild/cmake/modules/sysbuild_extensions.cmake

@ -146,9 +146,9 @@ function(sysbuild_cache) @@ -146,9 +146,9 @@ function(sysbuild_cache)
endif()
endforeach()
if(DEFINED BOARD_REVISION)
list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}@${BOARD_REVISION}\n")
list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}@${BOARD_REVISION}${BOARD_IDENTIFIER}\n")
else()
list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}\n")
list(APPEND sysbuild_cache_strings "BOARD:STRING=${BOARD}${BOARD_IDENTIFIER}\n")
endif()
list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${SB_CACHE_APPLICATION}\n")

Loading…
Cancel
Save