diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index d7b9d15f4e7..7bbfe138760 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -26,62 +26,12 @@ project(sysbuild LANGUAGES) get_filename_component(APP_DIR ${APP_DIR} ABSOLUTE) get_filename_component(app_name ${APP_DIR} NAME) - -# Include zephyr modules generated sysbuild CMake file. -foreach(SYSBUILD_CURRENT_MODULE_NAME ${SYSBUILD_MODULE_NAMES}) - # Note the second, binary_dir parameter requires the added - # subdirectory to have its own, local cmake target(s). If not then - # this binary_dir is created but stays empty. Object files land in - # the main binary dir instead. - # https://cmake.org/pipermail/cmake/2019-June/069547.html - zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${SYSBUILD_CURRENT_MODULE_NAME}) - if(NOT ${SYSBUILD_${MODULE_NAME_UPPER}_CMAKE_DIR} STREQUAL "") - set(SYSBUILD_CURRENT_MODULE_DIR ${SYSBUILD_${MODULE_NAME_UPPER}_MODULE_DIR}) - set(SYSBUILD_CURRENT_CMAKE_DIR ${SYSBUILD_${MODULE_NAME_UPPER}_CMAKE_DIR}) - add_subdirectory(${SYSBUILD_CURRENT_CMAKE_DIR} ${CMAKE_BINARY_DIR}/modules/${SYSBUILD_CURRENT_MODULE_NAME}) - endif() -endforeach() -# Done processing modules, clear SYSBUILD_CURRENT_MODULE_DIR and SYSBUILD_CURRENT_CMAKE_DIR. -set(SYSBUILD_CURRENT_MODULE_DIR) -set(SYSBUILD_CURRENT_CMAKE_DIR) - -# This adds the primary application to the build. -ExternalZephyrProject_Add( - APPLICATION ${app_name} - SOURCE_DIR ${APP_DIR} - APP_TYPE MAIN -) set(DEFAULT_IMAGE "${app_name}") -add_subdirectory(bootloader) - -# This allows for board and app specific images to be included. -include(${BOARD_DIR}/sysbuild.cmake OPTIONAL) +# This is where all Zephyr applications are added to the multi-image build. +sysbuild_add_subdirectory(images) -# This allows image specific sysbuild.cmake to be processed. get_property(IMAGES GLOBAL PROPERTY sysbuild_images) -list(LENGTH IMAGES images_length) -while(NOT "${images_length}" EQUAL "${processed_length}") - foreach(image ${IMAGES}) - if(NOT image IN_LIST images_sysbuild_processed) - ExternalProject_Get_property(${image} SOURCE_DIR) - include(${SOURCE_DIR}/sysbuild.cmake OPTIONAL) - list(APPEND images_sysbuild_processed ${image}) - endif() - endforeach() - - get_property(IMAGES GLOBAL PROPERTY sysbuild_images) - list(LENGTH IMAGES images_length) - list(LENGTH images_sysbuild_processed processed_length_new) - - # Check for any duplicate entries in image names to prevent an infinite loop - if("${processed_length_new}" EQUAL "${processed_length}") - # Image length was different than processed length, but no new images are processed. - message(FATAL_ERROR "A duplicate image name was provided, image names must be unique.") - endif() - set(processed_length ${processed_length_new}) -endwhile() - sysbuild_module_call(PRE_CMAKE MODULES ${SYSBUILD_MODULE_NAMES} IMAGES ${IMAGES}) sysbuild_images_order(IMAGES_CONFIGURATION_ORDER CONFIGURE IMAGES ${IMAGES}) foreach(image ${IMAGES_CONFIGURATION_ORDER}) diff --git a/share/sysbuild/Kconfig b/share/sysbuild/Kconfig index 74c46ba2f71..b08db20e5df 100644 --- a/share/sysbuild/Kconfig +++ b/share/sysbuild/Kconfig @@ -39,4 +39,4 @@ config WARN_DEPRECATED Print a warning when the Kconfig tree is parsed if any deprecated features are enabled. -rsource "bootloader/Kconfig" +rsource "images/Kconfig" diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index fd776f8e4ed..a3838415eee 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -145,6 +145,13 @@ function(ExternalZephyrProject_Add) ) endif() + if(TARGET ${ZBUILD_APPLICATION}) + message(FATAL_ERROR + "ExternalZephyrProject_Add(APPLICATION ${ZBUILD_APPLICATION} ...) " + "already exists. Application names must be unique." + ) + endif() + if(DEFINED ZBUILD_APP_TYPE) if(NOT ZBUILD_APP_TYPE IN_LIST app_types) message(FATAL_ERROR @@ -155,6 +162,16 @@ function(ExternalZephyrProject_Add) endif() + if(NOT DEFINED SYSBUILD_CURRENT_SOURCE_DIR) + message(FATAL_ERROR + "ExternalZephyrProject_Add(${ARGV0} ...) must not be called outside of" + " sysbuild_add_subdirectory(). SYSBUILD_CURRENT_SOURCE_DIR is undefined." + ) + endif() + set_property( + DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}" + APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION} + ) set_property( GLOBAL APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION} @@ -566,6 +583,45 @@ function(set_config_string image setting value) set_property(TARGET ${image} APPEND_STRING PROPERTY CONFIG "${setting}=\"${value}\"\n") endfunction() +# Usage: +# sysbuild_add_subdirectory( []) +# +# This function extends the standard add_subdirectory() command with additional, +# recursive processing of the sysbuild images added via . +# +# After exiting , this function will take every image added so far, +# and include() its sysbuild.cmake file (if found). If more images get added at +# this stage, their sysbuild.cmake files will be included as well, and so on. +# This continues until all expected images have been added, before returning. +# +function(sysbuild_add_subdirectory source_dir) + if(ARGC GREATER 2) + message(FATAL_ERROR + "sysbuild_add_subdirectory(...) called with incorrect number of arguments" + " (expected at most 2, got ${ARGC})" + ) + endif() + set(binary_dir ${ARGV1}) + + # Update SYSBUILD_CURRENT_SOURCE_DIR in this scope, to support nesting + # of sysbuild_add_subdirectory() and even regular add_subdirectory(). + cmake_path(ABSOLUTE_PATH source_dir NORMALIZE OUTPUT_VARIABLE SYSBUILD_CURRENT_SOURCE_DIR) + add_subdirectory(${source_dir} ${binary_dir}) + + while(TRUE) + get_property(added_images DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}" PROPERTY sysbuild_images) + if(NOT added_images) + break() + endif() + set_property(DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}" PROPERTY sysbuild_images "") + + foreach(image ${added_images}) + ExternalProject_Get_property(${image} SOURCE_DIR) + include(${SOURCE_DIR}/sysbuild.cmake OPTIONAL) + endforeach() + endwhile() +endfunction() + # Usage: # sysbuild_add_dependencies( [ ...]) # diff --git a/share/sysbuild/images/CMakeLists.txt b/share/sysbuild/images/CMakeLists.txt new file mode 100644 index 00000000000..2b553181d06 --- /dev/null +++ b/share/sysbuild/images/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright (c) 2021-2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# The primary application is the first image to be added to the build, so that +# it is available while processing the remaining images. +ExternalZephyrProject_Add( + APPLICATION ${DEFAULT_IMAGE} + SOURCE_DIR ${APP_DIR} + APP_TYPE MAIN +) + +# This allows for MCUboot to be included. +sysbuild_add_subdirectory(bootloader) + +# Include zephyr modules generated sysbuild CMake file. +foreach(SYSBUILD_CURRENT_MODULE_NAME ${SYSBUILD_MODULE_NAMES}) + # Note the second, binary_dir parameter requires the added + # subdirectory to have its own, local cmake target(s). If not then + # this binary_dir is created but stays empty. Object files land in + # the main binary dir instead. + # https://cmake.org/pipermail/cmake/2019-June/069547.html + zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${SYSBUILD_CURRENT_MODULE_NAME}) + if(NOT ${SYSBUILD_${MODULE_NAME_UPPER}_CMAKE_DIR} STREQUAL "") + set(SYSBUILD_CURRENT_MODULE_DIR ${SYSBUILD_${MODULE_NAME_UPPER}_MODULE_DIR}) + set(SYSBUILD_CURRENT_CMAKE_DIR ${SYSBUILD_${MODULE_NAME_UPPER}_CMAKE_DIR}) + sysbuild_add_subdirectory(${SYSBUILD_CURRENT_CMAKE_DIR} + ${CMAKE_BINARY_DIR}/modules/${SYSBUILD_CURRENT_MODULE_NAME}) + endif() +endforeach() +# Done processing modules, clear SYSBUILD_CURRENT_MODULE_DIR and SYSBUILD_CURRENT_CMAKE_DIR. +set(SYSBUILD_CURRENT_MODULE_DIR) +set(SYSBUILD_CURRENT_CMAKE_DIR) + +# This allows for board specific images to be included. +sysbuild_add_subdirectory(boards) diff --git a/share/sysbuild/images/Kconfig b/share/sysbuild/images/Kconfig new file mode 100644 index 00000000000..616b0a7c23d --- /dev/null +++ b/share/sysbuild/images/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2021-2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +rsource "bootloader/Kconfig" diff --git a/share/sysbuild/images/boards/CMakeLists.txt b/share/sysbuild/images/boards/CMakeLists.txt new file mode 100644 index 00000000000..663bfc8d10b --- /dev/null +++ b/share/sysbuild/images/boards/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2021-2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +include(${BOARD_DIR}/sysbuild.cmake OPTIONAL) diff --git a/share/sysbuild/bootloader/CMakeLists.txt b/share/sysbuild/images/bootloader/CMakeLists.txt similarity index 100% rename from share/sysbuild/bootloader/CMakeLists.txt rename to share/sysbuild/images/bootloader/CMakeLists.txt diff --git a/share/sysbuild/bootloader/Kconfig b/share/sysbuild/images/bootloader/Kconfig similarity index 100% rename from share/sysbuild/bootloader/Kconfig rename to share/sysbuild/images/bootloader/Kconfig