Skip to content

Commit

Permalink
llext: define add_llext_target() for llext compilation
Browse files Browse the repository at this point in the history
This patch defines a generic function that encapsulates all the
architecture-specific machinery needed to compile llexts from source
files. Current tests are updated to use this function.

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.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
  • Loading branch information
pillo79 committed Jan 12, 2024
1 parent 24acecb commit ee9a514
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 28 deletions.
79 changes: 79 additions & 0 deletions subsys/llext/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,84 @@
if(CONFIG_LLEXT)

# Include all llext kernel sources as a library target
zephyr_library()
zephyr_library_sources(llext.c llext_export.c buf_loader.c)
zephyr_library_sources_ifdef(CONFIG_LLEXT_SHELL shell.c)

# 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}")

# 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}
)

# Compile the source file to an .llext file
if(CONFIG_ARM)
list(PREPEND LLEXT_C_FLAGS "-mlong-calls" "-mthumb")
add_custom_command(OUTPUT ${output_file}
COMMAND ${CMAKE_C_COMPILER} ${LLEXT_C_FLAGS} -c
-I ${ZEPHYR_BASE}/include
-imacros ${AUTOCONF_H}
-o ${output_file}
${source_file}
DEPENDS ${source_file}
)
elseif(CONFIG_XTENSA)
list(PREPEND LLEXT_C_FLAGS "-shared" "-fPIC" "-nostdlib" "-nodefaultlibs")
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)
add_custom_command(OUTPUT ${output_file}
COMMAND ${CMAKE_C_COMPILER} ${LLEXT_C_FLAGS}
-I ${ZEPHYR_BASE}/include
-imacros ${AUTOCONF_H}
-o ${pre_output_file}
${source_file}
COMMAND ${CROSS_COMPILE}strip -R .xt.*
-o ${output_file}
${pre_output_file}
DEPENDS ${source_file}
)
else()
message(FATAL_ERROR "add_llext_target: unsupported architecture")
endif()
endfunction()

endif()
2 changes: 1 addition & 1 deletion tests/subsys/llext/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ generate_inc_file_for_target(
${gen_dir}/hello_world.inc
)

add_dependencies(app hello_world)
add_dependencies(app hello_world_llext)
34 changes: 7 additions & 27 deletions tests/subsys/llext/hello_world/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,14 @@ elseif(CONFIG_MODULES AND NOT CONFIG_LLEXT_TEST_HELLO STREQUAL "m")
message(FATAL_ERROR "CONFIG_LLEXT_TEST_HELLO must be set to 'm' when CONFIG_MODULES is enabled")
else()

# TODO check which architecture is being used
if(CONFIG_ARM)
set(CMAKE_C_FLAGS "-mlong-calls" "-mthumb")
set(llext_src_file ${PROJECT_SOURCE_DIR}/hello_world.c)
set(llext_bin_file ${PROJECT_BINARY_DIR}/hello_world.llext)

add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext
COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -c
-I ${PROJECT_SOURCE_DIR}/../../../../include
-imacros${PROJECT_BINARY_DIR}/../zephyr/include/generated/autoconf.h
-o ${PROJECT_BINARY_DIR}/hello_world.llext
${PROJECT_SOURCE_DIR}/hello_world.c
)
elseif(CONFIG_XTENSA)
set(CMAKE_C_FLAGS "-shared" "-fPIC" "-nostdlib" "-nodefaultlibs")
add_llext_target(hello_world_llext
OUTPUT ${llext_bin_file}
SOURCES ${llext_src_file}
)

add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/hello_world.llext
COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS}
-I ${PROJECT_SOURCE_DIR}/../../../../include
-imacros${PROJECT_BINARY_DIR}/../zephyr/include/generated/autoconf.h
-o ${PROJECT_BINARY_DIR}/hello_world.pre.llext
${PROJECT_SOURCE_DIR}/hello_world.c
COMMAND ${CROSS_COMPILE}strip -R .xt.*
-o ${PROJECT_BINARY_DIR}/hello_world.llext
${PROJECT_BINARY_DIR}/hello_world.pre.llext
)
endif()

set(HELLO_WORLD_LLEXT ${PROJECT_BINARY_DIR}/hello_world.llext PARENT_SCOPE)

add_custom_target(hello_world DEPENDS ${PROJECT_BINARY_DIR}/hello_world.llext)
set(HELLO_WORLD_LLEXT ${llext_bin_file} PARENT_SCOPE)

endif()

0 comments on commit ee9a514

Please sign in to comment.