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
155Compile flags
156-------------
157
158The EDK includes the convenience files ``cmake.cflags`` (for CMake-based
159projects) and ``Makefile.cflags`` (for Make-based ones), which define a set of
160variables that contain the compile flags needed by the project. The full list
161of flags needed to build an extension is provided by ``LLEXT_CFLAGS``. Also
162provided is a more granular set of flags that can be used in support of
163different use cases, such as when building mocks for unit tests:
164
165``LLEXT_INCLUDE_CFLAGS``
166
167        Compiler flags to add directories containing non-autogenerated headers
168        to the compiler's include search paths.
169
170``LLEXT_GENERATED_INCLUDE_CFLAGS``
171
172        Compiler flags to add directories containing autogenerated headers to
173        the compiler's include search paths.
174
175``LLEXT_ALL_INCLUDE_CFLAGS``
176
177        Compiler flags to add all directories containing headers used in the
178        build to the compiler's include search paths. This is a combination of
179        ``LLEXT_INCLUDE_CFLAGS`` and ``LLEXT_GENERATED_INCLUDE_CFLAGS``.
180
181``LLEXT_GENERATED_IMACROS_CFLAGS``
182
183        Compiler flags for autogenerated headers that must be included in the
184        build via ``-imacros``.
185
186``LLEXT_BASE_CFLAGS``
187
188        Other compiler flags that control code generation for the target CPU.
189        None of these flags are included in the above lists.
190
191``LLEXT_CFLAGS``
192
193        All flags required to build an extension. This is a combination of
194        ``LLEXT_ALL_INCLUDE_CFLAGS``, ``LLEXT_GENERATED_IMACROS_CFLAGS`` and
195        ``LLEXT_BASE_CFLAGS``.
196
197.. _llext_kconfig_edk:
198
199LLEXT EDK Kconfig options
200-------------------------
201
202The LLEXT EDK can be configured using the following Kconfig options:
203
204:kconfig:option:`CONFIG_LLEXT_EDK_NAME`
205    The name of the generated EDK tarball.
206
207:kconfig:option:`CONFIG_LLEXT_EDK_USERSPACE_ONLY`
208    If set, the EDK will include headers that do not contain code to route
209    syscalls to the kernel. This is useful when building extensions that will
210    run exclusively in user mode.
211
212EDK Sample
213----------
214
215Refer to :zephyr:code-sample:`llext-edk` for an example of how to use the
216LLEXT EDK.
217