Skip to content

Commit ef0d90b

Browse files
tejlmand57300
authored andcommitted
[nrf fromlist] cmake: scripts: support board extension
Upstream PR: zephyrproject-rtos/zephyr#72857 Fixes: #69548 Support extending an existing board with new board variants. This commit introduces the following changes to allow a board to be extended out-of-tree. The board yaml schema is extended to support an extend field which will be used to identify the board to be extended. A board 'plank' can be extended like this: > board: > extend: plank > variants: > - name: ext > qualifier: soc1 For the rest of the build system this means that there is no longer a single board directory. The existing CMake variable BOARD_DIR is kept and reference the directory which defines the board. A new CMake variable BOARD_DIRECTORIES provides a list of all directories which defines board targets for the board. This means the directory which defines the board as well as all directories that extends the board. Signed-off-by: Torsten Rasmussen <[email protected]> (cherry picked from commit 92599711f5e0201997da95e6c18d33dd85fbbc1e)
1 parent 64d5ae8 commit ef0d90b

File tree

10 files changed

+167
-87
lines changed

10 files changed

+167
-87
lines changed

cmake/modules/boards.cmake

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,7 @@ set(format_str "{NAME}\;{DIR}\;{HWM}\;")
185185
set(format_str "${format_str}{REVISION_FORMAT}\;{REVISION_DEFAULT}\;{REVISION_EXACT}\;")
186186
set(format_str "${format_str}{REVISIONS}\;{SOCS}\;{QUALIFIERS}")
187187

188-
if(BOARD_DIR)
189-
set(board_dir_arg "--board-dir=${BOARD_DIR}")
190-
endif()
188+
list(TRANSFORM BOARD_DIRECTORIES PREPEND "--board-dir=" OUTPUT_VARIABLE board_dir_arg)
191189
execute_process(${list_boards_commands} --board=${BOARD} ${board_dir_arg}
192190
--cmakeformat=${format_str}
193191
OUTPUT_VARIABLE ret_board
@@ -200,29 +198,15 @@ endif()
200198

201199
if(NOT "${ret_board}" STREQUAL "")
202200
string(STRIP "${ret_board}" ret_board)
203-
string(FIND "${ret_board}" "\n" idx REVERSE)
204-
if(idx GREATER -1)
205-
while(TRUE)
206-
math(EXPR start "${idx} + 1")
207-
string(SUBSTRING "${ret_board}" ${start} -1 line)
208-
string(SUBSTRING "${ret_board}" 0 ${idx} ret_board)
209-
210-
cmake_parse_arguments(LIST_BOARD "" "DIR" "" ${line})
211-
set(board_dirs "${board_dirs}\n${LIST_BOARD_DIR}")
212-
213-
if(idx EQUAL -1)
214-
break()
215-
endif()
216-
string(FIND "${ret_board}" "\n" idx REVERSE)
217-
endwhile()
218-
message(FATAL_ERROR "Multiple boards named '${BOARD}' found in:${board_dirs}")
219-
endif()
220-
221-
set(single_val "NAME;DIR;HWM;REVISION_FORMAT;REVISION_DEFAULT;REVISION_EXACT")
222-
set(multi_val "REVISIONS;SOCS;QUALIFIERS")
201+
set(single_val "NAME;HWM;REVISION_FORMAT;REVISION_DEFAULT;REVISION_EXACT")
202+
set(multi_val "DIR;REVISIONS;SOCS;QUALIFIERS")
223203
cmake_parse_arguments(LIST_BOARD "" "${single_val}" "${multi_val}" ${ret_board})
224-
set(BOARD_DIR ${LIST_BOARD_DIR} CACHE PATH "Board directory for board (${BOARD})" FORCE)
225-
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${BOARD_DIR}/board.yml)
204+
list(GET LIST_BOARD_DIR 0 BOARD_DIR)
205+
set(BOARD_DIR ${BOARD_DIR} CACHE PATH "Main board directory for board (${BOARD})" FORCE)
206+
set(BOARD_DIRECTORIES ${LIST_BOARD_DIR} CACHE PATH "List of board directories for board (${BOARD})" FORCE)
207+
foreach(dir ${BOARD_DIRECTORIES})
208+
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${dir}/board.yml)
209+
endforeach()
226210

227211
# Create two CMake variables identifying the hw model.
228212
# CMake variable: HWM=[v1,v2]

cmake/modules/dts.cmake

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ find_package(Dtc 1.4.6)
7070
#
7171
# Optional variables:
7272
# - BOARD: board name to use when looking for DTS_SOURCE
73-
# - BOARD_DIR: board directory to use when looking for DTS_SOURCE
73+
# - BOARD_DIRECTORIES: list of board directories to use when looking for DTS_SOURCE
7474
# - BOARD_REVISION_STRING: used when looking for a board revision's
75-
# devicetree overlay file in BOARD_DIR
75+
# devicetree overlay file in one of the BOARD_DIRECTORIES
7676
# - DTC_OVERLAY_FILE: list of devicetree overlay files which will be
7777
# used to modify or extend the base devicetree.
7878
# - EXTRA_DTC_OVERLAY_FILE: list of extra devicetree overlay files.
@@ -86,7 +86,7 @@ find_package(Dtc 1.4.6)
8686
# C preprocessor when generating the devicetree from DTS_SOURCE
8787
# - DTS_SOURCE: the devicetree source file to use may be pre-set
8888
# with this variable; otherwise, it defaults to
89-
# ${BOARD_DIR}/${BOARD}.dts
89+
# ${BOARD_DIRECTORIES}/${BOARD}.dts
9090
#
9191
# Variables set by this module and not mentioned above are for internal
9292
# use only, and may be removed, renamed, or re-purposed without prior notice.
@@ -127,28 +127,30 @@ if(NOT DEFINED DTS_SOURCE)
127127
zephyr_build_string(board_string SHORT shortened_board_string
128128
BOARD ${BOARD} BOARD_QUALIFIERS ${BOARD_QUALIFIERS}
129129
)
130-
if(EXISTS ${BOARD_DIR}/${shortened_board_string}.dts AND NOT BOARD_${BOARD}_SINGLE_SOC)
131-
message(FATAL_ERROR "Board ${ZFILE_BOARD} defines multiple SoCs.\nShortened file name "
132-
"(${shortened_board_string}.dts) not allowed, use '<board>_<soc>.dts' naming"
133-
)
134-
elseif(EXISTS ${BOARD_DIR}/${board_string}.dts AND EXISTS ${BOARD_DIR}/${shortened_board_string}.dts)
135-
message(FATAL_ERROR "Conflicting file names discovered. Cannot use both "
136-
"${board_string}.dts and ${shortened_board_string}.dts. "
137-
"Please choose one naming style, ${board_string}.dts is recommended."
138-
)
139-
elseif(EXISTS ${BOARD_DIR}/${board_string}.dts)
140-
set(DTS_SOURCE ${BOARD_DIR}/${board_string}.dts)
141-
elseif(EXISTS ${BOARD_DIR}/${shortened_board_string}.dts)
142-
set(DTS_SOURCE ${BOARD_DIR}/${shortened_board_string}.dts)
143-
endif()
130+
foreach(dir ${BOARD_DIRECTORIES})
131+
if(EXISTS ${dir}/${shortened_board_string}.dts AND NOT BOARD_${BOARD}_SINGLE_SOC)
132+
message(FATAL_ERROR "Board ${ZFILE_BOARD} defines multiple SoCs.\nShortened file name "
133+
"(${shortened_board_string}.dts) not allowed, use '<board>_<soc>.dts' naming"
134+
)
135+
elseif(EXISTS ${dir}/${board_string}.dts AND EXISTS ${dir}/${shortened_board_string}.dts)
136+
message(FATAL_ERROR "Conflicting file names discovered. Cannot use both "
137+
"${board_string}.dts and ${shortened_board_string}.dts. "
138+
"Please choose one naming style, ${board_string}.dts is recommended."
139+
)
140+
elseif(EXISTS ${dir}/${board_string}.dts)
141+
set(DTS_SOURCE ${dir}/${board_string}.dts)
142+
elseif(EXISTS ${dir}/${shortened_board_string}.dts)
143+
set(DTS_SOURCE ${dir}/${shortened_board_string}.dts)
144+
endif()
145+
endforeach()
144146
endif()
145147

146148
if(EXISTS ${DTS_SOURCE})
147149
# We found a devicetree. Append all relevant dts overlays we can find...
148-
zephyr_file(CONF_FILES ${BOARD_DIR} DTS DTS_SOURCE)
150+
zephyr_file(CONF_FILES ${BOARD_DIRECTORIES} DTS DTS_SOURCE)
149151

150152
zephyr_file(
151-
CONF_FILES ${BOARD_DIR}
153+
CONF_FILES ${BOARD_DIRECTORIES}
152154
DTS no_rev_suffix_dts_board_overlays
153155
BOARD ${BOARD}
154156
BOARD_QUALIFIERS ${BOARD_QUALIFIERS}

cmake/modules/hwm_v2.cmake

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,15 @@ endwhile()
9595
list(REMOVE_DUPLICATES kconfig_soc_source_dir)
9696

9797
# Support multiple ARCH_ROOT, SOC_ROOT and BOARD_ROOT
98-
kconfig_gen("arch" "Kconfig" "${kconfig_arch_source_dir}" "Zephyr Arch Kconfig")
99-
kconfig_gen("soc" "Kconfig.defconfig" "${kconfig_soc_source_dir}" "Zephyr SoC defconfig")
100-
kconfig_gen("soc" "Kconfig" "${kconfig_soc_source_dir}" "Zephyr SoC Kconfig")
101-
kconfig_gen("soc" "Kconfig.soc" "${kconfig_soc_source_dir}" "SoC Kconfig")
102-
kconfig_gen("soc" "Kconfig.sysbuild" "${kconfig_soc_source_dir}" "Sysbuild SoC Kconfig")
98+
kconfig_gen("arch" "Kconfig" "${kconfig_arch_source_dir}" "Zephyr Arch Kconfig")
99+
kconfig_gen("soc" "Kconfig.defconfig" "${kconfig_soc_source_dir}" "Zephyr SoC defconfig")
100+
kconfig_gen("soc" "Kconfig" "${kconfig_soc_source_dir}" "Zephyr SoC Kconfig")
101+
kconfig_gen("soc" "Kconfig.soc" "${kconfig_soc_source_dir}" "SoC Kconfig")
102+
kconfig_gen("soc" "Kconfig.sysbuild" "${kconfig_soc_source_dir}" "Sysbuild SoC Kconfig")
103+
kconfig_gen("boards" "Kconfig.defconfig" "${BOARD_DIRECTORIES}" "Zephyr board defconfig")
104+
kconfig_gen("boards" "Kconfig.${BOARD}" "${BOARD_DIRECTORIES}" "board Kconfig")
105+
kconfig_gen("boards" "Kconfig" "${BOARD_DIRECTORIES}" "Zephyr board Kconfig")
106+
kconfig_gen("boards" "Kconfig.sysbuild" "${BOARD_DIRECTORIES}" "Sysbuild board Kconfig")
103107

104108
# Clear variables created by cmake_parse_arguments
105109
unset(SOC_V2_NAME)

cmake/modules/kconfig.cmake

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/config)
2020
set_ifndef(KCONFIG_NAMESPACE "CONFIG")
2121

2222
set_ifndef(KCONFIG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/Kconfig)
23+
set(KCONFIG_BOARD_DIR ${KCONFIG_BINARY_DIR}/boards)
2324
file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR})
2425

2526
if(HWMv1)
27+
# HWMv1 only supoorts a single board dir which points directly to the board dir.
28+
set(KCONFIG_BOARD_DIR ${BOARD_DIR})
2629
# Support multiple SOC_ROOT
2730
file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}/soc)
2831
set(kconfig_soc_root ${SOC_ROOT})
@@ -75,7 +78,7 @@ else()
7578
endif()
7679

7780
if(NOT DEFINED BOARD_DEFCONFIG)
78-
zephyr_file(CONF_FILES ${BOARD_DIR} DEFCONFIG BOARD_DEFCONFIG)
81+
zephyr_file(CONF_FILES ${BOARD_DIRECTORIES} DEFCONFIG BOARD_DEFCONFIG)
7982
endif()
8083

8184
if(DEFINED BOARD_REVISION)
@@ -157,7 +160,7 @@ set(COMMON_KCONFIG_ENV_SETTINGS
157160
APP_VERSION_TWEAK_STRING=${APP_VERSION_TWEAK_STRING}
158161
CONFIG_=${KCONFIG_NAMESPACE}_
159162
KCONFIG_CONFIG=${DOTCONFIG}
160-
BOARD_DIR=${BOARD_DIR}
163+
BOARD_DIR=${KCONFIG_BOARD_DIR}
161164
BOARD=${BOARD}
162165
BOARD_REVISION=${BOARD_REVISION}
163166
BOARD_QUALIFIERS=${BOARD_QUALIFIERS}

cmake/modules/kernel.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ if(CONFIG_LLEXT AND CONFIG_LLEXT_TYPE_ELF_SHAREDLIB)
173173
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
174174
endif()
175175

176-
include(${BOARD_DIR}/board.cmake OPTIONAL)
176+
foreach(dir ${BOARD_DIRECTORIES})
177+
include(${dir}/board.cmake OPTIONAL)
178+
endforeach()
177179

178180
# If we are using a suitable ethernet driver inside qemu, then these options
179181
# must be set, otherwise a zephyr instance cannot receive any network packets.

doc/_extensions/zephyr/kconfig/__init__.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def kconfig_load(app: Sphinx) -> Tuple[kconfiglib.Kconfig, Dict[str, str]]:
9191
root_args = argparse.Namespace(**{'soc_roots': [Path(ZEPHYR_BASE)]})
9292
v2_systems = list_hardware.find_v2_systems(root_args)
9393

94-
soc_folders = {soc.folder for soc in v2_systems.get_socs()}
94+
soc_folders = {soc.folder[0] for soc in v2_systems.get_socs()}
9595
with open(Path(td) / "soc" / "Kconfig.defconfig", "w") as f:
9696
f.write('')
9797

@@ -114,8 +114,9 @@ def kconfig_load(app: Sphinx) -> Tuple[kconfiglib.Kconfig, Dict[str, str]]:
114114

115115
(Path(td) / 'boards').mkdir(exist_ok=True)
116116
root_args = argparse.Namespace(**{'board_roots': [Path(ZEPHYR_BASE)],
117-
'soc_roots': [Path(ZEPHYR_BASE)], 'board': None})
118-
v2_boards = list_boards.find_v2_boards(root_args)
117+
'soc_roots': [Path(ZEPHYR_BASE)], 'board': None,
118+
'board_dir': []})
119+
v2_boards = list_boards.find_v2_boards(root_args).values()
119120

120121
with open(Path(td) / "boards" / "Kconfig.boards", "w") as f:
121122
for board in v2_boards:
@@ -126,7 +127,7 @@ def kconfig_load(app: Sphinx) -> Tuple[kconfiglib.Kconfig, Dict[str, str]]:
126127
board_str = 'BOARD_' + re.sub(r"[^a-zA-Z0-9_]", "_", qualifier).upper()
127128
f.write('config ' + board_str + '\n')
128129
f.write('\t bool\n')
129-
f.write('source "' + (board.dir / ('Kconfig.' + board.name)).as_posix() + '"\n\n')
130+
f.write('source "' + (board.dir[0] / ('Kconfig.' + board.name)).as_posix() + '"\n\n')
130131

131132
# base environment
132133
os.environ["ZEPHYR_BASE"] = str(ZEPHYR_BASE)

scripts/ci/check_compliance.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,12 +452,13 @@ def get_v2_model(self, kconfig_dir):
452452
kconfig_defconfig_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.defconfig')
453453

454454
root_args = argparse.Namespace(**{'board_roots': [Path(ZEPHYR_BASE)],
455-
'soc_roots': [Path(ZEPHYR_BASE)], 'board': None})
456-
v2_boards = list_boards.find_v2_boards(root_args)
455+
'soc_roots': [Path(ZEPHYR_BASE)], 'board': None,
456+
'board_dir': []})
457+
v2_boards = list_boards.find_v2_boards(root_args).values()
457458

458459
with open(kconfig_defconfig_file, 'w') as fp:
459460
for board in v2_boards:
460-
fp.write('osource "' + (Path(board.dir) / 'Kconfig.defconfig').as_posix() + '"\n')
461+
fp.write('osource "' + (board.dir[0] / 'Kconfig.defconfig').as_posix() + '"\n')
461462

462463
with open(kconfig_boards_file, 'w') as fp:
463464
for board in v2_boards:
@@ -470,15 +471,15 @@ def get_v2_model(self, kconfig_dir):
470471
fp.write('config ' + board_str + '\n')
471472
fp.write('\t bool\n')
472473
fp.write(
473-
'source "' + (Path(board.dir) / ('Kconfig.' + board.name)).as_posix() + '"\n\n'
474+
'source "' + (board.dir[0] / ('Kconfig.' + board.name)).as_posix() + '"\n\n'
474475
)
475476

476477
with open(kconfig_file, 'w') as fp:
477478
fp.write(
478479
'osource "' + (Path(kconfig_dir) / 'boards' / 'Kconfig.syms.v1').as_posix() + '"\n'
479480
)
480481
for board in v2_boards:
481-
fp.write('osource "' + (Path(board.dir) / 'Kconfig').as_posix() + '"\n')
482+
fp.write('osource "' + (Path(board.dir[0]) / 'Kconfig').as_posix() + '"\n')
482483

483484
kconfig_defconfig_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.defconfig')
484485
kconfig_soc_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.soc')
@@ -487,7 +488,7 @@ def get_v2_model(self, kconfig_dir):
487488
root_args = argparse.Namespace(**{'soc_roots': [Path(ZEPHYR_BASE)]})
488489
v2_systems = list_hardware.find_v2_systems(root_args)
489490

490-
soc_folders = {soc.folder for soc in v2_systems.get_socs()}
491+
soc_folders = {soc.folder[0] for soc in v2_systems.get_socs()}
491492
with open(kconfig_defconfig_file, 'w') as fp:
492493
for folder in soc_folders:
493494
fp.write('osource "' + (Path(folder) / 'Kconfig.defconfig').as_posix() + '"\n')
@@ -860,6 +861,9 @@ def check_no_undef_outside_kconfig(self, kconf):
860861
# Zephyr toolchain variant and therefore not
861862
# visible to compliance.
862863
"BOARD_", # Used as regex in scripts/utils/board_v1_to_v2.py
864+
"BOARD_MPS2_AN521_CPUTEST", # Used for board and SoC extension feature
865+
"BOARD_NATIVE_SIM_NATIVE_64_TWO", # Used for board and SoC extension feature
866+
"BOARD_NATIVE_SIM_NATIVE_ONE", # Used for board and SoC extension feature
863867
"BOOT_ENCRYPTION_KEY_FILE", # Used in sysbuild
864868
"BOOT_ENCRYPT_IMAGE", # Used in sysbuild
865869
"BINDESC_", # Used in documentation as a prefix

0 commit comments

Comments
 (0)