diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake index 41e36b99a27..9bc1d465057 100644 --- a/cmake/compiler/host-gcc/target.cmake +++ b/cmake/compiler/host-gcc/target.cmake @@ -36,3 +36,12 @@ foreach(file_name include/stddef.h) list(APPEND NOSTDINC ${_OUTPUT}) endforeach() + +list(APPEND LLEXT_EDK_REMOVE_FLAGS + --sysroot=.* + -fmacro-prefix-map=.* + ) + +list(APPEND LLEXT_EDK_APPEND_FLAGS + -nodefaultlibs + ) diff --git a/tests/misc/llext-edk/CMakeLists.txt b/tests/misc/llext-edk/CMakeLists.txt new file mode 100644 index 00000000000..4fee915a57f --- /dev/null +++ b/tests/misc/llext-edk/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(llext_edk_test LANGUAGES C) + +target_sources(app PRIVATE src/main.c) +zephyr_include_directories(include) +zephyr_include_directories($ENV{ZEPHYR_BASE}/boards/native/common) diff --git a/tests/misc/llext-edk/extension/CMakeLists.txt b/tests/misc/llext-edk/extension/CMakeLists.txt new file mode 100644 index 00000000000..1b1a9142ee4 --- /dev/null +++ b/tests/misc/llext-edk/extension/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.20.0) + +project(extension) + +include($ENV{LLEXT_EDK_INSTALL_DIR}/cmake.cflags) + +# Add LLEXT_CFLAGS to our flags +add_compile_options(${LLEXT_CFLAGS}) +add_compile_options("-Werror") +add_compile_options("-c") + +# Get flags from COMPILE_OPTIONS +get_property(COMPILE_OPTIONS_PROP DIRECTORY PROPERTY COMPILE_OPTIONS) + +add_custom_command( + OUTPUT + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.llext + COMMAND ${CMAKE_C_COMPILER} ${COMPILE_OPTIONS_PROP} + -o ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.llext + ${PROJECT_SOURCE_DIR}/src/main.c +) + +add_custom_target(extension ALL DEPENDS ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.llext) diff --git a/tests/misc/llext-edk/extension/src/main.c b/tests/misc/llext-edk/extension/src/main.c new file mode 100644 index 00000000000..c4843bee333 --- /dev/null +++ b/tests/misc/llext-edk/extension/src/main.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +int start(void) +{ + int bar = 42; + + printk("foo(%d) is %d\n", bar, foo(bar)); + return 0; +} diff --git a/tests/misc/llext-edk/include/app_api.h b/tests/misc/llext-edk/include/app_api.h new file mode 100644 index 00000000000..5270bca6873 --- /dev/null +++ b/tests/misc/llext-edk/include/app_api.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _TEST_EDK_H_ +#define _TEST_EDK_H_ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +__syscall int foo(int bar); + +#ifdef __cplusplus +} +#endif + +#include +#endif /* _TEST_EDK_H_ */ diff --git a/tests/misc/llext-edk/prj.conf b/tests/misc/llext-edk/prj.conf new file mode 100644 index 00000000000..a479f3a569c --- /dev/null +++ b/tests/misc/llext-edk/prj.conf @@ -0,0 +1,3 @@ +CONFIG_APPLICATION_DEFINED_SYSCALL=y +#CONFIG_USERSPACE=y +CONFIG_LLEXT=y diff --git a/tests/misc/llext-edk/pytest/test_edk.py b/tests/misc/llext-edk/pytest/test_edk.py new file mode 100644 index 00000000000..d85a138d48b --- /dev/null +++ b/tests/misc/llext-edk/pytest/test_edk.py @@ -0,0 +1,66 @@ +# Copyright (c) 2024 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os +import shutil +import tempfile + +from pathlib import Path +from subprocess import check_output +from twister_harness import DeviceAdapter + +logger = logging.getLogger(__name__) + +def test_edk(dut: DeviceAdapter): + # Can we build the edk? + command = [ + "west", + "build", + "-t", + "llext-edk", + "--build-dir", + dut.device_config.build_dir, + ] + output = check_output(command, text=True) + logger.info(output) + + # Install the edk to a temporary location + with tempfile.TemporaryDirectory() as tempdir: + # Copy the edk to the temporary directory using python methods + logger.debug(f"Copying llext-edk.tar.xz to {tempdir}") + edk_path = Path(dut.device_config.build_dir) / "zephyr/llext-edk.tar.xz" + shutil.copy(edk_path, tempdir) + + # Extract the edk using tar + logger.debug(f"Extracting llext-edk.tar.xz to {tempdir}") + command = ["tar", "-xf", "llext-edk.tar.xz"] + output = check_output(command, text=True, cwd=tempdir) + logger.info(output) + + # Copy the extension to another temporary directory to test out of tree builds + with tempfile.TemporaryDirectory() as tempdir_extension: + logger.debug(f"Copying extension to {tempdir_extension}") + ext_dir = Path(os.environ["ZEPHYR_BASE"]) / "tests/misc/llext-edk/extension" + shutil.copytree(ext_dir, tempdir_extension, dirs_exist_ok=True) + + # Set the LLEXT_EDK_INSTALL_DIR environment variable so that the extension + # knows where the EDK is installed + edk_dir = Path(tempdir) / "llext-edk" + env = os.environ.copy() + env.update({"LLEXT_EDK_INSTALL_DIR": edk_dir}) + + # Build the extension using the edk + logger.debug(f"Building extension in {tempdir_extension} - cmake") + command = ["cmake", "-B", "build"] + output = check_output(command, text=True, cwd=tempdir_extension, env=env) + logger.info(output) + + logger.debug(f"Building extension in {tempdir_extension} - make") + command = ["make", "-C", "build"] + output = check_output(command, text=True, cwd=tempdir_extension, env=env) + logger.info(output) + + # Check if the extension was built + assert os.path.exists(Path(tempdir_extension) / "build/extension.llext") diff --git a/tests/misc/llext-edk/src/foo.c b/tests/misc/llext-edk/src/foo.c new file mode 100644 index 00000000000..190dac2bea6 --- /dev/null +++ b/tests/misc/llext-edk/src/foo.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int z_impl_foo(int bar) +{ + return bar * bar; +} +EXPORT_SYMBOL(z_impl_foo); + +#ifdef CONFIG_USERSPACE +static inline int z_vrfy_foo(int bar) +{ + /* Nothing to verify */ + return z_impl_foo(bar); +} +#include +#endif diff --git a/tests/misc/llext-edk/src/main.c b/tests/misc/llext-edk/src/main.c new file mode 100644 index 00000000000..a5e7ab2e198 --- /dev/null +++ b/tests/misc/llext-edk/src/main.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +int main(void) +{ + return 0; +} diff --git a/tests/misc/llext-edk/testcase.yaml b/tests/misc/llext-edk/testcase.yaml new file mode 100644 index 00000000000..81f7ce0bd56 --- /dev/null +++ b/tests/misc/llext-edk/testcase.yaml @@ -0,0 +1,9 @@ +tests: + misc.edk.pytest: + harness: pytest + tags: + - pytest + - edk + platform_allow: + - native_sim + toolchain_exclude: llvm