Browse Source

tests/misc: Add llext EDK test

This test uses pytest to generate an EDK from a simple Zephyr
application, and uses this EDK to build a simple extension, to ensure
that EDK generation is sane.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
pull/72896/head
Ederson de Souza 1 year ago committed by Fabio Baltieri
parent
commit
a0ee472a6f
  1. 9
      cmake/compiler/host-gcc/target.cmake
  2. 9
      tests/misc/llext-edk/CMakeLists.txt
  3. 23
      tests/misc/llext-edk/extension/CMakeLists.txt
  4. 17
      tests/misc/llext-edk/extension/src/main.c
  5. 22
      tests/misc/llext-edk/include/app_api.h
  6. 3
      tests/misc/llext-edk/prj.conf
  7. 66
      tests/misc/llext-edk/pytest/test_edk.py
  8. 23
      tests/misc/llext-edk/src/foo.c
  9. 14
      tests/misc/llext-edk/src/main.c
  10. 9
      tests/misc/llext-edk/testcase.yaml

9
cmake/compiler/host-gcc/target.cmake

@ -36,3 +36,12 @@ foreach(file_name include/stddef.h) @@ -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
)

9
tests/misc/llext-edk/CMakeLists.txt

@ -0,0 +1,9 @@ @@ -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)

23
tests/misc/llext-edk/extension/CMakeLists.txt

@ -0,0 +1,23 @@ @@ -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)

17
tests/misc/llext-edk/extension/src/main.c

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
/*
* Copyright (c) 2024 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <app_api.h>
int start(void)
{
int bar = 42;
printk("foo(%d) is %d\n", bar, foo(bar));
return 0;
}

22
tests/misc/llext-edk/include/app_api.h

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _TEST_EDK_H_
#define _TEST_EDK_H_
#include <zephyr/kernel.h>
#ifdef __cplusplus
extern "C" {
#endif
__syscall int foo(int bar);
#ifdef __cplusplus
}
#endif
#include <syscalls/app_api.h>
#endif /* _TEST_EDK_H_ */

3
tests/misc/llext-edk/prj.conf

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
CONFIG_APPLICATION_DEFINED_SYSCALL=y
#CONFIG_USERSPACE=y
CONFIG_LLEXT=y

66
tests/misc/llext-edk/pytest/test_edk.py

@ -0,0 +1,66 @@ @@ -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")

23
tests/misc/llext-edk/src/foo.c

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <app_api.h>
#include <app_api.h>
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 <syscalls/foo_mrsh.c>
#endif

14
tests/misc/llext-edk/src/main.c

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <app_api.h>
#include <zephyr/llext/llext.h>
int main(void)
{
return 0;
}

9
tests/misc/llext-edk/testcase.yaml

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
tests:
misc.edk.pytest:
harness: pytest
tags:
- pytest
- edk
platform_allow:
- native_sim
toolchain_exclude: llvm
Loading…
Cancel
Save