diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 8a47db809f6a9ce..85617a4febccdfe 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -4802,6 +4802,14 @@ endmacro() # loadable extensions (llexts). # +# Usage: +# add_llext_target( +# OUTPUT +# SOURCES +# [C_FLAGS ...] +# [POSTPROC_CMD [POSTPROC_ARGS ...]] +# ) +# # Add a custom target that compiles a single source file to a .llext file. # # Output and source files must be specified using the OUTPUT and SOURCES @@ -4811,10 +4819,21 @@ endmacro() # in the Zephyr build, but with some important modifications. The list of # flags to remove and flags to append is controlled respectively by the # LLEXT_REMOVE_FLAGS and LLEXT_APPEND_FLAGS global variables. - +# # The C_FLAGS argument can be used to pass additional compiler flags to the # compilation of this particular llext. # +# The POSTPROC_CMD and POSTPROC_ARGS arguments can be used to specify a command +# to run on the generated llext file after compilation and before stripping. +# This is useful for post-processing the llext file in some way, such as +# adjusting the addressess of certain symbols. +# The post processor will be invoked by CMake as: +# +# +# +# POSTPROC_ARGS can also use generator expressions that refer to the +# "${target_name}_lib" target to get additional flags. +# # Example usage: # add_llext_target(hello_world # OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext @@ -4825,8 +4844,8 @@ endmacro() # ${PROJECT_BINARY_DIR}/hello_world.llext, adding -Werror to the compilation. # function(add_llext_target target_name) - set(single_args OUTPUT) - set(multi_args SOURCES;C_FLAGS) + set(single_args OUTPUT;POSTPROC_CMD) + set(multi_args SOURCES;C_FLAGS;POSTPROC_ARGS) cmake_parse_arguments(PARSE_ARGV 1 LLEXT "${options}" "${single_args}" "${multi_args}") # Check that the llext subsystem is enabled for this build @@ -4915,14 +4934,37 @@ function(add_llext_target target_name) zephyr_generated_headers ) + if(LLEXT_POSTPROC_CMD) + + # Post-process the linked llext file + set(postproc_target ${target_name}_pp) + set(postproc_file ${target_name}_pp.llext) + add_custom_command( + OUTPUT ${postproc_file} + COMMAND ${LLEXT_POSTPROC_CMD} + ${linked_file} + ${postproc_file} + ${LLEXT_POSTPROC_ARGS} + DEPENDS ${link_target} ${linked_file} + COMMAND_EXPAND_LISTS) + add_custom_target(${postproc_target} DEPENDS ${postproc_file}) + + else() + + # Skip post-processing and reuse the original file + set(postproc_target ${link_target}) + set(postproc_file ${linked_file}) + + endif() + # Arch-specific conversion of the object file to an llext if(CONFIG_ARM) # No conversion required, simply copy the object file add_custom_command( OUTPUT ${output_file} - COMMAND ${CMAKE_COMMAND} -E copy ${linked_file} ${output_file} - DEPENDS ${link_target} ${linked_file} + COMMAND ${CMAKE_COMMAND} -E copy ${postproc_file} ${output_file} + DEPENDS ${postproc_target} ${postproc_file} ) elseif(CONFIG_XTENSA) @@ -4933,10 +4975,10 @@ function(add_llext_target target_name) COMMAND $ $ $.xt.* - $${linked_file} + $${postproc_file} $${output_file} $ - DEPENDS ${link_target} ${linked_file} + DEPENDS ${postproc_target} ${postproc_file} ) else()