1Building extensions 2################### 3 4The LLEXT subsystem allows for the creation of extensions that can be loaded 5into a running Zephyr application. When building these extensions, it's very 6often useful to have access to the headers and compiler flags used by the main 7Zephyr application. 8 9The easiest path to achieve this is to build the extension as part of the 10Zephyr application, using the `native Zephyr CMake features 11<llext_build_native_>`_. This will result in a single build providing both the 12main Zephyr application and the extension(s), which will all automatically be 13built with the same parameters. 14 15In some cases, involving the full Zephyr build system may not be feasible or 16convenient; maybe the extension is built using a different compiler suite or as 17part of a different project altogether. In this case, the extension developer 18needs to export the headers and compiler flags used by the main Zephyr 19application. This can be done using the `LLEXT Extension Development Kit 20<llext_build_edk_>`_. 21 22.. _llext_build_native: 23 24Using the Zephyr CMake features 25******************************* 26 27The Zephyr build system provides a set of features that can be used to build 28extensions as part of the Zephyr application. This is the simplest way to build 29extensions, as it requires minimal additions to an application build system. 30 31Building the extension 32---------------------- 33 34An extension can be defined in the app's ``CMakeLists.txt`` by invoking the 35``add_llext_target`` function, providing the target name, the output and the 36source files. Usage is similar to the standard ``add_custom_target`` CMake 37function: 38 39.. code-block:: cmake 40 41 add_llext_target( 42 <target_name> 43 OUTPUT <ext_file.llext> 44 SOURCES <src1> [<src2>...] 45 ) 46 47where: 48 49- ``<target_name>`` is the name of the final CMake target that will result in 50 the LLEXT binary being created; 51- ``<ext_file.llext>`` is the name of the output file that will contain the 52 packaged extension; 53- ``<src1> [<src2>...]`` is the list of source files that will be compiled to 54 create the extension. 55 56The exact steps of the extension building process depend on the currently 57selected :ref:`ELF object format <llext_kconfig_type>`. 58 59The following custom properties of ``<target_name>`` are defined and can be 60retrieved using the ``get_target_property()`` CMake function: 61 62``lib_target`` 63 64 Target name for the source compilation and/or link step. 65 66``lib_output`` 67 68 The binary file resulting from compilation and/or linking steps. 69 70``pkg_input`` 71 72 The file to be used as input for the packaging step. 73 74``pkg_output`` 75 76 The final extension file name. 77 78Tweaking the build process 79-------------------------- 80 81The following CMake functions can be used to modify the build system behavior 82during the extension build process to a fine degree. Each of the below 83functions takes the LLEXT target name as its first argument; it is otherwise 84functionally equivalent to the common Zephyr ``target_*`` version. 85 86* ``llext_compile_definitions`` 87* ``llext_compile_features`` 88* ``llext_compile_options`` 89* ``llext_include_directories`` 90* ``llext_link_options`` 91 92Custom build steps 93------------------ 94 95The ``add_llext_command`` CMake function can be used to add custom build steps 96that will be executed during the extension build process. The command will be 97run at the specified build step and can refer to the properties of the target 98for build-specific details. 99 100The function signature is: 101 102.. code-block:: cmake 103 104 add_llext_command( 105 TARGET <target_name> 106 [PRE_BUILD | POST_BUILD | POST_PKG] 107 COMMAND <command> [args...] 108 ) 109 110The different build steps are: 111 112``PRE_BUILD`` 113 114 Before the extension code is linked, if the architecture uses dynamic 115 libraries. This step can access ``lib_target`` and its own properties. 116 117``POST_BUILD`` 118 119 After the extension code is built, but before packaging it in an ``.llext`` 120 file. This step is expected to create a :file:`pkg_input` file by reading the 121 contents of :file:`lib_output`. 122 123``POST_PKG`` 124 125 After the extension output file has been created. The command can operate 126 on the final llext file :file:`pkg_output`. 127 128Anything else after ``COMMAND`` will be passed to ``add_custom_command()`` as-is 129(including multiple commands and other options). 130 131.. _llext_build_edk: 132 133LLEXT Extension Development Kit (EDK) 134************************************* 135 136When building extensions as a standalone project, outside of the main Zephyr 137build system, it's important to have access to the same set of generated 138headers and compiler flags used by the main Zephyr application, since they have 139a direct impact on how Zephyr headers are interpreted and the extension is 140compiled in general. 141 142This can be achieved by asking Zephyr to generate an Extension Development Kit 143(EDK) from the build artifacts of the main Zephyr application, by running the 144following command which uses the ``llext-edk`` target: 145 146.. code-block:: shell 147 148 west build -t llext-edk 149 150The generated EDK can be found in the build directory under the ``zephyr`` 151directory. It's a tarball that contains the headers and compile flags needed 152to build extensions. The extension developer can then include the headers 153and use the compile flags in their build system to build the extension. 154 155EDK definition files 156-------------------- 157 158The EDK includes several convenience files which define a set of variables that 159contain the compile flags needed by the project, as well as other build-related 160information, when enabled. The information is currently exported in the 161following formats: 162 163- ``Makefile.cflags``, for Makefile-based projects; 164- ``cmake.cflags``, for CMake-based projects. 165 166Paths to the headers and flags are prefixed by the EDK root directory. This is 167automatically obtained for CMake projects from ``CMAKE_CURRENT_LIST_DIR``; 168other formats refer to an ``LLEXT_EDK_INSTALL_DIR`` variable, which must be set 169by the user with the path where the EDK is installed before including the 170generated file. 171 172.. note:: 173 The ``LLEXT_EDK`` prefix in the variable name may be changed with the 174 :kconfig:option:`CONFIG_LLEXT_EDK_NAME` option. 175 176Compile flags 177------------- 178 179The full list of flags needed to build an extension is provided by 180``LLEXT_CFLAGS``. Also provided is a more granular set of flags that can be 181used in support of different use cases, such as when building mocks for unit 182tests: 183 184``LLEXT_INCLUDE_CFLAGS`` 185 186 Compiler flags to add directories containing non-autogenerated headers 187 to the compiler's include search paths. 188 189``LLEXT_GENERATED_INCLUDE_CFLAGS`` 190 191 Compiler flags to add directories containing autogenerated headers to 192 the compiler's include search paths. 193 194``LLEXT_ALL_INCLUDE_CFLAGS`` 195 196 Compiler flags to add all directories containing headers used in the 197 build to the compiler's include search paths. This is a combination of 198 ``LLEXT_INCLUDE_CFLAGS`` and ``LLEXT_GENERATED_INCLUDE_CFLAGS``. 199 200``LLEXT_GENERATED_IMACROS_CFLAGS`` 201 202 Compiler flags for autogenerated headers that must be included in the 203 build via ``-imacros``. 204 205``LLEXT_BASE_CFLAGS`` 206 207 Other compiler flags that control code generation for the target CPU. 208 None of these flags are included in the above lists. 209 210``LLEXT_CFLAGS`` 211 212 All flags required to build an extension. This is a combination of 213 ``LLEXT_ALL_INCLUDE_CFLAGS``, ``LLEXT_GENERATED_IMACROS_CFLAGS`` and 214 ``LLEXT_BASE_CFLAGS``. 215 216Target information 217------------------ 218 219The EDK includes information that identifies the target of the current Zephyr 220build. The following variables are currently defined and mirror the information 221available in the Zephyr build system: 222 223``LLEXT_EDK_BOARD_NAME`` 224 The board name used in the Zephyr build. 225 226``LLEXT_EDK_BOARD_QUALIFIERS`` 227 The board qualifiers, if provided, used in the Zephyr build. 228 229``LLEXT_EDK_BOARD_REVISION`` 230 The board revision, if provided, used in the Zephyr build. 231 232``LLEXT_EDK_BOARD_TARGET`` 233 The fully qualified board target used in the Zephyr build. 234 235.. note:: 236 The ``LLEXT_EDK`` prefix in the variable names may be changed with the 237 :kconfig:option:`CONFIG_LLEXT_EDK_NAME` option. 238 239.. _llext_kconfig_edk: 240 241LLEXT EDK Kconfig options 242------------------------- 243 244The LLEXT EDK can be configured using the following Kconfig options: 245 246:kconfig:option:`CONFIG_LLEXT_EDK_NAME` 247 The name of the generated EDK tarball. This is also used as the prefix for 248 several variables defined in the EDK files. 249 250:kconfig:option:`CONFIG_LLEXT_EDK_USERSPACE_ONLY` 251 If set, the EDK will include headers that do not contain code to route 252 syscalls to the kernel. This is useful when building extensions that will 253 run exclusively in user mode. 254 255EDK Sample 256---------- 257 258Refer to :zephyr:code-sample:`llext-edk` for an example of how to use the 259LLEXT EDK. 260