diff --git a/cmake/llext-edk.cmake b/cmake/llext-edk.cmake index c62aec4b030..9501133f3ab 100644 --- a/cmake/llext-edk.cmake +++ b/cmake/llext-edk.cmake @@ -34,25 +34,15 @@ cmake_minimum_required(VERSION 3.20.0) 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") - -cmake_path(CONVERT "${INTERFACE_INCLUDE_DIRECTORIES}" TO_CMAKE_PATH_LIST include_dirs) - -set(autoconf_h_edk ${llext_edk_inc}/${AUTOCONF_H}) -cmake_path(RELATIVE_PATH AUTOCONF_H BASE_DIRECTORY ${PROJECT_BINARY_DIR} OUTPUT_VARIABLE autoconf_h_rel) - -list(APPEND base_flags_make - "${llext_cflags} -imacros\$(${install_dir_var})/include/zephyr/${autoconf_h_rel}") -list(APPEND base_flags_cmake - "${llext_cflags} -imacros\${CMAKE_CURRENT_LIST_DIR}/include/zephyr/${autoconf_h_rel}") - -file(MAKE_DIRECTORY ${llext_edk_inc}) -foreach(dir ${include_dirs}) - if (NOT EXISTS ${dir}) - continue() - endif() +# Usage: +# relative_dir( ) +# +# Helper function to generate relative paths to a few key directories +# (PROJECT_BINARY_DIR, ZEPHYR_BASE, WEST_TOPDIR and APPLICATION_SOURCE_DIR). +# The generated path is relative to the key directory, and the bindir_out +# output variable is set to TRUE if the path is relative to PROJECT_BINARY_DIR. +# +function(relative_dir dir relative_out bindir_out) cmake_path(IS_PREFIX PROJECT_BINARY_DIR ${dir} NORMALIZE to_prj_bindir) cmake_path(IS_PREFIX ZEPHYR_BASE ${dir} NORMALIZE to_zephyr_base) if("${WEST_TOPDIR}" STREQUAL "") @@ -87,6 +77,58 @@ foreach(dir ${include_dirs}) set(dest ${llext_edk_inc}/${dir}) endif() + set(${relative_out} ${dest} PARENT_SCOPE) + if(to_prj_bindir) + set(${bindir_out} TRUE PARENT_SCOPE) + else() + set(${bindir_out} FALSE PARENT_SCOPE) + endif() +endfunction() + +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_CFLAGS NATIVE_COMMAND ${llext_cflags}) + +set(make_relative FALSE) +foreach(flag ${llext_cflags}) + if (flag STREQUAL "-imacros") + set(make_relative TRUE) + elseif (make_relative) + set(make_relative FALSE) + cmake_path(GET flag PARENT_PATH parent) + cmake_path(GET flag FILENAME name) + relative_dir(${parent} dest bindir) + cmake_path(RELATIVE_PATH dest BASE_DIRECTORY ${llext_edk} OUTPUT_VARIABLE dest_rel) + if(bindir) + list(APPEND imacros_gen_make "-imacros\$(${install_dir_var})/${dest_rel}/${name}") + list(APPEND imacros_gen_cmake "-imacros\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}/${name}") + else() + list(APPEND imacros_make "-imacros\$(${install_dir_var})/${dest_rel}/${name}") + list(APPEND imacros_cmake "-imacros\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}/${name}") + endif() + else() + list(APPEND new_cflags ${flag}) + endif() +endforeach() +set(LLEXT_CFLAGS ${new_cflags}) + +cmake_path(CONVERT "${INTERFACE_INCLUDE_DIRECTORIES}" TO_CMAKE_PATH_LIST include_dirs) + +set(autoconf_h_edk ${llext_edk_inc}/${AUTOCONF_H}) +cmake_path(RELATIVE_PATH AUTOCONF_H BASE_DIRECTORY ${PROJECT_BINARY_DIR} OUTPUT_VARIABLE autoconf_h_rel) + +list(APPEND base_flags_make ${llext_cflags} ${imacros_make}) +list(APPEND base_flags_cmake ${llext_cflags} ${imacros_cmake}) + +file(MAKE_DIRECTORY ${llext_edk_inc}) +foreach(dir ${include_dirs}) + if (NOT EXISTS ${dir}) + continue() + endif() + + relative_dir(${dir} dest bindir) # Use destination parent, as the last part of the source directory is copied as well cmake_path(GET dest PARENT_PATH dest_p) @@ -94,10 +136,10 @@ foreach(dir ${include_dirs}) file(COPY ${dir} DESTINATION ${dest_p} FILES_MATCHING PATTERN "*.h") cmake_path(RELATIVE_PATH dest BASE_DIRECTORY ${llext_edk} OUTPUT_VARIABLE dest_rel) - if(to_prj_bindir) + if(bindir) list(APPEND inc_gen_flags_make "-I\$(${install_dir_var})/${dest_rel}") list(APPEND inc_gen_flags_cmake "-I\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}") - else(to_zephyr_base) + else() list(APPEND inc_flags_make "-I\$(${install_dir_var})/${dest_rel}") list(APPEND inc_flags_cmake "-I\${CMAKE_CURRENT_LIST_DIR}/${dest_rel}") endif() @@ -107,11 +149,11 @@ endforeach() if(CONFIG_LLEXT_EDK_USERSPACE_ONLY) # Copy syscall headers from edk directory, as they were regenerated there. - file(COPY ${PROJECT_BINARY_DIR}/edk/include/generated/ DESTINATION ${LLEXT_EDK_INC}/zephyr/include/generated) + file(COPY ${PROJECT_BINARY_DIR}/edk/include/generated/ DESTINATION ${llext_edk_inc}/zephyr/include/generated) endif() # Generate flags for Makefile -list(APPEND all_flags_make ${base_flags_make} ${all_inc_flags_make}) +list(APPEND all_flags_make ${base_flags_make} ${imacros_gen_make} ${all_inc_flags_make}) list(JOIN all_flags_make " " all_flags_str) file(WRITE ${llext_edk}/Makefile.cflags "LLEXT_CFLAGS = ${all_flags_str}") @@ -127,8 +169,11 @@ file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_GENERATED_INCLUDE_CFLAGS = $ list(JOIN base_flags_make " " base_flags_str) file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_BASE_CFLAGS = ${base_flags_str}") +list(JOIN imacros_gen_make " " imacros_gen_str) +file(APPEND ${llext_edk}/Makefile.cflags "\n\nLLEXT_GENERATED_IMACROS_CFLAGS = ${imacros_gen_str}") + # Generate flags for CMake -list(APPEND all_flags_cmake ${base_flags_cmake} ${all_inc_flags_cmake}) +list(APPEND all_flags_cmake ${base_flags_cmake} ${imacros_gen_make} ${all_inc_flags_cmake}) file(WRITE ${llext_edk}/cmake.cflags "set(LLEXT_CFLAGS ${all_flags_cmake})") file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_ALL_INCLUDE_CFLAGS ${all_inc_flags_cmake})") @@ -139,6 +184,8 @@ file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_GENERATED_INCLUDE_CFLAGS ${ file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_BASE_CFLAGS ${base_flags_cmake})") +file(APPEND ${llext_edk}/cmake.cflags "\n\nset(LLEXT_GENERATED_IMACROS_CFLAGS ${imacros_gen_cmake})") + # Generate the tarball file(ARCHIVE_CREATE OUTPUT ${llext_edk_file}