From 5d3fe7e85a0d569eada39bbdadc388835646737e Mon Sep 17 00:00:00 2001 From: Luca Burelli Date: Wed, 8 Jan 2025 12:11:11 +0100 Subject: [PATCH] llext-edk: import data from build_info.yml and .config Currently, the llext-edk.cmake script requires a number of variables to be passed in from the main CMakeLists.txt file as arguments to be able to customize the generated files. To improve this rigid approach, the script is modified to read in the following files in the build directory: * 'zephyr/.config', for the final set of Kconfig options used; * 'build_info.yml', for the cmake-related variables. This is more flexible and also easier to maintain, as it doesn't require manual changes to the main CMakelists.txt file when new variables need to be referenced. Signed-off-by: Luca Burelli --- CMakeLists.txt | 27 +++++++----------- cmake/llext-edk.cmake | 49 +++++++++++++++++++------------- cmake/modules/extensions.cmake | 2 +- scripts/schemas/build-schema.yml | 13 +++++++++ 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c2b73040bc4..16a471ae6ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1990,7 +1990,6 @@ if (CONFIG_LLEXT AND CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) --elf-file ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} --slid-listing ${PROJECT_BINARY_DIR}/slid_listing.txt ) - endif() if(NOT CMAKE_C_COMPILER_ID STREQUAL "ARMClang") @@ -2236,6 +2235,10 @@ list(APPEND llext_edk_cflags ${llext_filt_flags}) list(APPEND llext_edk_cflags ${LLEXT_APPEND_FLAGS}) list(APPEND llext_edk_cflags ${LLEXT_EDK_APPEND_FLAGS}) +build_info(llext-edk file PATH ${llext_edk_file}) +build_info(llext-edk cflags VALUE ${llext_edk_cflags}) +build_info(llext-edk include-dirs VALUE "$") + add_custom_command( OUTPUT ${llext_edk_file} # Regenerate syscalls in case CONFIG_LLEXT_EDK_USERSPACE_ONLY @@ -2252,17 +2255,8 @@ add_custom_command( ${SYSCALL_LONG_REGISTERS_ARG} ${SYSCALL_SPLIT_TIMEOUT_ARG} COMMAND ${CMAKE_COMMAND} - -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} - -DAPPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR} - -DINTERFACE_INCLUDE_DIRECTORIES="$" - -Dllext_edk_file=${llext_edk_file} - -Dllext_edk_cflags="${llext_edk_cflags}" - -Dllext_edk_name=${CONFIG_LLEXT_EDK_NAME} - -DWEST_TOPDIR=${WEST_TOPDIR} - -DZEPHYR_BASE=${ZEPHYR_BASE} - -DCONFIG_LLEXT_EDK_USERSPACE_ONLY=${CONFIG_LLEXT_EDK_USERSPACE_ONLY} -P ${ZEPHYR_BASE}/cmake/llext-edk.cmake - DEPENDS ${logical_target_for_zephyr_elf} + DEPENDS ${logical_target_for_zephyr_elf} build_info_yaml_saved COMMAND_EXPAND_LISTS ) add_custom_target(llext-edk DEPENDS ${llext_edk_file}) @@ -2286,9 +2280,8 @@ add_subdirectory_ifdef( toolchain_linker_finalize() -yaml_context(EXISTS NAME build_info result) -if(result) - build_info(zephyr version VALUE ${PROJECT_VERSION_STR}) - build_info(zephyr zephyr-base VALUE ${ZEPHYR_BASE}) - yaml_save(NAME build_info) -endif() +# export build information +build_info(zephyr version VALUE ${PROJECT_VERSION_STR}) +build_info(zephyr zephyr-base VALUE ${ZEPHYR_BASE}) + +yaml_save(NAME build_info) diff --git a/cmake/llext-edk.cmake b/cmake/llext-edk.cmake index b6d7e3d943d..ff3f1660f01 100644 --- a/cmake/llext-edk.cmake +++ b/cmake/llext-edk.cmake @@ -11,25 +11,24 @@ # directories (build/zephyr, zephyr base, west top dir and application source # dir), to avoid leaking any information about the host system. # -# The following arguments are expected: -# - llext_edk_name: Name of the extension, used to name the tarball and the -# install directory variable for Makefile. -# - INTERFACE_INCLUDE_DIRECTORIES: List of include directories to copy headers -# from. It should simply be the INTERFACE_INCLUDE_DIRECTORIES property of the -# zephyr_interface target. -# - llext_edk_file: Output file name for the tarball. -# - llext_edk_cflags: Flags to be used for source compile commands. -# - ZEPHYR_BASE: Path to the zephyr base directory. -# - WEST_TOPDIR: Path to the west top directory. -# - APPLICATION_SOURCE_DIR: Path to the application source directory. -# - PROJECT_BINARY_DIR: Path to the project binary build directory. -# - CONFIG_LLEXT_EDK_USERSPACE_ONLY: Whether to copy syscall headers from the -# edk directory. This is necessary when building an extension that only -# supports userspace, as the syscall headers are regenerated in the edk -# directory. +# 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 llext-edk cflags +# - cmake llext-edk file +# - cmake llext-edk include-dirs +# - west topdir cmake_minimum_required(VERSION 3.20.0) +# initialize the same paths as the main CMakeLists.txt for consistency +set(PROJECT_BINARY_DIR ${CMAKE_BINARY_DIR}) +set(ZEPHYR_BASE ${CMAKE_CURRENT_LIST_DIR}/../) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules") + +include(extensions) +include(yaml) + # Usage: # relative_dir( ) # @@ -142,11 +141,24 @@ endfunction() +# read in computed build configuration +import_kconfig(CONFIG ${PROJECT_BINARY_DIR}/.config) + if (CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID) message(FATAL_ERROR "The LLEXT EDK is not compatible with CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID.") endif() +set(build_info_file ${PROJECT_BINARY_DIR}/../build_info.yml) +yaml_load(FILE ${build_info_file} NAME build_info) + +yaml_get(llext_edk_cflags NAME build_info KEY cmake llext-edk cflags) +yaml_get(llext_edk_file NAME build_info KEY cmake llext-edk file) +yaml_get(INTERFACE_INCLUDE_DIRECTORIES NAME build_info KEY cmake llext-edk include-dirs) +yaml_get(APPLICATION_SOURCE_DIR NAME build_info KEY cmake application source-dir) +yaml_get(WEST_TOPDIR NAME build_info KEY west topdir) + +set(llext_edk_name ${CONFIG_LLEXT_EDK_NAME}) set(llext_edk ${PROJECT_BINARY_DIR}/${llext_edk_name}) set(llext_edk_inc ${llext_edk}/include) @@ -154,8 +166,6 @@ 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") -separate_arguments(llext_edk_cflags NATIVE_COMMAND ${llext_edk_cflags}) - set(make_relative FALSE) foreach(flag ${llext_edk_cflags}) if (flag STREQUAL "-imacros") @@ -179,9 +189,8 @@ set(llext_edk_cflags ${new_cflags}) list(APPEND base_flags ${llext_edk_cflags} ${imacros}) -separate_arguments(include_dirs NATIVE_COMMAND ${INTERFACE_INCLUDE_DIRECTORIES}) file(MAKE_DIRECTORY ${llext_edk_inc}) -foreach(dir ${include_dirs}) +foreach(dir ${INTERFACE_INCLUDE_DIRECTORIES}) if (NOT EXISTS ${dir}) continue() endif() diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 8236722837e..8350b2f3974 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -5881,7 +5881,7 @@ endfunction() # depending on the exact use of the function in script mode. # # Current Zephyr CMake scripts which includes `extensions.cmake` in script mode -# are: package_helper.cmake, verify-toolchain.cmake +# are: package_helper.cmake, verify-toolchain.cmake, llext-edk.cmake # if(CMAKE_SCRIPT_MODE_FILE) diff --git a/scripts/schemas/build-schema.yml b/scripts/schemas/build-schema.yml index 5086afbb25b..b07d5754454 100644 --- a/scripts/schemas/build-schema.yml +++ b/scripts/schemas/build-schema.yml @@ -71,6 +71,19 @@ mapping: type: seq sequence: - type: str + llext-edk: + type: map + mapping: + cflags: + type: seq + sequence: + - type: str + file: + type: str + include-dirs: + type: seq + sequence: + - type: str sysbuild: type: bool toolchain: