-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmake: move add_llext_target() to llext.cmake
The CMake function add_llext_target() is used to wrap the building of an llext. Move this code to cmake/modules/llext.cmake instead of being in a subsystem-specific CMakeFile. The function is moved verbatim except for an additional check for CONFIG_LLEXT to be enabled (previously it was done at CMakeFile level). Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
- Loading branch information
Showing
3 changed files
with
114 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
include_guard(GLOBAL) | ||
|
||
# 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 | ||
# arguments. Only one source file is currently supported. | ||
# | ||
# Arch-specific flags will be added automatically. The C_FLAGS argument | ||
# can be used to pass additional compiler flags to the compilation of | ||
# the source file. | ||
# | ||
# Example usage: | ||
# add_llext_target(hello_world | ||
# OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext | ||
# SOURCES ${PROJECT_SOURCE_DIR}/src/llext/hello_world.c | ||
# C_FLAGS -Werror | ||
# ) | ||
# will compile the source file src/llext/hello_world.c to a file | ||
# ${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) | ||
cmake_parse_arguments(PARSE_ARGV 1 LLEXT "${options}" "${single_args}" "${multi_args}") | ||
|
||
# Check that the llext subsystem is enabled for this build | ||
if (NOT CONFIG_LLEXT) | ||
message(FATAL_ERROR "add_llext_target: CONFIG_LLEXT must be enabled") | ||
endif() | ||
|
||
# Output file must be provided | ||
if(NOT LLEXT_OUTPUT) | ||
message(FATAL_ERROR "add_llext_target: OUTPUT argument must be provided") | ||
endif() | ||
|
||
# Source list length must currently be 1 | ||
list(LENGTH LLEXT_SOURCES source_count) | ||
if(NOT source_count EQUAL 1) | ||
message(FATAL_ERROR "add_llext_target: only one source file is supported") | ||
endif() | ||
|
||
set(output_file ${LLEXT_OUTPUT}) | ||
set(source_file ${LLEXT_SOURCES}) | ||
get_filename_component(output_name ${output_file} NAME) | ||
|
||
# Add user-visible target and dependency | ||
add_custom_target(${target_name} ALL | ||
COMMENT "Compiling ${output_name}" | ||
DEPENDS ${output_file} | ||
) | ||
|
||
# Define arch-specific flags for the supported architectures | ||
if(CONFIG_ARM) | ||
list(PREPEND LLEXT_C_FLAGS "-mlong-calls" "-mthumb") | ||
elseif(CONFIG_XTENSA) | ||
list(PREPEND LLEXT_C_FLAGS "-shared" "-fPIC" "-nostdlib" "-nodefaultlibs") | ||
else() | ||
message(FATAL_ERROR "add_llext_target: unsupported architecture") | ||
endif() | ||
|
||
# Compile the source file to an object file using current Zephyr settings | ||
# but a different set of flags | ||
add_library(${target_name}_lib OBJECT ${source_file}) | ||
target_compile_definitions(${target_name}_lib PRIVATE | ||
$<TARGET_PROPERTY:zephyr_interface,INTERFACE_COMPILE_DEFINITIONS> | ||
) | ||
target_compile_options(${target_name}_lib PRIVATE | ||
${LLEXT_C_FLAGS} | ||
-imacros "${AUTOCONF_H}" | ||
) | ||
target_include_directories(${target_name}_lib PRIVATE | ||
$<TARGET_PROPERTY:zephyr_interface,INTERFACE_INCLUDE_DIRECTORIES> | ||
) | ||
target_include_directories(${target_name}_lib SYSTEM PUBLIC | ||
$<TARGET_PROPERTY:zephyr_interface,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES> | ||
) | ||
|
||
# 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 $<TARGET_OBJECTS:${target_name}_lib> ${output_file} | ||
DEPENDS ${target_name}_lib $<TARGET_OBJECTS:${target_name}_lib> | ||
) | ||
|
||
elseif(CONFIG_XTENSA) | ||
|
||
# Generate an intermediate file name | ||
get_filename_component(output_dir ${output_file} DIRECTORY) | ||
get_filename_component(output_name_we ${output_file} NAME_WE) | ||
set(pre_output_file ${output_dir}/${output_name_we}.pre.llext) | ||
|
||
# Need to convert the object file to a shared library, then strip some sections | ||
add_custom_command( | ||
OUTPUT ${output_file} | ||
BYPRODUCTS ${pre_output_file} | ||
COMMAND ${CMAKE_C_COMPILER} ${LLEXT_C_FLAGS} | ||
-o ${pre_output_file} | ||
$<TARGET_OBJECTS:${target_name}_lib> | ||
COMMAND ${CROSS_COMPILE}strip -R .xt.* | ||
-o ${output_file} | ||
${pre_output_file} | ||
DEPENDS ${target_name}_lib $<TARGET_OBJECTS:${target_name}_lib> | ||
) | ||
|
||
endif() | ||
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters