shields: scripts: cmake: use list_shields.py in shields.cmake

The logic to "guess" shield names/dirs was duplicated between
list_shields.py (which is used by e.g. west shields) and shields.cmake.
This commit moves the logic to list_shields.py, and updates
shields.cmake to call the script and process its JSON output.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
This commit is contained in:
Benjamin Cabé 2025-05-21 15:43:29 +02:00 committed by Benjamin Cabé
commit 66fda826e1
2 changed files with 50 additions and 26 deletions

View file

@ -31,6 +31,7 @@
include_guard(GLOBAL) include_guard(GLOBAL)
include(extensions) include(extensions)
include(python)
# Check that SHIELD has not changed. # Check that SHIELD has not changed.
zephyr_check_cache(SHIELD WATCH) zephyr_check_cache(SHIELD WATCH)
@ -46,31 +47,42 @@ endif()
# After processing all shields, only invalid shields will be left in this list. # After processing all shields, only invalid shields will be left in this list.
set(SHIELD-NOTFOUND ${SHIELD_AS_LIST}) set(SHIELD-NOTFOUND ${SHIELD_AS_LIST})
foreach(root ${BOARD_ROOT}) # Prepare list shields command.
set(shield_dir ${root}/boards/shields) # This command is used for locating the shield dir as well as printing all shields
# Match the Kconfig.shield files in the shield directories to make sure we are # in the system in the following cases:
# finding shields, e.g. x_nucleo_iks01a1/Kconfig.shield # - User specifies an invalid SHIELD
file(GLOB_RECURSE shields_refs_list ${shield_dir}/*/Kconfig.shield) # - User invokes '<build-command> shields' target
list(TRANSFORM BOARD_ROOT PREPEND "--board-root=" OUTPUT_VARIABLE board_root_args)
# The above gives a list of Kconfig.shield files, like this: set(list_shields_commands
# COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/list_shields.py
# x_nucleo_iks01a1/Kconfig.shield;x_nucleo_iks01a2/Kconfig.shield ${board_root_args} --json
# )
# we construct a list of shield names by extracting the directories
# from each file and looking for <shield>.overlay files in there. # Get list of shields in JSON format
# Each overlay corresponds to a shield. We obtain the shield name by execute_process(${list_shields_commands}
# removing the .overlay extension. OUTPUT_VARIABLE shields_json
# We also create a SHIELD_DIR_${name} variable for each shield's directory. ERROR_VARIABLE err_shields
foreach(shields_refs ${shields_refs_list}) RESULT_VARIABLE ret_val
get_filename_component(shield_path ${shields_refs} DIRECTORY) )
file(GLOB shield_overlays RELATIVE ${shield_path} ${shield_path}/*.overlay)
foreach(overlay ${shield_overlays}) if(ret_val)
get_filename_component(shield ${overlay} NAME_WE) message(FATAL_ERROR "Error finding shields\nError message: ${err_shields}")
list(APPEND SHIELD_LIST ${shield}) endif()
set(SHIELD_DIR_${shield} ${shield_path})
string(JSON shields_length LENGTH ${shields_json})
if(shields_length GREATER 0)
math(EXPR shields_length "${shields_length} - 1")
foreach(i RANGE ${shields_length})
string(JSON shield GET "${shields_json}" "${i}")
string(JSON shield_name GET ${shield} name)
string(JSON shield_dir GET ${shield} dir)
list(APPEND SHIELD_LIST ${shield_name})
set(SHIELD_DIR_${shield_name} ${shield_dir})
endforeach() endforeach()
endforeach() endif()
endforeach()
# Process shields in-order # Process shields in-order
if(DEFINED SHIELD) if(DEFINED SHIELD)

View file

@ -5,6 +5,7 @@
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
import argparse import argparse
import json
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
@ -57,6 +58,7 @@ def find_shields_in(root):
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(allow_abbrev=False) parser = argparse.ArgumentParser(allow_abbrev=False)
add_args(parser) add_args(parser)
add_args_formatting(parser)
return parser.parse_args() return parser.parse_args()
def add_args(parser): def add_args(parser):
@ -66,9 +68,19 @@ def add_args(parser):
type=Path, action='append', type=Path, action='append',
help='add a board root, may be given more than once') help='add a board root, may be given more than once')
def add_args_formatting(parser):
parser.add_argument("--json", action='store_true',
help='''output list of shields in JSON format''')
def dump_shields(shields): def dump_shields(shields):
if args.json:
print(
json.dumps([{'dir': shield.dir.as_posix(), 'name': shield.name} for shield in shields])
)
else:
for shield in shields: for shield in shields:
print(f' {shield.name}') print(f' {shield.name}')
if __name__ == '__main__': if __name__ == '__main__':
dump_shields(find_shields(parse_args())) args = parse_args()
dump_shields(find_shields(args))