sysbuild: split running of CMake from ExternalZephyrProject_add()

Split running CMake from ExternalZephyrProject_add().

This will allow systems to define all Zephyr projects and then at later
stages run the CMake configure stage.

This makes it both cleaner when CMake is invoked as well as prepare for
future work where images could be depending on CMake outcome from other
projects.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
This commit is contained in:
Jamie McCrae 2023-02-20 09:55:14 +00:00 committed by Carles Cufí
parent 8cc716792a
commit 631fa63610
2 changed files with 128 additions and 68 deletions

View file

@ -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)

View file

@ -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 <image>_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 <image>_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 <name>)
#
# 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>: Name of the application.
#
function(ExternalZephyrProject_Cmake)
cmake_parse_arguments(ZCMAKE "" "APPLICATION" "" ${ARGN})
if(ZBUILD_UNPARSED_ARGUMENTS)
message(FATAL_ERROR
"ExternalZephyrProject_Cmake(${ARGV0} <val> ...) 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 <image>_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()