scripts: west_command: build: Support for conditional platform configs

extra_configs or extra_args can use additional filtering which was not
supported by the west build command. West is not aware of arch so that
filter type is not supported but platform (board) is known so it can
be used to apply expected configuration.

Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruściński
2025-08-07 16:39:31 +02:00
committed by Benjamin Cabé
parent 004955b58c
commit 5718af02c5

View File

@@ -193,6 +193,7 @@ class Build(Forceable):
# Store legacy -s option locally
source_dir = self.args.source_dir
self._parse_remainder(remainder)
board, origin = self._find_board()
# Parse testcase.yaml or sample.yaml files for additional options.
if self.args.test_item:
# we get path + testitem
@@ -203,7 +204,7 @@ class Build(Forceable):
test_path = os.path.dirname(self.args.test_item)
if test_path and os.path.exists(test_path):
self.args.source_dir = test_path
if not self._parse_test_item(item):
if not self._parse_test_item(item, board):
self.die("No test metadata found")
else:
self.die("test item path does not exist")
@@ -263,7 +264,6 @@ class Build(Forceable):
except Exception as e:
self.wrn(f'Failed to create info file: {build_info_file},', e)
board, origin = self._find_board()
self._run_cmake(board, origin, self.args.cmake_opts)
if args.cmake_only:
return
@@ -311,7 +311,24 @@ class Build(Forceable):
except IndexError:
pass
def _parse_test_item(self, test_item):
def _parse_extra_entry(self, arg, board):
equals = arg.find('=')
colon = arg.rfind(':', 0, equals)
if colon != -1:
elem = arg.split(':')
if elem[0] != 'platform':
# conditional configs other than platform
# (xxx:yyy:CONFIG_FOO=bar) are not supported by 'west build'
self.wrn(f'"west build" does not support conditional config "{arg}". Add '
f'"-D{arg[colon+1:]}" to the supplied CMake arguments if desired.')
return None
elif elem[1] not in board:
return None
return elem[2]
else:
return arg
def _parse_test_item(self, test_item, board):
found_test_metadata = False
for yp in ['sample.yaml', 'testcase.yaml']:
yf = os.path.join(self.args.source_dir, yp)
@@ -359,24 +376,23 @@ class Build(Forceable):
if data == 'extra_configs':
args = []
for arg in arg_list:
equals = arg.find('=')
colon = arg.rfind(':', 0, equals)
if colon != -1:
# conditional configs (xxx:yyy:CONFIG_FOO=bar)
# are not supported by 'west build'
self.wrn('"west build" does not support '
f'conditional config "{arg}". Add "-D{arg[colon+1:]}" '
'to the supplied CMake arguments if '
'desired.')
continue
args.append("-D{}".format(arg.replace('"', '\"')))
entry = self._parse_extra_entry(arg, board)
if entry is not None:
args.append("-D{}".format(entry.replace('"', '\"')))
elif data == 'extra_args':
# Retain quotes around config options
config_options = [arg for arg in arg_list if arg.startswith("CONFIG_")]
non_config_options = [
non_config_option_candidates = [
arg for arg in arg_list if not arg.startswith("CONFIG_")
]
args = ["-D{}".format(a.replace('"', '\"')) for a in config_options]
non_config_options = []
for arg in non_config_option_candidates:
entry = self._parse_extra_entry(arg, board)
if entry is not None:
non_config_options.append(entry)
args.extend([
"-D{}".format(arg.replace('"', '')) for arg in non_config_options
])