Skip to content

llext-edk: minor fix, add board info #86655

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions cmake/llext-edk.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
# The script expects a build_info.yml file in the project binary directory.
# This file should contain the following entries:
# - cmake application source-dir
# - cmake board name
# - cmake board qualifiers
# - cmake board revision
# - cmake llext-edk cflags
# - cmake llext-edk file
# - cmake llext-edk include-dirs
Expand Down Expand Up @@ -158,19 +161,37 @@ yaml_get(INTERFACE_INCLUDE_DIRECTORIES NAME build_info KEY cmake llext-edk inclu
yaml_get(APPLICATION_SOURCE_DIR NAME build_info KEY cmake application source-dir)
yaml_get(WEST_TOPDIR NAME build_info KEY west topdir)

yaml_get(board_name NAME build_info KEY cmake board name)
yaml_get(board_qualifiers NAME build_info KEY cmake board qualifiers)
yaml_get(board_revision NAME build_info KEY cmake board revision)
zephyr_build_string(normalized_board_target
BOARD ${board_name}
BOARD_QUALIFIERS ${board_qualifiers}
BOARD_REVISION ${board_revision})

set(llext_edk_name ${CONFIG_LLEXT_EDK_NAME})
set(llext_edk ${PROJECT_BINARY_DIR}/${llext_edk_name})
set(llext_edk_inc ${llext_edk}/include)

string(REGEX REPLACE "[^a-zA-Z0-9]" "_" llext_edk_name_sane ${llext_edk_name})
string(TOUPPER ${llext_edk_name_sane} llext_edk_name_sane)
set(install_dir_var "${llext_edk_name_sane}_INSTALL_DIR")
zephyr_string(SANITIZE TOUPPER var_prefix ${llext_edk_name})
set(install_dir_var "${var_prefix}_INSTALL_DIR")

set(make_relative FALSE)
foreach(flag ${llext_edk_cflags})
if (flag STREQUAL "-imacros")
# Detect all combinations of 'imacros' flag:
# - with one or two preceding dashes
# - separated from the argument, joined by '=', or joined (no separator)
if(flag MATCHES "^--?imacros$")
# imacros followed by a space, convert next argument
set(make_relative TRUE)
continue()
elseif(flag MATCHES "^--?imacros=?([^=].*)$")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just want to mention that -imacros= != --imacros=.

The single dash version doesn't support a = as arg-val separator, meanining -imacros=foo.h will include the file =foo.h, but --imacros=foo.h will include foo.h.

So:
-imacrosfoo.h == --imacrosfoo.h == --imacros=foo.h

and
-imacros=foo.h == --imacros==foo.h == --imacros =foo.h (note the space)

I don't expect anyone to create or generate header files having = as first character but still wanted to mention this slight difference between -imacros and --imacros.

Copy link
Contributor Author

@pillo79 pillo79 Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I knew the catch-all regexp would match extra combinations, but... is it valid to have relative paths among the zephyr_interface flags anyway? I intutively expect that to cause build issues (outside of the EDK).

Anyways, I personally prefer the simplicity; if that becomes an issue we can switch to a more formal definition.

# imacros=<stuff> or imacros<stuff>, immediately convert <stuff>
set(flag ${CMAKE_MATCH_1})
set(make_relative TRUE)
elseif (make_relative)
endif()

if(make_relative)
set(make_relative FALSE)
cmake_path(GET flag PARENT_PATH parent)
cmake_path(GET flag FILENAME name)
Expand Down Expand Up @@ -229,6 +250,12 @@ set(edk_file_CMAKE ${llext_edk}/cmake.cflags)
foreach(target ${edk_targets})
edk_write_header(${target})

edk_write_comment(${target} "Target information")
edk_write_var(${target} "${var_prefix}_BOARD_NAME" "${board_name}")
edk_write_var(${target} "${var_prefix}_BOARD_QUALIFIERS" "${board_qualifiers}")
edk_write_var(${target} "${var_prefix}_BOARD_REVISION" "${board_revision}")
edk_write_var(${target} "${var_prefix}_BOARD_TARGET" "${normalized_board_target}")

edk_write_comment(${target} "Compile flags")
edk_write_var(${target} "LLEXT_CFLAGS" "${all_flags}")
edk_write_var(${target} "LLEXT_ALL_INCLUDE_CFLAGS" "${all_inc_flags}")
Expand Down
57 changes: 50 additions & 7 deletions doc/services/llext/build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,34 @@ directory. It's a tarball that contains the headers and compile flags needed
to build extensions. The extension developer can then include the headers
and use the compile flags in their build system to build the extension.

EDK definition files
--------------------

The EDK includes several convenience files which define a set of variables that
contain the compile flags needed by the project, as well as other build-related
information, when enabled. The information is currently exported in the
following formats:

- ``Makefile.cflags``, for Makefile-based projects;
- ``cmake.cflags``, for CMake-based projects.

Paths to the headers and flags are prefixed by the EDK root directory. This is
automatically obtained for CMake projects from ``CMAKE_CURRENT_LIST_DIR``;
other formats refer to an ``LLEXT_EDK_INSTALL_DIR`` variable, which must be set
by the user with the path where the EDK is installed before including the
generated file.

.. note::
The ``LLEXT_EDK`` prefix in the variable name may be changed with the
:kconfig:option:`CONFIG_LLEXT_EDK_NAME` option.

Compile flags
-------------

The EDK includes the convenience files ``cmake.cflags`` (for CMake-based
projects) and ``Makefile.cflags`` (for Make-based ones), which define a set of
variables that contain the compile flags needed by the project. The full list
of flags needed to build an extension is provided by ``LLEXT_CFLAGS``. Also
provided is a more granular set of flags that can be used in support of
different use cases, such as when building mocks for unit tests:
The full list of flags needed to build an extension is provided by
``LLEXT_CFLAGS``. Also provided is a more granular set of flags that can be
used in support of different use cases, such as when building mocks for unit
tests:

``LLEXT_INCLUDE_CFLAGS``

Expand Down Expand Up @@ -194,6 +213,29 @@ different use cases, such as when building mocks for unit tests:
``LLEXT_ALL_INCLUDE_CFLAGS``, ``LLEXT_GENERATED_IMACROS_CFLAGS`` and
``LLEXT_BASE_CFLAGS``.

Target information
------------------

The EDK includes information that identifies the target of the current Zephyr
build. The following variables are currently defined and mirror the information
available in the Zephyr build system:

``LLEXT_EDK_BOARD_NAME``
The board name used in the Zephyr build.

``LLEXT_EDK_BOARD_QUALIFIERS``
The board qualifiers, if provided, used in the Zephyr build.

``LLEXT_EDK_BOARD_REVISION``
The board revision, if provided, used in the Zephyr build.

``LLEXT_EDK_BOARD_TARGET``
The fully qualified board target used in the Zephyr build.

.. note::
The ``LLEXT_EDK`` prefix in the variable names may be changed with the
:kconfig:option:`CONFIG_LLEXT_EDK_NAME` option.

.. _llext_kconfig_edk:

LLEXT EDK Kconfig options
Expand All @@ -202,7 +244,8 @@ LLEXT EDK Kconfig options
The LLEXT EDK can be configured using the following Kconfig options:

:kconfig:option:`CONFIG_LLEXT_EDK_NAME`
The name of the generated EDK tarball.
The name of the generated EDK tarball. This is also used as the prefix for
several variables defined in the EDK files.

:kconfig:option:`CONFIG_LLEXT_EDK_USERSPACE_ONLY`
If set, the EDK will include headers that do not contain code to route
Expand Down
Loading