1.. _sysbuild_images: 2 3Sysbuild images 4############### 5 6Sysbuild can be used to add additional images to builds, these can be added by projects or boards 7though at present must be Zephyr applications. 8 9Methods of adding images 10************************ 11 12Images can be added to project or projects in various ways, multiple ways can be used 13simultaneously, they can be added in the following ways: 14 15Applications 16============ 17 18Applications can add sysbuild images using the ``sysbuild.cmake`` file in the application 19directory, the inclusion of images can be controlled with a ``Kconfig.sysbuild`` file in the 20application directory. 21 22Boards 23====== 24 25Boards can add sysbuild images by using the ``sysbuild.cmake`` file in the board directory, the 26inclusion of images can be controlled with a ``Kconfig.sysbuild`` file in the board directory. 27 28SoCs 29==== 30 31SoCs can add sysbuild images by using the ``sysbuild.cmake`` file in the soc directory. 32 33Modules 34======= 35 36:ref:`modules` can add sysbuild images with the ``sysbuild-cmake`` and ``sysbuild-kconfig`` 37options in a ``module.yml`` file, see :ref:`sysbuild_module_integration` for details. 38 39Adding images 40************* 41 42Images can be added in one of two ways: 43 44Single unchangeable image 45========================= 46 47With this setup, the image to be added is fixed to a specific application and cannot be changed 48(although it cannot be changed to another image, the version of the image itself can be changed by 49use of a west manifest bringing in a different version of the application repo or from an 50alternate source, assuming that the image is in it's own repository). 51 52.. note:: 53 54 This method should only be used if the image is locked to a specific interface and has no 55 extensibility. 56 57An example of how to create such an image, this assumes that a 58:ref:`Zephyr application has been created <application>`: 59 60.. tabs:: 61 62 .. group-tab:: ``Kconfig.sysbuild`` 63 64 .. code-block:: kconfig 65 66 config MY_IMAGE 67 bool "Include my amazing image" 68 help 69 If enabled, will include my amazing image in the build which does... 70 71 .. note:: 72 73 Remember to have ``source "share/sysbuild/Kconfig"`` in the file if this 74 is being applied in an application ``Kconfig.sysbuild`` file. 75 76 77 .. group-tab:: ``sysbuild.cmake`` 78 79 .. code-block:: cmake 80 81 if(SB_CONFIG_MY_IMAGE) 82 ExternalZephyrProject_Add( 83 APPLICATION my_image 84 SOURCE_DIR ${ZEPHYR_MY_IMAGE_MODULE_DIR}/path/to/my_image 85 ) 86 endif() 87 88Additional dependency ordering can be set here if needed, see 89:ref:`sysbuild_zephyr_application_dependencies` for details, image configuration can also be set 90here, see :ref:`sysbuild_images_config` for details. 91 92This image can be enabled when building with west like so: 93 94.. zephyr-app-commands:: 95 :tool: west 96 :zephyr-app: <app> 97 :board: nrf52840dk/nrf52840 98 :goals: build 99 :west-args: --sysbuild 100 :gen-args: -DSB_CONFIG_MY_IMAGE=y 101 :compact: 102 103Extensible changeable image 104=========================== 105 106With this setup, the image to be added can be one of any number of possible applications which the 107user has selection over, this list of selections can also be extended downstream to add additional 108options for out-of-tree specific applications that are not available in upstream Zephyr. This is 109more complex to create but is the preferred method for adding images to upstream Zephyr. 110 111.. tabs:: 112 113 .. group-tab:: ``Kconfig.sysbuild`` 114 115 .. code-block:: kconfig 116 117 config SUPPORT_OTHER_APP 118 bool 119 # Conditions can be placed here if this application type is only usable on certain platforms 120 default y 121 122 config SUPPORT_OTHER_APP_MY_IMAGE 123 bool 124 # Conditions can be placed here if this image is only usable on certain platforms 125 default y 126 127 choice OTHER_APP 128 prompt "Other app image" 129 # Defaults can be specified here if a default image should be loaded if e.g. it is supported 130 default OTHER_APP_NONE 131 depends on SUPPORT_OTHER_APP 132 133 config OTHER_APP_IMAGE_NONE 134 bool "None" 135 help 136 Do not Include an other app image in the build. 137 138 config OTHER_APP_IMAGE_MY_IMAGE 139 bool "my_image" 140 depends on SUPPORT_OTHER_APP_MY_IMAGE 141 help 142 Include my amazing image as the other app image to use, which does... 143 144 endchoice 145 146 config OTHER_APP_IMAGE_NAME 147 string 148 default "my_image" if OTHER_APP_IMAGE_MY_IMAGE 149 help 150 Name of other app image. 151 152 config OTHER_APP_IMAGE_PATH 153 string 154 default "$(ZEPHYR_MY_IMAGE_MODULE_DIR)/path/to/my_image" if OTHER_APP_IMAGE_MY_IMAGE 155 help 156 Source directory of other app image. 157 158 .. note:: 159 160 Remember to have ``source "$(ZEPHYR_BASE)/share/sysbuild/Kconfig"`` in the file if this 161 is being applied in an application ``Kconfig.sysbuild`` file. 162 163 .. group-tab:: ``sysbuild.cmake`` 164 165 .. code-block:: cmake 166 167 if(SB_CONFIG_OTHER_APP_IMAGE_PATH) 168 ExternalZephyrProject_Add( 169 APPLICATION ${SB_CONFIG_OTHER_APP_IMAGE_NAME} 170 SOURCE_DIR ${SB_CONFIG_OTHER_APP_IMAGE_PATH} 171 ) 172 endif() 173 174Additional dependency ordering can be set here if needed, see 175:ref:`sysbuild_zephyr_application_dependencies` for details, image configuration can also be set 176here, see :ref:`sysbuild_images_config` for details. 177 178This secondary image can be enabled when building with west like so: 179 180.. zephyr-app-commands:: 181 :tool: west 182 :zephyr-app: <app> 183 :board: nrf52840dk/nrf52840 184 :goals: build 185 :west-args: --sysbuild 186 :gen-args: -DSB_CONFIG_MY_IMAGE=y 187 :compact: 188 189This can then be extended by :ref:`modules` like so: 190 191.. tabs:: 192 193 .. group-tab:: ``Kconfig.sysbuild`` 194 195 .. code-block:: kconfig 196 197 config SUPPORT_OTHER_APP_MY_SECOND_IMAGE 198 bool 199 default y 200 201 choice OTHER_APP 202 203 config OTHER_APP_IMAGE_MY_SECOND_IMAGE 204 bool "my_second_image" 205 depends on SUPPORT_OTHER_APP_MY_SECOND_IMAGE 206 help 207 Include my other amazing image as the other app image to use, which does... 208 209 endchoice 210 211 config OTHER_APP_IMAGE_NAME 212 default "my_second_image" if OTHER_APP_IMAGE_MY_SECOND_IMAGE 213 214 config OTHER_APP_IMAGE_PATH 215 default "$(ZEPHYR_MY_SECOND_IMAGE_MODULE_DIR)/path/to/my_second_image" if OTHER_APP_IMAGE_MY_SECOND_IMAGE 216 217As can be seen, no additional CMake changes are needed to add an alternative image as the base 218CMake code will add the replacement image instead of the original image, if selected. 219 220This alternative secondary image can be enabled when building with west like so: 221 222.. zephyr-app-commands:: 223 :tool: west 224 :zephyr-app: <app> 225 :board: nrf52840dk/nrf52840 226 :goals: build 227 :west-args: --sysbuild 228 :gen-args: -DSB_CONFIG_MY_SECOND_IMAGE=y 229 :compact: 230 231.. _sysbuild_images_config: 232 233Image configuration 234******************* 235 236Sysbuild supports being able to set image configuration (Kconfig options) and also supports 237reading the output of image configuration (Kconfig) which can be used to allow an 238option to be added to sysbuild itself and then to configure it globally or selectively. 239 240Setting image configuration 241=========================== 242 243Kconfig 244------- 245 246Sysbuild can be used to set image configuration **before the CMake configuration of images takes 247place**. An important note about setting Kconfig options in images is that these are persistent 248and cannot be changed by the images. The following functions can be used to set configuration on 249an image: 250 251.. code-block:: cmake 252 253 set_config_bool(<image> CONFIG_<setting> <value>) 254 set_config_string(<image> CONFIG_<setting> <value>) 255 set_config_int(<image> CONFIG_<setting> <value>) 256 257For example, to change the default image to output a hex file: 258 259.. code-block:: cmake 260 261 set_config_bool(${DEFAULT_IMAGE} CONFIG_BUILD_OUTPUT_HEX y) 262 263These can safely be used in an application, board or SoC ``sysbuild.cmake`` file, as that file is 264included before the image CMake processes are invoked. When extending 265:ref:`sysbuild using modules <sysbuild_module_integration>` the pre-CMake hook should be used 266instead, for example: 267 268.. code-block:: cmake 269 270 function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) 271 cmake_parse_arguments(PRE_CMAKE "" "" "IMAGES" ${ARGN}) 272 273 foreach(image ${PRE_CMAKE_IMAGES}) 274 set_config_bool(${image} CONFIG_BUILD_OUTPUT_HEX y) 275 endforeach() 276 endfunction() 277 278Image configuration script 279========================== 280 281An image configuration script is a CMake file that can be used to configure an image with common 282configuration values, multiple can be used per image, the configuration should be transferrable to 283different images to correctly configure them based upon options set in sysbuild. MCUboot 284configuration options are configured in both the application the MCUboot image using this method 285which allows sysbuild to be the central location for things like the signing key which are then 286kept in-sync in the main application bootloader images. 287 288Inside image configuration scripts, the ``ZCMAKE_APPLICATION`` variable is set to the name of the 289application being configured, the ``set_config_*`` sysbuild CMake functions can be used to set 290configuration and the sysbuild Kconfig can be read, for example: 291 292.. code-block:: cmake 293 294 if(SB_CONFIG_BOOTLOADER_MCUBOOT AND "${SB_CONFIG_SIGNATURE_TYPE}" STREQUAL "NONE") 295 set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE y) 296 endif() 297 298Image configuration script (module/application) 299----------------------------------------------- 300 301Module/application image configuration scripts can be set from module or application code, this 302must be done in a ``sysbuild.cmake`` file for an application. This can be used to add an image 303configuration script as follows: 304 305.. tabs:: 306 307 .. group-tab:: ``sysbuild.cmake`` 308 309 .. code-block:: cmake 310 311 # This applies the image configuration script to the default image only 312 get_property(tmp_conf_scripts TARGET ${DEFAULT_IMAGE} PROPERTY IMAGE_CONF_SCRIPT) 313 list(APPEND tmp_conf_scripts "${CMAKE_SOURCE_DIR}/image_configurations/MY_CUSTOM_TYPE_image_default.cmake") 314 set_target_properties(${DEFAULT_IMAGE} PROPERTIES IMAGE_CONF_SCRIPT "${tmp_conf_scripts}") 315 316 317 .. group-tab:: Module CMake 318 319 .. code-block:: cmake 320 321 function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) 322 cmake_parse_arguments(PRE_CMAKE "" "" "IMAGES" ${ARGN}) 323 324 # This applies the image configuration script to all images 325 foreach(image ${PRE_CMAKE_IMAGES}) 326 get_property(tmp_conf_scripts TARGET ${image} PROPERTY IMAGE_CONF_SCRIPT) 327 list(APPEND tmp_conf_scripts "${CMAKE_SOURCE_DIR}/image_configurations/MY_CUSTOM_TYPE_image_default.cmake") 328 set_target_properties(${image} PROPERTIES IMAGE_CONF_SCRIPT "${tmp_conf_scripts}") 329 endforeach() 330 endfunction(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) 331 332Image configuration script (Zephyr-wide) 333---------------------------------------- 334 335Global Zephyr provided image configuration scripts, which allow specifying the type when using 336``ExternalZephyrProject_Add()`` require changes to sysbuild code in Zephyr. This should only be 337added to when adding a new type that any project should be able to select, generally this should 338only be needed for upstream Zephyr though forked versions of Zephyr might use this to add 339additional types without restriction. 340 341Image configuration has an allow-list of names which must be set in the Zephyr file 342:zephyr_file:`share/sysbuild/cmake/modules/sysbuild_extensions.cmake` in the 343``ExternalZephyrProject_Add`` function. After adding a new type, it can be used when adding a 344sysbuild image, for example: 345 346.. tabs:: 347 348 .. group-tab:: ``sysbuild_extensions.cmake`` 349 350 Full file path: ``share/sysbuild/cmake/modules/sysbuild_extensions.cmake`` 351 352 .. code-block:: cmake 353 354 # ... 355 # Usage: 356 # ExternalZephyrProject_Add(APPLICATION <name> 357 # SOURCE_DIR <dir> 358 # [BOARD <board> [BOARD_REVISION <revision>]] 359 # [APP_TYPE <MAIN|BOOTLOADER|MY_CUSTOM_TYPE>] 360 # ) 361 # ... 362 # APP_TYPE <MAIN|BOOTLOADER|MY_CUSTOM_TYPE>: Application type. 363 # MAIN indicates this application is the main application 364 # and where user defined settings should be passed on as-is 365 # except for multi image build flags. 366 # For example, -DCONF_FILES=<files> will be passed on to the 367 # MAIN_APP unmodified. 368 # BOOTLOADER indicates this app is a bootloader 369 # MY_CUSTOM_TYPE indicates this app is... 370 # ... 371 function(ExternalZephyrProject_Add) 372 set(app_types MAIN BOOTLOADER MY_CUSTOM_TYPE) 373 # ... 374 375 .. group-tab:: ``sysbuild.cmake`` 376 377 .. code-block:: cmake 378 379 if(SB_CONFIG_OTHER_APP_IMAGE_PATH) 380 ExternalZephyrProject_Add( 381 APPLICATION ${SB_CONFIG_OTHER_APP_IMAGE_NAME} 382 SOURCE_DIR ${SB_CONFIG_OTHER_APP_IMAGE_PATH} 383 APP_TYPE MY_CUSTOM_TYPE 384 ) 385 endif() 386 387 388 .. group-tab:: ``MY_CUSTOM_TYPE_image_default.cmake`` 389 390 Full file path: ``share/sysbuild/image_configurations/MY_CUSTOM_TYPE_image_default.cmake`` 391 392 .. code-block:: cmake 393 394 # Here, the ZCMAKE_APPLICATION variable will be replaced with the image being configured 395 set_config_bool(${ZCMAKE_APPLICATION} CONFIG_BUILD_OUTPUT_HEX y) 396 397Reading image configuration 398=========================== 399 400Kconfig 401------- 402 403Kconfig values from images can be read by sysbuild **after the CMake configuration of images has 404taken place**. This can be used to check configuration or to adjust additional sysbuild tasks 405depending upon configuration. The following function can be used for this purpose: 406 407.. code-block:: cmake 408 409 sysbuild_get(<variable> IMAGE <image> [VAR <image-variable>] KCONFIG) 410 411This function can only be used when 412:ref:`sysbuild is extended by a module <sysbuild_module_integration>` or inside of a ``sysbuild/CMakeLists.txt`` file after ``find_package(Sysbuild)`` has been used. An example of outputting 413values from all images is shown: 414 415.. tabs:: 416 417 .. group-tab:: Module CMake 418 419 .. code-block:: cmake 420 421 function(${SYSBUILD_CURRENT_MODULE_NAME}_post_cmake) 422 cmake_parse_arguments(POST_CMAKE "" "" "IMAGES" ${ARGN}) 423 424 foreach(image ${POST_CMAKE_IMAGES}) 425 # Note that the variable to read in to must not be set before using the sysbuild_get() function 426 set(tmp_val) 427 sysbuild_get(tmp_val IMAGE ${image} VAR CONFIG_BUILD_OUTPUT_HEX KCONFIG) 428 message(STATUS "Image ${image} build hex: ${tmp_val}") 429 endforeach() 430 endfunction() 431 432 .. group-tab:: ``sysbuild/CMakeLists.txt`` 433 434 .. code-block:: cmake 435 436 find_package(Sysbuild REQUIRED HINTS $ENV{ZEPHYR_BASE}) 437 438 project(sysbuild LANGUAGES) 439 440 sysbuild_get(tmp_val IMAGE ${DEFAULT_IMAGE} VAR CONFIG_BUILD_OUTPUT_HEX KCONFIG) 441 message(STATUS "Image ${DEFAULT_IMAGE} build hex: ${tmp_val}") 442