diff --git a/cmake/modules/root.cmake b/cmake/modules/root.cmake index e14b853831f..696de94fe76 100644 --- a/cmake/modules/root.cmake +++ b/cmake/modules/root.cmake @@ -28,6 +28,7 @@ zephyr_get(BOARD_ROOT MERGE SYSBUILD GLOBAL) zephyr_get(SOC_ROOT MERGE SYSBUILD GLOBAL) zephyr_get(ARCH_ROOT MERGE SYSBUILD GLOBAL) zephyr_get(SCA_ROOT MERGE SYSBUILD GLOBAL) +zephyr_get(SNIPPET_ROOT MERGE SYSBUILD GLOBAL) # Convert paths to absolute, relative from APPLICATION_SOURCE_DIR zephyr_file(APPLICATION_ROOT MODULE_EXT_ROOT) @@ -35,6 +36,7 @@ zephyr_file(APPLICATION_ROOT BOARD_ROOT) zephyr_file(APPLICATION_ROOT SOC_ROOT) zephyr_file(APPLICATION_ROOT ARCH_ROOT) zephyr_file(APPLICATION_ROOT SCA_ROOT) +zephyr_file(APPLICATION_ROOT SNIPPET_ROOT) if(unittest IN_LIST Zephyr_FIND_COMPONENTS) # Zephyr used in unittest mode, use dedicated unittest root. diff --git a/cmake/modules/snippets.cmake b/cmake/modules/snippets.cmake index 550d236a2f4..fba7818c650 100644 --- a/cmake/modules/snippets.cmake +++ b/cmake/modules/snippets.cmake @@ -45,19 +45,23 @@ zephyr_check_cache(SNIPPET WATCH) function(zephyr_process_snippets) set(snippets_py ${ZEPHYR_BASE}/scripts/snippets.py) set(snippets_generated ${CMAKE_BINARY_DIR}/zephyr/snippets_generated.cmake) + set_ifndef(SNIPPET_NAMESPACE SNIPPET) + set_ifndef(SNIPPET_PYTHON_EXTRA_ARGS "") + set_ifndef(SNIPPET_APP_DIR "${APPLICATION_SOURCE_DIR}") # Set SNIPPET_AS_LIST, removing snippets_generated.cmake if we are # running cmake again and snippets are no longer requested. - if (NOT DEFINED SNIPPET) + if(NOT DEFINED SNIPPET) set(SNIPPET_AS_LIST "" PARENT_SCOPE) file(REMOVE ${snippets_generated}) else() - string(REPLACE " " ";" SNIPPET_AS_LIST "${SNIPPET}") + string(REPLACE " " ";" SNIPPET_AS_LIST "${${SNIPPET_NAMESPACE}}") set(SNIPPET_AS_LIST "${SNIPPET_AS_LIST}" PARENT_SCOPE) endif() # Set SNIPPET_ROOT. - list(APPEND SNIPPET_ROOT ${APPLICATION_SOURCE_DIR}) + zephyr_get(SNIPPET_ROOT MERGE SYSBUILD GLOBAL) + list(APPEND SNIPPET_ROOT ${SNIPPET_APP_DIR}) list(APPEND SNIPPET_ROOT ${ZEPHYR_BASE}) unset(real_snippet_root) foreach(snippet_dir ${SNIPPET_ROOT}) @@ -85,6 +89,7 @@ function(zephyr_process_snippets) ${snippet_root_args} ${requested_snippet_args} --cmake-out ${snippets_generated} + ${SNIPPET_PYTHON_EXTRA_ARGS} OUTPUT_VARIABLE output ERROR_VARIABLE output RESULT_VARIABLE ret) diff --git a/scripts/schemas/snippet-schema.yml b/scripts/schemas/snippet-schema.yml index 307e27be2ca..319097c58f8 100644 --- a/scripts/schemas/snippet-schema.yml +++ b/scripts/schemas/snippet-schema.yml @@ -13,6 +13,8 @@ schema;append-schema: type: str EXTRA_CONF_FILE: type: str + SB_EXTRA_CONF_FILE: + type: str DTS_EXTRA_CPPFLAGS: type: str diff --git a/scripts/snippets.py b/scripts/snippets.py index 0cdc0d31e13..d725f08891e 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -48,11 +48,11 @@ class Snippet: appends: Appends = field(default_factory=_new_append) board2appends: Dict[str, Appends] = field(default_factory=_new_board2appends) - def process_data(self, pathobj: Path, snippet_data: dict): + def process_data(self, pathobj: Path, snippet_data: dict, sysbuild: bool): '''Process the data in a snippet.yml file, after it is loaded into a python object and validated by pykwalify.''' def append_value(variable, value): - if variable in ('EXTRA_DTC_OVERLAY_FILE', 'EXTRA_CONF_FILE'): + if variable in ('SB_EXTRA_CONF_FILE', 'EXTRA_DTC_OVERLAY_FILE', 'EXTRA_CONF_FILE'): path = pathobj.parent / value if not path.is_file(): _err(f'snippet file {pathobj}: {variable}: file not found: {path}') @@ -62,14 +62,18 @@ class Snippet: _err(f'unknown append variable: {variable}') for variable, value in snippet_data.get('append', {}).items(): - self.appends[variable].append(append_value(variable, value)) + if (sysbuild is True and variable[0:3] == 'SB_') or \ + (sysbuild is False and variable[0:3] != 'SB_'): + self.appends[variable].append(append_value(variable, value)) for board, settings in snippet_data.get('boards', {}).items(): if board.startswith('/') and not board.endswith('/'): _err(f"snippet file {pathobj}: board {board} starts with '/', so " "it must end with '/' to use a regular expression") for variable, value in settings.get('append', {}).items(): - self.board2appends[board][variable].append( - append_value(variable, value)) + if (sysbuild is True and variable[0:3] == 'SB_') or \ + (sysbuild is False and variable[0:3] != 'SB_'): + self.board2appends[board][variable].append( + append_value(variable, value)) class Snippets(UserDict): '''Type for all the information we have discovered about all snippets. @@ -212,6 +216,8 @@ def parse_args(): parser.add_argument('--cmake-out', type=Path, help='''file to write cmake output to; include() this file after calling this script''') + parser.add_argument('--sysbuild', action="store_true", + help='''set if this is running as sysbuild''') return parser.parse_args() def setup_logging(): @@ -234,7 +240,7 @@ def process_snippets(args: argparse.Namespace) -> Snippets: # Process each path in snippet_root in order, adjusting # snippets as needed for each one. for root in args.snippet_root: - process_snippets_in(root, snippets) + process_snippets_in(root, snippets, args.sysbuild) return snippets @@ -250,11 +256,11 @@ def find_snippets_in_roots(requested_snippets, snippet_roots) -> Snippets: # Process each path in snippet_root in order, adjusting # snippets as needed for each one. for root in snippet_roots: - process_snippets_in(root, snippets) + process_snippets_in(root, snippets, False) return snippets -def process_snippets_in(root_dir: Path, snippets: Snippets) -> None: +def process_snippets_in(root_dir: Path, snippets: Snippets, sysbuild: bool) -> None: '''Process snippet.yml files in *root_dir*, updating *snippets* as needed.''' @@ -276,7 +282,7 @@ def process_snippets_in(root_dir: Path, snippets: Snippets) -> None: name = snippet_data['name'] if name not in snippets: snippets[name] = Snippet(name=name) - snippets[name].process_data(snippet_yml, snippet_data) + snippets[name].process_data(snippet_yml, snippet_data, sysbuild) snippets.paths.add(snippet_yml) def load_snippet_yml(snippet_yml: Path) -> dict: diff --git a/share/sysbuild/cmake/modules/sysbuild_default.cmake b/share/sysbuild/cmake/modules/sysbuild_default.cmake index 2d45bc1d934..f3ffa81bb28 100644 --- a/share/sysbuild/cmake/modules/sysbuild_default.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_default.cmake @@ -15,6 +15,7 @@ include(zephyr_module) include(boards) include(shields) include(hwm_v2) +include(sysbuild_snippets) include(sysbuild_kconfig) include(native_simulator_sb_extensions) include(sysbuild_images) diff --git a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake index 41094454116..00a2a58d2e4 100644 --- a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake @@ -105,6 +105,14 @@ set(KCONFIG_NAMESPACE SB_CONFIG) if(EXISTS ${APP_DIR}/Kconfig.sysbuild) set(KCONFIG_ROOT ${APP_DIR}/Kconfig.sysbuild) endif() + +# Apply any EXTRA_CONF_FILE variables from snippets +if(TARGET snippets_scope) + get_property(snippets_EXTRA_CONF_FILE TARGET snippets_scope PROPERTY SB_EXTRA_CONF_FILE) + list(APPEND EXTRA_CONF_FILE ${snippets_EXTRA_CONF_FILE}) +endif() + include(${ZEPHYR_BASE}/cmake/modules/kconfig.cmake) set(CONF_FILE) set(EXTRA_CONF_FILE) +set(SB_EXTRA_CONF_FILE) diff --git a/share/sysbuild/cmake/modules/sysbuild_root.cmake b/share/sysbuild/cmake/modules/sysbuild_root.cmake index ca9f37238cf..19a7034c80c 100644 --- a/share/sysbuild/cmake/modules/sysbuild_root.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_root.cmake @@ -31,6 +31,7 @@ zephyr_get(BOARD_ROOT MERGE) zephyr_get(SOC_ROOT MERGE) zephyr_get(ARCH_ROOT MERGE) zephyr_get(SCA_ROOT MERGE) +zephyr_get(SNIPPET_ROOT MERGE) # Convert paths to absolute, relative from APP_DIR zephyr_file(APPLICATION_ROOT MODULE_EXT_ROOT BASE_DIR ${APP_DIR}) @@ -38,6 +39,7 @@ zephyr_file(APPLICATION_ROOT BOARD_ROOT BASE_DIR ${APP_DIR}) zephyr_file(APPLICATION_ROOT SOC_ROOT BASE_DIR ${APP_DIR}) zephyr_file(APPLICATION_ROOT ARCH_ROOT BASE_DIR ${APP_DIR}) zephyr_file(APPLICATION_ROOT SCA_ROOT BASE_DIR ${APP_DIR}) +zephyr_file(APPLICATION_ROOT SNIPPET_ROOT BASE_DIR ${APP_DIR}) # Sysbuild must ensure any locally defined variables in sysbuild/CMakeLists.txt # have been added to the cache in order for the settings to propagate to images. @@ -61,3 +63,7 @@ endif() if(DEFINED SCA_ROOT) set(SCA_ROOT ${SCA_ROOT} CACHE PATH "Sysbuild adjusted SCA_ROOT" FORCE) endif() + +if(DEFINED SNIPPET_ROOT) + set(SNIPPET_ROOT ${SNIPPET_ROOT} CACHE PATH "Sysbuild adjusted SNIPPET_ROOT" FORCE) +endif() diff --git a/share/sysbuild/cmake/modules/sysbuild_snippets.cmake b/share/sysbuild/cmake/modules/sysbuild_snippets.cmake new file mode 100644 index 00000000000..32ece9f593a --- /dev/null +++ b/share/sysbuild/cmake/modules/sysbuild_snippets.cmake @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_get(SB_SNIPPET) +if(NOT SB_SNIPPET AND SNIPPET) + set_ifndef(SB_SNIPPET ${SNIPPET}) +endif() +set(SNIPPET_NAMESPACE SB_SNIPPET) +set(SNIPPET_PYTHON_EXTRA_ARGS --sysbuild) +set(SNIPPET_APP_DIR ${APP_DIR}) +include(${ZEPHYR_BASE}/cmake/modules/snippets.cmake) + +set(SNIPPET_NAMESPACE) +set(SNIPPET_PYTHON_EXTRA_ARGS) +set(SNIPPET_APP_DIR)