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