1.. _sysbuild:
2
3Sysbuild (System build)
4#######################
5
6Sysbuild is a higher-level build system that can be used to combine multiple
7other build systems together. It is a higher-level layer that combines one
8or more Zephyr build systems and optional additional build systems
9into a hierarchical build system.
10
11For example, you can use sysbuild to build a Zephyr application together
12with the MCUboot bootloader, flash them both onto your device, and
13debug the results.
14
15Sysbuild works by configuring and building at least a Zephyr application and, optionally, as many
16additional projects as you want. The additional projects can be either Zephyr applications
17or other types of builds you want to run.
18
19Like Zephyr's :ref:`build system <build_overview>`, sysbuild is written in
20CMake and uses :ref:`Kconfig <kconfig>`.
21
22Definitions
23***********
24
25The following are some key concepts used in this document:
26
27Single-image build
28    When sysbuild is used to create and manage just one Zephyr application's
29    build system.
30
31Multi-image build
32   When sysbuild is used to manage multiple build systems.
33   The word "image" is used because your main goal is usually to generate the binaries of the firmware
34   application images from each build system.
35
36Domain
37   Every Zephyr CMake build system managed by sysbuild.
38
39Multi-domain
40   When more than one Zephyr CMake build system (domain) is managed by sysbuild.
41
42Architectural Overview
43**********************
44
45This figure is an overview of sysbuild's inputs, outputs, and user interfaces:
46
47.. figure:: sysbuild.svg
48    :align: center
49    :alt: Sysbuild architectural overview
50    :figclass: align-center
51    :width: 80%
52
53The following are some key sysbuild features indicated in this figure:
54
55- You can run sysbuild either with :ref:`west build
56  <west-building>` or directly via ``cmake``.
57
58- You can use sysbuild to generate application images from each build system,
59  shown above as ELF, BIN, and HEX files.
60
61- You can configure sysbuild or any of the build systems it manages using
62  various configuration variables. These variables are namespaced so that
63  sysbuild can direct them to the right build system. In some cases, such as
64  the ``BOARD`` variable, these are shared among multiple build systems.
65
66- Sysbuild itself is also configured using Kconfig. For example, you can
67  instruct sysbuild to build the MCUboot bootloader, as well as to build and
68  link your main Zephyr application as an MCUboot child image, using sysbuild's
69  Kconfig files.
70
71- Sysbuild integrates with west's :ref:`west-build-flash-debug` commands. It
72  does this by managing the :ref:`west-runner`, and specifically the
73  :file:`runners.yaml` files that each Zephyr build system will contain. These
74  are packaged into a global view of how to flash and debug each build system
75  in a :file:`domains.yaml` file generated and managed by sysbuild.
76
77- Build names are prefixed with the target name and an underscore, for example
78  the sysbuild target is prefixed with ``sysbuild_`` and if MCUboot is enabled
79  as part of sysbuild, it will be prefixed with ``mcuboot_``. This also allows
80  for running things like menuconfig with the prefix, for example (if using
81  ninja) ``ninja sysbuild_menuconfig`` to configure sysbuild or (if using make)
82  ``make mcuboot_menuconfig``.
83
84Building with sysbuild
85**********************
86
87As mentioned above, you can run sysbuild via ``west build`` or ``cmake``.
88
89.. tabs::
90
91   .. group-tab:: ``west build``
92
93      Here is an example. For details, see :ref:`west-multi-domain-builds` in
94      the ``west build documentation``.
95
96      .. zephyr-app-commands::
97         :tool: west
98         :app: samples/hello_world
99         :board: reel_board
100         :goals: build
101         :west-args: --sysbuild
102         :compact:
103
104      .. tip::
105
106         To configure ``west build`` to use ``--sysbuild`` by default from now on,
107         run::
108
109           west config build.sysbuild True
110
111         Since sysbuild supports both single- and multi-image builds, this lets you
112         use sysbuild all the time, without worrying about what type of build you are
113         running.
114
115         To turn this off, run this before generating your build system::
116
117           west config build.sysbuild False
118
119         To turn this off for just one ``west build`` command, run::
120
121           west build --no-sysbuild ...
122
123   .. group-tab:: ``cmake``
124
125      Here is an example using CMake and Ninja.
126
127      .. zephyr-app-commands::
128         :tool: cmake
129         :app: share/sysbuild
130         :board: reel_board
131         :goals: build
132         :gen-args: -DAPP_DIR=samples/hello_world
133         :compact:
134
135      To use sysbuild directly with CMake, you must specify the sysbuild
136      project as the source folder, and give ``-DAPP_DIR=<path-to-sample>`` as
137      an extra CMake argument. ``APP_DIR`` is the path to the main Zephyr
138      application managed by sysbuild.
139
140Configuration namespacing
141*************************
142
143When building a single Zephyr application without sysbuild, all CMake cache
144settings and Kconfig build options given on the command line as
145``-D<var>=<value>`` or ``-DCONFIG_<var>=<value>`` are handled by the Zephyr
146build system.
147
148However, when sysbuild combines multiple Zephyr build systems, there could be
149Kconfig settings exclusive to sysbuild (and not used by any of the applications).
150To handle this, sysbuild has namespaces for configuration variables. You can use these
151namespaces to direct settings either to sysbuild itself or to a specific Zephyr
152application managed by sysbuild using the information in these sections.
153
154The following example shows how to build :ref:`hello_world` with MCUboot enabled,
155applying to both images debug optimizations:
156
157.. tabs::
158
159   .. group-tab:: ``west build``
160
161      .. zephyr-app-commands::
162         :tool: west
163         :app: samples/hello_world
164         :board: reel_board
165         :goals: build
166         :west-args: --sysbuild
167         :gen-args: -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_DEBUG_OPTIMIZATIONS=y -Dmcuboot_DEBUG_OPTIMIZATIONS=y
168         :compact:
169
170   .. group-tab:: ``cmake``
171
172      .. zephyr-app-commands::
173         :tool: cmake
174         :app: share/sysbuild
175         :board: reel_board
176         :goals: build
177         :gen-args: -DAPP_DIR=samples/hello_world -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_DEBUG_OPTIMIZATIONS=y -Dmcuboot_DEBUG_OPTIMIZATIONS=y
178         :compact:
179
180See the following subsections for more information.
181
182.. _sysbuild_cmake_namespace:
183
184CMake variable namespacing
185==========================
186
187CMake variable settings can be passed to CMake using ``-D<var>=<value>`` on the
188command line. You can also set Kconfig options via CMake as
189``-DCONFIG_<var>=<value>`` or ``-D<namespace>_CONFIG_<var>=<value>``.
190
191Since sysbuild is the entry point for the build system, and sysbuild is written
192in CMake, all CMake variables are first processed by sysbuild.
193
194Sysbuild creates a namespace for each domain. The namespace prefix is the
195domain's application name. See :ref:`sysbuild_zephyr_application` for more
196information.
197
198To set the variable ``<var>`` in the namespace ``<namespace>``, use this syntax::
199
200  -D<namespace>_<var>=<value>
201
202For example, to set the CMake variable ``FOO`` in the ``my_sample`` application
203build system to the value ``BAR``, run the following commands:
204
205.. tabs::
206
207   .. group-tab:: ``west build``
208
209      ::
210
211         west build --sysbuild ... -- -Dmy_sample_FOO=BAR
212
213   .. group-tab:: ``cmake``
214
215      ::
216
217        cmake -Dmy_sample_FOO=BAR ...
218
219.. _sysbuild_kconfig_namespacing:
220
221Kconfig namespacing
222===================
223
224To set the sysbuild Kconfig option ``<var>`` to the value ``<value>``, use this syntax::
225
226  -DSB_CONFIG_<var>=<value>
227
228In the previous example, ``SB_CONFIG`` is the namespace prefix for sysbuild's Kconfig
229options.
230
231To set a Zephyr application's Kconfig option instead, use this syntax::
232
233  -D<namespace>_CONFIG_<var>=<value>
234
235In the previous example, ``<namespace>`` is the application name discussed above in
236:ref:`sysbuild_cmake_namespace`.
237
238For example, to set the Kconfig option ``FOO`` in the ``my_sample`` application
239build system to the value ``BAR``, run the following commands:
240
241.. tabs::
242
243   .. group-tab:: ``west build``
244
245      ::
246
247         west build --sysbuild ... -- -Dmy_sample_CONFIG_FOO=BAR
248
249   .. group-tab:: ``cmake``
250
251      ::
252
253        cmake -Dmy_sample_CONFIG_FOO=BAR ...
254
255.. tip::
256   When no ``<namespace>`` is used, the Kconfig setting is passed to the main
257   Zephyr application ``my_sample``.
258
259   This means that passing ``-DCONFIG_<var>=<value>`` and
260   ``-Dmy_sample_CONFIG_<var>=<value>`` are equivalent.
261
262   This allows you to build the same application with or without sysbuild using
263   the same syntax for setting Kconfig values at CMake time.
264   For example, the following commands will work in the same way:
265
266   ::
267
268     west build -b <board> my_sample -- -DCONFIG_FOO=BAR
269
270   ::
271
272     west build -b <board> --sysbuild my_sample -- -DCONFIG_FOO=BAR
273
274Sysbuild flashing using ``west flash``
275**************************************
276
277You can use :ref:`west flash <west-flashing>` to flash applications with
278sysbuild.
279
280When invoking ``west flash`` on a build consisting of multiple images, each
281image is flashed in sequence. Extra arguments such as ``--runner jlink`` are
282passed to each invocation.
283
284For more details, see :ref:`west-multi-domain-flashing`.
285
286Sysbuild debugging using ``west debug``
287***************************************
288
289You can use ``west debug``  to debug the main application, whether you are using sysbuild or not.
290Just follow the existing :ref:`west debug <west-debugging>` guide to debug the main sample.
291
292To debug a different domain (Zephyr application), such as ``mcuboot``, use
293the ``--domain`` argument, as follows::
294
295  west debug --domain mcuboot
296
297For more details, see :ref:`west-multi-domain-debugging`.
298
299Building a sample with MCUboot
300******************************
301
302Sysbuild supports MCUboot natively.
303
304To build a sample like ``hello_world`` with MCUboot,
305enable MCUboot and build and flash the sample as follows:
306
307.. tabs::
308
309   .. group-tab:: ``west build``
310
311      .. zephyr-app-commands::
312         :tool: west
313         :app: samples/hello_world
314         :board: reel_board
315         :goals: build
316         :west-args: --sysbuild
317         :gen-args: -DSB_CONFIG_BOOTLOADER_MCUBOOT=y
318         :compact:
319
320   .. group-tab:: ``cmake``
321
322      .. zephyr-app-commands::
323         :tool: cmake
324         :app: share/sysbuild
325         :board: reel_board
326         :goals: build
327         :gen-args: -DAPP_DIR=samples/hello_world -DSB_CONFIG_BOOTLOADER_MCUBOOT=y
328         :compact:
329
330This builds ``hello_world`` and ``mcuboot`` for the ``reel_board``, and then
331flashes both the ``mcuboot`` and ``hello_world`` application images to the
332board.
333
334More detailed information regarding the use of MCUboot with Zephyr can be found
335in the `MCUboot with Zephyr`_ documentation page on the MCUboot website.
336
337.. note::
338
339   MCUBoot default configuration will perform a full chip erase when flashed.
340   This can be controlled through the MCUBoot Kconfig option
341   ``CONFIG_ZEPHYR_TRY_MASS_ERASE``. If this option is enabled, then flashing
342   only MCUBoot, for example using ``west flash --domain mcuboot``, may erase
343   the entire flash, including the main application image.
344
345Sysbuild Kconfig file
346*********************
347
348You can set sysbuild's Kconfig options for a single application using
349configuration files. By default, sysbuild looks for a configuration file named
350``sysbuild.conf`` in the application top-level directory.
351
352In the following example, there is a :file:`sysbuild.conf` file that enables building and flashing with
353MCUboot whenever sysbuild is used:
354
355.. code-block:: none
356
357   <home>/application
358   ├── CMakeLists.txt
359   ├── prj.conf
360   └── sysbuild.conf
361
362
363.. code-block:: none
364
365   SB_CONFIG_BOOTLOADER_MCUBOOT=y
366
367You can set a configuration file to use with the
368``-DSB_CONF_FILE=<sysbuild-conf-file>`` CMake build setting.
369
370For example, you can create ``sysbuild-mcuboot.conf`` and then
371specify this file when building with sysbuild, as follows:
372
373.. tabs::
374
375   .. group-tab:: ``west build``
376
377      .. zephyr-app-commands::
378         :tool: west
379         :app: samples/hello_world
380         :board: reel_board
381         :goals: build
382         :west-args: --sysbuild
383         :gen-args: -DSB_CONF_FILE=sysbuild-mcuboot.conf
384         :compact:
385
386   .. group-tab:: ``cmake``
387
388      .. zephyr-app-commands::
389         :tool: cmake
390         :app: share/sysbuild
391         :board: reel_board
392         :goals: build
393         :gen-args: -DAPP_DIR=samples/hello_world -DSB_CONF_FILE=sysbuild-mcuboot.conf
394         :compact:
395
396Sysbuild targets
397****************
398
399Sysbuild creates build targets for each image (including sysbuild itself) for
400the following modes:
401
402 * menuconfig
403 * hardenconfig
404 * guiconfig
405
406For the main application (as is the same without using sysbuild) these can be
407ran normally without any prefix. For other images (including sysbuild), these
408are ran with a prefix of the image name and an underscore e.g. ``sysbuild_`` or
409``mcuboot_``, using ninja or make - for details on how to run image build
410targets that do not have mapped build targets in sysbuild, see the
411:ref:`sysbuild_dedicated_image_build_targets` section.
412
413.. _sysbuild_dedicated_image_build_targets:
414
415Dedicated image build targets
416*****************************
417
418Not all build targets for images are given equivalent prefixed build targets
419when sysbuild is used, for example build targets like ``ram_report``,
420``rom_report``, ``footprint``, ``puncover`` and ``pahole`` are not exposed.
421When using :ref:`Trusted Firmware <tfm_build_system>`, this includes build
422targets prefix with ``tfm_`` and ``bl2_``, for example: ``tfm_rom_report``
423and ``bl2_ram_report``. To run these build targets, the build directory of the
424image can be provided to west/ninja/make along with the name of the build
425target to execute and it will run.
426
427.. tabs::
428
429   .. group-tab:: ``west``
430
431      Assuming that a project has been configured and built using ``west``
432      using sysbuild with mcuboot enabled in the default ``build`` folder
433      location, the ``rom_report`` build target for ``mcuboot`` can be ran
434      with:
435
436      .. code-block:: bash
437
438         west build -d build/mcuboot -t rom_report
439
440   .. group-tab:: ``ninja``
441
442      Assuming that a project has been configured using ``cmake`` and built
443      using ``ninja`` using sysbuild with mcuboot enabled, the ``rom_report``
444      build target for ``mcuboot`` can be ran with:
445
446      .. code-block:: bash
447
448         ninja -C mcuboot rom_report
449
450   .. group-tab:: ``make``
451
452      Assuming that a project has been configured using ``cmake`` and built
453      using ``make`` using sysbuild with mcuboot enabled, the ``rom_report``
454      build target for ``mcuboot`` can be ran with:
455
456      .. code-block:: bash
457
458         make -C mcuboot rom_report
459
460.. _sysbuild_zephyr_application:
461
462Adding Zephyr applications to sysbuild
463**************************************
464
465You can use the ``ExternalZephyrProject_Add()`` function to add Zephyr
466applications as sysbuild domains. Call this CMake function from your
467application's :file:`sysbuild.cmake` file, or any other CMake file you know will
468run as part sysbuild CMake invocation.
469
470Targeting the same board
471========================
472
473To include ``my_sample`` as another sysbuild domain, targeting the same board
474as the main image, use this example:
475
476.. code-block:: cmake
477
478   ExternalZephyrProject_Add(
479     APPLICATION my_sample
480     SOURCE_DIR <path-to>/my_sample
481   )
482
483This could be useful, for example, if your board requires you to build and flash an
484SoC-specific bootloader along with your main application.
485
486Targeting a different board
487===========================
488
489In sysbuild and Zephyr CMake build system a board may refer to:
490
491* A physical board with a single core SoC.
492* A specific core on a physical board with a multi-core SoC, such as
493  :ref:`nrf5340dk_nrf5340`.
494* A specific SoC on a physical board with multiple SoCs, such as
495  :ref:`nrf9160dk_nrf9160` and :ref:`nrf9160dk_nrf52840`.
496
497If your main application, for example, is built for ``mps2_an521``, and your
498helper application must target the ``mps2_an521_remote`` board (cpu1), add
499a CMake function call that is structured as follows:
500
501.. code-block:: cmake
502
503   ExternalZephyrProject_Add(
504     APPLICATION my_sample
505     SOURCE_DIR <path-to>/my_sample
506     BOARD mps2_an521_remote
507   )
508
509This could be useful, for example, if your main application requires another
510helper Zephyr application to be built and flashed alongside it, but the helper
511runs on another core in your SoC.
512
513Targeting conditionally using Kconfig
514=====================================
515
516You can control whether extra applications are included as sysbuild domains
517using Kconfig.
518
519If the extra application image is specific to the board or an application,
520you can create two additional files: :file:`sysbuild.cmake` and :file:`Kconfig.sysbuild`.
521
522For an application, this would look like this:
523
524.. code-block:: none
525
526   <home>/application
527   ├── CMakeLists.txt
528   ├── prj.conf
529   ├── Kconfig.sysbuild
530   └── sysbuild.cmake
531
532In the previous example, :file:`sysbuild.cmake` would be structured as follows:
533
534.. code-block:: cmake
535
536   if(SB_CONFIG_SECOND_SAMPLE)
537     ExternalZephyrProject_Add(
538       APPLICATION second_sample
539       SOURCE_DIR <path-to>/second_sample
540     )
541   endif()
542
543:file:`Kconfig.sysbuild` would be structured as follows:
544
545.. code-block:: kconfig
546
547   source "sysbuild/Kconfig"
548
549   config SECOND_SAMPLE
550           bool "Second sample"
551           default y
552
553This will include ``second_sample`` by default, while still allowing you to
554disable it using the Kconfig option ``SECOND_SAMPLE``.
555
556For more information on setting sysbuild Kconfig options,
557see :ref:`sysbuild_kconfig_namespacing`.
558
559Zephyr application configuration
560================================
561
562When adding a Zephyr application to sysbuild, such as MCUboot, then the
563configuration files from the application (MCUboot) itself will be used.
564
565When integrating multiple applications with each other, then it is often
566necessary to make adjustments to the configuration of extra images.
567
568Sysbuild gives users the ability of creating Kconfig fragments or devicetree
569overlays that will be used together with the application's default configuration.
570Sysbuild also allows users to change :ref:`application-configuration-directory`
571in order to give users full control of an image's configuration.
572
573Zephyr application Kconfig fragment and devicetree overlay
574----------------------------------------------------------
575
576In the folder of the main application, create a Kconfig fragment or a devicetree
577overlay under a sysbuild folder, where the name of the file is
578:file:`<image>.conf` or :file:`<image>.overlay`, for example if your main
579application includes ``my_sample`` then create a :file:`sysbuild/my_sample.conf`
580file or a devicetree overlay :file:`sysbuild/my_sample.overlay`.
581
582A Kconfig fragment could look as:
583
584.. code-block:: none
585
586   # sysbuild/my_sample.conf
587   CONFIG_FOO=n
588
589Zephyr application configuration directory
590------------------------------------------
591
592In the folder of the main application, create a new folder under
593:file:`sysbuild/<image>/`.
594This folder will then be used as ``APPLICATION_CONFIG_DIR`` when building
595``<image>``.
596As an example, if your main application includes ``my_sample`` then create a
597:file:`sysbuild/my_sample/` folder and place any configuration files in
598there as you would normally do:
599
600.. code-block:: none
601
602   <home>/application
603   ├── CMakeLists.txt
604   ├── prj.conf
605   └── sysbuild
606       └── my_sample
607           ├── prj.conf
608           ├── app.overlay
609           └── boards
610               ├── <board_A>.conf
611               ├── <board_A>.overlay
612               ├── <board_B>.conf
613               └── <board_B>.overlay
614
615All configuration files under the :file:`sysbuild/my_sample/` folder will now
616be used when ``my_sample`` is included in the build, and the default
617configuration files for ``my_sample`` will be ignored.
618
619This give you full control on how images are configured when integrating those
620with ``application``.
621
622Adding non-Zephyr applications to sysbuild
623******************************************
624
625You can include non-Zephyr applications in a multi-image build using the
626standard CMake module `ExternalProject`_. Please refer to the CMake
627documentation for usage details.
628
629When using ``ExternalProject``, the non-Zephyr application will be built as
630part of the sysbuild build invocation, but ``west flash`` or ``west debug``
631will not be aware of the application. Instead, you must manually flash and
632debug the application.
633
634.. _MCUboot with Zephyr: https://docs.mcuboot.com/readme-zephyr
635.. _ExternalProject: https://cmake.org/cmake/help/latest/module/ExternalProject.html
636
637Extending sysbuild
638******************
639
640Sysbuild can be extended by other modules to give it additional functionality
641or include other configuration or images, an example could be to add support
642for another bootloader or external signing method.
643
644Modules can be extended by adding custom CMake or Kconfig files as normal
645:ref:`modules <module-yml>` do, this will cause the files to be included in
646each image that is part of a project. Alternatively, there are
647:ref:`sysbuild-specific module extension <sysbuild_module_integration>` files
648which can be used to include CMake and Kconfig files for the overall sysbuild
649image itself, this is where e.g. a custom image for a particular board or SoC
650can be added.
651