Skip to content

Commit e9ae3e6

Browse files
committed
sysbuild: Autogenerate secondary slot
Generation of the secendary slot is not trivial if one considers all of the configuration options available in sysbuild, such as: - per-image overrides through variables - setting FILE_SUFFIX - additional images appearing as a result of enabling SNIPPETs Achieving this through the regular approach (adding images), requires enumerating all slotted images in CMake files, applying the same set of overlays manually, which partially makes the configurability provided by sysbuild nearly unusable for the secondary slot. Since sysbuild is an entity that is aware of the images being built and their configuration parameters, this commit tries to rerun the image build if the user provides the <image>_slot_b.overlay. There is no need to add Kconfig overlays as the main point of slotted images is that exactly two identical configurations are built, with only one difference - the start address, controlled through the zephyr,code-partition symbol. Ref: NCSDK-NONE Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 693769a commit e9ae3e6

File tree

1 file changed

+121
-52
lines changed

1 file changed

+121
-52
lines changed

share/sysbuild/cmake/modules/sysbuild_extensions.cmake

Lines changed: 121 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ endfunction()
216216
# and debugging.
217217
#
218218
function(ExternalZephyrProject_Add)
219-
set(app_types MAIN BOOTLOADER)
219+
set(app_types MAIN BOOTLOADER SLOT_B)
220220
cmake_parse_arguments(ZBUILD "" "APPLICATION;BOARD;BOARD_REVISION;SOURCE_DIR;APP_TYPE;BUILD_ONLY" "" ${ARGN})
221221

222222
if(ZBUILD_UNPARSED_ARGUMENTS)
@@ -226,9 +226,15 @@ function(ExternalZephyrProject_Add)
226226
)
227227
endif()
228228

229-
if(TARGET ${ZBUILD_APPLICATION})
229+
if("${ZBUILD_APP_TYPE}" STREQUAL "SLOT_B")
230+
set(app_target ${ZBUILD_APPLICATION}_slot_b)
231+
else()
232+
set(app_target ${ZBUILD_APPLICATION})
233+
endif()
234+
235+
if(TARGET ${app_target})
230236
message(FATAL_ERROR
231-
"ExternalZephyrProject_Add(APPLICATION ${ZBUILD_APPLICATION} ...) "
237+
"ExternalZephyrProject_Add(APPLICATION ${app_target} ...) "
232238
"already exists. Application names must be unique."
233239
)
234240
endif()
@@ -251,19 +257,58 @@ function(ExternalZephyrProject_Add)
251257
endif()
252258
set_property(
253259
DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}"
254-
APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION}
260+
APPEND PROPERTY sysbuild_images ${app_target}
255261
)
256262
set_property(
257263
GLOBAL
258-
APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION}
264+
APPEND PROPERTY sysbuild_images ${app_target}
259265
)
260266

261267
set(sysbuild_image_conf_dir ${APP_DIR}/sysbuild)
262268
set(sysbuild_image_name_conf_dir ${APP_DIR}/sysbuild/${ZBUILD_APPLICATION})
269+
270+
# There is no need to look for application slot "b" overlays.
271+
# It is enough to use values calculated for slot "a".
272+
if("${ZBUILD_APP_TYPE}" STREQUAL "SLOT_B")
273+
if(EXISTS ${sysbuild_image_name_conf_dir})
274+
set(${app_target}_APPLICATION_CONFIG_DIR ${sysbuild_image_name_conf_dir}
275+
CACHE INTERNAL "Application configuration dir controlled by sysbuild"
276+
)
277+
endif()
278+
279+
if (${ZBUILD_APPLICATION}_EXTRA_CONF_FILE)
280+
set(${app_target}_EXTRA_CONF_FILE ${${ZBUILD_APPLICATION}_EXTRA_CONF_FILE}
281+
CACHE INTERNAL "Kconfig fragment defined by main application"
282+
)
283+
endif()
284+
285+
if (DEFINED ${ZBUILD_APPLICATION}_DTC_OVERLAY_FILE)
286+
set(${app_target}_DTC_OVERLAY_FILE "${${ZBUILD_APPLICATION}_DTC_OVERLAY_FILE}"
287+
CACHE INTERNAL "devicetree overlay file defined by main application"
288+
)
289+
endif()
290+
291+
# Append <ZBUILD_APPLICATION>_slot_b.overlay.
292+
set(sysbuild_image_slot_dts_overlay ${sysbuild_image_conf_dir}/${app_target}.overlay)
293+
if (NOT EXISTS ${sysbuild_image_slot_dts_overlay})
294+
# Slot "b" not configured for the application.
295+
return()
296+
else()
297+
if (DEFINED ${ZBUILD_APPLICATION}_EXTRA_DTC_OVERLAY_FILE)
298+
set(${app_target}_EXTRA_DTC_OVERLAY_FILE "${${ZBUILD_APPLICATION}_EXTRA_DTC_OVERLAY_FILE};${sysbuild_image_slot_dts_overlay}"
299+
CACHE INTERNAL "additional devicetree overlay file defined by main application"
300+
)
301+
else()
302+
set(${app_target}_EXTRA_DTC_OVERLAY_FILE ${sysbuild_image_slot_dts_overlay}
303+
CACHE INTERNAL "additional devicetree overlay file defined by main application"
304+
)
305+
endif()
306+
endif()
307+
263308
# User defined `-D<image>_CONF_FILE=<file.conf>` takes precedence over anything else.
264-
if (NOT ${ZBUILD_APPLICATION}_CONF_FILE)
309+
elseif (NOT ${ZBUILD_APPLICATION}_CONF_FILE)
265310
if(EXISTS ${sysbuild_image_name_conf_dir})
266-
set(${ZBUILD_APPLICATION}_APPLICATION_CONFIG_DIR ${sysbuild_image_name_conf_dir}
311+
set(${app_target}_APPLICATION_CONFIG_DIR ${sysbuild_image_name_conf_dir}
267312
CACHE INTERNAL "Application configuration dir controlled by sysbuild"
268313
)
269314
endif()
@@ -275,18 +320,18 @@ function(ExternalZephyrProject_Add)
275320
NAMES ${ZBUILD_APPLICATION}.conf SUFFIX ${FILE_SUFFIX}
276321
)
277322

278-
if (NOT (${ZBUILD_APPLICATION}_OVERLAY_CONFIG OR ${ZBUILD_APPLICATION}_EXTRA_CONF_FILE)
323+
if (NOT (${app_target}_OVERLAY_CONFIG OR ${app_target}_EXTRA_CONF_FILE)
279324
AND EXISTS ${sysbuild_image_conf_fragment}
280325
)
281-
set(${ZBUILD_APPLICATION}_EXTRA_CONF_FILE ${sysbuild_image_conf_fragment}
326+
set(${app_target}_EXTRA_CONF_FILE ${sysbuild_image_conf_fragment}
282327
CACHE INTERNAL "Kconfig fragment defined by main application"
283328
)
284329
endif()
285330

286331
# Check for overlay named <ZBUILD_APPLICATION>.overlay.
287332
set(sysbuild_image_dts_overlay ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}.overlay)
288-
if (NOT ${ZBUILD_APPLICATION}_DTC_OVERLAY_FILE AND EXISTS ${sysbuild_image_dts_overlay})
289-
set(${ZBUILD_APPLICATION}_DTC_OVERLAY_FILE ${sysbuild_image_dts_overlay}
333+
if (NOT ${app_target}_DTC_OVERLAY_FILE AND EXISTS ${sysbuild_image_dts_overlay})
334+
set(${app_target}_DTC_OVERLAY_FILE ${sysbuild_image_dts_overlay}
290335
CACHE INTERNAL "devicetree overlay file defined by main application"
291336
)
292337
endif()
@@ -295,10 +340,16 @@ function(ExternalZephyrProject_Add)
295340
# Update ROOT variables with relative paths to use absolute paths based on
296341
# the source application directory.
297342
foreach(type MODULE_EXT BOARD SOC ARCH SCA)
298-
if(DEFINED CACHE{${ZBUILD_APPLICATION}_${type}_ROOT} AND NOT IS_ABSOLUTE $CACHE{${ZBUILD_APPLICATION}_${type}_ROOT})
299-
set(rel_path $CACHE{${ZBUILD_APPLICATION}_${type}_ROOT})
300-
cmake_path(ABSOLUTE_PATH rel_path BASE_DIRECTORY "${ZBUILD_SOURCE_DIR}" NORMALIZE OUTPUT_VARIABLE abs_path)
301-
set(${ZBUILD_APPLICATION}_${type}_ROOT ${abs_path} CACHE PATH "Sysbuild adjusted absolute path" FORCE)
343+
if("${ZBUILD_APP_TYPE}" STREQUAL "SLOT_B")
344+
if(DEFINED CACHE{${ZBUILD_APPLICATION}_${type}_ROOT})
345+
set(${app_target}_${type}_ROOT $CACHE{${ZBUILD_APPLICATION}_${type}_ROOT} CACHE PATH "Sysbuild adjusted absolute path" FORCE)
346+
endif()
347+
else()
348+
if(DEFINED CACHE{${app_target}_${type}_ROOT} AND NOT IS_ABSOLUTE $CACHE{${app_target}_${type}_ROOT})
349+
set(rel_path $CACHE{${app_target}_${type}_ROOT})
350+
cmake_path(ABSOLUTE_PATH rel_path BASE_DIRECTORY "${ZBUILD_SOURCE_DIR}" NORMALIZE OUTPUT_VARIABLE abs_path)
351+
set(${app_target}_${type}_ROOT ${abs_path} CACHE PATH "Sysbuild adjusted absolute path" FORCE)
352+
endif()
302353
endif()
303354
endforeach()
304355

@@ -311,7 +362,7 @@ function(ExternalZephyrProject_Add)
311362
CMAKE_VERBOSE_MAKEFILE
312363
)
313364

314-
set(sysbuild_cache_file ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}_sysbuild_cache.txt)
365+
set(sysbuild_cache_file ${CMAKE_BINARY_DIR}/${app_target}_sysbuild_cache.txt)
315366

316367
set(shared_cmake_vars_argument)
317368
foreach(shared_var ${shared_cmake_variables_list})
@@ -328,37 +379,43 @@ function(ExternalZephyrProject_Add)
328379
endif()
329380
endforeach()
330381

331-
foreach(kconfig_target
332-
menuconfig
333-
hardenconfig
334-
guiconfig
335-
$CACHE{EXTRA_KCONFIG_TARGETS}
336-
)
382+
if("${ZBUILD_APP_TYPE}" STREQUAL "SLOT_B")
383+
# There is no need for Kconfig targets in slot "b".
384+
# Kconfigs should be configured in slot "a".
385+
set(image_extra_kconfig_targets )
386+
else()
387+
foreach(kconfig_target
388+
menuconfig
389+
hardenconfig
390+
guiconfig
391+
$CACHE{EXTRA_KCONFIG_TARGETS}
392+
)
337393

338-
if(NOT ZBUILD_APP_TYPE STREQUAL "MAIN")
339-
set(image_prefix "${ZBUILD_APPLICATION}_")
340-
endif()
394+
if(NOT ZBUILD_APP_TYPE STREQUAL "MAIN")
395+
set(image_prefix "${ZBUILD_APPLICATION}_")
396+
endif()
341397

342-
add_custom_target(${image_prefix}${kconfig_target}
343-
${CMAKE_MAKE_PROGRAM} ${kconfig_target}
344-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}
345-
USES_TERMINAL
346-
)
347-
endforeach()
398+
add_custom_target(${image_prefix}${kconfig_target}
399+
${CMAKE_MAKE_PROGRAM} ${kconfig_target}
400+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}
401+
USES_TERMINAL
402+
)
403+
endforeach()
348404

349-
set(list_separator ",")
350-
set(image_extra_kconfig_targets "-DEXTRA_KCONFIG_TARGETS=$CACHE{EXTRA_KCONFIG_TARGETS}")
351-
string(REPLACE ";" "${list_separator}" image_extra_kconfig_targets "${image_extra_kconfig_targets}")
352-
foreach(target $CACHE{EXTRA_KCONFIG_TARGETS})
353-
list(APPEND image_extra_kconfig_targets
354-
-DEXTRA_KCONFIG_TARGET_COMMAND_FOR_${target}=$CACHE{EXTRA_KCONFIG_TARGET_COMMAND_FOR_${target}}
355-
)
356-
endforeach()
405+
set(list_separator ",")
406+
set(image_extra_kconfig_targets "-DEXTRA_KCONFIG_TARGETS=$CACHE{EXTRA_KCONFIG_TARGETS}")
407+
string(REPLACE ";" "${list_separator}" image_extra_kconfig_targets "${image_extra_kconfig_targets}")
408+
foreach(target $CACHE{EXTRA_KCONFIG_TARGETS})
409+
list(APPEND image_extra_kconfig_targets
410+
-DEXTRA_KCONFIG_TARGET_COMMAND_FOR_${target}=$CACHE{EXTRA_KCONFIG_TARGET_COMMAND_FOR_${target}}
411+
)
412+
endforeach()
413+
endif()
357414

358415
include(ExternalProject)
359-
set(application_binary_dir ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION})
416+
set(application_binary_dir ${CMAKE_BINARY_DIR}/${app_target})
360417
ExternalProject_Add(
361-
${ZBUILD_APPLICATION}
418+
${app_target}
362419
SOURCE_DIR ${ZBUILD_SOURCE_DIR}
363420
BINARY_DIR ${application_binary_dir}
364421
CONFIGURE_COMMAND ""
@@ -372,25 +429,25 @@ function(ExternalZephyrProject_Add)
372429
BUILD_ALWAYS True
373430
USES_TERMINAL_BUILD True
374431
)
375-
set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY APP_TYPE ${ZBUILD_APP_TYPE})
376-
set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY CONFIG
432+
set_property(TARGET ${app_target} PROPERTY APP_TYPE ${ZBUILD_APP_TYPE})
433+
set_property(TARGET ${app_target} PROPERTY CONFIG
377434
"# sysbuild controlled configuration settings\n"
378435
)
379-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES CACHE_FILE ${sysbuild_cache_file})
380-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES KCONFIG_BINARY_DIR
436+
set_target_properties(${app_target} PROPERTIES CACHE_FILE ${sysbuild_cache_file})
437+
set_target_properties(${app_target} PROPERTIES KCONFIG_BINARY_DIR
381438
${application_binary_dir}/Kconfig
382439
)
383440
if("${ZBUILD_APP_TYPE}" STREQUAL "MAIN")
384-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES MAIN_APP True)
441+
set_target_properties(${app_target} PROPERTIES MAIN_APP True)
385442
endif()
386443

387444
set(image_default "${CMAKE_SOURCE_DIR}/image_configurations/ALL_image_default.cmake")
388445

389-
if(DEFINED ZBUILD_APP_TYPE)
446+
if(DEFINED ZBUILD_APP_TYPE AND NOT ZBUILD_APP_TYPE STREQUAL "SLOT_B")
390447
list(APPEND image_default "${CMAKE_SOURCE_DIR}/image_configurations/${ZBUILD_APP_TYPE}_image_default.cmake")
391448
endif()
392449

393-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES IMAGE_CONF_SCRIPT "${image_default}")
450+
set_target_properties(${app_target} PROPERTIES IMAGE_CONF_SCRIPT "${image_default}")
394451

395452
if(DEFINED ZBUILD_BOARD)
396453
# Only set image specific board if provided.
@@ -407,15 +464,15 @@ function(ExternalZephyrProject_Add)
407464
list(REMOVE_AT split_board_qualifiers 0)
408465
list(PREPEND split_board_qualifiers ${target_board})
409466
string(REPLACE ";" "/" board_qualifiers "${split_board_qualifiers}")
410-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${board_qualifiers})
467+
set_target_properties(${app_target} PROPERTIES BOARD ${board_qualifiers})
411468
set(split_board_qualifiers)
412469
set(board_qualifiers)
413470
else()
414471
# Legacy HWMv1 support, version goes at end
415-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${ZBUILD_BOARD}@${ZBUILD_BOARD_REVISION})
472+
set_target_properties(${app_target} PROPERTIES BOARD ${ZBUILD_BOARD}@${ZBUILD_BOARD_REVISION})
416473
endif()
417474
else()
418-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${ZBUILD_BOARD})
475+
set_target_properties(${app_target} PROPERTIES BOARD ${ZBUILD_BOARD})
419476
endif()
420477
elseif(DEFINED ZBUILD_BOARD_REVISION)
421478
message(FATAL_ERROR
@@ -425,7 +482,19 @@ function(ExternalZephyrProject_Add)
425482
endif()
426483

427484
if(DEFINED ZBUILD_BUILD_ONLY)
428-
set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BUILD_ONLY ${ZBUILD_BUILD_ONLY})
485+
set_target_properties(${app_target} PROPERTIES BUILD_ONLY ${ZBUILD_BUILD_ONLY})
486+
endif()
487+
488+
set(sysbuild_image_slot_b_dts_overlay ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}_slot_b.overlay)
489+
if (EXISTS ${sysbuild_image_slot_b_dts_overlay} AND NOT "${ZBUILD_APP_TYPE}" STREQUAL "SLOT_B")
490+
ExternalZephyrProject_Add(
491+
APPLICATION ${ZBUILD_APPLICATION}
492+
BOARD ${ZBUILD_BOARD}
493+
BOARD_REVISION ${ZBUILD_BOARD_REVISION}
494+
SOURCE_DIR ${ZBUILD_SOURCE_DIR}
495+
APP_TYPE "SLOT_B"
496+
BUILD_ONLY ${ZBUILD_BUILD_ONLY}
497+
)
429498
endif()
430499
endfunction()
431500

0 commit comments

Comments
 (0)