extensions

Zephyr’s CMake extension commands.

This module defines the commands that Zephyr applications, Zephyr modules, and the build system itself use to describe what they build.

Many commands come in an _ifdef and an _ifndef flavour, taking a Kconfig option as their first argument, so that build rules can be made conditional without wrapping them in an if() block.

This module is loaded as part of find_package(Zephyr), which means that every command documented below is available in the CMakeLists.txt of any Zephyr application or module.

Zephyr-aware extensions

zephyr_*

The following methods are for modifying the CMake library called zephyr. zephyr is a catch-all CMake library for source files that can be built purely with the include paths, defines, and other compiler flags that all zephyr source files use.

Example usage:

zephyr_sources(
  random_esp32.c
  utils.c
)

Is short for:

target_sources(zephyr PRIVATE
  ${CMAKE_CURRENT_SOURCE_DIR}/random_esp32.c
  ${CMAKE_CURRENT_SOURCE_DIR}/utils.c
)

As a very high-level introduction, here are two call graphs that are purposely minimalistic and incomplete.

zephyr_library_cc_option()
         |
         v
zephyr_library_compile_options()  -->  target_compile_options()
zephyr_cc_option()           --->  target_cc_option()
                                        |
                                        v
zephyr_cc_option_fallback()  --->  target_cc_option_fallback()
                                        |
                                        v
zephyr_compile_options()     --->  target_compile_options()
zephyr_sources(<sources>...)

Add sources to the zephyr library.

See target_sources for details.

zephyr_include_directories(<dirs>...)

Add include directories to the zephyr library.

See target_include_directories for details.

zephyr_system_include_directories(<dirs>...)

Add system include directories to the zephyr library.

See target_include_directories for details.

zephyr_compile_definitions(<defs>...)

Add compile definitions to the zephyr library.

See target_compile_definitions for details.

zephyr_compile_options(<options>...)

Add compile options to the zephyr library.

See target_compile_options for details.

Add link libraries to the zephyr library.

See target_link_libraries for details.

Add link libraries to the zephyr library’s LIBC_LINK_LIBRARIES property.

This function allows subsystems to define libraries which get added to the link command after all other libraries and modules. It’s useful when using a toolchain library, like libc or libgcc, as those can get added when processing the ‘lib’ directory, before any module libraries and hence might not get used to resolve symbols from modules.

zephyr_cc_option(<option>...)

Add compiler options to the zephyr library, if supported by the compiler.

This function checks if the compiler supports each option. If supported, it adds the option to the ‘zephyr’ library.

zephyr_cc_option_fallback(<option1> <option2>)

Add a compiler option to the zephyr library, falling back to a second option if the first is not supported.

This function checks if the compiler supports <option1>. If so, it is added. Otherwise, it checks <option2> and adds it if supported.

zephyr_ld_options(<options>...)

Add linker options to the zephyr library.

See target_ld_options() for details.

zephyr_get_include_directories_for_lang_as_string(<lang> <var> [STRIP_PREFIX])

Get include directories for a specific language as a string.

Writes the include directories for language <lang> to variable <var> as a string.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_get_system_include_directories_for_lang_as_string(<lang> <var> [STRIP_PREFIX])

Get system include directories for a specific language as a string.

Writes the system include directories for language <lang> to variable <var> as a string.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_get_compile_definitions_for_lang_as_string(<lang> <var> [STRIP_PREFIX])

Get compile definitions for a specific language as a string.

Writes the compile definitions for language <lang> to variable <var> as a string.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_get_compile_options_for_lang_as_string(<lang> <var> [STRIP_PREFIX])

Get compile options for a specific language as a string.

Writes the compile options for language <lang> to variable <var> as a string.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_get_include_directories_for_lang(<lang> <var> [STRIP_PREFIX])

Get include directories for a specific language as a list.

Writes the include directories for language <lang> to variable <var> as a list.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_get_system_include_directories_for_lang(<lang> <var> [STRIP_PREFIX])

Get system include directories for a specific language as a list.

Writes the system include directories for language <lang> to variable <var> as a list.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_get_compile_definitions_for_lang(<lang> <var> [STRIP_PREFIX])

Get compile definitions for a specific language as a list.

Writes the compile definitions for language <lang> to variable <var> as a list.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_get_compile_options_for_lang(<lang> <var> [STRIP_PREFIX])

Get compile options for a specific language as a list.

Writes the compile options for language <lang> to variable <var> as a list.

<lang> can be one of C, CXX, or ASM.

STRIP_PREFIX can be specified to omit the prefix from the result.

zephyr_library_*

Zephyr libraries use CMake’s library concept and a set of assumptions about how zephyr code is organized to cut down on boilerplate code.

A Zephyr library can be constructed by the function zephyr_library() or zephyr_library_named(). The constructors create a CMake library with a name accessible through the variable ZEPHYR_CURRENT_LIBRARY.

The variable ZEPHYR_CURRENT_LIBRARY should seldom be needed since the zephyr libraries have methods that modify the libraries. These methods have the signature: zephyr_library_<target-function>.

The methods are wrappers around the CMake target_* functions. See manual:cmake-commands(7) for documentation on the underlying target_* functions.

The methods modify the CMake target_* API to reduce boilerplate; PRIVATE is assumed.

The target is assumed to be ZEPHYR_CURRENT_LIBRARY

When a flag that is given through the zephyr_* API conflicts with the zephyr_library_* API then precedence will be given to the zephyr_library_* API. In other words, local configuration overrides global configuration.

zephyr_library()

Create a Zephyr library with a directory-inferred name. This sets the ZEPHYR_CURRENT_LIBRARY variable to the inferred name.

zephyr_library_named(<name>)

Create a Zephyr library with an explicitly given name. This sets the ZEPHYR_CURRENT_LIBRARY variable to the given name.

zephyr_library_amend([<dir>])

Provides amend functionality to a Zephyr library for out-of-tree usage.

When called from a Zephyr module, the corresponding zephyr library defined within Zephyr will be looked up.

<dir>: Use <dir> as out-of-tree base directory from where the Zephyr library name shall be generated. <dir> can be used in cases where the structure for the library is not placed directly at the ZEPHYR_MODULE’s root directory or for cases where the module integration file is located in a ‘MODULE_EXT_ROOT’.

Note, in order to ensure correct library when amending, the folder structure in the Zephyr module or <dir> base directory must resemble the structure used in Zephyr, as example:

Example: to amend the zephyr library created in ZEPHYR_BASE/drivers/entropy/CMakeLists.txt, add a ZEPHYR_MODULE/drivers/entropy/CMakeLists.txt file with the following content:

zephyr_library_amend()
zephyr_library_sources(...)

It is also possible to use generator expression when amending to Zephyr libraries.

For example, in case it is required to expose the Zephyr library’s folder as include path then the following is possible:

zephyr_library_amend()
zephyr_library_include_directories($<TARGET_PROPERTY:SOURCE_DIR>)

See the CMake documentation for more target properties or generator expressions.

zephyr_library_sources(<source> ...)

Add source files to the current Zephyr library.

zephyr_library_include_directories(<include_dir> ...)

Add include directories to the current Zephyr library.

Add link libraries to the current Zephyr library.

zephyr_library_compile_definitions(<item> ...)

Add compile definitions to the current Zephyr library.

zephyr_library_compile_options(<item> ...)

Add compile options to the current Zephyr library.

zephyr_library_cc_option(<option> ...)

Add compile options to the current Zephyr library if the C compiler supports them. Unsupported options are ignored.

zephyr_library_add_dependencies(<item> ...)

Add dependencies to the current Zephyr library.

See add_dependencies() for more information.

zephyr_append_cmake_library(<library>)

Add the existing CMake library ‘library’ to the global list of Zephyr CMake libraries. This is done automatically by the constructor but must be called explicitly on CMake libraries that do not use a zephyr library constructor.

zephyr_library_import(<library_name> <library_path>)

Add the imported library ‘library_name’, located at ‘library_path’ to the global list of Zephyr CMake libraries.

zephyr_library_app_memory(<partition>)

Place the current zephyr library in the application memory partition.

The partition argument is the name of the partition where the library shall be placed.

Note: Ensure the given partition has been defined using K_APPMEM_PARTITION_DEFINE in source code.

zephyr_interface_library_*

A Zephyr interface library is a thin wrapper over a CMake INTERFACE library. The most important responsibility of this abstraction is to ensure that when a user KConfig-enables a library then the header files of this library will be accessible to the ‘app’ library.

This is done because when a user uses Kconfig to enable a library he expects to be able to include its header files and call its functions out-of-the box.

A Zephyr interface library should be used when there exists some build information (include directories, defines, compiler flags, etc.) that should be applied to a set of Zephyr libraries and ‘app’ might be one of these libraries.

Zephyr libraries must explicitly call zephyr_library_link_libraries(<interface_library>) to use this build information. ‘app’ is treated as a special case for usability reasons; a Kconfig option (CONFIG_APP_LINK_WITH_<interface_library>) should exist for each interface_library and will determine if ‘app’ links with the interface_library.

This API has a constructor like the zephyr_library API has, but it does not have wrappers over the other cmake target functions.

zephyr_interface_library_named(<name>)

Create a Zephyr interface library with a given name.

generate_inc_*

These functions are useful if there is a need to generate a file that can be included into the application at build time. The file can also be compressed automatically when embedding it.

See tests/application_development/gen_inc_file for an example of usage.

generate_inc_file(<source_file> <generated_file> ...)

Generate a file that can be included into the application at build time.

source_file

The source file to be converted to hex

generated_file

The generated file

...

Extra arguments are passed to file2hex.py

board_*

This section is for extensions related to Zephyr board handling.

Zephyr board runners

Zephyr board runner extension functions control Zephyr’s board runners from the build system. The Zephyr build system has targets for flashing and debugging supported boards. These are wrappers around a “runner” Python subpackage that is part of Zephyr’s “west” tool.

This section provides glue between CMake and the Python code that manages the runners.

board_set_runner(<type> <runner>)

This function sets the runner for the board unconditionally. It’s meant to be used from application’s CMakeLists.txt files.

NOTE: Usually board_set_xxx_ifnset() is best in board.cmake files.

This lets the user set the runner at cmake time, or in their own application’s CMakeLists.txt.

Example usage:

board_set_runner(FLASH pyocd)

This would set the board’s flash runner to “pyocd”.

In general, “type” is FLASH, DEBUG, SIM or ROBOT and “runner” is the name of a runner.

board_set_runner_ifnset(<type> <runner>)

This macro is like board_set_runner(), but will only make a change if that runner is currently not set.

See also board_set_flasher_ifnset() and board_set_debugger_ifnset().

board_set_flasher(<runner>)

A convenience macro for board_set_runner(FLASH ${runner}).

board_set_debugger(<runner>)

A convenience macro for board_set_runner(DEBUG ${runner}).

board_set_flasher_ifnset(<runner>)

A convenience macro for board_set_runner_ifnset(FLASH ${runner}).

board_set_debugger_ifnset(<runner>)

A convenience macro for board_set_runner_ifnset(DEBUG ${runner}).

board_set_robot_runner_ifnset(<runner>)

A convenience macro for board_set_runner_ifnset(ROBOT ${runner}).

board_set_sim_runner_ifnset(<runner>)

A convenience macro for board_set_runner_ifnset(SIM ${runner}).

board_runner_args(<runner> <args>...)

This function is intended for board.cmake files and application CMakeLists.txt files.

Usage from board.cmake files:

board_runner_args(runner "--some-arg=val1" "--another-arg=val2")

The build system will then ensure the command line used to create the runner contains:

--some-arg=val1 --another-arg=val2

Within application CMakeLists.txt files, ensure that all calls to board_runner_args() are part of a macro named app_set_runner_args(), like this, which is defined before calling find_package(Zephyr):.

macro(app_set_runner_args)
  board_runner_args(runner "--some-app-setting=value")
endmacro()

The build system tests for the existence of the macro and will invoke it at the appropriate time if it is defined.

Any explicitly provided settings given by this function override defaults provided by the build system.

board_set_rimage_target(<target>)

Set the rimage target for the current board.

Zephyr board revision

This section provides a function for revision checking.

board_check_revision(FORMAT <LETTER | NUMBER | MAJOR.MINOR.PATCH> [EXACT] [DEFAULT_REVISION <revision>] [HIGHEST_REVISION <revision>] [VALID_REVISIONS <revision> ...] )

Zephyr board extension function.

This function can be used in boards/board/revision.cmake to check a user requested revision against available board revisions.

The function will check the revision from -DBOARD=board@revision that is provided by the user according to the arguments. When EXACT is not specified, this function will set the Zephyr build system variable ACTIVE_BOARD_REVISION with the selected revision.

FORMAT <LETTER | NUMBER | MAJOR.MINOR.PATCH>

Specify the revision format.

LETTER

Revision format is a single letter from A - Z.

NUMBER

Revision format is a single integer number.

MAJOR.MINOR.PATCH

Revision format is three numbers, separated by ., x.y.z. Trailing zeroes may be omitted on the command line, which means that 1.0.0 == 1.0 == 1.

OPTIONAL

Revision specifier is optional.

If revision is not provided the base board will be used. If both EXACT and OPTIONAL are given, then specifying the revision is optional, but if it is given then the EXACT requirements apply. Mutually exclusive with DEFAULT_REVISION.

EXACT

Revision is required to be an exact match.

As example, available revisions are: 0.1.0 and 0.3.0, and user provides 0.2.0, then an error is reported when EXACT is given. If EXACT is not provided, then closest lower revision will be selected as the active revision, which in the example will be 0.1.0.

DEFAULT_REVISION

Provides a default revision to use when user has not selected a revision number.

If no default revision is provided then user will be printed with an error if no revision is given on the command line.

HIGHEST_REVISION

Allows to specify highest valid revision for a board.

This can be used to ensure that a newer board cannot be used with an older Zephyr. As example, if current board supports revisions 0.x.0-0.99.99 and 1.0.0-1.99.99, and it is expected that current board implementation will not work with board revision 2.0.0, then HIGHEST_REVISION can be set to 1.99.99, and user will be printed with an error if using <board>@2.0.0 or higher. This field is not needed when EXACT is used.

VALID_REVISIONS

A list of valid revisions for this board.

If this argument is not provided, then each Kconfig fragment of the form board_revision.conf in the board folder will be used as a valid revision for the board.

Misc.

pow2round(<variable>)

Round number to next power of two.

Example usage:

set(test 2)
pow2round(test)
# test is still 2

set(test 5)
pow2round(test)
# test is now 8
zephyr_build_string(outvar [BOARD board] [SHORT short_outvar] [BOARD_QUALIFIERS qualifiers] [BOARD_REVISION revision] [MERGE] [REVERSE])

Create a build string based on BOARD, BOARD_REVISION, and BOARD_QUALIFIER. This is a common function to ensure that build strings are always created in a uniform way.

When MERGE is supplied a list of build strings will be returned with the full build string as first item in the list. The full order of build strings returned in the list will be:

  • Normalized board target build string, this includes qualifiers and revision ;

  • Build string with board variants removed in addition ;

  • Build string with cpuset removed in addition ;

  • Build string with soc removed in addition.

If REVISION is supplied or obtained as system wide setting a build string with the sanitized revision string will be added in addition to the non-revisioned entry for each entry.

outvar

Output variable where the build string will be returned.

BOARD board

Board name to use when creating the build string.

SHORT short_outvar

Output variable where the shortened build string will be returned.

BOARD_QUALIFIERS qualifiers

Board qualifiers to use.

BOARD_REVISION revision

Board revision to use.

MERGE

Return a list of build strings instead of a single build string.

REVERSE

Reverse the list before returning it.

Example usage:

zephyr_build_string(build_string BOARD alpha)
# Returns "alpha" in build_string

zephyr_build_string(build_string BOARD alpha
                                 BOARD_REVISION 1.0.0)
# Returns "alpha_1_0_0" in build_string

zephyr_build_string(build_string BOARD alpha
                                 BOARD_QUALIFIERS /soc/bar)
# Returns "alpha_soc_bar" in build_string

zephyr_build_string(build_string BOARD alpha
                                 BOARD_REVISION 1.0.0
                                 BOARD_QUALIFIERS /soc/bar
                                 MERGE)
# Returns list "alpha_soc_bar_1_0_0;alpha_soc_bar" in build_string

zephyr_build_string(build_string SHORT short_build_string
                                 BOARD alpha
                                 BOARD_REVISION 1.0.0
                                 BOARD_QUALIFIERS /soc/bar
                                 MERGE)
# Returns list "alpha_soc_bar_1_0_0;alpha_soc_bar" in build_string
# Returns list "alpha_bar_1_0_0;alpha_bar" in short_build_string

zephyr_build_string(build_string BOARD_QUALIFIERS /soc/bar/foo)
# Returns "soc_bar_foo" in build_string
zephyr_syscall_include_directories(<directories>...)

Add one or more directories to the include list passed to the syscall generator.

<directories>...

One or more directories to add.

zephyr_syscall_header(<headers>...)

Add one or more header files to the list passed to the syscall generator.

<headers>...

One or more header files to add.

zephyr_syscall_header_ifdef(feature_toggle <headers>...)

Add one or more header files to the list passed to the syscall generator if``feature_toggle`` is true.

feature_toggle

The name of the boolean variable to check.

<headers>...

One or more header files to add.

zephyr_blobs_verify(<MODULE module | FILES file [files...]> [REQUIRED])

Verify blobs fetched using west. If the sha256 checksum isn’t valid, a warning/fatal error message is printed (level depends on REQUIRED flag).

MODULE module

Verify all blobs in the given module.

FILES file [files...]

Verify the specified files.

REQUIRED

If specified, a fatal error is raised if the verification fails. Otherwise, a warning is printed.

Example usage:

# Verify all blobs in my_module and fail on error
zephyr_blobs_verify(MODULE my_module REQUIRED)

# Verify a single file and print on error
zephyr_blobs_verify(FILES img/file.bin)

Kconfig-aware extensions

Kconfig is a configuration language developed for the Linux kernel. The below functions integrate CMake with Kconfig.

Misc

import_kconfig(prefix kconfig_fragment [keys] [TARGET target])

Parse a KConfig fragment (typically with extension .config) and introduce all the symbols that are prefixed with prefix into the CMake namespace. List all created variable names in the keys output variable if present.

prefix

symbol prefix of settings in the Kconfig fragment.

kconfig_fragment

absolute path to the config fragment file.

keys

output variable which will be populated with variable names loaded from the kconfig fragment.

TARGET

set all symbols on target instead of adding them to the CMake namespace.

CMake-generic extensions

These functions extend the CMake API in a way that is not particular to Zephyr. Primarily, they work around limitations in the CMake language to allow cleaner build scripts.

add_subdirectory_ifdef

This function adds a subdirectory to the build if feature_toggle is enabled.

Debugging CMake

print(arg)

Print the value of a variable.

Example usage:

print(BOARD)
# will print: "BOARD: nrf52dk"
assert(test comment)

Assert that a condition is true.

This macro will cause a fatal error and print an error message if the first expression is false.

test

The boolean expression to test.

comment

The error message to print if the assertion fails.

Example usage:

assert(ZEPHYR_TOOLCHAIN_VARIANT "ZEPHYR_TOOLCHAIN_VARIANT not set.")
assert_not(test comment)

Assert that a condition is false.

This macro will cause a fatal error and print an error message if the first expression is true.

test

The boolean expression to test.

comment

The error message to print if the assertion fails.

Example usage:

assert_not(OBSOLETE_VAR "OBSOLETE_VAR has been removed; use NEW_VAR instead")
assert_exists(var)

Assert that a file or directory exists.

This macro will cause a fatal error if the file or directory pointed to by the variable does not exist.

var

The name of the variable containing the path to check.

Example usage:

assert_exists(CMAKE_READELF)

File system management

generate_unique_target_name_from_filename(filename target_name)

Generate a unique target name from a filename.

filename

The filename to generate a unique name from.

target_name

The name of the variable to store the generated target name in.

zephyr_file(APPLICATION_ROOT <path> [BASE_DIR <base-dir>])
zephyr_file(CONF_FILES <paths> [DTS <list>] [KCONF <list>] [DEFCONF <list>] [BOARD <board> [BOARD_REVISION <revision>] | NAMES <name> ...] [SUFFIX <suffix>] [REQUIRED])

Zephyr file function extension. This function currently supports the following modes:

APPLICATION_ROOT

Check all paths in provided variable, and convert those paths that are defined with -D<path>=<val> to absolute path, relative from APPLICATION_SOURCE_DIR. Issue an error for any relative path not specified by user with -D<path>.

BASE_DIR <base-dir>

Convert paths relative to <base-dir> instead of APPLICATION_SOURCE_DIR.

Returns an updated list of absolute paths.

CONF_FILES

Find all configuration files in the list of paths and return them in a list. If paths is empty then no configuration files are returned.

Configuration files will be:

  • DTS: Overlay files (.overlay)

  • Kconfig: Config fragments (.conf)

  • defconfig: defconfig files (_defconfig)

The conf file search will return existing configuration files for the current board.

CONF_FILES takes the following additional arguments:

BOARD <board>

Find configuration files for specified board.

BOARD_REVISION <revision>

Find configuration files for specified board revision. Requires BOARD to be specified. If no board is given the current BOARD and BOARD_REVISION will be used, unless NAMES are specified.

NAMES <name1> [name2] ...

List of file names to look for and instead of creating file names based on board settings. Only the first match found in <paths> will be returned in the <list>.

DTS <list>

List to append DTS overlay files in <path> to.

KCONF <list>

List to append Kconfig fragment files in <path> to.

DEFCONF <list>

List to append _defconfig files in <path> to.

SUFFIX <name>

Suffix name to check for instead of the default name but with a fallback to the default name if not found.

For example: SUFFIX fish, will look for <file>_fish.conf and use if found but will use <file>.conf if not found.

REQUIRED

Option to indicate that the <list> specified by DTS or KCONF must contain at least one element, else an error will be raised.

zephyr_file_copy(<oldname> <newname> [ONLY_IF_DIFFERENT])

Zephyr file copy extension.

Deprecated: this function only existed because file(COPY_FILE...) was not available with CMake 3.20; call file(COPY_FILE ...) directly instead.

oldname

Old file name.

newname

New file name.

ONLY_IF_DIFFERENT

Only copy if the files are different.

zephyr_file_suffix(<filename> SUFFIX <suffix>)

Update the filename(s) with the suffix if a file with the suffix exists.

This function checks the provided filename or list of filenames to see if a file with the _<suffix> extension exists. If so, it updates the supplied variable/list with the new path/paths.

<filename>

Variable (singular or list) of absolute path filename(s).

<suffix>

The suffix to test for and append to the end of the provided filename.

Returns an updated variable of absolute path(s).

Others

zephyr_string(ESCAPE <out-var> <input> ...)
zephyr_string(SANITIZE <out-var> <input> ...)
zephyr_string(SANITIZE TOUPPER <out-var> <input> ...)

Zephyr string function extension.

This function extends the CMake string function by providing additional manipulation options for the <mode> argument, namely:

ESCAPE

Ensure that every character of the input arguments is considered by CMake as a literal by prefixing the escape character \ where appropriate. This is useful for handling Windows path separators in strings, or when it is desired to write \n as an actual string of four characters instead of a single newline. Note that this operation must be performed exactly once during the lifetime of a string, or previous escape characters will be treated as literals and escaped further.

SANITIZE

Ensure that the output string does not contain any special characters. Special characters, such as -, +, =, $, etc. are converted to underscores _. Multiple arguments are concatenated.

SANITIZE TOUPPER

Ensure that the output string does not contain any special characters. Special characters, such as -, +, =, $, etc. are converted to underscores _. Multiple arguments are concatenated. The sanitized string will be returned in UPPER case.

Returns the updated string in <out-var>.

zephyr_list(TRANSFORM <list> <ACTION> [OUTPUT_VARIABLE <output variable>])

Zephyr list function extension.

Like CMake’s list(TRANSFORM ...) this is intended as a placeholder for storing current and future Zephyr-related extensions for list processing.

<ACTION>

This currently must be NORMALIZE_PATHS. This action converts the argument list <list> to a ;-list with CMake path names, after passing its contents through a configure_file transformation. The input list may be whitespace- or semicolon-separated.

OUTPUT_VARIABLE

the result is normally stored in place, but an alternative variable to store the result can be provided with this.

zephyr_get(<variable> [MERGE [REVERSE]] [SYSBUILD [LOCAL|GLOBAL]] [VAR <var1> ...])

Return the value of <variable> as local scoped variable of same name.

If MERGE is supplied, will return a list of found items.

If REVERSE is supplied together with MERGE, the order of the list will be reversed before being returned. Reverse will happen before the list is returned and hence it will not change the order of precedence in which the list itself is constructed.

VAR can be used either to store the result in a variable with a different name, or to look for values from multiple variables.

zephyr_get(FOO VAR FOO_A FOO_B)
zephyr_get(FOO MERGE VAR FOO_A FOO_B)

zephyr_get() is a common function to provide a uniform way of supporting build settings that can be set from sysbuild, CMakeLists.txt, CMake cache, or in environment.

The order of precedence for variables defined in multiple scopes:

  • Sysbuild defined when sysbuild is used. Sysbuild variables can be defined as global or local to specific image. Examples:

    • BOARD is considered a global sysbuild cache variable

    • blinky_BOARD is considered a local sysbuild cache variable only for the blinky image.

    If no sysbuild scope is specified, GLOBAL is assumed. If using MERGE then SYSBUILD GLOBAL will get both the local and global sysbuild scope variables (in that order, if both exist).

  • CMake cache, set by -D<var>=<value> or set(<var> <val> CACHE ...)

  • Environment

  • Locally in CMakeLists.txt before find_package(Zephyr)

For example, if ZEPHYR_TOOLCHAIN_VARIANT is set in environment but locally overridden by setting ZEPHYR_TOOLCHAIN_VARIANT directly in the CMake cache using -DZEPHYR_TOOLCHAIN_VARIANT=<val>, then the value from the cache is returned.

zephyr_create_scope(<scope>)

Create a new scope for the creation of scoped variables.

<scope>

Name of new scope.

zephyr_scope_exists(<result> <scope>)

Check if <scope> exists.

<result>

Variable to set with result. TRUE if scope exists, FALSE otherwise.

<scope>

Name of scope.

zephyr_get_scoped(<output> <scope> <var>)

Get the current value of <var> in a specific <scope>, as defined by a previous zephyr_set() call. The value will be stored in the <output> var.

<output>

Variable to store the value in

<scope>

Scope for the variable look up

<var>

Name to look up in the specific scope

zephyr_set(<variable> <value> SCOPE <scope> [APPEND])

Zephyr extension of CMake set which allows a variable to be set in a specific scope.

The scope is used on later zephyr_get() invocation for precedence handling when a variable it set in multiple scopes.

<variable>

Name of variable

<value>

Value of variable, multiple values will create a list. The SCOPE argument identifies the end of value list.

SCOPE <scope>

Name of scope for the variable

APPEND

Append values to the already existing variable in <scope>

zephyr_check_cache(<variable> [REQUIRED] [WATCH])

Check the current CMake cache for <variable> and warn the user if the value is being modified.

This can be used to ensure the user does not accidentally try to change Zephyr build variables, such as:

  • BOARD

  • SHIELD

<variable>

Name of <variable> to check and set, for example BOARD.

REQUIRED

Optional flag. If specified, then an unset <variable> will be treated as an error.

WATCH

Optional flag. If specified, watch the variable and print a warning if the variable is later being changed.

Details:

<variable> can be set by 3 sources.

  • Using CMake argument, -D<variable>

  • Using an environment variable

  • In the project CMakeLists.txt before find_package(Zephyr).

CLI has the highest precedence, then comes environment variables, and then finally CMakeLists.txt.

The value defined on the first CMake invocation will be stored in the CMake cache as CACHED_<variable>. This allows the Zephyr build system to detect when a user reconfigures a sticky variable.

A user can ignore all the precedence rules if the same source is always used E.g. always specifies -D<variable>= on the command line, always has an environment <variable> set, or always has a set(<variable> foo) line in his CMakeLists.txt and avoids mixing sources.

The selected <variable> can be accessed through the variable ‘<variable>’ in following Zephyr CMake code.

If the user tries to change <variable> to a new value, then a warning will be printed, and the previously cached value (CACHED_<variable>) will be used, as it has precedence.

Together with the warning, user is informed that in order to change <variable> the build directory must be cleaned.

zephyr_get_targets(<directory> <types> <targets>)

Get build targets for a given directory and sub-directories.

This functions will traverse the build tree, starting from <directory>. It will read the BUILDSYSTEM_TARGETS for each directory in the build tree and return the build types matching the <types> list.

Example of types: OBJECT_LIBRARY, STATIC_LIBRARY, INTERFACE_LIBRARY, UTILITY.

Returns a list of targets in <targets> matching the required <types>.

target_byproducts(TARGET <target> BYPRODUCTS <file> ...)

Specify additional BYPRODUCTS that this target produces.

This function allows the build system to specify additional byproducts to target created with add_executable. When linking an executable the linker may produce additional files, like map files. Those files are not known to the build system. This function makes it possible to describe such additional byproducts in an easy manner.

TARGET <target>

The target to add byproducts to.

BYPRODUCTS <file> ...

List of byproducts that the target produces.

topological_sort(TARGETS <target> ... PROPERTY_NAME <property> RESULT <out-variable>)

This function performs topological sorting of CMake targets using a specific <property>, which dictates target dependencies. A fatal error occurs if the provided dependencies cannot be met, e.g., if they contain cycles.

TARGETS <target> ...

List of target names.

PROPERTY_NAME <property>

Name of the target property to be used when sorting. For every target listed in TARGETS, this property must contain a list (possibly empty) of other targets, which this target depends on for a particular purpose. The property must not contain any target which is not also found in TARGETS.

RESULT <out-variable>

Output variable, where the topologically sorted list of target names will be returned.

build_info(<tag>... VALUE <value>...)
build_info(<tag>... PATH <path>...)

Populates the build_info.yml info file with exchangeable build information related to the current build.

Example usage:

# This will update the 'devicetree.files' key in the build info yaml with the list of files
# file1.dts, file2.dts, file3.dts
build_info(devicetree files VALUE file1.dts file2.dts file3.dts)
# This will place the vendor specific 'foo' key with value 'bar' in the vendor-specific
# section of the build info file.
build_info(vendor-specific foo VALUE bar)
<tag>...

One of the pre-defined valid CMake keys supported by build info or vendor-specific. See scripts/schemas/build-schema.yaml, cmake section, for valid tags.

VALUE <value>...

Value(s) to place in the build_info.yml file.

PATH  <path>...

Path(s) to place in the build_info.yml file. All paths are converted to CMake style. If no conversion is required, for example when paths are already guaranteed to be CMake style, then VALUE can also be used.

Devicetree extensions

dt_*

The following methods are for retrieving devicetree information in CMake.

Notes:

  • In CMake, we refer to the nodes using the node’s path, therefore there is no dt_path(...) function for obtaining a node identifier like there is in the C devicetree.h API.

  • As another difference from the C API, you can generally use an alias at the beginning of a path interchangeably with the full path to the aliased node in these functions. The usage comments will make this clear in each case.

  • These methods are also available to sysbuild. To retrieve the DT information of some <image>, after its CMake configuration step, the dt_* function call must include a TARGET <image> argument.

dt_nodelabel(<var> NODELABEL <label> [REQUIRED] [TARGET <target>])

Function for retrieving the node path for the node having nodelabel <label>.

The node’s path will be returned in the <var> parameter. <var> will be undefined if node does not exist.

<var>

Return variable where the node path will be stored

NODELABEL <label>

Node label

REQUIRED

Generate a fatal error if the node-label is not found

TARGET <target>

Optional target to retrieve devicetree information from

Example devicetree fragment:

/ {
   soc {
       nvic: interrupt-controller@e000e100  { ... };
   };
};

Example usage:

# Sets 'nvic_path' to "/soc/interrupt-controller@e000e100"
dt_nodelabel(nvic_path NODELABEL "nvic")
dt_alias(<var> PROPERTY <prop> [REQUIRED] [TARGET <target>])

Get a node path for an /aliases node property.

The node’s path will be returned in the <var> parameter. The variable will be left undefined if the alias does not exist.

<var>

Return variable where the node path will be stored

PROPERTY <prop>

The alias to check

REQUIRED

Generate a fatal error if the alias is not found

TARGET <target>

Optional target to retrieve devicetree information from

Example usage:

# The full path to the 'led0' alias is returned in 'path'.
dt_alias(path PROPERTY "led0")

# The variable 'path' will be left undefined for a nonexistent
# alias "does-not-exist".
dt_alias(path PROPERTY "does-not-exist")
dt_node_exists(<var> PATH <path> [TARGET <target>])

Tests whether a node with path <path> exists in the devicetree.

The <path> value may be any of these:

  • absolute path to a node, like /foo/bar

  • a node alias, like my-alias

  • a node alias followed by a path to a child node, like my-alias/child-node

The result of the check, either TRUE or FALSE, will be returned in the <var> parameter.

<var>

Return variable where the check result will be returned

PATH <path>

Node path

TARGET <target>

Optional target to retrieve devicetree information from

dt_node_has_status(<var> PATH <path> STATUS <status> [TARGET <target>])

Tests whether <path> refers to a node which:

  • exists in the devicetree, and

  • has a status property matching the <status> argument (a missing status or an “ok” status is treated as if it were “okay” instead)

The <path> value may be any of these:

  • absolute path to a node, like ‘/foo/bar’

  • a node alias, like ‘my-alias’

  • a node alias followed by a path to a child node, like ‘my-alias/child-node’

The result of the check, either TRUE or FALSE, will be returned in the <var> parameter.

<var>

Return variable where the check result will be returned

PATH <path>

Node path

STATUS <status>

Status to check

TARGET <target>

Optional target to retrieve devicetree information from

dt_prop(<var> PATH <path> PROPERTY <prop> [INDEX <idx>] [REQUIRED] [TARGET <target>])

Get a devicetree property value. The value will be returned in the <var> parameter.

The <path> value may be any of these:

  • absolute path to a node, like ‘/foo/bar’

  • a node alias, like ‘my-alias’

  • a node alias followed by a path to a child node, like ‘my-alias/child-node’

This function currently only supports properties with the following devicetree binding types: string, int, boolean, array, uint8-array, string-array, path.

For array valued properties (including uint8-array and string-array), the entire array is returned as a CMake list unless INDEX is given. If INDEX is given, just the array element at index <idx> is returned.

The property value will be returned in the <var> parameter if the node exists and has a property <prop> with one of the above types. <var> will be undefined otherwise.

<var>

Return variable where the property value will be stored

PATH <path>

Node path

PROPERTY <prop>

Property for which a value should be returned, as it appears in the DTS source

INDEX <idx>

Optional index when retrieving a value in an array property

REQUIRED

Generate a fatal error if the property is not found

TARGET <target>

Optional target to retrieve devicetree information from

To test if the property is defined before using it, use DEFINED on the return <var>, like this:

dt_prop(reserved_ranges PATH "/soc/gpio@deadbeef" PROPERTY "gpio-reserved-ranges")
if(DEFINED reserved_ranges)
  # Node exists and has the "gpio-reserved-ranges" property.
endif()

To distinguish a missing node from a missing property, combine dt_prop() and dt_node_exists(), like this:

dt_node_exists(node_exists PATH "/soc/gpio@deadbeef")
dt_prop(reserved_ranges    PATH "/soc/gpio@deadbeef" PROPERTY "gpio-reserved-ranges")
if(DEFINED reserved_ranges)
  # Node "/soc/gpio@deadbeef" exists and has the "gpio-reserved-ranges" property
elseif(node_exists)
  # Node exists, but doesn't have the property, or the property has an unsupported type.
endif()
dt_comp_path(<var> COMPATIBLE <compatible> [INDEX <idx>] [TARGET <target>])

Get a list of paths for the nodes with the given compatible. The value will be returned in the <var> parameter. <var> will be undefined if no such compatible exists.

For details and considerations about the format of <path> and the returned parameter refer to dt_prop().

<var>

Return variable where the property value will be stored

COMPATIBLE <compatible>

Compatible for which the list of paths should be returned, as it appears in the DTS source

INDEX <idx>

Optional index when retrieving a value in an array property

TARGET <target>

Optional target to retrieve devicetree information from

dt_num_regs(<var> PATH <path> [TARGET <target>])

Get the number of register blocks in the node’s reg property; this may be zero.

The value will be returned in the <var> parameter.

The <path> value may be any of these:

  • absolute path to a node, like ‘/foo/bar’

  • a node alias, like ‘my-alias’

  • a node alias followed by a path to a child node, like ‘my-alias/child-node’

<var>

Return variable where the property value will be stored

PATH <path>

Node path

TARGET <target>

Optional target to retrieve devicetree information from

dt_reg_addr(<var> PATH <path> [INDEX <idx>] [NAME <name>] [TARGET <target>])

Get the base address of the register block at index <idx>, or with name <name>. If <idx> and <name> are both omitted, the value at index 0 will be returned. Do not give both <idx> and <name>.

The value will be returned in the <var> parameter.

The <path> value may be any of these:

  • absolute path to a node, like ‘/foo/bar’

  • a node alias, like ‘my-alias’

  • a node alias followed by a path to a child node, like ‘my-alias/child-node’

Results can be:

  • The base address of the register block

  • <var> will be undefined if node does not exists or does not have a register block at the requested index or with the requested name

<var>

Return variable where the address value will be stored

PATH <path>

Node path

INDEX <idx>

Register block index number

NAME <name>

Register block name

TARGET <target>

Optional target to retrieve devicetree information from

dt_reg_size(<var> PATH <path> [INDEX <idx>] [NAME <name>] [TARGET <target>])

Get the size of the register block at index <idx>, or with name <name>. If <idx> and <name> are both omitted, the value at index 0 will be returned. Do not give both <idx> and <name>.

The value will be returned in the <value> parameter.

The <path> value may be any of these:

  • absolute path to a node, like ‘/foo/bar’

  • a node alias, like ‘my-alias’

  • a node alias followed by a path to a child node, like ‘my-alias/child-node’

<var>

Return variable where the size value will be stored

PATH <path>

Node path

INDEX <idx>

Register block index number

NAME <name>

Register block name

TARGET <target>

Optional target to retrieve devicetree information from

dt_has_chosen(<var> PROPERTY <prop> [TARGET <target>])

Test if the devicetree’s /chosen node has a given property <prop> which contains the path to a node.

The result of the check, either TRUE or FALSE, will be stored in the <var> parameter.

<var>

Return variable

PROPERTY <prop>

Chosen property

TARGET <target>

Optional target to retrieve devicetree information from

Example devicetree fragment:

chosen {
        foo = &bar;
};

Example usage:

# Sets 'result' to TRUE
dt_has_chosen(result PROPERTY "foo")

# Sets 'result' to FALSE
dt_has_chosen(result PROPERTY "baz")
dt_chosen(<var> PROPERTY <prop> [TARGET <target>])

Get a node path for a /chosen node property.

The node’s path will be returned in the <var> parameter. The variable will be left undefined if the chosen node does not exist.

<var>

Return variable where the node path will be stored

PROPERTY <prop>

Chosen property

TARGET <target>

Optional target to retrieve devicetree information from

*_if_dt_node

This section is similar to the extensions named *_ifdef, except actions are performed if the devicetree contains some node. *_if_dt_node functions may be added as needed, or if they are likely to be useful for user applications.

target_sources_if_dt_node(<path> <target> <scope> <item>...)

Add item(s) to a target’s SOURCES list if a devicetree node exists.

<path>

Path to devicetree node to check

<target>

Build system target whose sources to add to

<scope>

Scope to add items to

<item>

Item (or items) to add to the target

Example usage:

# If the devicetree alias "led0" refers to a node, this
# adds "blink_led.c" to the sources list for the "app" target.
target_sources_if_dt_node("led0" app PRIVATE blink_led.c)

# If the devicetree path "/soc/serial@4000" is a node, this
# adds "uart.c" to the sources list for the "lib" target,
target_sources_if_dt_node("/soc/serial@4000" lib PRIVATE uart.c)

zephyr_dt_*

The following methods are common code for dealing with devicetree related files in CMake.

Note that functions related to accessing the contents of the devicetree belong in section 4.1. This section is just for DT file processing at configuration time.

zephyr_dt_preprocess(CPP <path> [<argument...>] SOURCE_FILES <file...> OUT_FILE <file> [DEPS_FILE <file> [EXTRA_CPPFLAGS <flag...>] [INCLUDE_DIRECTORIES <dir...>] [WORKING_DIRECTORY <dir>])

Preprocess one or more devicetree source files. The preprocessor symbol __DTS__ will be defined. If the preprocessor command fails, a fatal error occurs.

Mandatory arguments:

CPP <path> [<argument...>]

path to C preprocessor, followed by any additional arguments

SOURCE_FILES <file...>

The source files to run the preprocessor on. These will, in effect, be concatenated in order and used as the preprocessor input.

OUT_FILE <file>

Where to store the preprocessor output.

Optional arguments:

DEPS_FILE <file>

If set, generate a dependency file here.

EXTRA_CPPFLAGS <flag...>

Additional flags to pass the preprocessor.

INCLUDE_DIRECTORIES <dir...>

Additional #include file directories.

WORKING_DIRECTORY <dir>

where to run the preprocessor.

zephyr_dt_import(EDT_PICKLE_FILE <file> TARGET <target>)

Parse devicetree information and make it available to CMake, so that it can be accessed by the dt_* CMake extensions from section 4.1.

This requires running a Python script, which can take the output of edtlib and generate a CMake source file from it. If that script fails, a fatal error occurs.

EDT_PICKLE_FILE <file>

Input edtlib.EDT object in pickle format

TARGET <target>

Target to populate with devicetree properties

Zephyr linker functions

zephyr_linker*

The following methods are for defining linker structure using CMake functions.

This allows Zephyr developers to define linker sections and their content and have this configuration rendered into an appropriate linker script based on the toolchain in use.

For example:

  • ld linker scripts with GNU ld

  • ARM scatter files with ARM linker.

Example usage:

zephyr_linker_section(
  NAME my_data
  VMA  RAM
  LMA  FLASH
)

# and to configure special input sections for the section
zephyr_linker_section_configure(
  SECTION my_data
  INPUT   "my_custom_data"
  KEEP
)
zephyr_linker([FORMAT <format>] [ENTRY <entry_symbol>])

Zephyr linker general settings. This function specifies general settings for the linker script to be generated.

FORMAT <format>

The output format of the linked executable.

ENTRY <entry_symbol>

The code entry symbol.

zephyr_linker_memory(NAME <name> START <address> SIZE <size> [FLAGS <flags>])

Zephyr linker memory. This function specifies a memory region for the platform in use.

Note

This function should generally be called with values obtained from devicetree or Kconfig.

NAME <name>

Name of the memory region, for example FLASH.

START <address>

Start address of the memory region. Start address can be given as decimal or hex value.

SIZE <size>

Size of the memory region.

Size can be given as decimal value, hex value, or decimal with postfix k or m. All the following are valid values: 1048576, 0x10000, 1024k, 1024K, 1m, and 1M.

FLAGS <flags>

Flags describing properties of the memory region.

  • r: Read-only region

  • w: Read-write region

  • x: Executable region

  • a: Allocatable region

  • i: Initialized region

  • l: Same as i

  • !: Invert the sense of any of the attributes that follow

The flags may be combined like: rx, rx!w.

zephyr_linker_memory_ifdef(<setting> NAME <name> START <address> SIZE <size> [FLAGS <flags>])

Will create memory region if <setting> is enabled.

<setting>

Setting to check for True value before invoking zephyr_linker_memory()

See zephyr_linker_memory() description for other supported arguments.

zephyr_linker_dts_section(PATH <path>)

Zephyr linker devicetree memory section from path.

This function specifies an output section for the platform in use based on its devicetree configuration.

The section will only be defined if the devicetree exists and has status okay.

PATH <path>

Devicetree node path.

zephyr_linker_dts_memory(PATH <path>)
zephyr_linker_dts_memory(NODELABEL <nodelabel>)
zephyr_linker_dts_memory(CHOSEN <prop>)

Zephyr linker devicetree memory.

This function specifies a memory region for the platform in use based on its devicetree configuration.

The memory will only be defined if the devicetree node or a devicetree node matching the nodelabel exists and has status okay.

Only one of PATH, NODELABEL, and CHOSEN parameters may be given.

PATH <path>

Devicetree node identifier.

NODELABEL <label>

Node label

CHOSEN <prop>

Chosen property, add memory section described by the /chosen property if it exists.

zephyr_linker_group(NAME <name> [VMA <region|group>] [LMA <region|group>] [GROUP <group>] [SYMBOL <SECTION>])

Zephyr linker group. This function specifies a group inside a memory region or another group.

The group ensures that all section inside the group are located together inside the specified group.

This also allows for section placement inside a given group without the section itself needing the precise knowledge regarding the exact memory region this section will be placed in, as that will be determined by the group setup.

Each group will define the following linker symbols:

  • __name_start: Start address of the group

  • __name_end: End address of the group

  • __name_size: Size of the group

Note: <name> will be converted to lower casing for linker symbols definitions.

NAME <name>

Name of the group.

VMA <region|group>

VMA Memory region or group to be used for this group. If a group is used then the VMA region of that group will be used.

LMA <region|group>

Memory region or group to be used for this group.

GROUP <group>

Place the new group inside the existing group <group>

SYMBOL <SECTION>

Specify that start symbol of the region should be identical to the start address of the first section in the group.

Note: VMA and LMA are mutual exclusive with GROUP

Example:

zephyr_linker_memory(NAME memA START ... SIZE ... FLAGS ...)
zephyr_linker_group(NAME groupA LMA memA)
zephyr_linker_group(NAME groupB LMA groupA)

will create two groups in same memory region as groupB will inherit the LMA from groupA:

+-----------------+
| memory region A |
|                 |
| +-------------+ |
| | groupA      | |
| +-------------+ |
|                 |
| +-------------+ |
| | groupB      | |
| +-------------+ |
|                 |
| +-------------+ |

whereas

zephyr_linker_memory(NAME memA START ... SIZE ... FLAGS ...)
zephyr_linker_group(NAME groupA LMA memA)
zephyr_linker_group(NAME groupB GROUP groupA)

will create groupB inside groupA:

+---------------------+
| memory region A     |
|                     |
| +-----------------+ |
| | groupA          | |
| |                 | |
| | +-------------+ | |
| | | groupB      | | |
| | +-------------+ | |
| |                 | |
| +-----------------+ |
|                     |
+---------------------+
zephyr_linker_section(NAME <name> [GROUP <group>] [VMA <region|group>] [LMA <region|group>] [ADDRESS <address>] [ALIGN <alignment>] [SUBALIGN <alignment>] [FLAGS <flags>] [MIN_SIZE <size>] [MAX_SIZE <size>] [HIDDEN] [NOINPUT] [NOINIT] [PASS [NOT] <name>...])

Zephyr linker output section. This function specifies an output section for the linker.

When using zephyr_linker_section(NAME <name>) an output section with <name> will be configured. This section will default include input sections of the same name, unless NOINPUT is specified. This means the section named foo will default include the sections matching foo and foo.* Each output section will define the following linker symbols:

  • __name_start: Start address of the section

  • __name_end: End address of the section

  • __name_size: Size of the section

  • __name_load_start: Load address of the section, if VMA = LMA then this value will be identical to __name_start

The location of the output section can be controlled using LMA, VMA, and address parameters

NAME <name>

Name of the output section.

VMA <region|group>

VMA Memory region or group where code / data is located runtime (VMA) If <group> is used here it means the section will use the same VMA memory region as <group> but will not be placed inside the group itself, see also GROUP argument.

KVMA <region|group>

Kernel VMA Memory region or group where code / data is located runtime (VMA) When MMU is active and Kernel VM base and offset is different from SRAM base and offset, then the region defined by KVMA will be used as VMA. If <group> is used here it means the section will use the same VMA memory region as <group> but will not be placed inside the group itself, see also GROUP argument.

LMA <region|group>

Memory region or group where code / data is loaded (LMA) If VMA is different from LMA, the code / data will be loaded from LMA into VMA at bootup, this is usually the case for global or static variables that are loaded in rom and copied to ram at boot time. If <group> is used here it means the section will use the same LMA memory region as <group> but will not be placed inside the group itself, see also GROUP argument.

GROUP <group>

Place this section inside the group <group>

ADDRESS <address>

Specific address to use for this section.

ALIGN_WITH_INPUT

The alignment difference between VMA and LMA is kept intact for this section.

ALIGN <alignment>

Align the execution address with alignment.

SUBALIGN <alignment>

Align input sections with alignment value.

ENDALIGN <alignment>

Align the end so that next output section will start aligned. This only has effect on Scatter scripts.

Note: Regarding all alignment attributes. Not all linkers may handle alignment in identical way. For example the Scatter file will align both load and execution address (LMA and VMA) to be aligned when given the ALIGN attribute.

MIN_SIZE <size>

Pad section so that it at least <size> bytes in size.

MAX_SIZE <size>

Check that the sections is not larger than <size> bytes.

NOINPUT

No default input sections will be defined, to setup input sections for section <name>, the corresponding zephyr_linker_section_configure() must be used.

PASS [NOT] <name>...

Linker pass where this section should be active. By default a section will be present during all linker passes.

PASS <p1> <p2>... makes the section present only in the given passes. Empty list means no passes.

PASS NOT <p1> <p2>... makes the section present in all but the given passes. Empty list means all passes.

TYPE <type>

Tag section for special treatment.

  • NOLOAD, BSS - Ensure that the section is NOLOAD

  • LINKER_SCRIPT_FOOTER - One single section to be generated last

Note: VMA and LMA are mutual exclusive with GROUP

zephyr_linker_section_ifdef(<setting> NAME <name> [GROUP <group>] [VMA <region|group>] [LMA <region|group>] [ADDRESS <address>] [ALIGN <alignment>] [SUBALIGN <alignment>] [FLAGS <flags>] [MIN_SIZE <size>] [MAX_SIZE <size>] [HIDDEN] [NOINPUT] [NOINIT] [PASS [NOT] <name>...])

Will create an output section if <setting> is enabled.

<setting>

Setting to check for True value before invoking zephyr_linker_section()

See zephyr_linker_section() description for other supported arguments.

zephyr_iterable_section(NAME <name> [GROUP <group>] [VMA <region|group>] [LMA <region|group>] [ALIGN_WITH_INPUT] [SUBALIGN <alignment>])

Define an output section which will set up an iterable area of equally-sized data structures. For use with STRUCT_SECTION_ITERABLE. Input sections will be sorted by name in lexicographical order.

Each list for an input section will define the following linker symbols:

  • _<name>_list_start: Start of the iterable list

  • _<name>_list_end: End of the iterable list

The output section will be named <name>_area and define the following linker symbols:

Symbol

Description

__name_area_start

Start address of the section

__name_area_end

End address of the section

__name_area_size

Size of the section

__name_area_load_start

Load address of the section, if VMA = LMA then this value will be identical to __name_area_start

The options are:

NAME <name>

Name of the struct type, the output section be named accordingly as: <name>_area.

VMA <region|group>

VMA Memory region where code / data is located runtime (VMA)

LMA <region|group>

Memory region where code / data is loaded (LMA) If VMA is different from LMA, the code / data will be loaded from LMA into VMA at bootup, this is usually the case for global or static variables that are loaded in rom and copied to ram at boot time.

GROUP <group>

Place this section inside the group <group>

ADDRESS <address>

Specific address to use for this section.

ALIGN_WITH_INPUT

The alignment difference between VMA and LMA is kept in tact for this section.

NUMERIC

Use numeric sorting.

SUBALIGN <alignment>

Force input alignment with size <alignment>

Note

Regarding all alignment attributes. Not all linkers may handle alignment in identical way. For example the Scatter file will align both load and execution address (LMA and VMA) to be aligned when given the ALIGN attribute.

zephyr_linker_section_obj_level(SECTION <section> LEVEL <level>)

Generate a symbol to mark the start of the objects array for the specified object and level, then link all of those objects (sorted by priority). Ensure the objects aren’t discarded if there is no direct reference to them.

This is useful content such as struct devices.

For example: zephyr_linker_section_obj_level(SECTION init LEVEL PRE_KERNEL_1) will create an input section matching .z_init_PRE_KERNEL_P_1_SUB_?_, .z_init_PRE_KERNEL_P_1_SUB_??_, and .z_init_PRE_KERNEL_P_1_SUB_???_.

SECTION <section>

Section in which the objects shall be placed

LEVEL <level>

Priority level, all input sections matching the level will be sorted.

zephyr_linker_section_configure(SECTION <section> [ALIGN <alignment>] [PASS [NOT] <name>] [PRIO <no>] [SORT <sort>] [MIN_SIZE <size>] [MAX_SIZE <size>] [ANY] [FIRST] [KEEP] [INPUT <input>] [SYMBOLS [<start> [<end>]]])

Configure an output section with additional input sections. An output section can be configured with additional input sections besides its default section. For example, to add the input section foo to the output section bar, with KEEP attribute, call: zephyr_linker_section_configure(SECTION bar INPUT foo KEEP)

SECTION <section>

The output section to configure

ALIGN <alignment>

Will align the input section placement inside the load region with <alignment>

FIRST

The first input section in the list should be marked as first section in output.

SORT <NAME>

Sort the input sections according to <type>. Currently only NAME is supported.

MIN_SIZE <size>

Pad section so that it at least <size> bytes in size.

MAX_SIZE <size>

Check that the sections is not larger than <size> bytes.

KEEP

Do not eliminate input section during linking

PRIO

The priority of the input section. Per default, input sections order is not guaranteed by all linkers, but using priority Zephyr CMake linker will create sections such that order can be guaranteed. All unprioritized sections will internally be given a CMake process order priority counting from 100, so first unprioritized section is handled internal prio 100, next 101, and so on. To ensure a specific input section come before those, you may use PRIO 50, PRIO 20 and so on. To ensure an input section is at the end, it is advised to use PRIO 200 and above.

PASS [NOT] <pass>...

Control in which linker passes this piece is present See zephyr_linker_section() PASS for details.

FLAGS <flags>

Special section flags such as “+RO”, +XO, “+ZI”. The FLAGS and ANY arguments only has effect for scatter files.

ANY

ANY section flag in scatter file. The FLAGS and ANY arguments only has effect for scatter files.

INPUT <input>

Input section name or list of input section names. <input> is either just a section name “.data*” or <file-pattern>(<section-patterns>... ) <file-pattern> is [library.a:]file e.g. foo.a:bar.o(.data*)

SYMBOLS <start> <end>

Generate start and end symbols for the input section.

zephyr_linker_symbol(SYMBOL <name> EXPR <expr>)

Add additional user defined symbol to the generated linker script.

SYMBOL <name>

Symbol name to be available.

EXPR <expr>

Expression that defines the symbol. Due to linker limitations all expressions should only contain simple math, such as +, -, * and similar. The expression will go directly into the linker, and all @<symbol>@ will be replaced with the referred symbol.

Example:

To create a new symbol bar pointing to the start VMA address of section foo + 1024, one can write:

zephyr_linker_symbol(SYMBOL bar EXPR "(@foo@ + 1024)")
zephyr_linker_include_generated((CMAKE | KCONFIG | HEADER) <name> [PASS [NOT] <pass>...])

Add file that is generated at build-time to be included when running the linker script generator.

CMAKE <name>

includes the given cmake file

KCONFIG <name>

import_kconfig() the given Kconfig file. gives @variable@ access to all the CONFIG_FOO settings

HEADER <name>

finds all #define FOO value in name. Plain regex, no proper preprocessing.

PASS [NOT] <pass>...

Rule for which PASSES to include file. see zephyr_linker_section() PASS

zephyr_linker_include_var(VAR <name> [VALUE <value>] [PASS [NOT] <pass>...])

Save the value of <name> for when the generator is running at build-time. If VALUE isn’t set, the current value of the variable is used.

VAR <name>

Variable to be set

VALUE <value>

The value

PASS [NOT] <pass>...

Rule for which PASSES to include variable see zephyr_linker_section() PASS for details.

zephyr_linker_generate_linker_settings_file(<file_name>)

Generate a file for the settings to the linker file generator script.

<file_name>

File to be created

Function helper macros

Set of CMake macros to facilitate argument processing when defining functions.

zephyr_check_arguments_required(<function_name> <prefix> <arg1> [<arg2> ...])

Helper macro for verifying that at least one of the required arguments has been provided by the caller.

A FATAL_ERROR will be raised if not one of the required arguments has been passed by the caller.

<function_name>

Name of the function the check is performed for. Used in error message generation.

<prefix>

Prefix used in cmake_parse_arguments, usually arg or the function name in uppercase.

<arg>

One or more arguments to check.

zephyr_check_arguments_required_allow_empty(<function_name> <prefix> <arg1> [<arg2> ...])

Helper macro for verifying that at least one of the required arguments has been provided by the caller. Arguments with empty values are allowed.

A FATAL_ERROR will be raised if not one of the required arguments has been passed by the caller.

<function_name>

Name of the function the check is performed for. Used in error message generation.

<prefix>

Prefix used in cmake_parse_arguments, usually arg or the function name in uppercase.

<arg>

One or more arguments to check.

zephyr_check_flags_required(<function_name> <prefix> <flag1> [<flag2> ...])

Helper macro for verifying that at least one of the required flags has been provided by the caller.

A FATAL_ERROR will be raised if not one of the required arguments has been passed by the caller.

<function_name>

Name of the function the check is performed for. Used in error message generation.

<prefix>

Prefix used in cmake_parse_arguments, usually arg or the function name in uppercase.

<flag>

One or more flags to check.

zephyr_check_arguments_required_all(<function_name> <prefix> <arg1> [<arg2> ...])

Helper macro for verifying that all the required arguments have been provided by the caller.

A FATAL_ERROR will be raised if one of the required arguments is missing.

<function_name>

Name of the function the check is performed for. Used in error message generation.

<prefix>

Prefix used in cmake_parse_arguments, usually arg or the function name in uppercase.

<arg>

One or more arguments to check.

zephyr_check_arguments_exclusive(<function_name> <prefix> <arg1> <arg2> [<arg3> ...])

Helper macro for verifying that none of the mutual exclusive arguments are provided together.

A FATAL_ERROR will be raised if any of the arguments are given together.

<function_name>

Name of the function the check is performed for. Used in error message generation.

<prefix>

Prefix used in cmake_parse_arguments, usually arg or the function name in uppercase.

<arg>

One or more arguments to check.

zephyr_check_flags_exclusive(<function_name> <prefix> <flag1> <flag2> [<flag3> ...])

Helper macro for verifying that none of the mutual exclusive flags are provided together.

A FATAL_ERROR will be raised if any of the flags are given together.

<function_name>

Name of the function the check is performed for. Used in error message generation.

<prefix>

Prefix used in cmake_parse_arguments, usually arg or the function name in uppercase.

<flag>

One or more flags to check.

zephyr_check_no_arguments(<function_name> <arg1> [<arg2> ...])

Helper macro for verifying that no unexpected arguments are provided.

A FATAL_ERROR will be raised if any unexpected argument is given.

<function_name>

Name of the function the check is performed for. Used in error message generation.

<arg>

One or more arguments to check.

Linkable loadable extensions (llext)

These functions simplify the creation and management of Linkable Loadable Extensions (LLEXT).

Configuration functions

The following functions simplify access to the compilation/link stage properties of an llext using the same API as CMake’s target_* functions.

llext_compile_definitions(target_name <defs>...)

Add compile definitions to the llext target.

target_name

Name of the llext target.

<defs>

Arguments passed to target_compile_definitions.

llext_compile_features(target_name <features>...)

Add compile features to the llext target.

target_name

Name of the llext target.

<features>

Arguments passed to target_compile_features.

llext_compile_options(target_name <options>...)

Add compile options to the llext target.

target_name

Name of the llext target.

<options>

Arguments passed to target_compile_options.

llext_include_directories(target_name <dirs>...)

Add include directories to the llext target.

target_name

Name of the llext target.

<dirs>

Arguments passed to target_include_directories.

Add link options to the llext target.

target_name

Name of the llext target.

<options>

Arguments passed to target_link_options.

Build control functions

The following functions add targets and subcommands to the build system to compile and link an llext.

add_llext_target(target_name OUTPUT <output_file> SOURCES <source_files>)

Add a custom target that compiles a set of source files to a .llext file.

Output and source files must be specified using the OUTPUT and SOURCES arguments. Only one source file is supported when CONFIG_LLEXT_TYPE_ELF_OBJECT is selected, since there is no linking step in that case.

The llext code will be compiled with mostly the same C compiler flags used in the Zephyr build, but with some important modifications. The list of flags to remove and flags to append is controlled respectively by the LLEXT_REMOVE_FLAGS and LLEXT_APPEND_FLAGS global variables.

The following custom properties of target_name are defined and can be retrieved using the get_target_property function:

  • lib_target: Target name for the source compilation and/or link step.

  • lib_output: The binary file resulting from compilation and/or linking steps.

  • pkg_input: The file to be used as input for the packaging step.

  • pkg_output: The final .llext file.

Example usage:

add_llext_target(hello_world
  OUTPUT  ${PROJECT_BINARY_DIR}/hello_world.llext
  SOURCES ${PROJECT_SOURCE_DIR}/src/llext/hello_world.c
)

This will compile the source file src/llext/hello_world.c` to a file named $PROJECT_BINARY_DIR/hello_world.llext.

add_llext_command(TARGET <target_name> PRE_BUILD <command> [...])
add_llext_command(TARGET <target_name> POST_BUILD <command> [...])
add_llext_command(TARGET <target_name> POST_PKG <command> [...])

Add a custom command to an llext target that will be executed during the build. The command will be executed at the specified build step and can refer to <target>’s properties for build-specific details.

The different build steps are:

PRE_BUILD

Before the llext code is linked, if the architecture uses dynamic libraries. This step can access lib_target and its own properties.

POST_BUILD

After the llext code is built, but before packaging it in an .llext file. This step is expected to create a pkg_input file by reading the contents of lib_output.

POST_PKG

After the .llext file has been created. This can operate on the final llext file pkg_output.

Anything else after COMMAND will be passed to add_custom_command as-is (including multiple commands and other options).