diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index f939e73cafe..f0ee3763186 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -91,4 +91,7 @@ while(NOT "${images_length}" EQUAL "${processed_length}") set(processed_length ${processed_length_new}) endwhile() +foreach(image ${IMAGES}) + ExternalZephyrProject_Cmake(APPLICATION ${image}) +endforeach() include(cmake/domains.cmake) diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index 9ae0daa749f..843ff2060e7 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Nordic Semiconductor +# Copyright (c) 2021-2023 Nordic Semiconductor # # SPDX-License-Identifier: Apache-2.0 @@ -178,44 +178,6 @@ function(ExternalZephyrProject_Add) set(sysbuild_cache_file ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}_sysbuild_cache.txt) - get_cmake_property(sysbuild_cache CACHE_VARIABLES) - foreach(var_name ${sysbuild_cache}) - if(NOT "${var_name}" MATCHES "^CMAKE_.*") - # We don't want to pass internal CMake variables. - # Required CMake variable to be passed, like CMAKE_BUILD_TYPE must be - # passed using `-D` on command invocation. - get_property(var_type CACHE ${var_name} PROPERTY TYPE) - set(cache_entry "${var_name}:${var_type}=$CACHE{${var_name}}") - string(REPLACE ";" "\;" cache_entry "${cache_entry}") - list(APPEND sysbuild_cache_strings "${cache_entry}\n") - endif() - endforeach() - list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${ZBUILD_APPLICATION}\n") - - if(ZBUILD_MAIN_APP) - list(APPEND sysbuild_cache_strings "SYSBUILD_MAIN_APP:BOOL=True\n") - endif() - - if(DEFINED ZBUILD_BOARD) - # Only set image specific board if provided. - # The sysbuild BOARD is exported through sysbuild cache, and will be used - # unless _BOARD is defined. - if(DEFINED ZBUILD_BOARD_REVISION) - # Use provided board revision - list(APPEND sysbuild_cache_strings "${ZBUILD_APPLICATION}_BOARD:STRING=${ZBUILD_BOARD}@${ZBUILD_BOARD_REVISION}\n") - else() - list(APPEND sysbuild_cache_strings "${ZBUILD_APPLICATION}_BOARD:STRING=${ZBUILD_BOARD}\n") - endif() - elseif(DEFINED ZBUILD_BOARD_REVISION) - message(FATAL_ERROR - "ExternalZephyrProject_Add(... BOARD_REVISION ${ZBUILD_BOARD_REVISION})" - " requires BOARD." - ) - endif() - - file(WRITE ${sysbuild_cache_file}.tmp ${sysbuild_cache_strings}) - zephyr_file_copy(${sysbuild_cache_file}.tmp ${sysbuild_cache_file} ONLY_IF_DIFFERENT) - set(shared_cmake_vars_argument) foreach(shared_var ${shared_cmake_variables_list}) if(DEFINED CACHE{${ZBUILD_APPLICATION}_${shared_var}}) @@ -231,34 +193,6 @@ function(ExternalZephyrProject_Add) endif() endforeach() - set(image_banner "* Running CMake for ${ZBUILD_APPLICATION} *") - string(LENGTH "${image_banner}" image_banner_width) - string(REPEAT "*" ${image_banner_width} image_banner_header) - message(STATUS "\n ${image_banner_header}\n" - " ${image_banner}\n" - " ${image_banner_header}\n" - ) - - execute_process( - COMMAND ${CMAKE_COMMAND} - -G${CMAKE_GENERATOR} - -DSYSBUILD:BOOL=True - -DSYSBUILD_CACHE:FILEPATH=${sysbuild_cache_file} - ${shared_cmake_vars_argument} - -B${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION} - -S${ZBUILD_SOURCE_DIR} - RESULT_VARIABLE return_val - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - - if(return_val) - message(FATAL_ERROR - "CMake configure failed for Zephyr project: ${ZBUILD_APPLICATION}\n" - "Location: ${ZBUILD_SOURCE_DIR}" - ) - endif() - load_cache(IMAGE ${ZBUILD_APPLICATION} BINARY_DIR ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}) - foreach(kconfig_target menuconfig hardenconfig @@ -282,10 +216,133 @@ function(ExternalZephyrProject_Add) SOURCE_DIR ${ZBUILD_SOURCE_DIR} BINARY_DIR ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION} CONFIGURE_COMMAND "" + CMAKE_ARGS -DSYSBUILD:BOOL=True + -DSYSBUILD_CACHE:FILEPATH=${sysbuild_cache_file} + ${shared_cmake_vars_argument} BUILD_COMMAND ${CMAKE_COMMAND} --build . INSTALL_COMMAND "" BUILD_ALWAYS True USES_TERMINAL_BUILD True ) - import_kconfig(CONFIG_ ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}/zephyr/.config TARGET ${ZBUILD_APPLICATION}) + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES CACHE_FILE ${sysbuild_cache_file}) + if(ZBUILD_MAIN_APP) + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES MAIN_APP True) + endif() + + if(DEFINED ZBUILD_BOARD) + # Only set image specific board if provided. + # The sysbuild BOARD is exported through sysbuild cache, and will be used + # unless _BOARD is defined. + if(DEFINED ZBUILD_BOARD_REVISION) + # Use provided board revision + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${ZBUILD_BOARD}@${ZBUILD_BOARD_REVISION}) + else() + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${ZBUILD_BOARD}) + endif() + elseif(DEFINED ZBUILD_BOARD_REVISION) + message(FATAL_ERROR + "ExternalZephyrProject_Add(... BOARD_REVISION ${ZBUILD_BOARD_REVISION})" + " requires BOARD." + ) + elseif(DEFINED BOARD_REVISION) + # Include build revision for target image + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${BOARD}@${BOARD_REVISION}) + endif() +endfunction() + +# Usage: +# ExternalZephyrProject_Cmake(APPLICATION ) +# +# This function invokes the CMake configure step on an external Zephyr project +# which has been added at an earlier stage using `ExternalZephyrProject_Add()` +# +# If the application is not due to ExternalZephyrProject_Add() being called, +# then an error is raised. +# +# APPLICATION: : Name of the application. +# +function(ExternalZephyrProject_Cmake) + cmake_parse_arguments(ZCMAKE "" "APPLICATION" "" ${ARGN}) + + if(ZBUILD_UNPARSED_ARGUMENTS) + message(FATAL_ERROR + "ExternalZephyrProject_Cmake(${ARGV0} ...) given unknown arguments:" + " ${ZBUILD_UNPARSED_ARGUMENTS}" + ) + endif() + + if(NOT DEFINED ZCMAKE_APPLICATION) + message(FATAL_ERROR "Missing required argument: APPLICATION") + endif() + + if(NOT TARGET ${ZCMAKE_APPLICATION}) + message(FATAL_ERROR + "${ZCMAKE_APPLICATION} does not exists. Remember to call " + "ExternalZephyrProject_Add(APPLICATION ${ZCMAKE_APPLICATION} ...) first." + ) + endif() + + set(image_banner "* Running CMake for ${ZCMAKE_APPLICATION} *") + string(LENGTH "${image_banner}" image_banner_width) + string(REPEAT "*" ${image_banner_width} image_banner_header) + message(STATUS "\n ${image_banner_header}\n" + " ${image_banner}\n" + " ${image_banner_header}\n" + ) + + ExternalProject_Get_Property(${ZCMAKE_APPLICATION} SOURCE_DIR BINARY_DIR CMAKE_ARGS) + get_target_property(${ZCMAKE_APPLICATION}_CACHE_FILE ${ZCMAKE_APPLICATION} CACHE_FILE) + get_target_property(${ZCMAKE_APPLICATION}_BOARD ${ZCMAKE_APPLICATION} BOARD) + get_target_property(${ZCMAKE_APPLICATION}_MAIN_APP ${ZCMAKE_APPLICATION} MAIN_APP) + + get_cmake_property(sysbuild_cache CACHE_VARIABLES) + foreach(var_name ${sysbuild_cache}) + if(NOT "${var_name}" MATCHES "^CMAKE_.*") + # We don't want to pass internal CMake variables. + # Required CMake variable to be passed, like CMAKE_BUILD_TYPE must be + # passed using `-D` on command invocation. + get_property(var_type CACHE ${var_name} PROPERTY TYPE) + set(cache_entry "${var_name}:${var_type}=${${var_name}}") + string(REPLACE ";" "\;" cache_entry "${cache_entry}") + list(APPEND sysbuild_cache_strings "${cache_entry}\n") + endif() + endforeach() + list(APPEND sysbuild_cache_strings "SYSBUILD_NAME:STRING=${ZCMAKE_APPLICATION}\n") + + if(${ZCMAKE_APPLICATION}_MAIN_APP) + list(APPEND sysbuild_cache_strings "SYSBUILD_MAIN_APP:BOOL=True\n") + endif() + + if(${ZCMAKE_APPLICATION}_BOARD) + # Only set image specific board if provided. + # The sysbuild BOARD is exported through sysbuild cache, and will be used + # unless _BOARD is defined. + list(APPEND sysbuild_cache_strings + "${ZCMAKE_APPLICATION}_BOARD:STRING=${${ZCMAKE_APPLICATION}_BOARD}\n" + ) + endif() + + file(WRITE ${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp ${sysbuild_cache_strings}) + zephyr_file_copy(${${ZCMAKE_APPLICATION}_CACHE_FILE}.tmp + ${${ZCMAKE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT + ) + + execute_process( + COMMAND ${CMAKE_COMMAND} + -G${CMAKE_GENERATOR} + ${CMAKE_ARGS} + -B${BINARY_DIR} + -S${SOURCE_DIR} + RESULT_VARIABLE return_val + WORKING_DIRECTORY ${BINARY_DIR} + ) + + if(return_val) + message(FATAL_ERROR + "CMake configure failed for Zephyr project: ${ZCMAKE_APPLICATION}\n" + "Location: ${SOURCE_DIR}" + ) + endif() + load_cache(IMAGE ${ZCMAKE_APPLICATION} BINARY_DIR ${BINARY_DIR}) + import_kconfig(CONFIG_ ${BINARY_DIR}/zephyr/.config TARGET ${ZCMAKE_APPLICATION}) endfunction()