From c90e99711d06f6ed6cfffd96e6dbb997121a6bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Costa?= Date: Wed, 5 Aug 2026 14:02:51 +0200 Subject: [PATCH] test(build): cleanup configs and build system (#10416) --- .github/workflows/ccpp.yml | 29 +- Kconfig | 8 + docs/src/integration/building/cmake.mdx | 13 +- docs/src/integration/configuration.mdx | 13 + env_support/cmake/dependencies.cmake | 11 + env_support/cmake/dependencies/egl.cmake | 45 ++ env_support/cmake/dependencies/glesv2.cmake | 46 ++ env_support/cmake/dependencies/libuv.cmake | 53 ++ env_support/cmake/kconfig.cmake | 32 +- env_support/cmake/main.cmake | 50 +- include/lvgl/config/lv_conf_internal.h | 12 + lv_conf_template.h | 9 + ref_imgs_vg_lite/widgets/canvas_1.png | Bin 0 -> 234 bytes ref_imgs_vg_lite/widgets/canvas_2.png | Bin 0 -> 6951 bytes .../widgets/canvas_layer_complex.png | Bin 0 -> 833 bytes scripts/install-prerequisites.bat | 4 +- scripts/prerequisites-apt.txt | 8 + scripts/run_tests_docker.sh | 2 +- src/debugging/test/Kconfig | 8 + src/debugging/test/lv_test_display_egl.c | 4 - src/draw/opengles/lv_draw_opengles.c | 13 +- src/drivers/x11/lv_x11_display.c | 10 +- tests/.gitignore | 1 - tests/CMakeLists.txt | 679 +++++------------- tests/README.md | 18 + tests/configs/builtin_heap.defconfig | 4 + tests/configs/common.defconfig | 11 + tests/configs/defheap.defconfig | 13 + tests/configs/depth_16.defconfig | 2 + tests/configs/depth_32.defconfig | 2 + tests/configs/full.defconfig | 131 ++++ tests/configs/gstreamer.defconfig | 1 + tests/configs/linux_egl.defconfig | 7 + tests/configs/linux_sw.defconfig | 22 + tests/configs/minimal.defconfig | 8 + tests/configs/nanovg.defconfig | 9 + tests/configs/nuttx.defconfig | 15 + tests/configs/riscv_v.defconfig | 3 + tests/configs/run_tests.defconfig | 11 + tests/configs/sys_heap.defconfig | 17 + tests/configs/unix.defconfig | 14 + tests/configs/vg_lite.defconfig | 32 + tests/configs/vg_lite_32bit.defconfig | 3 + tests/configs/windows.defconfig | 6 + tests/configs/windows_sw.defconfig | 7 + tests/main.py | 458 ++++++++---- tests/src/lv_test_assert.h | 23 + tests/src/lv_test_attributes.h | 20 + tests/src/lv_test_conf.h | 141 ---- tests/src/lv_test_conf_full.h | 217 ------ tests/src/lv_test_conf_minimal.h | 28 - tests/src/lv_test_conf_vg_lite.h | 51 -- tests/src/lv_test_init.c | 4 +- tests/src/test_cases/test_check_obj.c | 4 - .../test_cases/test_check_obj_cls_no_vld.c | 2 - tests/src/test_cases/test_check_obj_no_arg.c | 2 - .../test_cases/test_check_obj_no_cls_no_vld.c | 2 - .../test_cases/test_check_obj_no_cls_vld.c | 2 - tests/src/test_cases/test_mem.c | 6 +- 59 files changed, 1195 insertions(+), 1151 deletions(-) create mode 100644 env_support/cmake/dependencies/egl.cmake create mode 100644 env_support/cmake/dependencies/glesv2.cmake create mode 100644 env_support/cmake/dependencies/libuv.cmake create mode 100644 ref_imgs_vg_lite/widgets/canvas_1.png create mode 100644 ref_imgs_vg_lite/widgets/canvas_2.png create mode 100644 ref_imgs_vg_lite/widgets/canvas_layer_complex.png create mode 100644 tests/configs/builtin_heap.defconfig create mode 100644 tests/configs/common.defconfig create mode 100644 tests/configs/defheap.defconfig create mode 100644 tests/configs/depth_16.defconfig create mode 100644 tests/configs/depth_32.defconfig create mode 100644 tests/configs/full.defconfig create mode 100644 tests/configs/gstreamer.defconfig create mode 100644 tests/configs/linux_egl.defconfig create mode 100644 tests/configs/linux_sw.defconfig create mode 100644 tests/configs/minimal.defconfig create mode 100644 tests/configs/nanovg.defconfig create mode 100644 tests/configs/nuttx.defconfig create mode 100644 tests/configs/riscv_v.defconfig create mode 100644 tests/configs/run_tests.defconfig create mode 100644 tests/configs/sys_heap.defconfig create mode 100644 tests/configs/unix.defconfig create mode 100644 tests/configs/vg_lite.defconfig create mode 100644 tests/configs/vg_lite_32bit.defconfig create mode 100644 tests/configs/windows.defconfig create mode 100644 tests/configs/windows_sw.defconfig create mode 100644 tests/src/lv_test_assert.h create mode 100644 tests/src/lv_test_attributes.h delete mode 100644 tests/src/lv_test_conf.h delete mode 100644 tests/src/lv_test_conf_full.h delete mode 100644 tests/src/lv_test_conf_minimal.h delete mode 100644 tests/src/lv_test_conf_vg_lite.h diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 848373c86c..05fd3e50a7 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -20,12 +20,11 @@ jobs: fail-fast: false matrix: # A valid option parameter to the cmake file. - # See BUILD_OPTIONS in tests/CMakeLists.txt. - build_option: ['OPTIONS_NORMAL_8BIT', - 'OPTIONS_16BIT', - 'OPTIONS_24BIT', - 'OPTIONS_FULL_32BIT', - 'OPTIONS_SDL'] + # See build_only_options and test_options in tests/main.py. + build_option: ['OPTIONS_MINIMAL', + 'OPTIONS_LINUX_SW', + 'OPTIONS_LINUX_OPENGLES', + 'OPTIONS_NUTTX'] name: Build ${{ matrix.build_option }} - Ubuntu steps: - uses: actions/checkout@v7 @@ -48,10 +47,9 @@ jobs: fail-fast: false matrix: # A valid option parameter to the cmake file. - # See BUILD_OPTIONS in tests/CMakeLists.txt. - build_option: ['OPTIONS_16BIT', - 'OPTIONS_24BIT', - 'OPTIONS_FULL_32BIT'] + # See build_only_options and test_options in tests/main.py. + build_option: ['OPTIONS_MINIMAL', + 'OPTIONS_WINDOWS_SW'] compiler: [gcc, cl] name: Build ${{ matrix.build_option }} - ${{matrix.compiler }} - Windows @@ -106,11 +104,12 @@ jobs: test-native: runs-on: ubuntu-24.04 strategy: - matrix: - # A valid option parameter to the cmake file. - # See BUILD_OPTIONS in tests/CMakeLists.txt. - build_config: ['64bit build', - '32bit build'] + fail-fast: false + matrix: + # A valid option parameter to the cmake file. + # See build_only_options and test_options in tests/main.py. + build_config: ['64bit build', + '32bit build'] name: Run tests with ${{ matrix.build_config }} steps: - uses: actions/checkout@v7 diff --git a/Kconfig b/Kconfig index c3598aee90..0676a5a035 100644 --- a/Kconfig +++ b/Kconfig @@ -3253,6 +3253,14 @@ config LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE When a reference image does not exist yet, create it from the rendered screen instead of failing the compare. +config LV_USE_NANOVG_TEST_HEADLESS + bool "Headless EGL display for NanoVG" + depends on LV_USE_DRAW_NANOVG + help + Render into an off-screen EGL pbuffer instead of a window and read the + pixels back into the LVGL draw buffer, so screenshot compares work the + same way as with the software renderer. Requires EGL and GLESv2. + endif #LV_USE_TEST config LV_USE_MONKEY diff --git a/docs/src/integration/building/cmake.mdx b/docs/src/integration/building/cmake.mdx index f7af0b427e..ee079cf53c 100644 --- a/docs/src/integration/building/cmake.mdx +++ b/docs/src/integration/building/cmake.mdx @@ -139,6 +139,16 @@ set(LV_BUILD_DEFCONFIG_PATH path/to/my_defconfig) add_subdirectory(lvgl) ``` +Several defconfigs can be given as a `;`-separated list. They are merged in the +given order, so a later one overrides a value set by an earlier one. This lets +related configurations share a common base instead of duplicating it: + +```cmake +set(LV_BUILD_USE_KCONFIG ON) +set(LV_BUILD_DEFCONFIG_PATH "configs/base.defconfig;configs/my_board.defconfig") +add_subdirectory(lvgl) +``` + To enable the demos and examples set these options: ```cmake @@ -205,7 +215,8 @@ Below is a list of the available options/variables | LV_BUILD_CONF_DIR | PATH | Allows to set a directory containing `lv_conf.h` | | LV_BUILD_USE_KCONFIG | BOOLEAN | When set KConfig is used as the configuration source. This option is disabled by default. | | LV_BUILD_DOTCONFIG_PATH | PATH | Specify the path to a .config file when using Kconfig | -| LV_BUILD_DEFCONFIG_PATH | PATH | Specify the path to a defconfig file when using Kconfig | +| LV_BUILD_DEFCONFIG_PATH | STRING | Specify to use a .defconfig file instead of the current .config in a Kconfig setup. Accepts a `;`-separated list of defconfigs, which are merged in the given order so that a later one overrides a value set by an earlier one. | +| LV_BUILD_DEFCONFIG_STRICT | BOOLEAN | When enabled, a defconfig that assigns an unknown or non-user-configurable symbol, or a value that ends up having no effect, fails the build instead of being ignored. This option is disabled by default. | | LV_BUILD_KCONFIG_ROOT | PATH | Override the root Kconfig file that is parsed by LVGL's build system (defaults to LVGL's Kconfig file) | | LV_BUILD_LVGL_H_SYSTEM_INCLUDE | BOOLEAN | Enable if LVGL will be installed to the system or your build system uses a sysroot. Turning this option on implies that the resources generated by the image generation script will include `lvgl.h` as a system include. i.e: `#include `. This option is disabled by default. | | LV_BUILD_LVGL_H_SIMPLE_INCLUDE | BOOLEAN | When enabled the resources will include `lvgl.h` as a simple include, this option is enabled by default. | diff --git a/docs/src/integration/configuration.mdx b/docs/src/integration/configuration.mdx index 1c15c60126..8e9899cedf 100644 --- a/docs/src/integration/configuration.mdx +++ b/docs/src/integration/configuration.mdx @@ -192,6 +192,19 @@ cmake -B build -DLV_BUILD_USE_KCONFIG=ON -DLV_BUILD_DEFCONFIG_PATH=configs/defco cmake --build build ``` +### Combining presets + +`LV_BUILD_DEFCONFIG_PATH` accepts a `;`-separated list of defconfigs. They are +merged in the given order, so a later one overrides a value set by an earlier +one. This way a set of related configurations can share a common base instead of +each repeating it: + +```bash +cmake -B build -DLV_BUILD_USE_KCONFIG=ON \ + "-DLV_BUILD_DEFCONFIG_PATH=configs/defconfigs/sdl2.defconfig;my_overrides.defconfig" +cmake --build build +``` + ### Empty configuration `configs/defconfigs/empty.defconfig` strips LVGL to its smallest sensible diff --git a/env_support/cmake/dependencies.cmake b/env_support/cmake/dependencies.cmake index 4d25b9622e..09c643a99a 100644 --- a/env_support/cmake/dependencies.cmake +++ b/env_support/cmake/dependencies.cmake @@ -54,6 +54,17 @@ if(CONFIG_LV_USE_GLFW) include(${CMAKE_CURRENT_LIST_DIR}/dependencies/glfw.cmake) endif() +# LV_USE_EGL dynamically loads egl so it doesn't appear here +if(CONFIG_LV_USE_NANOVG_TEST_HEADLESS) + include(${CMAKE_CURRENT_LIST_DIR}/dependencies/egl.cmake) + include(${CMAKE_CURRENT_LIST_DIR}/dependencies/glesv2.cmake) +endif() + +# ====== OS ====== # +if(CONFIG_LV_USE_NUTTX_LIBUV) + include(${CMAKE_CURRENT_LIST_DIR}/dependencies/libuv.cmake) +endif() + # ====== Indev ====== # if(CONFIG_LV_USE_WAYLAND OR CONFIG_LV_USE_LIBINPUT) include(${CMAKE_CURRENT_LIST_DIR}/dependencies/xkbcommon.cmake) diff --git a/env_support/cmake/dependencies/egl.cmake b/env_support/cmake/dependencies/egl.cmake new file mode 100644 index 0000000000..5b233e8ccf --- /dev/null +++ b/env_support/cmake/dependencies/egl.cmake @@ -0,0 +1,45 @@ +# ============================================================ +# EGL Configuration +# ============================================================ +set(PKG_CONFIG_NAME "egl") +set(PKG_LIB_PRIVATE "-lEGL") + +option(LV_USE_FIND_PACKAGE_EGL "Resolve EGL via find_package" + ${LV_USE_FIND_PACKAGE}) +option(LV_USE_PKG_CONFIG_EGL "Resolve EGL via pkg-config" ${LV_USE_PKG_CONFIG}) + +if(LV_USE_FIND_PACKAGE_EGL) + find_package(OpenGL QUIET COMPONENTS EGL) + if(TARGET OpenGL::EGL) + message(STATUS "lvgl: EGL: found via find_package") + lvgl_link_packages( + PRIVATE + TARGETS + OpenGL::EGL + CMAKE_PACKAGE + OpenGL + PKG_CONFIG + ${PKG_CONFIG_NAME} + PKG_LIB_PRIVATE + ${PKG_LIB_PRIVATE}) + return() + endif() +endif() + +if(LV_USE_PKG_CONFIG_EGL AND PkgConfig_FOUND) + pkg_check_modules(EGL IMPORTED_TARGET QUIET ${PKG_CONFIG_NAME}) + if(EGL_FOUND) + message(STATUS "lvgl: EGL: found via pkg-config") + lvgl_link_pkg_config( + PRIVATE + TARGETS + PkgConfig::EGL + PKG_CONFIG + ${PKG_CONFIG_NAME} + PKG_LIB_PRIVATE + ${PKG_LIB_PRIVATE}) + return() + endif() +endif() + +message(FATAL_ERROR "lvgl: EGL not found. Please install libegl") diff --git a/env_support/cmake/dependencies/glesv2.cmake b/env_support/cmake/dependencies/glesv2.cmake new file mode 100644 index 0000000000..46f21cc50a --- /dev/null +++ b/env_support/cmake/dependencies/glesv2.cmake @@ -0,0 +1,46 @@ +# ============================================================ +# OpenGL ES v2 Configuration +# ============================================================ +set(PKG_CONFIG_NAME "glesv2") +set(PKG_LIB_PRIVATE "-lGLESv2") + +option(LV_USE_FIND_PACKAGE_GLESV2 "Resolve OpenGL ES via find_package" + ${LV_USE_FIND_PACKAGE}) +option(LV_USE_PKG_CONFIG_GLESV2 "Resolve OpenGL ES via pkg-config" + ${LV_USE_PKG_CONFIG}) + +if(LV_USE_FIND_PACKAGE_GLESV2) + find_package(OpenGL QUIET COMPONENTS GLES2) + if(TARGET OpenGL::GLES2) + message(STATUS "lvgl: OpenGL ES: found via find_package") + lvgl_link_packages( + PRIVATE + TARGETS + OpenGL::GLES2 + CMAKE_PACKAGE + OpenGL + PKG_CONFIG + ${PKG_CONFIG_NAME} + PKG_LIB_PRIVATE + ${PKG_LIB_PRIVATE}) + return() + endif() +endif() + +if(LV_USE_PKG_CONFIG_GLESV2 AND PkgConfig_FOUND) + pkg_check_modules(GLESV2 IMPORTED_TARGET QUIET ${PKG_CONFIG_NAME}) + if(GLESV2_FOUND) + message(STATUS "lvgl: OpenGL ES: found via pkg-config") + lvgl_link_pkg_config( + PRIVATE + TARGETS + PkgConfig::GLESV2 + PKG_CONFIG + ${PKG_CONFIG_NAME} + PKG_LIB_PRIVATE + ${PKG_LIB_PRIVATE}) + return() + endif() +endif() + +message(FATAL_ERROR "lvgl: OpenGL ES not found. Please install libgles") diff --git a/env_support/cmake/dependencies/libuv.cmake b/env_support/cmake/dependencies/libuv.cmake new file mode 100644 index 0000000000..fd3b72daf0 --- /dev/null +++ b/env_support/cmake/dependencies/libuv.cmake @@ -0,0 +1,53 @@ +# ============================================================ +# libuv Configuration +# ============================================================ +set(CMAKE_PACKAGE_NAME "libuv") +set(PKG_CONFIG_NAME "libuv") +set(PKG_LIB_PRIVATE "-luv") + +option(LV_USE_FIND_PACKAGE_LIBUV "Resolve libuv via find_package" + ${LV_USE_FIND_PACKAGE}) +option(LV_USE_PKG_CONFIG_LIBUV "Resolve libuv via pkg-config" + ${LV_USE_PKG_CONFIG}) + +if(LV_USE_FIND_PACKAGE_LIBUV) + find_package(${CMAKE_PACKAGE_NAME} CONFIG QUIET) + # libuv exports the shared library as libuv::uv and the static one as + # libuv::uv_a. Which of them exists depends on how it was built. + foreach(_target libuv::uv_a libuv::uv) + if(TARGET ${_target}) + message(STATUS "lvgl: libuv: found via find_package") + lvgl_link_packages( + PRIVATE + TARGETS + ${_target} + CMAKE_PACKAGE + ${CMAKE_PACKAGE_NAME} + PKG_CONFIG + ${PKG_CONFIG_NAME} + PKG_LIB_PRIVATE + ${PKG_LIB_PRIVATE}) + return() + endif() + endforeach() +endif() + +if(LV_USE_PKG_CONFIG_LIBUV AND PkgConfig_FOUND) + pkg_check_modules(LIBUV IMPORTED_TARGET QUIET ${PKG_CONFIG_NAME}) + if(LIBUV_FOUND) + message(STATUS "lvgl: libuv: found via pkg-config") + lvgl_link_pkg_config( + PRIVATE + TARGETS + PkgConfig::LIBUV + PKG_CONFIG + ${PKG_CONFIG_NAME} + PKG_LIB_PRIVATE + ${PKG_LIB_PRIVATE}) + return() + endif() +endif() + +message( + FATAL_ERROR + "lvgl: libuv not found. Please install libuv.") diff --git a/env_support/cmake/kconfig.cmake b/env_support/cmake/kconfig.cmake index d0a258c2c3..7ba1d515f7 100644 --- a/env_support/cmake/kconfig.cmake +++ b/env_support/cmake/kconfig.cmake @@ -18,7 +18,26 @@ endmacro() # Check if the user wants to use a defconfig, using the -DLV_BUILD_DEFCONFIG_PATH option if(LV_BUILD_DEFCONFIG_PATH) - lv_normalize_config_path(LV_BUILD_DEFCONFIG_PATH "defconfig" DOTCONFIG) + # Several defconfigs can be given as a ";"-separated list. They are merged in + # order, so a later fragment overrides the value set by an earlier one. This + # lets related configurations share a common base instead of duplicating it. + set(DOTCONFIG) + foreach(defconfig IN LISTS LV_BUILD_DEFCONFIG_PATH) + lv_normalize_config_path(defconfig "defconfig" defconfig_abs) + list(APPEND DOTCONFIG ${defconfig_abs}) + endforeach() + + list(LENGTH DOTCONFIG defconfig_count) + if(LV_BUILD_DEFCONFIG_STRICT) + # Apply the stricter checks: assignments to unknown or promptless + # symbols, and values that end up not taking effect, become errors. + # Overriding a symbol set by an earlier fragment is allowed. + set(KCONFIG_INPUT_FLAGS --handwritten-input-configs) + elseif(defconfig_count GREATER 1) + # Merging without the strict checks needs this, otherwise overriding a + # symbol set by an earlier fragment is reported as an error. + set(KCONFIG_INPUT_FLAGS --forced-input-configs) + endif() elseif(LV_BUILD_DOTCONFIG_PATH) lv_normalize_config_path(LV_BUILD_DOTCONFIG_PATH ".config" DOTCONFIG) else() @@ -36,14 +55,17 @@ else() endif() endif() -if (NOT EXISTS ${DOTCONFIG}) - message(FATAL_ERROR "defconfig: ${DOTCONFIG} - does not exist") -endif() +foreach(config IN LISTS DOTCONFIG) + if (NOT EXISTS ${config}) + message(FATAL_ERROR "defconfig: ${config} - does not exist") + endif() +endforeach() execute_process( COMMAND ${CMAKE_COMMAND} -E env LVGL_DIR=${LVGL_ROOT_DIR} - ${Python_EXECUTABLE} + ${Python_EXECUTABLE} ${LVGL_ROOT_DIR}/scripts/build-tools/kconfig.py + ${KCONFIG_INPUT_FLAGS} ${LV_BUILD_KCONFIG_ROOT} ${OUTPUT_DOTCONFIG} ${AUTOCONF_H} diff --git a/env_support/cmake/main.cmake b/env_support/cmake/main.cmake index 22d8e6acb8..4ce0da8292 100644 --- a/env_support/cmake/main.cmake +++ b/env_support/cmake/main.cmake @@ -10,8 +10,14 @@ set(LV_BUILD_CONF_DIR "" CACHE PATH "Can be used to specify the include dir containing lv_conf.h, to be used in conjunction with LV_CONF_INCLUDE_SIMPLE") option(LV_BUILD_USE_KCONFIG "Use Kconfig" OFF) -set(LV_BUILD_DEFCONFIG_PATH "" CACHE PATH - "Supply the default Kconfig configuration - used with Kconfig") +set(LV_BUILD_DEFCONFIG_PATH "" CACHE STRING + "Supply the default Kconfig configuration - used with Kconfig. Accepts a \ +\";\"-separated list of defconfigs, merged in order so later ones override earlier ones") + +option(LV_BUILD_DEFCONFIG_STRICT + "Fail if a defconfig assigns an unknown or promptless symbol, or a value \ +that ends up having no effect. Off by default so that existing configurations \ +keep working" OFF) set(LV_BUILD_DOTCONFIG_PATH "" CACHE PATH "Path to .config path - used with Kconfig") @@ -41,6 +47,8 @@ option(LV_USE_FIND_PACKAGE "Resolve dependencies via find_package" ON) option(LV_USE_PKG_CONFIG "Resolve dependencies via pkg-config (requires pkg-config to be installed)" ON) option(LV_FETCH_DEPENDENCIES "Fetch dependencies from source if not found on the system" ON) +option(LV_BUILD_TESTS "Build the unit tests in the tests directory" OFF) + option(CONFIG_LV_BUILD_DEMOS "Build demos" ON) option(CONFIG_LV_BUILD_EXAMPLES "Build examples" ON) option(CONFIG_LV_USE_THORVG_INTERNAL "Use the internal version of ThorVG" ON) @@ -52,6 +60,31 @@ if (LV_BUILD_CONF_PATH AND LV_BUILD_CONF_DIR) message(FATAL_ERROR "can not use LV_BUILD_CONF_DIR and LV_BUILD_CONF_PATH at the same time") endif() +if (LV_BUILD_TESTS) + if (NOT EXISTS ${LVGL_ROOT_DIR}/tests/CMakeLists.txt) + message(FATAL_ERROR "LV_BUILD_TESTS is set but the tests directory is missing") + endif() + + # Every test configuration is a set of Kconfig defconfigs, see + # tests/configs and the recipes in tests/main.py + set(LV_BUILD_USE_KCONFIG ON) + set(LV_BUILD_DEFCONFIG_STRICT ON) + + set(CMAKE_C_STANDARD 99) + set(CMAKE_CXX_STANDARD 14) + + # Lets `ctest -T memcheck` work. include(CTest) reads this, so it has to be + # found here rather than in tests/CMakeLists.txt. + find_program(VALGRIND_EXECUTABLE valgrind) + if (VALGRIND_EXECUTABLE) + set(MEMORYCHECK_COMMAND ${VALGRIND_EXECUTABLE}) + set(MEMORYCHECK_COMMAND_OPTIONS --error-exitcode=1) + endif() + + enable_testing() + include(CTest) +endif() + if (LV_BUILD_USE_KCONFIG) # If Kconfig is used then the configuration has to be expanded set(LV_BUILD_SET_CONFIG_OPTS ON) @@ -510,10 +543,17 @@ if (HAS_PARENT_SCOPE) set(LVGL_COMPILER_DEFINES ${COMP_DEF} PARENT_SCOPE) else() - # The file has been included by tests/CMakeLists.txt - - # or somewhere else, set variable containing the normalized path of the include dir - # containing the configuration file + # Building LVGL as the top-level project, set variable containing the + # normalized path of the include dir containing the configuration file set(LVGL_CONF_INC_DIR ${CONF_INC_DIR}) set(LVGL_CONF_PATH ${CONF_PATH}) set(LVGL_COMPILER_DEFINES ${COMP_DEF}) endif() + +############################## TESTS ###################################### + +# Added last so that the tests can adjust the targets created above, e.g. to +# compile LVGL itself with the sanitizers and the strict warning set. +if (LV_BUILD_TESTS) + add_subdirectory(${LVGL_ROOT_DIR}/tests tests) +endif() diff --git a/include/lvgl/config/lv_conf_internal.h b/include/lvgl/config/lv_conf_internal.h index a53f813c5e..15cb170518 100644 --- a/include/lvgl/config/lv_conf_internal.h +++ b/include/lvgl/config/lv_conf_internal.h @@ -4168,6 +4168,14 @@ #endif #endif +#ifndef LV_USE_NANOVG_TEST_HEADLESS + #ifdef CONFIG_LV_USE_NANOVG_TEST_HEADLESS + #define LV_USE_NANOVG_TEST_HEADLESS CONFIG_LV_USE_NANOVG_TEST_HEADLESS + #else + #define LV_USE_NANOVG_TEST_HEADLESS 0 + #endif +#endif + #ifndef LV_USE_MONKEY #ifdef CONFIG_LV_USE_MONKEY #define LV_USE_MONKEY CONFIG_LV_USE_MONKEY @@ -5374,6 +5382,10 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #error "LV_USE_TEST_SCREENSHOT_COMPARE requires LV_USE_TEST (Kconfig depends on)" #endif +#if LV_USE_NANOVG_TEST_HEADLESS && !(LV_USE_DRAW_NANOVG && LV_USE_TEST) + #error "LV_USE_NANOVG_TEST_HEADLESS requires LV_USE_DRAW_NANOVG && LV_USE_TEST (Kconfig depends on)" +#endif + #if LV_GLOBAL_USE_CUSTOM_INCLUDE && !(LV_ENABLE_GLOBAL_CUSTOM) #error "LV_GLOBAL_USE_CUSTOM_INCLUDE requires LV_ENABLE_GLOBAL_CUSTOM (Kconfig depends on)" #endif diff --git a/lv_conf_template.h b/lv_conf_template.h index 3ae936cbb6..e91b359b7e 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -2129,6 +2129,15 @@ #define LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE 1 #endif /*LV_USE_TEST_SCREENSHOT_COMPARE*/ + +#if LV_USE_DRAW_NANOVG +/** Render into an off-screen EGL pbuffer instead of a window and read the + * pixels back into the LVGL draw buffer, so screenshot compares work the + * same way as with the software renderer. Requires EGL and GLESv2. + */ +#define LV_USE_NANOVG_TEST_HEADLESS 0 + +#endif /*LV_USE_DRAW_NANOVG*/ #endif /*LV_USE_TEST*/ /** Feed random input events to the UI for stress testing. */ diff --git a/ref_imgs_vg_lite/widgets/canvas_1.png b/ref_imgs_vg_lite/widgets/canvas_1.png new file mode 100644 index 0000000000000000000000000000000000000000..95ee249c0484aa2a5f1e8da14a8810535d4cdb3d GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV0^&D3=~nwe3%BLI0Jk_T)%$(%J3h^`ER+> z!v#ps@pN$vsbG9_k&%}{frr_#psmyM@cWdU%y%MRE`u}^4|sNl=2tZfD9+}*siyv9 zdCL)-NkU9$+BtXGS_pu|1fJyEo)AToMdf}FcK^$nf6K<^H%Q#m)z4*}Q$iB}9r!IO literal 0 HcmV?d00001 diff --git a/ref_imgs_vg_lite/widgets/canvas_2.png b/ref_imgs_vg_lite/widgets/canvas_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ab26e10f3698e622a4ff49a38a831fd4e028bcf9 GIT binary patch literal 6951 zcmd^Ec{r49+rJpQ!B|R`n8{KiW$;+S%%EniqElLZC zBB>~2O-jfzsfm<*XAIwUPw)G^|9t;`-|@Z2dpHjFb)DyR{(isncV74H4;OYjlBFb+ zB>(_YJ1Dl!0HCk{2z(Jk!H9p?LLJ;3*=_H#ZDwW$M%Zk2X=&+~FJJE8zaInlGyqoM z!?3v-tgP^tAPay@KR@8>3*%A%OaXwFk^|t=& z5Ey2HOfWeK(f67FU-;A11f{H!20yQYdndulO>p-liwIN`OKEK|w%71Z>y<_U{J~5#Y&_CtHdl zJ_Dc>wZoR=5-u>D-ktXN4@_Koz#rn8R$c*(gL5&BOYZIuPW&nK^>we05!*QHSl)8< z;f4_hvJ1Cp>K>A}Pj zE>5F=^=(yBOB|L_5zMj>HaN=qICK^BAkMDmw9qqoIu@E|xT-b>C-3LluehpTZsw`F zG48EA3S&{0%n23WQ0m8+;tkPH619nVb?xJpKr2%1fQ~xe2 z=r!Jxl&FM1G1}jlf=Q0kz4lhfOy1feA0~WA0WdNA-JPl1FH&wm8jZueL)vn~?1{Hm zJ`lx~wchrWWI0TBV6>8Y&8VN~`|;GarZ+ZBt$x9KUZhWPVr${t1~xHpHn;41jATez zBfqA~D{%<7;u$#L%xBm$=uG_h__#)#25#jTg=vT*Duxa+pGkVZW$H}n6X*xUCjxEg zJ>mit2=yV1ZoGZQKHfZ}W_aG_-4Xv4iNrlI8u9jP%7~;ZantuovBzI8szEn|#k^~n zOHSD$!q96O_Na68u>0%kU$ALsI#wH9pBq9XSewed&UL0=6K~`~AO##l*k)4HBS-j| zTnXD5^76xf;TQroC3Pg+>%8 zkT~(2mQEuNq~Y}P$_#bxmGKYj5PS{BXJ(IV!UJ`js(Ae_132V22GFAhS=#{0Xq=rV zQx`YCNt<>3k!gHIFoi@vDphacIl~jnTPO688~rivi4#1%Q_j|(GBB~to~ebKyStf{ z_2`d_@U#!0qf%&lI>RH6HALa9n=p^q*i1EzQoxK8r>wBfXL95I)1ZiB0Jpv$fI z{NQ{qizC|QZK;%&LWgv@g02@hVir{S>itXT?ry>)F8z z?OcQnfF&=`lBcyeRhIBox^fda?useF<>&6JL54f|i49%ei$cuN6YF5U->m3E*AowN zWz&nq?}^Nxom=VB?HDP$u;rpYFW~W0BM0|6>GOh8X%X$ZDD0NzXkQkB*A49<0j6B5Q!hC z^Pl0FT%rMN1yf-|Hhw9-O7d5_RS=a-_~YuC>Ck7tlNvu*Aw);2Kv)h$e~uVW3> zERiiEr{|l#TtdI@Q(Z?&L@O$&^3LkB}7tfF?_Bg*#<%V6pWK9)GBAIAQ~CW5R!fK>fb5Fd}kFSAM;+(^Mw}r z_G)O8zar<}!|I4R{pFIWslaM(4n9ZuaG-SI0cK%ZIpLbC;xbazqeBQh`-sybP~1jYYM_O)q&186 zDalh`f1!Q$*#aVt#LNpXP^`sktW*|%H_7%>ehJ5PjuihbbsOeVV$Z2>-cACkSc4|+ z$NUMFCgoFNPpFR@KeEs&|21_NQ%|XD#d09W@XxbZ{WHsETbQ3~y+O3+V=4E@rA{LhNagz%icIi9Kp?292uU$DDxf7nVHBFCrBN=^)p^nCci7|ux^1B3u z`$}f4+jhMJyt}MP;Y?=gy!(M#jW3fz1-~8&4ONCDIH2HYr07OIP*m;?2xmw9ydGIX zUD>JgDsFEyzBr3glOR}q=y(k>NB9Ri45E3jPKmWsVb0!C?<+TxQU85!h8rkLmcw6V zPwAlAX38O2(_ji6zVOzhtgVoT<^_4Yh@Z-NsN>64Ttu}8a}Lt5%+&-;2w0EmUCb9g&)f8&*P1M+ zeqT{))jOFnli~78sMeOQs(8|u_?Z_S&Msl=!)v;Zl#Djf#d;7lDePkQC<^(Ma5_%~ z3zqcdzl|AgcR%@c=bGA}=H&2qHu&Vg9V+PN&1$*nQ+I z%CN?Ar&EtS9R8rn+S?g(B`KxKj6<}SMigYIA_N9zup3eD(+F}c2a&<3hjTH*q{GkW zX{>g_e|W*2hACM!ole(7wTK;e8&1cO?`A~}Xd$lM_&E|4N4Bo9nvz4TbTYo4G)@r{ z=C(*8ZrbkcPKMjP%~sR8ztf(HaG&R;zPJkUpV8pc^r3okGjsQ&T|9X2I7Hja23LkW zhXf1#XYUX4AwIe%jv*0oDek9WgmRs~@;5!6ZUWKzmDMbo5999>@S(a*)VY25c*5@@ zi?`brT^EVgH80LE5L~106S)=(hU&C9dej&|ijHoqBsOr~siGj&tKVm;LTS&}#|*5Y z9PJd zA!>g2P&XJTWYZ9di}DB?Wh0l^@Nw)gc5m~GMLt{fCf9pfk#d85i^RS?)qm3B;-h9{ zBZGhRquc_^Dtpg7_D%6V`dJij$7{ht`ghClEj&9-TpkV+Wwi)MP8s9JUPr(lpJr(5zz^A41xX5z=oH!vp5 zdL3qApIs>gP?@=cZa=DARG>)9CE>HdZA`%~>fQ7J zNoC3@3C-5XLMu!M>UZXpptwf6n}W4SiG^@U86?yIvE!MC5i ztAmO0op07c^ov2vj%lRv?Q;fKX?mqO{^(kDm8jE7XM>$rP+ioY?Iri?qlEBG;;+I1 z;=y;E^hW5&q8epQl~szhLRNR3vq(wX*}G;CbM)0-h{=n1T||cOP(KSj$gk{DsQ=`Mezt z)^OspImE4!g1GMdAuSFXY!)qPjksrwi78qseu5}cW@%SOshtnF7o|orV-g4N&k_&r z;`$tivzRetZfQ#=<0OpV`M60_Z%*xt#4g)U?NNcY%^1Kr&G2uNd56Kqx#B}9MrxH9 z2I12}+jhumiKeCxHRUr;7(b{fguYsw(ZO_l2!AdM)ykk2a16t z$U{s6On1{gnx2t*KnfK-FAmkMVVt1*V`;Sf=G3P-3%Q`m>;kRR*G-CgOFlo z-#|o`NF$`UUwp;?mK&z$Bd!Whm=}-OV&1L39FedbA8mtJ;?dhXIQE|18jRRcklkyO zQ_YKAzL@hnIV_VBu{=3#U1A~@{#o_N6DD_165wU~@y=T#p8{E8#ons3D^OO}g1@%%9! z3<+B?Oj#Nco$f&MXZ`H(+^GhQm3eWV*`NHW9vG2HxskGDc-FjzzyI9R+h{Sl+4KDe zC6Va?O_8>Mx!nyK@2c~z8e;f8)i00lANscStf>tRzT>gPWuIKfQ|TRati-*rm#gz_ zUuxBA^sQ*fD;(b1@ZsS#-O#9?Yo`lW!YX;a77e90YwGDI9V4)ha}JFSIyKNnwWTV| zzSEk*qaz}F>INub=_0+?CW&ezvnf*>9PIqkMUm~OWmQX4{$I%tv}KXgJ!hjMvU|yd z)^<&6liL*OI(^NawbRE{7;Er{HafRs(t5FJDG7myOoPonq}LkA}jDU>1^4zVK*gY@7X zip|#Wu(L*REJ!Pn1auNDk2`9Qvp()gk;aimxUT>tL7QmCKjIMh*SYAC~0Dk7Ien zFfUJj+!LiVq&KX>j|W5b5|w`=+RmY=pWF6!3iIPWSW$C{O2m1Vn@+aI+VdWW22PRD zrrtPlq^oO}lO10xAZJ?^Y5!bpuMn#wL9;OTq>)UKIbv?{Pef+zU7P>qL}82-bLI1G zpAS1X_RPv6(*q;fG&DM@NsSSe4{njyw}Q&70w#V2`Krih3Sr hM_&9tdT^^_mgTdhD4KoM@P9#I$2LdX2iAw_{{>70ucZJ0 literal 0 HcmV?d00001 diff --git a/ref_imgs_vg_lite/widgets/canvas_layer_complex.png b/ref_imgs_vg_lite/widgets/canvas_layer_complex.png new file mode 100644 index 0000000000000000000000000000000000000000..506dd921fc926c665428e6ceb09b147ab86ad637 GIT binary patch literal 833 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV0^&A3>3+_`SUoCG7j(wasB%B>wh4df#EI# zLpcM35(C3-1_l=fhBTl&1A`y~!zu=bPzHu~3=C%&7&;gjW->7Ns-8T`z`%6U)5S5Q zg7MAOy?t{Xcp5JDBy#ZBPyb$j>pv_)BBa(ULTy>lvr5 z=7zf}*jzE4u=HHCyz|XRThDsGJhrQp>ES}X#*)Hk7yMKE?;qY*_vc-l$h!j0l)kbK zjqL2l`?y-%f2&Q%vz@x>op-mdg3V3U33_qIv;WSy5(wrPx!J$T)%d-IzxvH_&zaAG zPPlA3;nS*%zaCG~(S23vdn{wNL&dUB>voH`T63@nF*UY0C@2be5W$250tVUe|Bn8* z2M%mNiG&IJzn1rdB8?ItR$ZU~3UY%J_kZnnXQjj_px$m Pass --build-options= to tests/main.py -# (e.g. OPTIONS_TEST_SYSHEAP, OPTIONS_16BIT, ...). +# (e.g. OPTIONS_TEST_SYSHEAP, OPTIONS_MINIMAL, ...). # When omitted, main.py runs its full matrix. # --test-suite Pass --test-suite= to tests/main.py # (ctest --tests-regex filter). diff --git a/src/debugging/test/Kconfig b/src/debugging/test/Kconfig index bef47cfefd..82246b0ed4 100644 --- a/src/debugging/test/Kconfig +++ b/src/debugging/test/Kconfig @@ -19,4 +19,12 @@ config LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE When a reference image does not exist yet, create it from the rendered screen instead of failing the compare. +config LV_USE_NANOVG_TEST_HEADLESS + bool "Headless EGL display for NanoVG" + depends on LV_USE_DRAW_NANOVG + help + Render into an off-screen EGL pbuffer instead of a window and read the + pixels back into the LVGL draw buffer, so screenshot compares work the + same way as with the software renderer. Requires EGL and GLESv2. + endif #LV_USE_TEST diff --git a/src/debugging/test/lv_test_display_egl.c b/src/debugging/test/lv_test_display_egl.c index 49ddb0641e..9275a9b9ec 100644 --- a/src/debugging/test/lv_test_display_egl.c +++ b/src/debugging/test/lv_test_display_egl.c @@ -12,10 +12,6 @@ *********************/ #include "../../lvgl_public.h" -#ifndef LV_USE_NANOVG_TEST_HEADLESS - #define LV_USE_NANOVG_TEST_HEADLESS 0 -#endif - #if LV_USE_TEST && LV_USE_DRAW_NANOVG && LV_USE_NANOVG_TEST_HEADLESS #include "../../draw/nanovg/lv_draw_nanovg.h" diff --git a/src/draw/opengles/lv_draw_opengles.c b/src/draw/opengles/lv_draw_opengles.c index 05af684df7..b3ba931a27 100644 --- a/src/draw/opengles/lv_draw_opengles.c +++ b/src/draw/opengles/lv_draw_opengles.c @@ -542,15 +542,6 @@ static void draw_from_cached_texture(lv_draw_task_t * t) lv_draw_opengles_unit_t * u = (lv_draw_opengles_unit_t *)t->draw_unit; cache_data_t data_to_find; data_to_find.draw_dsc = (lv_draw_dsc_base_t *)t->draw_dsc; - bool h_flip = false; - bool v_flip = false; -#if LV_USE_3DTEXTURE - if(t->type == LV_DRAW_TASK_TYPE_3D) { - lv_draw_3d_dsc_t * _3d_dsc = (lv_draw_3d_dsc_t *)t->draw_dsc; - h_flip = _3d_dsc->h_flip; - v_flip = _3d_dsc->v_flip; - } -#endif data_to_find.w = lv_area_get_width(&t->_real_area); data_to_find.h = lv_area_get_height(&t->_real_area); data_to_find.texture = 0; @@ -639,8 +630,8 @@ static void execute_drawing(lv_draw_opengles_unit_t * u) } if(fill_dsc->opa >= LV_OPA_MAX) { - float tex_w = (float)lv_area_get_width(&fill_area); - float tex_h = (float)lv_area_get_height(&fill_area); + int32_t tex_w = lv_area_get_width(&fill_area); + int32_t tex_h = lv_area_get_height(&fill_area); GL_CALL(glEnable(GL_SCISSOR_TEST)); GL_CALL(glScissor(fill_area.x1, targ_tex_h - fill_area.y1 - tex_h, tex_w, tex_h)); /* swap red and blue channels here as they will be swapped back during flushing*/ diff --git a/src/drivers/x11/lv_x11_display.c b/src/drivers/x11/lv_x11_display.c index f6a3ccd31b..dde7dcac62 100644 --- a/src/drivers/x11/lv_x11_display.c +++ b/src/drivers/x11/lv_x11_display.c @@ -23,14 +23,6 @@ #define MIN(A, B) ((A) < (B) ? (A) : (B)) #define MAX(A, B) ((A) > (B) ? (A) : (B)) -#if LV_X11_RENDER_MODE_PARTIAL - #define LV_X11_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL -#elif defined LV_X11_RENDER_MODE_DIRECT - #define LV_X11_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT -#elif defined LV_X11_RENDER_MODE_FULL - #define LV_X11_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL -#endif - /********************** * TYPEDEFS **********************/ @@ -74,7 +66,7 @@ typedef struct { typedef lv_color32_t color_t; static inline lv_color32_t get_px(color_t p) { - return (lv_color32_t)p; + return p; } #elif LV_COLOR_DEPTH == 24 typedef lv_color_t color_t; diff --git a/tests/.gitignore b/tests/.gitignore index d2510409a0..1355309c46 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -6,4 +6,3 @@ *_err.png build_*/ report*/ -wayland_protocols/ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2ac9208b9b..e5cd8979d0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,45 +1,54 @@ -if(ESP_PLATFORM) +# Unit tests for LVGL. Not a project of its own: this is pulled in by +# env_support/cmake/main.cmake when LV_BUILD_TESTS is set, after the lvgl, +# lvgl_thorvg, lvgl_examples and lvgl_demos targets have been created. +# +# tests/main.py drives the build. It picks a configuration by passing the list +# of defconfig fragments from tests/configs in LV_BUILD_DEFCONFIG_PATH, and +# everything below is derived from the resulting CONFIG_LV_* variables, so +# adding a test configuration only takes a new recipe in main.py. -################################### -# Tests do not build for ESP-IDF. # -################################### +option(LVGL_TEST_ENABLE "Build and register the test executables" OFF) -else() +set(LVGL_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -cmake_minimum_required(VERSION 3.16) - -if(WIN32) - set(VCPKG_TARGET_TRIPLET "x64-windows") - include($ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake) +if(NOT MSVC) + set(IS_GNU_LIKE TRUE) endif() -project(lvgl_tests LANGUAGES C CXX) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_C_STANDARD 99) +# Set by the CI job that builds and runs the tests as 32-bit binaries. The +# -m32 flags themselves come from main.py, they have to be in place before the +# compiler and library checks run. +set(NON_AMD64_BUILD "$ENV{NON_AMD64_BUILD}") +########################### COMPILER OPTIONS ########################### + +# Options that check_c_compiler_flag() can not detect, either because they only +# fail when linking or because they are accepted but warn. set(FLAG_CHECK_WHITELIST --coverage -fsanitize=address -Werror) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) + +# Copy the subset of ARGN that this compiler supports into ${options_out}. function(filter_compiler_options lang options_out) set(options ${ARGN}) foreach(option ${options}) - if (option IN_LIST FLAG_CHECK_WHITELIST) + if(option IN_LIST FLAG_CHECK_WHITELIST) list(APPEND ${options_out} ${option}) continue() - endif () + endif() string(TOUPPER FLAG_SUPPORTED_FOR_${lang}_${option} option_var_name) string(REPLACE "-" "_" option_var_name ${option_var_name}) string(REPLACE "+" "_" option_var_name ${option_var_name}) - if (${lang} STREQUAL C) + if(${lang} STREQUAL C) check_c_compiler_flag(${option} ${option_var_name}) - elseif (${lang} STREQUAL CXX) + elseif(${lang} STREQUAL CXX) check_cxx_compiler_flag(${option} ${option_var_name}) else() message(FATAL_ERROR "Unknown language ${lang}") - endif () + endif() if(${option_var_name}) list(APPEND ${options_out} ${option}) endif() @@ -47,212 +56,10 @@ function(filter_compiler_options lang options_out) set(${options_out} ${${options_out}} PARENT_SCOPE) endfunction() -find_program(VALGRIND_EXECUTABLE valgrind) -if (VALGRIND_EXECUTABLE) - set(MEMORYCHECK_COMMAND ${VALGRIND_EXECUTABLE}) - set(MEMORYCHECK_COMMAND_OPTIONS --error-exitcode=1) -endif() - -include(CTest) - -set(LVGL_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}) - -set(SANITIZE_AND_COVERAGE_OPTIONS - -fsanitize=address - -fsanitize=leak - -fsanitize=undefined - --coverage -) - -set(LVGL_TEST_OPTIONS_VG_LITE - -DLV_TEST_OPTION=6 - -Wno-dangling-pointer # workaround for thorvg dangling-pointer warning -) - -set(LVGL_TEST_OPTIONS_RISCV_V - -DLV_TEST_OPTION=5 - -DLVGL_CI_USING_SYS_HEAP - -DLV_USE_DRAW_SW_ASM=LV_DRAW_SW_ASM_RISCV_V -) - -set(LVGL_TEST_OPTIONS_SDL - -DLV_TEST_OPTION=7 -) - -set(LVGL_TEST_OPTIONS_NANOVG - -DLV_TEST_OPTION=8 - -DLVGL_CI_USING_SYS_HEAP - ${SANITIZE_AND_COVERAGE_OPTIONS} -) - -set(LVGL_TEST_OPTIONS_MINIMAL_MONOCHROME - -DLV_TEST_OPTION=1 -) - -set(LVGL_TEST_OPTIONS_NORMAL_8BIT - -DLV_TEST_OPTION=2 -) - -set(LVGL_TEST_OPTIONS_16BIT - -DLV_TEST_OPTION=3 -) - -set(LVGL_TEST_OPTIONS_FULL_24BIT - -DLV_TEST_OPTION=4 -) - -set(LVGL_TEST_OPTIONS_FULL_32BIT - -DLV_TEST_OPTION=5 -) - -set(LVGL_TEST_OPTIONS_TEST_SYSHEAP - -DLV_TEST_OPTION=5 - -DLVGL_CI_USING_SYS_HEAP - -Wno-unused-but-set-variable # unused variables are common in the dual-heap arrangement - ${SANITIZE_AND_COVERAGE_OPTIONS} -) - -set(LVGL_TEST_OPTIONS_TEST_DEFHEAP - -DLV_TEST_OPTION=5 - -DLV_USE_OBJ_PROPERTY=1 # add obj property test and disable pedantic - -DLV_USE_OBJ_PROPERTY_NAME=1 - -DLVGL_CI_USING_DEF_HEAP - ${SANITIZE_AND_COVERAGE_OPTIONS} -) - -# Set up the 32-bit (non-amd64) target BEFORE any pkg-config lookups or link tests so -# that find_library/pkg_check_modules/check_c_source_compiles resolve libraries from the -# i386 paths and build with the correct architecture instead of the default 64-bit one. -if ($ENV{NON_AMD64_BUILD}) - message("Non AMD64 target is specified") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") - set(CMAKE_LIBRARY_PATH "/usr/lib/i386-linux-gnu" CACHE PATH "search 32bit lib path firstly") - set(ENV{PKG_CONFIG_PATH} "/usr/lib/i386-linux-gnu/pkgconfig:$ENV{PKG_CONFIG_PATH}") -endif() - -# Verify EGL/GLESv2 actually link for the current architecture. pkg-config may still -# hand back a wrong-arch .pc (e.g. the 64-bit one) when the i386 package is missing, and -# that only fails at link time. This helper does a real compile+link with the discovered -# flags and sets LVGL_NANOVG_GL_ARCH_OK accordingly. -include(CheckCSourceCompiles) -function(lvgl_nanovg_check_gl_arch) - if(NOT (EGL_FOUND AND GLESV2_FOUND)) - set(LVGL_NANOVG_GL_ARCH_OK FALSE PARENT_SCOPE) - return() - endif() - set(CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS}") - set(CMAKE_REQUIRED_INCLUDES ${EGL_INCLUDE_DIRS} ${GLESV2_INCLUDE_DIRS}) - set(CMAKE_REQUIRED_LIBRARIES ${EGL_LDFLAGS} ${GLESV2_LDFLAGS}) - check_c_source_compiles(" - #include - #include - int main(void) { (void)eglGetError(); (void)glGetError(); return 0; } - " LVGL_NANOVG_GL_ARCH_LINK) - set(LVGL_NANOVG_GL_ARCH_OK ${LVGL_NANOVG_GL_ARCH_LINK} PARENT_SCOPE) -endfunction() - -if (OPTIONS_SDL) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_SDL}) -elseif (OPTIONS_NORMAL_8BIT) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_NORMAL_8BIT}) -elseif (OPTIONS_16BIT) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_16BIT}) -elseif (OPTIONS_24BIT) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_24BIT}) -elseif (OPTIONS_FULL_32BIT) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_FULL_32BIT}) -elseif (OPTIONS_TEST_SYSHEAP) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_TEST_SYSHEAP}) - filter_compiler_options (C TEST_LIBS ${SANITIZE_AND_COVERAGE_OPTIONS}) - set (CONFIG_LV_BUILD_EXAMPLES OFF CACHE BOOL "disable examples" FORCE) - set (ENABLE_TESTS ON) - add_definitions(-DREF_IMGS_PATH="ref_imgs/") -elseif (OPTIONS_TEST_DEFHEAP) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_TEST_DEFHEAP}) - filter_compiler_options (C TEST_LIBS ${SANITIZE_AND_COVERAGE_OPTIONS}) - set (CONFIG_LV_BUILD_EXAMPLES OFF CACHE BOOL "disable examples" FORCE) - set (ENABLE_TESTS ON) - add_definitions(-DREF_IMGS_PATH="ref_imgs/") -elseif (OPTIONS_TEST_MEMORYCHECK) - # sanitizer is disabled because valgrind uses LD_PRELOAD and the - # sanitizer lib needs to load first - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_TEST_SYSHEAP}) - set (CONFIG_LV_BUILD_EXAMPLES OFF CACHE BOOL "disable examples" FORCE) - set (ENABLE_TESTS ON) - add_definitions(-DREF_IMGS_PATH="ref_imgs/") -elseif (OPTIONS_TEST_VG_LITE) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_VG_LITE} -DLVGL_CI_USING_SYS_HEAP ${SANITIZE_AND_COVERAGE_OPTIONS}) - filter_compiler_options (C TEST_LIBS ${SANITIZE_AND_COVERAGE_OPTIONS}) - set (CONFIG_LV_BUILD_EXAMPLES OFF CACHE BOOL "disable examples" FORCE) - set (ENABLE_TESTS ON) - add_definitions(-DREF_IMGS_PATH="ref_imgs_vg_lite/") - - # In 32-bit systems, the output of ThorVG's anti-aliasing algorithm has a slight deviation. - if ($ENV{NON_AMD64_BUILD}) - # Set a tolerance value for the VG-Lite tests. - add_definitions(-DREF_IMG_TOLERANCE=9) - endif() -elseif (OPTIONS_TEST_RISCV_V) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_RISCV_V} ${SANITIZE_AND_COVERAGE_OPTIONS}) - filter_compiler_options (C TEST_LIBS ${SANITIZE_AND_COVERAGE_OPTIONS}) - set (CONFIG_LV_BUILD_EXAMPLES OFF CACHE BOOL "disable examples" FORCE) - set (ENABLE_TESTS ON) - add_definitions(-DREF_IMGS_PATH="ref_imgs/") - message(STATUS "RISC-V Vector (RVV) software emulation test enabled") -elseif (OPTIONS_TEST_NANOVG) - set (BUILD_OPTIONS ${LVGL_TEST_OPTIONS_NANOVG}) - filter_compiler_options (C TEST_LIBS ${SANITIZE_AND_COVERAGE_OPTIONS}) - set (CONFIG_LV_BUILD_EXAMPLES OFF CACHE BOOL "disable examples" FORCE) - set (ENABLE_TESTS ON) - add_definitions(-DREF_IMGS_PATH="ref_imgs_nanovg/") - add_definitions(-DLV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE=1) - # Locate EGL/GLESv2 for the headless NanoVG test. Use IMPORTED_TARGET so the full - # pkg-config metadata (include dirs, lib paths, transitive deps) is propagated, - # matching the FFMPEG pattern below. Bare -lEGL/-lGLESv2 would drop custom SDK paths. - # PKG_CONFIG_PATH was already pointed at the i386 dir above for 32-bit builds, so this - # resolves to the correct architecture. The check is adaptive: if EGL/GLESv2 for the - # target architecture can't be found or linked, fail with an actionable message. - find_package(PkgConfig REQUIRED) - pkg_check_modules(EGL IMPORTED_TARGET egl) - pkg_check_modules(GLESV2 IMPORTED_TARGET glesv2) - - lvgl_nanovg_check_gl_arch() - - if(NOT (EGL_FOUND AND GLESV2_FOUND AND LVGL_NANOVG_GL_ARCH_OK)) - message(FATAL_ERROR - "OPTIONS_TEST_NANOVG requires EGL and GLESv2 libraries matching the build " - "architecture.\n" - " EGL found: ${EGL_FOUND}\n" - " GLESv2 found: ${GLESV2_FOUND}\n" - " arch link test: ${LVGL_NANOVG_GL_ARCH_OK}\n" - "On a 32-bit (NON_AMD64_BUILD) build, install the i386 packages, e.g.:\n" - " sudo apt-get install libegl-dev:i386 libgles-dev:i386 libgl1-mesa-dri:i386\n" - "or run this option on a 64-bit build only.") - endif() - - message(STATUS "NanoVG headless rendering test enabled (EGL + GLESv2 found)") -else() - message(FATAL_ERROR "Must provide a known options value (check main.py?).") -endif() - -if ($ENV{NON_AMD64_BUILD}) - set(BUILD_TARGET_DEF -DNON_AMD64_BUILD) -endif() - -# Options lvgl and examples are compiled with. -set(COMPILE_OPTIONS - ${BUILD_OPTIONS} - ${BUILD_TARGET_DEF} -) - -if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC")) - list(APPEND COMPILE_OPTIONS +if(IS_GNU_LIKE) + set(COMPILE_OPTIONS -pedantic-errors -Wall - -Wformat-security -Wclobbered -Wdeprecated -Wdouble-promotion @@ -262,322 +69,204 @@ if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC")) -Wformat-security -Wmaybe-uninitialized -Wmissing-prototypes - -Wpointer-arith -Wmultichar -Wpedantic + -Wpointer-arith -Wreturn-type -Wshadow -Wshift-negative-value -Wsizeof-pointer-memaccess - #-Wstack-usage=6000 -Wtype-limits -Wundef -Wuninitialized -Wunreachable-code + -Wunused-function -Werror=float-conversion -Werror=strict-aliasing -Wno-double-promotion - -Wno-unreachable-code -Wno-gnu-zero-variadic-macro-arguments - -Wunused-function - -Wno-overlength-strings + -Wno-overlength-strings + -Wno-unreachable-code ) else() - list(APPEND COMPILE_OPTIONS + set(COMPILE_OPTIONS /W3 # enable all "production quality" warnings /we4013 # treat function undefined as error ) endif() -list(APPEND COMPILE_OPTIONS - ${BUILD_OPTIONS} - ${BUILD_TARGET_DEF} -) +# The configurations whose tests are executed also run under the sanitizers and +# collect coverage. +if(LVGL_TEST_ENABLE AND IS_GNU_LIKE) + set(SANITIZE_AND_COVERAGE_OPTIONS + -fsanitize=address + -fsanitize=leak + -fsanitize=undefined + --coverage + ) + list(APPEND COMPILE_OPTIONS ${SANITIZE_AND_COVERAGE_OPTIONS}) +endif() -# LV_USE_OBJ_PROPERTY is enabled in option OPTIONS_TEST_DEFHEAP -# It relies on C11 anonymous struct/union support, thus disable warnings. -if(OPTIONS_TEST_DEFHEAP) - list(REMOVE_ITEM COMPILE_OPTIONS -pedantic-errors -Wpedantic) +# Configuration dependent compiler options. Deriving these from the resulting +# configuration rather than from the name of the test configuration keeps them +# in step with the defconfigs. +if(IS_GNU_LIKE) + if(CONFIG_LV_USE_VG_LITE_THORVG) + # Workaround for a ThorVG dangling-pointer warning + list(APPEND COMPILE_OPTIONS -Wno-dangling-pointer) + endif() + + if(NOT CONFIG_LV_USE_BUILTIN_MALLOC) + # Unused variables are common in the dual-heap arrangement + list(APPEND COMPILE_OPTIONS -Wno-unused-but-set-variable) + endif() + + if(CONFIG_LV_USE_OBJ_PROPERTY) + # The property API relies on C11 anonymous structs and unions + list(REMOVE_ITEM COMPILE_OPTIONS -pedantic-errors -Wpedantic) + endif() endif() filter_compiler_options(C LVGL_C_COMPILE_OPTIONS ${COMPILE_OPTIONS}) -if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC")) - # Options test cases are compiled with. - filter_compiler_options(C LVGL_TESTFILE_COMPILE_OPTIONS ${LVGL_C_COMPILE_OPTIONS} -Wno-missing-prototypes) - +if(IS_GNU_LIKE) + # The test cases define their functions without a prototype + filter_compiler_options(C LVGL_TESTFILE_COMPILE_OPTIONS + ${LVGL_C_COMPILE_OPTIONS} + -Wno-missing-prototypes + ) filter_compiler_options(CXX LVGL_CXX_COMPILE_OPTIONS ${COMPILE_OPTIONS} - -Wno-shadow - -Wno-unused-parameter -Wno-c++11-extensions - -Wno-missing-prototypes -Wno-deprecated-copy-with-user-provided-dtor -Wno-float-conversion + -Wno-missing-prototypes -Wno-pedantic + -Wno-shadow + -Wno-unused-parameter ) else() - # Options test cases are compiled with. filter_compiler_options(C LVGL_TESTFILE_COMPILE_OPTIONS ${LVGL_C_COMPILE_OPTIONS}) - - filter_compiler_options(CXX LVGL_CXX_COMPILE_OPTIONS - ${COMPILE_OPTIONS} - ) + filter_compiler_options(CXX LVGL_CXX_COMPILE_OPTIONS ${COMPILE_OPTIONS}) endif() -get_filename_component(LVGL_DIR ${LVGL_TEST_DIR} DIRECTORY) +# LV_DISABLE_API_MAPPING is not an lv_conf.h option, it can only be set from the +# build system. The tests must use the current API names. +set(COMPILE_DEFINITIONS LV_BUILD_TEST LV_DISABLE_API_MAPPING=1) -# Include lvgl project file. -# Set LV_BUILD_CONF_PATH so main.cmake knows about it before compiling lvgl -# Used to preprocess lv_conf_internal.h with the test config -set(LV_BUILD_CONF_PATH "${LVGL_TEST_DIR}/src/lv_test_conf.h" CACHE STRING "set test configuration") - -include(${LVGL_DIR}/CMakeLists.txt) -target_compile_options(lvgl PUBLIC $<$: ${LVGL_C_COMPILE_OPTIONS}>) -target_compile_options(lvgl PUBLIC $<$:${LVGL_CXX_COMPILE_OPTIONS}>) -target_compile_definitions(lvgl PUBLIC LV_BUILD_TEST) - -# Link EGL and GLESv2 for NanoVG headless test via pkg-config imported targets -# so include/library paths from pkg-config are propagated to consumers of lvgl. -if(OPTIONS_TEST_NANOVG) - target_link_libraries(lvgl PUBLIC PkgConfig::EGL PkgConfig::GLESV2) -endif() -if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC")) - target_compile_options(lvgl PUBLIC $<$:${LVGL_C_COMPILE_OPTIONS}>) +if(NON_AMD64_BUILD) + list(APPEND COMPILE_DEFINITIONS NON_AMD64_BUILD) endif() -if (TARGET lvgl_thorvg) - target_compile_options(lvgl_thorvg PUBLIC $<$:${LVGL_C_COMPILE_OPTIONS}>) - target_compile_options(lvgl_thorvg PUBLIC $<$:${LVGL_CXX_COMPILE_OPTIONS}>) +######################## ADJUST THE LVGL TARGETS ######################## + +foreach(target lvgl lvgl_thorvg lvgl_examples lvgl_demos) + if(TARGET ${target}) + target_compile_options(${target} PUBLIC + $<$:${LVGL_C_COMPILE_OPTIONS}> + $<$:${LVGL_CXX_COMPILE_OPTIONS}> + ) + if(IS_GNU_LIKE) + target_compile_options(${target} PUBLIC + $<$:${LVGL_C_COMPILE_OPTIONS}>) + endif() + endif() +endforeach() + +if(SANITIZE_AND_COVERAGE_OPTIONS) + # The sanitizer and coverage runtimes have to be on the link line as well + target_link_options(lvgl PUBLIC ${SANITIZE_AND_COVERAGE_OPTIONS}) endif() -if (TARGET lvgl_examples) - target_compile_options(lvgl_examples PUBLIC $<$:${LVGL_C_COMPILE_OPTIONS}>) - target_compile_options(lvgl_examples PUBLIC $<$:${LVGL_CXX_COMPILE_OPTIONS}>) +# Reference images are renderer specific, each renderer has its own set +if(CONFIG_LV_USE_DRAW_VG_LITE) + set(REF_IMGS_PATH "ref_imgs_vg_lite/") +elseif(CONFIG_LV_USE_DRAW_NANOVG) + set(REF_IMGS_PATH "ref_imgs_nanovg/") +else() + set(REF_IMGS_PATH "ref_imgs/") endif() -if (TARGET lvgl_demos) - target_compile_options(lvgl_demos PUBLIC $<$:${LVGL_C_COMPILE_OPTIONS}>) - target_compile_options(lvgl_demos PUBLIC $<$:${LVGL_CXX_COMPILE_OPTIONS}>) +# lv_test_screenshot_compare() is part of LVGL, so the reference image location +# has to be given to the library, not to the test cases. +target_compile_definitions(lvgl PUBLIC + ${COMPILE_DEFINITIONS} + REF_IMGS_PATH="${REF_IMGS_PATH}") + +if(CONFIG_LV_USE_DRAW_VG_LITE AND NON_AMD64_BUILD) + # On 32-bit systems the output of ThorVG's anti-aliasing algorithm deviates + # slightly + target_compile_definitions(lvgl PUBLIC REF_IMG_TOLERANCE=9) endif() - -# LVGL_CONF_DIR and LVGL_CONF_PATH are normalized and set by main.cmake +############################# BUILD TESTS ############################# set(TEST_INCLUDE_DIRS $ $ $ - $ ) -file(GLOB_RECURSE TEST_IMAGES_SRC - ${LVGL_TEST_DIR}/test_images/*.c - ${LVGL_TEST_DIR}/../examples/assets/*.c) +# Only the configurations that execute their tests need the test cases, the test +# harness and the test assets. For the others this listfile exists purely to +# build LVGL itself with the strict warning set. +if(NOT LVGL_TEST_ENABLE) + return() +endif() -add_library(test_common - STATIC - src/lv_test_init.c - src/test_assets/test_animimg001.c - src/test_assets/test_animimg002.c - src/test_assets/test_animimg003.c - src/test_assets/test_img_cogwheel_i4.c - src/test_assets/test_img_cogwheel_a8.c - src/test_assets/test_img_cogwheel_rgb565.c - src/test_assets/test_img_cogwheel_rgb565a8.c - src/test_assets/test_img_cogwheel_xrgb8888.c - src/test_assets/test_img_cogwheel_argb8888.c - src/test_assets/test_img_svg.c - src/test_assets/test_font_1.c - src/test_assets/test_font_2.c - src/test_assets/test_font_3.c - src/test_assets/test_font_montserrat_ascii_1bpp.c - src/test_assets/test_font_montserrat_ascii_2bpp.c - src/test_assets/test_font_montserrat_ascii_4bpp.c - src/test_assets/test_font_montserrat_ascii_8bpp.c - src/test_assets/test_font_montserrat_ascii_3bpp_compressed.c - src/test_assets/test_font_1_bin.c - src/test_assets/test_font_2_bin.c - src/test_assets/test_font_3_bin.c - src/test_assets/test_img_caret_down.c - src/test_assets/test_arc_bg.c - src/test_assets/test_img_bulb_gif.c - src/test_assets/test_img_lvgl_logo_png.c - src/test_assets/test_img_lvgl_logo_jpg.c - src/test_assets/test_img_emoji_F617.c - src/test_assets/test_ubuntu_font.c - src/test_assets/test_kern_one_otf.c - src/test_assets/test_imagebutton_left.c - src/test_assets/test_imagebutton_mid.c - src/test_assets/test_imagebutton_right.c - src/test_assets/test_music_button_play.c - src/test_assets/test_lottie_approve.c - unity/unity.c - ${TEST_IMAGES_SRC} +file(GLOB TEST_ASSETS_SRC ${LVGL_TEST_DIR}/src/test_assets/*.c) +file(GLOB_RECURSE TEST_IMAGES_SRC + ${LVGL_TEST_DIR}/test_images/*.c + ${LVGL_ROOT_DIR}/examples/assets/*.c) + +add_library(test_common STATIC + src/lv_test_init.c + unity/unity.c + ${TEST_ASSETS_SRC} + ${TEST_IMAGES_SRC} ) target_include_directories(test_common PUBLIC ${TEST_INCLUDE_DIRS}) target_compile_options(test_common PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS}) -target_compile_definitions(test_common PRIVATE LV_BUILD_TEST ${LVGL_COMPILER_DEFINES}) +# Linking LVGL also brings in its include directories and the definitions that +# select the configuration +target_link_libraries(test_common PUBLIC lvgl) +target_compile_definitions(test_common PRIVATE + # A few test cases use an image from examples/assets, whose sources are + # guarded by LV_BUILD_EXAMPLES. Compile them in even when the examples + # library itself is not built. + LV_BUILD_EXAMPLES=1 +) -# Generate one test executable for each source file pair. -# The sources in ${CMAKE_CURRENT_BINARY_DIR} is auto-generated, the -# sources in src/test_cases is the actual test case. -find_package(Ruby REQUIRED) -set(generate_test_runner_rb - ${CMAKE_CURRENT_SOURCE_DIR}/unity/generate_test_runner.rb) -set(generate_test_runner_config ${CMAKE_CURRENT_SOURCE_DIR}/config.yml) +file(GLOB_RECURSE TEST_CASE_FILES src/test_cases/*.c) +file(GLOB_RECURSE TEST_LIBS_FILES src/test_libs/*.c) -if(NOT WIN32) - # libjpeg is required for the jpeg test case - find_package(JPEG REQUIRED) - include_directories(${JPEG_INCLUDE_DIR}) - - find_package(PkgConfig) - pkg_check_modules(WebP libwebp) - - if (WebP_FOUND) - include_directories(${WebP_INCLUDEDIR}) - else() - message("WebP not found, defaulting to 0") - add_definitions(-DLV_USE_LIBWEBP=0) - endif() - - # Wayland - find_package(PkgConfig) - pkg_check_modules(wayland_client wayland-client) - - if (wayland_client_FOUND) - pkg_check_modules(WAYLAND REQUIRED wayland-cursor wayland-client wayland-egl xkbcommon) - link_libraries(${WAYLAND_LIBRARIES}) - - # Add auto generated source required for XDG shell - include_directories("${LVGL_TEST_DIR}/wayland_protocols") - target_sources(test_common PUBLIC "wayland_protocols/wayland_xdg_shell.c") - else() - add_definitions(-DLV_USE_WAYLAND=0) - endif() -endif() - -# libpng is required for the png test case -find_package(PNG REQUIRED) -include_directories(${PNG_INCLUDE_DIR}) - -if(NOT WIN32) - # FFmpeg is optional for the image and video test cases - find_package(PkgConfig) - pkg_check_modules(FFMPEG IMPORTED_TARGET - libavformat - libavcodec - libswscale - libavutil - ) - - if(FFMPEG_FOUND) - include_directories(${FFMPEG_INCLUDE_DIRS}) - else() - message("FFmpeg not found, defaulting to 0") - add_definitions(-DLV_USE_FFMPEG=0) - endif() -else() - message("Disable FFmpeg for Windows") - add_definitions(-DLV_USE_FFMPEG=0) -endif() - -# libfreetype is required for the font test case -find_package(Freetype REQUIRED) -include_directories(${FREETYPE_INCLUDE_DIRS}) - -if(OPTIONS_SDL) - find_package(SDL2 REQUIRED) - include_directories(${SDL2_INCLUDE_DIRS}) -endif() - -# libinput is required for the libinput device driver test case -find_package(Libinput OPTIONAL_COMPONENTS) -if ($ENV{NON_AMD64_BUILD}) - include_directories(${LIBINPUT_INCLUDE_DIRS}) -endif() - -# OpenGL ES is required for its driver -if ($ENV{NON_AMD64_BUILD}) - message("Disable OpenGL, glfw3 for non-amd64 build") -else() - find_package(OpenGL) - find_package(glfw3) - - if(OpenGL_FOUND AND glfw3_FOUND) - # Include directories - include_directories(${OPENGL_INCLUDE_DIR}) - include_directories(${GLFW_INCLUDE_DIRS}) - message("Enable LV_USE_OPENGLES") - endif() -endif() - -if (NOT LIBINPUT_FOUND) - message("libinput not found, defaulting to 0") - add_definitions(-DLV_USE_LIBINPUT=0) -endif() - -find_package(PkgConfig) -pkg_check_modules(XKB xkbcommon) - -if (NOT XKB_FOUND) - message("xkbcommon not found, defaulting to 0") - add_definitions(-DLV_LIBINPUT_XKB=0) -endif() - -# libdrm is required for the DRM display driver test case -include(${CMAKE_CURRENT_LIST_DIR}/FindLibDRM.cmake) -if(Libdrm_FOUND) - include_directories(${Libdrm_INCLUDE_DIRS}) -else() - message("libdrm not found, defaulting to 0") - add_definitions(-DLV_USE_LINUX_DRM=0) -endif() - -# If we are running on mac, set LV_USE_LINUX_FBDEV to 0 -if(APPLE) - add_definitions(-DLV_USE_LINUX_FBDEV=0) -endif() - -if(WIN32) - add_definitions(-DLV_USE_LINUX_FBDEV=0) - add_definitions(-DLV_USE_WINDOWS=1) - add_definitions(-DLV_USE_WAYLAND=0) - add_definitions(-DLV_USE_OS=LV_OS_WINDOWS) -endif() - -# disable test targets for build only tests -if (ENABLE_TESTS) - file(GLOB_RECURSE TEST_CASE_FILES src/test_cases/*.c) - file(GLOB_RECURSE TEST_LIBS_FILES src/test_libs/*.c) -else() - set(TEST_CASE_FILES) - set(TEST_LIBS_FILES) -endif() - -# build a test libs target -if (TEST_LIBS_FILES) +if(TEST_LIBS_FILES) add_library(test_libs STATIC ${TEST_LIBS_FILES}) - target_include_directories(test_libs PUBLIC ${TEST_INCLUDE_DIRS} "src/test_libs") - target_compile_definitions(test_libs PRIVATE LV_BUILD_TEST ${LVGL_COMPILER_DEFINES}) + target_include_directories(test_libs PUBLIC ${TEST_INCLUDE_DIRS} src/test_libs) target_compile_options(test_libs PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS}) - list(APPEND TEST_LIBS test_libs) + target_link_libraries(test_libs PUBLIC lvgl) endif() -foreach( test_case_fname ${TEST_CASE_FILES} ) - # If test file is foo/bar/baz.c then test_name is "baz". +# Generate one test executable per test case source file. The runner source is +# produced by Unity's ruby script into the build directory. +find_package(Ruby) +if(NOT RUBY_EXECUTABLE) + message(FATAL_ERROR "Ruby interpreter not found") +endif() + +set(generate_test_runner_rb ${LVGL_TEST_DIR}/unity/generate_test_runner.rb) +set(generate_test_runner_config ${LVGL_TEST_DIR}/config.yml) + +foreach(test_case_fname ${TEST_CASE_FILES}) + # If the test file is foo/bar/baz.c then test_name is "baz" get_filename_component(test_name ${test_case_fname} NAME_WLE) - if (${test_name} STREQUAL "_test_template") + if(${test_name} STREQUAL "_test_template") continue() endif() - # gather all test cases list(APPEND TEST_CASES ${test_name}) - # Create path to auto-generated source file. set(test_runner_fname ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_Runner.c) - # Run ruby to generate source in build directory add_custom_command( OUTPUT ${test_runner_fname} COMMAND ${RUBY_EXECUTABLE} ${generate_test_runner_rb} @@ -586,58 +275,34 @@ foreach( test_case_fname ${TEST_CASE_FILES} ) DEPENDS ${generate_test_runner_rb} ${test_case_fname} ${generate_test_runner_config} ) - add_executable( ${test_name} - ${test_case_fname} - ${test_runner_fname} - ) - target_link_libraries(${test_name} PRIVATE - test_common - lvgl_demos - lvgl - lvgl_thorvg - ${PNG_LIBRARIES} - ${FREETYPE_LIBRARIES} - ${LIBDRM_LIBRARIES} - ${LIBINPUT_LIBRARIES} - ${JPEG_LIBRARIES} - ${WebP_LINK_LIBRARIES} - PkgConfig::FFMPEG - m - pthread - ${TEST_LIBS}) - - if(OPTIONS_SDL) - target_link_libraries(${test_name} PRIVATE ${SDL_LIBRARY}) - endif() - - if (NOT $ENV{NON_AMD64_BUILD}) - if (NOT OPTIONS_TEST_NANOVG) - target_link_libraries(${test_name} PRIVATE - ${OPENGL_LIBRARIES} glfw) - endif() - endif() - - # EGL/GLESv2 already linked via lvgl PUBLIC for OPTIONS_TEST_NANOVG + add_executable(${test_name} ${test_case_fname} ${test_runner_fname}) target_include_directories(${test_name} PUBLIC ${TEST_INCLUDE_DIRS}) target_compile_options(${test_name} PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS}) + target_link_libraries(${test_name} PRIVATE + test_common + lvgl + $ + $ + $ + ) add_test( NAME ${test_name} WORKING_DIRECTORY ${LVGL_TEST_DIR} COMMAND ${test_name}) - if(OPTIONS_TEST_NANOVG) - set_tests_properties(${test_name} PROPERTIES - ENVIRONMENT "LSAN_OPTIONS=suppressions=${LVGL_TEST_DIR}/lsan-nanovg.supp:fast_unwind_on_malloc=0;__EGL_VENDOR_LIBRARY_FILENAMES=${LVGL_TEST_DIR}/egl_vendor_mesa_only.json") + if(CONFIG_LV_USE_NANOVG_TEST_HEADLESS) + # Force the Mesa driver so that rendering is reproducible, and suppress + # the allocations the GL stack makes once per process. + set_tests_properties(${test_name} PROPERTIES ENVIRONMENT + "LSAN_OPTIONS=suppressions=${LVGL_TEST_DIR}/lsan-nanovg.supp:fast_unwind_on_malloc=0;__EGL_VENDOR_LIBRARY_FILENAMES=${LVGL_TEST_DIR}/egl_vendor_mesa_only.json") endif() -endforeach( test_case_fname ${TEST_CASE_FILES} ) +endforeach() add_custom_target(run COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure --timeout 300 - WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${TEST_CASES} USES_TERMINAL ) - -endif() diff --git a/tests/README.md b/tests/README.md index 39b769c87e..7149b76279 100644 --- a/tests/README.md +++ b/tests/README.md @@ -71,10 +71,28 @@ GitHub's CI automatically runs these tests on pushes and pull requests to `maste - `test_cases_perf` The performance tests, - `test_runners` Generated automatically from the files in `test_cases`. - other miscellaneous files and folders +- `configs` Kconfig defconfig fragments the build configurations are made of - `ref_imgs` - Reference images for screenshot compare - `report` - Coverage report. Generated if the `report` flag was passed to `./main.py` - `unity` Source files of the test engine +## Build configurations + +Every build configuration is a list of defconfig fragments from `configs`, +merged in order so that a later fragment overrides an earlier one. The recipes +live in `build_only_options` and `test_options` in [`main.py`](./main.py), which +passes them to CMake through `LV_BUILD_DEFCONFIG_PATH`. `CMakeLists.txt` derives +the rest - warning flags, which reference images to compare against, which +libraries LVGL needs - from the resulting configuration, so a new configuration +usually only takes a new fragment plus an entry in `main.py`. + +```sh +cmake -B build -DLV_BUILD_TESTS=ON -DLVGL_TEST_ENABLE=ON \ + -DLV_BUILD_DEFCONFIG_PATH="tests/configs/common.defconfig;tests/configs/full.defconfig;..." +``` + +Prefer `main.py` as it picks the right fragments for the host and architecture but this is useful when debugging the build itself. + ## Add new tests ### Create new test file diff --git a/tests/configs/builtin_heap.defconfig b/tests/configs/builtin_heap.defconfig new file mode 100644 index 0000000000..ed02e9a6e8 --- /dev/null +++ b/tests/configs/builtin_heap.defconfig @@ -0,0 +1,4 @@ +CONFIG_LV_USE_BUILTIN_MALLOC=y +CONFIG_LV_USE_BUILTIN_STRING=y +CONFIG_LV_USE_BUILTIN_SPRINTF=y +CONFIG_LV_MEM_SIZE=33554432 diff --git a/tests/configs/common.defconfig b/tests/configs/common.defconfig new file mode 100644 index 0000000000..83052c02fb --- /dev/null +++ b/tests/configs/common.defconfig @@ -0,0 +1,11 @@ +# Route failed asserts to lv_test_assert_fail() so they fail the test case +# instead of halting. The path is relative to the LVGL root directory. +CONFIG_LV_ASSERT_USE_CUSTOM_INCLUDE=y +CONFIG_LV_ASSERT_CUSTOM_INCLUDE="tests/src/lv_test_assert.h" + +# Test helpers: emulated input devices, time emulation and screenshot compare. +CONFIG_LV_USE_TEST=y +CONFIG_LV_USE_TEST_SCREENSHOT_COMPARE=y +CONFIG_LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE=y + +CONFIG_LV_USE_LOG=y diff --git a/tests/configs/defheap.defconfig b/tests/configs/defheap.defconfig new file mode 100644 index 0000000000..0d2eb6970b --- /dev/null +++ b/tests/configs/defheap.defconfig @@ -0,0 +1,13 @@ +# Test configuration to be added on top of builtin_heap.defconfig. + +CONFIG_LV_USE_MEM_MONITOR=y +CONFIG_LV_OBJ_STYLE_CACHE=y + +# Non power of 2 so that we do not accidentally rely on the alignment +# lv_malloc() happens to return. +CONFIG_LV_DRAW_BUF_ALIGN=852 + +# Exercise the generic widget property get/set API. Only covered here because it +# relies on C11 anonymous structs and unions, so the build cannot be pedantic. +CONFIG_LV_USE_OBJ_PROPERTY=y +CONFIG_LV_USE_OBJ_PROPERTY_NAME=y diff --git a/tests/configs/depth_16.defconfig b/tests/configs/depth_16.defconfig new file mode 100644 index 0000000000..7d339a469e --- /dev/null +++ b/tests/configs/depth_16.defconfig @@ -0,0 +1,2 @@ +CONFIG_LV_COLOR_DEPTH_16=y +CONFIG_LV_DPI_DEF=90 diff --git a/tests/configs/depth_32.defconfig b/tests/configs/depth_32.defconfig new file mode 100644 index 0000000000..585858fdc9 --- /dev/null +++ b/tests/configs/depth_32.defconfig @@ -0,0 +1,2 @@ +CONFIG_LV_COLOR_DEPTH_32=y +CONFIG_LV_DPI_DEF=160 diff --git a/tests/configs/full.defconfig b/tests/configs/full.defconfig new file mode 100644 index 0000000000..6f6b17e4f4 --- /dev/null +++ b/tests/configs/full.defconfig @@ -0,0 +1,131 @@ +# Enable as much of LVGL as possible, so that the test suite exercises the +# widest feature set. + +CONFIG_LV_CACHE_DEF_SIZE=10485760 +CONFIG_LV_DRAW_SW_SHADOW_CACHE_SIZE=8 +# Increase the draw thread stack size to 64KB in order to run ThorVG +CONFIG_LV_DRAW_THREAD_STACK_SIZE=65536 +CONFIG_LV_USE_DRAW_SW_COMPLEX_GRADIENTS=y +CONFIG_LV_USE_FLOAT=y +CONFIG_LV_USE_MATRIX=y + +CONFIG_LV_LOG_LEVEL_TRACE=y +CONFIG_LV_LOG_PRINTF=y +CONFIG_LV_USE_ASSERT_STYLE=y +CONFIG_LV_USE_ASSERT_MEM_INTEGRITY=y +CONFIG_LV_USE_ASSERT_OBJ=y + +CONFIG_LV_USE_PROFILER=y +CONFIG_LV_USE_PROFILER_BUILTIN=y +CONFIG_LV_USE_PROFILER_BUILTIN_POSIX=y +CONFIG_LV_USE_SYSMON=y +CONFIG_LV_USE_PERF_MONITOR=y +CONFIG_LV_USE_MONKEY=y + +# Fonts +CONFIG_LV_FONT_MONTSERRAT_8=y +CONFIG_LV_FONT_MONTSERRAT_10=y +CONFIG_LV_FONT_MONTSERRAT_12=y +CONFIG_LV_FONT_MONTSERRAT_16=y +CONFIG_LV_FONT_MONTSERRAT_18=y +CONFIG_LV_FONT_MONTSERRAT_20=y +CONFIG_LV_FONT_MONTSERRAT_22=y +CONFIG_LV_FONT_MONTSERRAT_24=y +CONFIG_LV_FONT_MONTSERRAT_26=y +CONFIG_LV_FONT_MONTSERRAT_28=y +CONFIG_LV_FONT_MONTSERRAT_30=y +CONFIG_LV_FONT_MONTSERRAT_32=y +CONFIG_LV_FONT_MONTSERRAT_34=y +CONFIG_LV_FONT_MONTSERRAT_36=y +CONFIG_LV_FONT_MONTSERRAT_38=y +CONFIG_LV_FONT_MONTSERRAT_40=y +CONFIG_LV_FONT_MONTSERRAT_42=y +CONFIG_LV_FONT_MONTSERRAT_44=y +CONFIG_LV_FONT_MONTSERRAT_46=y +CONFIG_LV_FONT_MONTSERRAT_48=y +CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED=y +CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW=y +CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_14_CJK=y +CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_16_CJK=y +CONFIG_LV_FONT_UNSCII_8=y +CONFIG_LV_FONT_UNSCII_16=y +CONFIG_LV_FONT_DEFAULT_MONTSERRAT_14=y +CONFIG_LV_FONT_FMT_TXT_LARGE=y +CONFIG_LV_USE_FONT_COMPRESSED=y +CONFIG_LV_USE_FONT_MANAGER=y +CONFIG_LV_USE_FREETYPE=y +# CONFIG_LV_FREETYPE_USE_LVGL_PORT is not set +CONFIG_LV_FREETYPE_CACHE_FT_GLYPH_CNT=64 +CONFIG_LV_USE_TINY_TTF=y +CONFIG_LV_TINY_TTF_FILE_SUPPORT=y +CONFIG_LV_USE_IMGFONT=y + +# Text +CONFIG_LV_USE_BIDI=y +CONFIG_LV_USE_ARABIC_PERSIAN_CHARS=y +CONFIG_LV_USE_TRANSLATION=y +CONFIG_LV_LABEL_TEXT_SELECTION=y + +# Widgets and layouts +CONFIG_LV_USE_FLEX=y +CONFIG_LV_USE_GRID=y +CONFIG_LV_USE_GRIDNAV=y +CONFIG_LV_USE_FRAGMENT=y +CONFIG_LV_USE_OBSERVER=y +CONFIG_LV_USE_FILE_EXPLORER=y +CONFIG_LV_USE_IME_PINYIN=y +CONFIG_LV_USE_CALENDAR_CHINESE=y +CONFIG_LV_USE_GESTURE_RECOGNITION=y + +# Object identification +CONFIG_LV_USE_OBJ_ID=y +CONFIG_LV_USE_OBJ_ID_BUILTIN=y +CONFIG_LV_OBJ_ID_AUTO_ASSIGN=y +CONFIG_LV_USE_OBJ_NAME=y + +# File systems +CONFIG_LV_USE_FS_STDIO=y +CONFIG_LV_FS_STDIO_LETTER=65 +CONFIG_LV_FS_STDIO_CACHE_SIZE=512 +CONFIG_LV_USE_FS_MEMFS=y +CONFIG_LV_FS_MEMFS_LETTER=77 +CONFIG_LV_FS_DEFAULT_DRIVER_LETTER=65 + +# Image and video decoders +CONFIG_LV_USE_RLE=y +CONFIG_LV_USE_LZ4=y +CONFIG_LV_USE_LZ4_INTERNAL=y +CONFIG_LV_USE_LODEPNG=y +CONFIG_LV_USE_LIBPNG=y +CONFIG_LV_USE_BMP=y +CONFIG_LV_USE_TJPGD=y +CONFIG_LV_USE_GIF=y +CONFIG_LV_USE_SNAPSHOT=y +CONFIG_LV_USE_QRCODE=y +CONFIG_LV_USE_BARCODE=y +CONFIG_LV_USE_LOTTIE=y + +# Vector graphics +CONFIG_LV_USE_VECTOR_GRAPHIC=y +CONFIG_LV_USE_THORVG=y +CONFIG_LV_USE_THORVG_INTERNAL=y +CONFIG_LV_USE_SVG=y +CONFIG_LV_USE_SVG_ANIMATION=y +CONFIG_LV_USE_SVG_DEBUG=y + +# Demos. Several test cases render them and compare against a reference image. +CONFIG_LV_USE_DEMO_WIDGETS=y +CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER=y +CONFIG_LV_USE_DEMO_STRESS=y +CONFIG_LV_USE_DEMO_RENDER=y +CONFIG_LV_USE_DEMO_MUSIC=y +CONFIG_LV_USE_DEMO_BENCHMARK=y +CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC=y + +# Display controller drivers +CONFIG_LV_USE_GENERIC_MIPI=y +CONFIG_LV_USE_ILI9341=y +CONFIG_LV_USE_ST7735=y +CONFIG_LV_USE_ST7789=y +CONFIG_LV_USE_ST7796=y +CONFIG_LV_USE_FT81X=y diff --git a/tests/configs/gstreamer.defconfig b/tests/configs/gstreamer.defconfig new file mode 100644 index 0000000000..8a72a931c9 --- /dev/null +++ b/tests/configs/gstreamer.defconfig @@ -0,0 +1 @@ +CONFIG_LV_USE_GSTREAMER=y diff --git a/tests/configs/linux_egl.defconfig b/tests/configs/linux_egl.defconfig new file mode 100644 index 0000000000..3ff34607ed --- /dev/null +++ b/tests/configs/linux_egl.defconfig @@ -0,0 +1,7 @@ +# Enables each driver's EGL backend to be added on top of linux_sw.defconfig + +CONFIG_LV_USE_DRAW_OPENGLES=y + +CONFIG_LV_LINUX_DRM_BACKEND_EGL=y +CONFIG_LV_WAYLAND_BACKEND_EGL=y +CONFIG_LV_SDL_BACKEND_EGL=y diff --git a/tests/configs/linux_sw.defconfig b/tests/configs/linux_sw.defconfig new file mode 100644 index 0000000000..788c64f9b5 --- /dev/null +++ b/tests/configs/linux_sw.defconfig @@ -0,0 +1,22 @@ +# Every Linux display and input driver, each on its software backend + +CONFIG_LV_USE_LINUX_FBDEV=y + +CONFIG_LV_USE_LINUX_DRM=y +# CONFIG_LV_LINUX_DRM_AUTO_BACKEND is not set +CONFIG_LV_LINUX_DRM_BACKEND_FBDEV=y + +CONFIG_LV_USE_WAYLAND=y +# CONFIG_LV_WAYLAND_AUTO_BACKEND is not set +CONFIG_LV_WAYLAND_BACKEND_SHM=y + +# X11 has no backend choice, it is software only +CONFIG_LV_USE_X11=y + +CONFIG_LV_USE_SDL=y +# CONFIG_LV_SDL_AUTO_BACKEND is not set +CONFIG_LV_SDL_BACKEND_SW=y + +CONFIG_LV_USE_LIBINPUT=y +CONFIG_LV_LIBINPUT_XKB=y +CONFIG_LV_USE_EVDEV=y diff --git a/tests/configs/minimal.defconfig b/tests/configs/minimal.defconfig new file mode 100644 index 0000000000..ef47d24185 --- /dev/null +++ b/tests/configs/minimal.defconfig @@ -0,0 +1,8 @@ +# Applied on top of the empty preset in configs/defconfigs, which is what +# actually switches the widgets, themes and layouts off. +# Disable assertions to catch unused variables errors + +CONFIG_LV_MEM_SIZE=65535 + +# CONFIG_LV_USE_ASSERT_NULL is not set +# CONFIG_LV_USE_ASSERT_MALLOC is not set diff --git a/tests/configs/nanovg.defconfig b/tests/configs/nanovg.defconfig new file mode 100644 index 0000000000..6c99d17ed2 --- /dev/null +++ b/tests/configs/nanovg.defconfig @@ -0,0 +1,9 @@ +# NanoVG rendering into an off-screen EGL pbuffer, so that screenshots can be +# compared without a window system. + +CONFIG_LV_USE_OPENGLES=y +CONFIG_LV_USE_DRAW_NANOVG=y +CONFIG_LV_USE_NANOVG_TEST_HEADLESS=y + +# NanoVG expects a compact stride (no padding) +CONFIG_LV_DRAW_BUF_STRIDE_ALIGN=1 diff --git a/tests/configs/nuttx.defconfig b/tests/configs/nuttx.defconfig new file mode 100644 index 0000000000..610fb174dd --- /dev/null +++ b/tests/configs/nuttx.defconfig @@ -0,0 +1,15 @@ +# NuttX port + +CONFIG_LV_USE_NUTTX=y +CONFIG_LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP=y +CONFIG_LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP=y +CONFIG_LV_USE_NUTTX_LIBUV=y +# CONFIG_LV_USE_NUTTX_CUSTOM_INIT is not set +CONFIG_LV_USE_NUTTX_LCD=y +CONFIG_LV_NUTTX_LCD_DOUBLE_BUFFER=y +CONFIG_LV_USE_NUTTX_TOUCHSCREEN=y +CONFIG_LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE=20 +CONFIG_LV_USE_NUTTX_MOUSE=y +CONFIG_LV_USE_NUTTX_MOUSE_MOVE_STEP=1 +CONFIG_LV_USE_NUTTX_TRACE_FILE=y +CONFIG_LV_NUTTX_TRACE_FILE_PATH="/data/lvgl-trace.log" diff --git a/tests/configs/riscv_v.defconfig b/tests/configs/riscv_v.defconfig new file mode 100644 index 0000000000..99fdf2f4a9 --- /dev/null +++ b/tests/configs/riscv_v.defconfig @@ -0,0 +1,3 @@ +# RISC-V Vector software rendering assembly, exercised under emulation. + +CONFIG_LV_DRAW_SW_ASM_RISCV_V=y diff --git a/tests/configs/run_tests.defconfig b/tests/configs/run_tests.defconfig new file mode 100644 index 0000000000..661e476dee --- /dev/null +++ b/tests/configs/run_tests.defconfig @@ -0,0 +1,11 @@ +# Added to the configurations whose test suites are actually executed, on top of +# the ones that are only compiled. + +# Reference images were rendered at this DPI +CONFIG_LV_DPI_DEF=130 + +# The test runner installs its own log callback +# CONFIG_LV_LOG_PRINTF is not set + +# The test cases do not use the examples +# CONFIG_LV_BUILD_EXAMPLES is not set diff --git a/tests/configs/sys_heap.defconfig b/tests/configs/sys_heap.defconfig new file mode 100644 index 0000000000..747c722b95 --- /dev/null +++ b/tests/configs/sys_heap.defconfig @@ -0,0 +1,17 @@ +# Use the C library allocator and string functions, so that ASan/LSan/UBSan can +# see every allocation. + +CONFIG_LV_USE_CLIB_MALLOC=y +CONFIG_LV_USE_CLIB_STRING=y +CONFIG_LV_USE_CLIB_SPRINTF=y + +# CONFIG_LV_OBJ_STYLE_CACHE is not set + +# Run the tests with bin images loaded to RAM +CONFIG_LV_BIN_DECODER_RAM_LOAD=y + +# Use a large stride so that any indexing issue causes a visible failure, and a +# non power of 2 buffer alignment so that we do not accidentally rely on the +# alignment malloc() happens to return. +CONFIG_LV_DRAW_BUF_STRIDE_ALIGN=64 +CONFIG_LV_DRAW_BUF_ALIGN=852 diff --git a/tests/configs/unix.defconfig b/tests/configs/unix.defconfig new file mode 100644 index 0000000000..bc3da0aded --- /dev/null +++ b/tests/configs/unix.defconfig @@ -0,0 +1,14 @@ +# Features that need a POSIX environment or libraries that are not built on +# Windows. + +CONFIG_LV_OS_PTHREAD=y + +CONFIG_LV_USE_FS_POSIX=y +CONFIG_LV_FS_POSIX_LETTER=66 + +CONFIG_LV_USE_LIBJPEG_TURBO=y +CONFIG_LV_USE_LIBWEBP=y + +CONFIG_LV_USE_FFMPEG=y +CONFIG_LV_FFMPEG_DUMP_FORMAT=y +CONFIG_LV_FFMPEG_PLAYER_USE_LV_FS=y diff --git a/tests/configs/vg_lite.defconfig b/tests/configs/vg_lite.defconfig new file mode 100644 index 0000000000..057e2561ff --- /dev/null +++ b/tests/configs/vg_lite.defconfig @@ -0,0 +1,32 @@ +# VG-Lite GPU rendering, simulated with ThorVG. + +CONFIG_LV_USE_DRAW_VG_LITE=y +CONFIG_LV_USE_VG_LITE_THORVG=y +CONFIG_LV_USE_THORVG_INTERNAL=y +CONFIG_LV_DRAW_TRANSFORM_USE_MATRIX=y + +# Enable the VG-Lite custom external 'gpu_init()' function +CONFIG_LV_VG_LITE_USE_GPU_INIT=y +CONFIG_LV_VG_LITE_USE_ASSERT=y + +# Let the GPU batch as many draw tasks as it can +CONFIG_LV_VG_LITE_FLUSH_MAX_COUNT=0 + +# Simulate shadows with a border. Usually faster, but does not render +# identically to the software renderer. +CONFIG_LV_VG_LITE_USE_BOX_SHADOW=y + +# 4K bytes per cached gradient image +CONFIG_LV_VG_LITE_GRAD_CACHE_CNT=32 + +# CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN is not set +# CONFIG_LV_VG_LITE_DISABLE_BLIT_RECT_OFFSET is not set + +# VG-Lite needs 64 byte aligned buffers. The draw buffers get this from +# LV_DRAW_BUF_ALIGN, the static font and image data from LV_ATTRIBUTE_MEM_ALIGN, +# which is not an lv_conf.h option of its own and so comes from a header. +CONFIG_LV_DRAW_BUF_ALIGN=64 +CONFIG_LV_ATTRIBUTE_USE_CUSTOM_INCLUDE=y +CONFIG_LV_ATTRIBUTE_CUSTOM_INCLUDE="tests/src/lv_test_attributes.h" + +CONFIG_LV_USE_PERF_MONITOR_LOG_MODE=y diff --git a/tests/configs/vg_lite_32bit.defconfig b/tests/configs/vg_lite_32bit.defconfig new file mode 100644 index 0000000000..c32d5547e4 --- /dev/null +++ b/tests/configs/vg_lite_32bit.defconfig @@ -0,0 +1,3 @@ +# On 32-bit hosts, cover the other side of this VG-Lite configuration switch. + +CONFIG_LV_VG_LITE_DISABLE_BLIT_RECT_OFFSET=y diff --git a/tests/configs/windows.defconfig b/tests/configs/windows.defconfig new file mode 100644 index 0000000000..faf6c9b44c --- /dev/null +++ b/tests/configs/windows.defconfig @@ -0,0 +1,6 @@ +# The Windows host, used instead of unix.defconfig on windows devices + +CONFIG_LV_OS_WINDOWS=y + +CONFIG_LV_USE_FS_WIN32=y +CONFIG_LV_FS_WIN32_LETTER=67 diff --git a/tests/configs/windows_sw.defconfig b/tests/configs/windows_sw.defconfig new file mode 100644 index 0000000000..8b5ce8a124 --- /dev/null +++ b/tests/configs/windows_sw.defconfig @@ -0,0 +1,7 @@ +# Counterpart of linux_sw.defconfig. Enables every driver that can run on windows + +CONFIG_LV_USE_WINDOWS=y + +CONFIG_LV_USE_SDL=y +# CONFIG_LV_SDL_AUTO_BACKEND is not set +CONFIG_LV_SDL_BACKEND_SW=y diff --git a/tests/main.py b/tests/main.py index 33c359b285..c29767d525 100755 --- a/tests/main.py +++ b/tests/main.py @@ -1,52 +1,200 @@ #!/usr/bin/env python3 import argparse +import os +import platform import shutil import subprocess import sys -import os -import platform from itertools import chain from pathlib import Path lvgl_test_dir = os.path.dirname(os.path.realpath(__file__)) +lvgl_dir = os.path.dirname(lvgl_test_dir) lvgl_script_path = os.path.join(lvgl_test_dir, "../scripts") sys.path.append(lvgl_script_path) -wayland_dir = os.path.join(lvgl_test_dir, "wayland_protocols") -wayland_protocols_dir = os.path.realpath("/usr/share/wayland-protocols") - +from LVGLImage import ColorFormat, CompressMethod, LVGLImage from perf import perf_test_options -from LVGLImage import LVGLImage, ColorFormat, CompressMethod -# Key values must match variable names in CMakeLists.txt. +lvgl_configs_dir = os.path.join(lvgl_test_dir, "configs") +lvgl_presets_dir = os.path.join(lvgl_dir, "configs", "defconfigs") + +# Placeholder for the defconfig fragment that depends on the host OS, expanded +# by host_defconfigs(). +HOST = "@host" + +# Prefix for a fragment that is one of the presets in configs/defconfigs +PRESET = "preset:" + +# Every build configuration is a list of defconfig fragments from tests/configs, +# merged in the given order so that a later fragment overrides an earlier one. build_only_options = { - 'OPTIONS_NORMAL_8BIT': 'Normal config, 8 bit color depth', - 'OPTIONS_16BIT': 'Minimal config, 16 bit color depth', - 'OPTIONS_24BIT': 'Normal config, 24 bit color depth', - 'OPTIONS_FULL_32BIT': 'Full config, 32 bit color depth', + "OPTIONS_MINIMAL": { + "description": "Empty config preset", + "defconfigs": [PRESET + "empty", "minimal", "depth_16"], + }, } -if platform.system() != 'Windows': - build_only_options['OPTIONS_SDL'] = 'SDL simulator with full config, 32 bit color depth' +if platform.system() == "Windows": + build_only_options["OPTIONS_WINDOWS_SW"] = { + "description": "Every Windows driver on its software backend, 32 bit color depth", + "defconfigs": ["full", "depth_32", HOST, "windows_sw", "builtin_heap"], + } + +if platform.system() == "Linux": + build_only_options["OPTIONS_LINUX_SW"] = { + "description": "Every Linux driver on its software backend, 32 bit color depth", + "defconfigs": ["full", "depth_32", HOST, "linux_sw", "builtin_heap"], + } + build_only_options["OPTIONS_LINUX_OPENGLES"] = { + "description": "The Linux drivers that have an EGL backend, 32 bit color depth", + "defconfigs": [ + "full", + "depth_32", + HOST, + "linux_sw", + "linux_egl", + "builtin_heap", + ], + } + build_only_options["OPTIONS_NUTTX"] = { + "description": "NuttX port with full config, 32 bit color depth", + "defconfigs": ["full", "depth_32", HOST, "nuttx", "builtin_heap"], + } test_options = { - 'OPTIONS_TEST_SYSHEAP': 'Test config, system heap, 32 bit color depth', - 'OPTIONS_TEST_DEFHEAP': 'Test config, LVGL heap, 32 bit color depth', - 'OPTIONS_TEST_VG_LITE': 'VG-Lite simulator with full config, 32 bit color depth', - 'OPTIONS_TEST_RISCV_V': 'RISC-V Vector emulation with full config, 32 bit color depth', - 'OPTIONS_TEST_NANOVG': 'NanoVG headless rendering with EGL, 32 bit color depth', + "OPTIONS_TEST_SYSHEAP": { + "description": "Test config, system heap, 32 bit color depth", + "defconfigs": ["full", "depth_32", HOST, "sys_heap", "run_tests"], + }, + "OPTIONS_TEST_DEFHEAP": { + "description": "Test config, LVGL heap, 32 bit color depth", + "defconfigs": [ + "full", + "depth_32", + HOST, + "builtin_heap", + "defheap", + "run_tests", + ], + }, + "OPTIONS_TEST_VG_LITE": { + "description": "VG-Lite simulator with full config, 32 bit color depth", + "defconfigs": ["full", "depth_32", HOST, "sys_heap", "run_tests", "vg_lite"], + # Cover the other side of a VG-Lite configuration switch on 32 bit + "defconfigs_non_amd64": ["vg_lite_32bit"], + }, + "OPTIONS_TEST_RISCV_V": { + "description": "RISC-V Vector emulation with full config, 32 bit color depth", + "defconfigs": ["full", "depth_32", HOST, "sys_heap", "run_tests", "riscv_v"], + }, + "OPTIONS_TEST_NANOVG": { + "description": "NanoVG headless rendering with EGL, 32 bit color depth", + "defconfigs": ["full", "depth_32", HOST, "sys_heap", "run_tests", "nanovg"], + }, } +def get_build_config(options_name): + if options_name in build_only_options: + return build_only_options[options_name] + return test_options[options_name] + + def get_option_description(option_name): - if option_name in build_only_options: - return build_only_options[option_name] - return test_options[option_name] + return get_build_config(option_name)["description"] + + +def non_amd64_build(): + """Return True when building for a non-amd64 (32 bit) target.""" + return bool(os.environ.get("NON_AMD64_BUILD")) + + +def host_defconfigs(): + """Return the defconfig fragment for the host OS. + + Only the platform neutral part: the file system driver, the libraries that + are not built on every platform, and the OS. Display and input drivers are + opted into per configuration, see linux_sw.defconfig.""" + if platform.system() == "Windows": + return ["windows"] + if non_amd64_build(): + return ["unix"] + return ["unix", "gstreamer"] + + +def target_cmake_args(): + """Return the cmake arguments that select the target architecture and + toolchain. + + These have to be given on the command line rather than set from a listfile, + because the compiler and library checks LVGL runs while resolving its + dependencies have to see them.""" + args = [] + + if platform.system() == "Windows": + vcpkg_root = os.environ.get("VCPKG_INSTALLATION_ROOT") + if vcpkg_root: + args += [ + "-DVCPKG_TARGET_TRIPLET=x64-windows", + "-DCMAKE_TOOLCHAIN_FILE=%s" + % os.path.join(vcpkg_root, "scripts", "buildsystems", "vcpkg.cmake"), + ] + + if non_amd64_build(): + print("Non AMD64 target is specified") + for flags in ( + "CMAKE_C_FLAGS", + "CMAKE_CXX_FLAGS", + "CMAKE_EXE_LINKER_FLAGS", + "CMAKE_SHARED_LINKER_FLAGS", + ): + args.append("-D%s=-m32" % flags) + # Search the i386 library paths first + args.append("-DCMAKE_LIBRARY_PATH=/usr/lib/i386-linux-gnu") + os.environ["PKG_CONFIG_PATH"] = os.pathsep.join( + filter( + None, + [ + "/usr/lib/i386-linux-gnu/pkgconfig", + os.environ.get("PKG_CONFIG_PATH"), + ], + ) + ) + + return args + + +def get_defconfig_paths(options_name): + """Return the defconfig paths for the given build options name.""" + config = get_build_config(options_name) + + fragments = ["common"] + for fragment in config["defconfigs"]: + if fragment == HOST: + fragments.extend(host_defconfigs()) + else: + fragments.append(fragment) + if non_amd64_build(): + fragments.extend(config.get("defconfigs_non_amd64", [])) + + paths = [] + for fragment in fragments: + if fragment.startswith(PRESET): + directory, name = lvgl_presets_dir, fragment[len(PRESET) :] + else: + directory, name = lvgl_configs_dir, fragment + path = os.path.join(directory, "%s.defconfig" % name) + if not os.path.isfile(path): + raise SystemExit("defconfig fragment not found: %s" % path) + paths.append(path) + + return paths def delete_dir_ignore_missing(dir_path): - '''Recursively delete a directory and ignore if missing.''' + """Recursively delete a directory and ignore if missing.""" try: shutil.rmtree(dir_path) except FileNotFoundError: @@ -54,69 +202,40 @@ def delete_dir_ignore_missing(dir_path): def options_abbrev(options_name): - '''Return an abbreviated version of the option name.''' - prefix = 'OPTIONS_' + """Return an abbreviated version of the option name.""" + prefix = "OPTIONS_" assert options_name.startswith(prefix) - return options_name[len(prefix):].lower() + return options_name[len(prefix) :].lower() def get_base_build_dir(options_name): - '''Given the build options name, return the build directory name. + """Given the build options name, return the build directory name. - Does not return the full path to the directory - just the base name.''' - return 'build_%s' % options_abbrev(options_name) + Does not return the full path to the directory - just the base name.""" + return "build_%s" % options_abbrev(options_name) def get_build_dir(options_name): - '''Given the build options name, return the build directory name. + """Given the build options name, return the build directory name. - Returns absolute path to the build directory.''' + Returns absolute path to the build directory.""" global lvgl_test_dir return os.path.join(lvgl_test_dir, get_base_build_dir(options_name)) -def gen_wayland_protocols(clean): - '''Generates the xdg shell interface from wayland protocol definitions''' - - if clean: - delete_dir_ignore_missing(wayland_dir) - - if not os.path.isdir(wayland_dir): - os.mkdir(wayland_dir) - subprocess.check_call(['wayland-scanner', - 'client-header', - os.path.join(wayland_protocols_dir, "stable/xdg-shell/xdg-shell.xml"), - os.path.join(wayland_dir, "wayland_xdg_shell.h.original"), - ]) - - subprocess.check_call(['wayland-scanner', - 'private-code', - os.path.join(wayland_protocols_dir, "stable/xdg-shell/xdg-shell.xml"), - os.path.join(wayland_dir, "wayland_xdg_shell.c.original"), - ]) - - # Insert guards - with open(os.path.join(wayland_dir, "wayland_xdg_shell.h"), "w") as outfile: - subprocess.check_call(['sed','-e', "1i #if LV_BUILD_TEST", '-e', '$a #endif', - os.path.join(wayland_dir, "wayland_xdg_shell.h.original")], stdout=outfile) - - with open(os.path.join(wayland_dir, "wayland_xdg_shell.c"), "w") as outfile: - subprocess.check_call(['sed','-e', "1i #if LV_BUILD_TEST", '-e', '$a #endif', - os.path.join(wayland_dir, "wayland_xdg_shell.c.original")], stdout=outfile) - - subprocess.check_call(['rm', os.path.join(wayland_dir, "wayland_xdg_shell.c.original")]) - subprocess.check_call(['rm', os.path.join(wayland_dir, "wayland_xdg_shell.h.original")]) def build_tests(options_name, build_type, clean): - '''Build all tests for the specified options name.''' + """Build all tests for the specified options name.""" global lvgl_test_dir print() print() - label = 'Building: %s: %s' % (options_abbrev( - options_name), get_option_description(options_name)) - print('=' * len(label)) + label = "Building: %s: %s" % ( + options_abbrev(options_name), + get_option_description(options_name), + ) + print("=" * len(label)) print(label) - print('=' * len(label)) + print("=" * len(label)) print(flush=True) build_dir = get_build_dir(options_name) @@ -125,45 +244,54 @@ def build_tests(options_name, build_type, clean): os.chdir(lvgl_test_dir) - if platform.system() != 'Windows': - gen_wayland_protocols(clean) - - created_build_dir = False if not os.path.isdir(build_dir): os.mkdir(build_dir) - created_build_dir = True - os.chdir(build_dir) - if created_build_dir: - cmake_args = ['cmake', '-GNinja', '-DCMAKE_BUILD_TYPE=%s' % build_type, - '-D%s=1' % options_name] + # The tests are built as part of the LVGL project, which pulls in + # tests/CMakeLists.txt when LV_BUILD_TESTS is set. + cmake_args = [ + "cmake", + "-GNinja", + "-S", + lvgl_dir, + "-B", + build_dir, + "-DCMAKE_BUILD_TYPE=%s" % build_type, + "-DLV_BUILD_TESTS=ON", + "-DLV_BUILD_DEFCONFIG_PATH=%s" + % ";".join(get_defconfig_paths(options_name)), + "-DLVGL_TEST_ENABLE=%s" % ("ON" if options_name in test_options else "OFF"), + ] + cmake_args += target_cmake_args() # Use ccache as a compiler launcher when available. This dramatically # speeds up rebuilds across the build matrix and repeated invocations # (notably under emulation), and is a no-op when ccache is absent. - if shutil.which('ccache'): - cmake_args += ['-DCMAKE_C_COMPILER_LAUNCHER=ccache', - '-DCMAKE_CXX_COMPILER_LAUNCHER=ccache'] - cmake_args.append('..') + if shutil.which("ccache"): + cmake_args += [ + "-DCMAKE_C_COMPILER_LAUNCHER=ccache", + "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", + ] subprocess.check_call(cmake_args) - subprocess.check_call(['cmake', '--build', build_dir, - '--parallel', str(os.cpu_count())]) + subprocess.check_call(["cmake", "--build", build_dir]) def run_tests(options_name, test_suite): - '''Run the tests for the given options name.''' + """Run the tests for the given options name.""" print() print() - label = 'Running tests for %s' % options_abbrev(options_name) - print('=' * len(label)) + label = "Running tests for %s" % options_abbrev(options_name) + print("=" * len(label)) print(label) - print('=' * len(label), flush=True) + print("=" * len(label), flush=True) os.chdir(get_build_dir(options_name)) args = [ - 'ctest', - '--timeout', '300', - '--parallel', str(os.cpu_count()), - '--output-on-failure', + "ctest", + "--timeout", + "300", + "--parallel", + str(os.cpu_count()), + "--output-on-failure", ] if test_suite is not None: args.extend(["--tests-regex", test_suite]) @@ -171,34 +299,48 @@ def run_tests(options_name, test_suite): def generate_code_coverage_report(): - '''Produce code coverage test reports for the test execution.''' + """Produce code coverage test reports for the test execution.""" global lvgl_test_dir print() print() - label = 'Generating code coverage reports' - print('=' * len(label)) + label = "Generating code coverage reports" + print("=" * len(label)) print(label) - print('=' * len(label)) + print("=" * len(label)) print(flush=True) os.chdir(lvgl_test_dir) - delete_dir_ignore_missing('report') - os.mkdir('report') - root_dir = os.path.dirname(lvgl_test_dir) # Get parent directory of tests (lvgl directory) - html_report_file = 'report/index.html' - cmd = ['gcovr', '--gcov-ignore-parse-errors', - '--root', root_dir, '--html-details', '--output', - html_report_file, '--xml', 'report/coverage.xml', - '-j', str(os.cpu_count()), '--print-summary', '--merge-mode-functions=merge-use-line-min', - '--html-title', 'LVGL Test Coverage'] + delete_dir_ignore_missing("report") + os.mkdir("report") + root_dir = os.path.dirname( + lvgl_test_dir + ) # Get parent directory of tests (lvgl directory) + html_report_file = "report/index.html" + cmd = [ + "gcovr", + "--gcov-ignore-parse-errors", + "--root", + root_dir, + "--html-details", + "--output", + html_report_file, + "--xml", + "report/coverage.xml", + "-j", + str(os.cpu_count()), + "--print-summary", + "--merge-mode-functions=merge-use-line-min", + "--html-title", + "LVGL Test Coverage", + ] subprocess.check_call(cmd) print("Done: See %s" % html_report_file, flush=True) def generate_test_images(): - invalids = (ColorFormat.UNKNOWN,ColorFormat.RAW,ColorFormat.RAW_ALPHA) + invalids = (ColorFormat.UNKNOWN, ColorFormat.RAW, ColorFormat.RAW_ALPHA) formats = [i for i in ColorFormat if i not in invalids] png_path = os.path.join(lvgl_test_dir, "test_images/pngs") pngs = list(Path(png_path).rglob("*.[pP][nN][gG]")) @@ -208,23 +350,32 @@ def generate_test_images(): for align in align_options: for compress in CompressMethod: - compress_name = compress.name if compress != CompressMethod.NONE else "UNCOMPRESSED" - outputs = os.path.join(lvgl_test_dir, f"test_images/stride_align{align}/{compress_name}/") + compress_name = ( + compress.name if compress != CompressMethod.NONE else "UNCOMPRESSED" + ) + outputs = os.path.join( + lvgl_test_dir, f"test_images/stride_align{align}/{compress_name}/" + ) os.makedirs(outputs, exist_ok=True) for fmt in formats: for png in pngs: - img = LVGLImage().from_png(png, cf=fmt, background=0xffffff) + img = LVGLImage().from_png(png, cf=fmt, background=0xFFFFFF) img.adjust_stride(align=16) output = os.path.join(outputs, f"{Path(png).stem}_{fmt.name}.bin") img.to_bin(output, compress=compress) - output = os.path.join(outputs, f"{Path(png).stem}_{fmt.name}_{compress.name}_align{align}.c") + output = os.path.join( + outputs, + f"{Path(png).stem}_{fmt.name}_{compress.name}_align{align}.c", + ) img.to_c_array(output, compress=compress) - print(f"converting {os.path.basename(png)}, format: {fmt.name}, compress: {compress_name}") + print( + f"converting {os.path.basename(png)}, format: {fmt.name}, compress: {compress_name}" + ) -def clean_build_dirs_with_filter(build_dir, clean_filters): - for entry in os.listdir(build_dir): - entry_path = os.path.join(build_dir, entry) +def clean_dir_with_filter(directory, clean_filters): + for entry in os.listdir(directory): + entry_path = os.path.join(directory, entry) if any(entry.endswith(filter) for filter in clean_filters): continue @@ -235,34 +386,69 @@ def clean_build_dirs_with_filter(build_dir, clean_filters): shutil.rmtree(entry_path) +def clean_build_dirs_with_filter(build_dir, clean_filters): + # The test executables are built in a "tests" subdirectory of the LVGL build + # directory, so the coverage data is spread over both. Clean the nested one + # first, then keep it while cleaning the top level. + tests_dir = os.path.join(build_dir, "tests") + if os.path.isdir(tests_dir): + clean_dir_with_filter(tests_dir, clean_filters) + + clean_dir_with_filter(build_dir, clean_filters + ["tests"]) + + if __name__ == "__main__": - epilog = '''This program builds and optionally runs the LVGL test programs. + epilog = """This program builds and optionally runs the LVGL test programs. There are two types of LVGL tests: "build", and "test". The build-only tests, as their name suggests, only verify that the program successfully compiles and links (with various build options). There are also a set of tests that execute to verify correct LVGL library behavior. - ''' + """ parser = argparse.ArgumentParser( - description='Build and/or run LVGL tests.', epilog=epilog) - parser.add_argument('--build-options', nargs=1, - choices=list(chain(build_only_options, test_options, perf_test_options)), - help='''the build option name to build or run. When + description="Build and/or run LVGL tests.", epilog=epilog + ) + parser.add_argument( + "--build-options", + nargs=1, + choices=list(chain(build_only_options, test_options, perf_test_options)), + help="""the build option name to build or run. When omitted all build configurations are used. - ''') - parser.add_argument('--clean', action='store_true', default=False, - help='clean existing build artifacts before operation.') - parser.add_argument('--report', action='store_true', - help='generate code coverage report for tests.') - parser.add_argument('actions', nargs='*', choices=['build', 'test'], - help='build: compile build tests, test: compile/run executable tests.') - parser.add_argument('--test-suite', default=None, - help='select test suite to run') - parser.add_argument('--update-image', action='store_true', default=False, - help='Update test image using LVGLImage.py script') - parser.add_argument('--auto-clean', action='store_true', default=False, - help='Automatically clean build directories') - parser.add_argument('--keep-report', action='store_true', default=False, - help='Skip cleaning gcov report files when --auto-clean and --report are enabled') + """, + ) + parser.add_argument( + "--clean", + action="store_true", + default=False, + help="clean existing build artifacts before operation.", + ) + parser.add_argument( + "--report", action="store_true", help="generate code coverage report for tests." + ) + parser.add_argument( + "actions", + nargs="*", + choices=["build", "test"], + help="build: compile build tests, test: compile/run executable tests.", + ) + parser.add_argument("--test-suite", default=None, help="select test suite to run") + parser.add_argument( + "--update-image", + action="store_true", + default=False, + help="Update test image using LVGLImage.py script", + ) + parser.add_argument( + "--auto-clean", + action="store_true", + default=False, + help="Automatically clean build directories", + ) + parser.add_argument( + "--keep-report", + action="store_true", + default=False, + help="Skip cleaning gcov report files when --auto-clean and --report are enabled", + ) args = parser.parse_args() @@ -272,8 +458,8 @@ if __name__ == "__main__": if args.build_options: options_to_build = args.build_options else: - if 'build' in args.actions: - if 'test' in args.actions: + if "build" in args.actions: + if "test" in args.actions: options_to_build = {**build_only_options, **test_options} else: options_to_build = build_only_options @@ -292,7 +478,7 @@ if __name__ == "__main__": sys.exit(e.returncode) continue - build_type = 'Debug' + build_type = "Debug" build_tests(options_name, build_type, args.clean) if is_test: try: @@ -306,7 +492,7 @@ if __name__ == "__main__": if args.report: # Keep the files that gcovr analysis depends on and delete # the rest to solve the storage capacity limit of GitHub CI - clean_filters = ['CMakeFiles', '.c'] + clean_filters = ["CMakeFiles", ".c"] clean_build_dirs_with_filter(build_dir, clean_filters) if args.keep_report: diff --git a/tests/src/lv_test_assert.h b/tests/src/lv_test_assert.h new file mode 100644 index 0000000000..49c83f8905 --- /dev/null +++ b/tests/src/lv_test_assert.h @@ -0,0 +1,23 @@ +/** + * @file lv_test_assert.h + * + * Custom assert handler for the unit tests. Pulled in by lv_conf_internal.h + * through LV_ASSERT_CUSTOM_INCLUDE, see tests/configs/common.defconfig. + */ + +#ifndef LV_TEST_ASSERT_H +#define LV_TEST_ASSERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +void lv_test_assert_fail(void); + +#define LV_ASSERT_HANDLER lv_test_assert_fail(); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEST_ASSERT_H*/ diff --git a/tests/src/lv_test_attributes.h b/tests/src/lv_test_attributes.h new file mode 100644 index 0000000000..d018fc1c36 --- /dev/null +++ b/tests/src/lv_test_attributes.h @@ -0,0 +1,20 @@ +/** + * @file lv_test_attributes.h + * + * Pulled in by lv_conf_internal.h through LV_ATTRIBUTE_CUSTOM_INCLUDE for the + * configurations that need aligned static data, see configs/vg_lite.defconfig. + */ + +#ifndef LV_TEST_ATTRIBUTES_H +#define LV_TEST_ATTRIBUTES_H + +/* VG-Lite refuses to work on unaligned image and glyph data. The generated font + * and image sources apply LV_ATTRIBUTE_MEM_ALIGN to their data arrays, so this + * is what aligns the test assets. */ +#ifdef _MSC_VER + #define LV_ATTRIBUTE_MEM_ALIGN __declspec(align(LV_DRAW_BUF_ALIGN)) +#else + #define LV_ATTRIBUTE_MEM_ALIGN __attribute__((aligned(LV_DRAW_BUF_ALIGN))) +#endif + +#endif /*LV_TEST_ATTRIBUTES_H*/ diff --git a/tests/src/lv_test_conf.h b/tests/src/lv_test_conf.h deleted file mode 100644 index 6362796a1d..0000000000 --- a/tests/src/lv_test_conf.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file lv_test_conf.h - * - */ - -#ifndef LV_TEST_CONF_H -#define LV_TEST_CONF_H - -#define LV_CONF_SUPPRESS_DEFINE_CHECK 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/*********************** - * PLATFORM CONFIGS - ***********************/ - -#ifdef LVGL_CI_USING_SYS_HEAP -#define LV_USE_STDLIB_MALLOC LV_STDLIB_CLIB -#define LV_USE_STDLIB_STRING LV_STDLIB_CLIB -#define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB -#define LV_USE_OS LV_OS_PTHREAD -#define LV_OBJ_STYLE_CACHE 0 -#define LV_BIN_DECODER_RAM_LOAD 1 /* Run test with bin image loaded to RAM */ -#ifndef LV_DRAW_BUF_STRIDE_ALIGN -#define LV_DRAW_BUF_STRIDE_ALIGN 64 /* Use a large value to be sure any issues will cause crash */ -#endif -#endif - -#ifdef LVGL_CI_USING_DEF_HEAP -#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN -#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN -#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN -#define LV_OBJ_STYLE_CACHE 1 -#define LV_BIN_DECODER_RAM_LOAD 0 -#define LV_USE_MEM_MONITOR 1 -#endif - -#ifdef MICROPYTHON -#define LV_USE_BUILTIN_MALLOC 0 -#define LV_USE_BUILTIN_MEMCPY 1 -#define LV_USE_BUILTIN_SNPRINTF 1 -#define LV_STDLIB_INCLUDE "include/lv_mp_mem_custom_include.h" -#define LV_MALLOC m_malloc -#define LV_REALLOC m_realloc -#define LV_FREE m_free -#define LV_MEMSET lv_memset_builtin -#define LV_MEMCPY lv_memcpy_builtin -#define LV_SNPRINTF lv_snprintf_builtin -#define LV_VSNPRINTF lv_vsnprintf_builtin -#define LV_STRLEN lv_strlen_builtin -#define LV_STRNCPY lv_strncpy_builtin - -#define LV_ENABLE_GC 1 -#define LV_GC_INCLUDE "py/mpstate.h" -#define LV_GC_ROOT(x) MP_STATE_PORT(x) -#endif - -#ifndef __ASSEMBLY__ -void lv_test_assert_fail(void); -#define LV_ASSERT_HANDLER lv_test_assert_fail(); - -typedef void * lv_user_data_t; -#endif -/*********************** - * TEST CONFIGS - ***********************/ - -#if !(defined(LV_TEST_OPTION)) || LV_TEST_OPTION == 5 -#define LV_COLOR_DEPTH 32 -#define LV_DPI_DEF 160 -#include "lv_test_conf_full.h" -#elif LV_TEST_OPTION == 6 -#define LV_COLOR_DEPTH 32 -#define LV_DPI_DEF 160 - -#define LV_DRAW_BUF_ALIGN 64 -#ifdef _MSC_VER -#define LV_ATTRIBUTE_MEM_ALIGN __declspec(align(LV_DRAW_BUF_ALIGN)) -#else -#define LV_ATTRIBUTE_MEM_ALIGN __attribute__((aligned(LV_DRAW_BUF_ALIGN))) -#endif - -#include "lv_test_conf_vg_lite.h" -#include "lv_test_conf_full.h" -#elif LV_TEST_OPTION == 7 -#define LV_COLOR_DEPTH 32 -#define LV_DPI_DEF 160 -#define LV_USE_DRAW_SDL 1 -#define LV_USE_SDL 1 -#define LV_SDL_AUTO_BACKEND 0 -#define LV_SDL_BACKEND LV_SDL_BACKEND_SW -#define LV_USE_NUTTX 1 -#include "lv_test_conf_full.h" -#elif LV_TEST_OPTION == 8 -#define LV_COLOR_DEPTH 32 -#define LV_DPI_DEF 160 -#define LV_USE_NANOVG_TEST_HEADLESS 1 -#define LV_USE_OPENGLES 1 -#define LV_USE_NANOVG 1 -#define LV_USE_DRAW_NANOVG 1 -#undef LV_DRAW_BUF_STRIDE_ALIGN -#define LV_DRAW_BUF_STRIDE_ALIGN 1 /* NanoVG expects compact stride (no padding) */ -#include "lv_test_conf_full.h" -#elif LV_TEST_OPTION == 4 -#define LV_COLOR_DEPTH 24 -#define LV_DPI_DEF 120 -#elif LV_TEST_OPTION == 3 -#define LV_COLOR_DEPTH 16 -#define LV_DPI_DEF 90 -#include "lv_test_conf_minimal.h" -#elif LV_TEST_OPTION == 2 -#define LV_COLOR_DEPTH 8 -#define LV_DPI_DEF 60 -#include "lv_test_conf_minimal.h" -#elif LV_TEST_OPTION == 1 -#define LV_COLOR_DEPTH 1 -#define LV_DPI_DEF 30 -#define LV_DRAW_SW_COMPLEX 0 -#include "lv_test_conf_minimal.h" -#endif - -#if defined(LVGL_CI_USING_SYS_HEAP) || defined(LVGL_CI_USING_DEF_HEAP) -#undef LV_LOG_PRINTF - -#ifndef LV_DRAW_BUF_ALIGN -/*Use non power of 2 to avoid the case when `malloc` returns aligned pointer by default, and use a large value be sure any issues will cause crash*/ -#define LV_DRAW_BUF_ALIGN 852 -#endif - -/*For screenshots*/ -#undef LV_DPI_DEF -#define LV_DPI_DEF 130 -#endif - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_TEST_CONF_H*/ diff --git a/tests/src/lv_test_conf_full.h b/tests/src/lv_test_conf_full.h deleted file mode 100644 index eeecc44055..0000000000 --- a/tests/src/lv_test_conf_full.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef LV_TEST_CONF_FULL_H -#define LV_TEST_CONF_FULL_H -#define LV_CHECK_ARG_LOG_MODE LV_CHECK_ARG_LOG_MODE_VERBOSE - -#define LV_MEM_SIZE (32 * 1024 * 1024) -#define LV_DRAW_SW_SHADOW_CACHE_SIZE 8 -#define LV_DRAW_THREAD_STACK_SIZE (64 * 1024) /*Increase stack size to 64KB in order to run ThorVG*/ -#define LV_USE_LOG 1 -#define LV_LOG_LEVEL LV_LOG_LEVEL_TRACE -#define LV_LOG_PRINTF 1 -#define LV_USE_ASSERT_NULL 1 -#define LV_USE_ASSERT_MALLOC 1 -#define LV_USE_ASSERT_MEM_INTEGRITY 1 -#define LV_USE_ASSERT_OBJ 1 -#define LV_USE_ASSERT_STYLE 1 -#define LV_USE_FLOAT 1 -#define LV_USE_MATRIX 1 - -#define LV_FONT_MONTSERRAT_8 1 -#define LV_FONT_MONTSERRAT_10 1 -#define LV_FONT_MONTSERRAT_12 1 -#define LV_FONT_MONTSERRAT_14 1 -#define LV_FONT_MONTSERRAT_16 1 -#define LV_FONT_MONTSERRAT_18 1 -#define LV_FONT_MONTSERRAT_20 1 -#define LV_FONT_MONTSERRAT_22 1 -#define LV_FONT_MONTSERRAT_24 1 -#define LV_FONT_MONTSERRAT_26 1 -#define LV_FONT_MONTSERRAT_28 1 -#define LV_FONT_MONTSERRAT_30 1 -#define LV_FONT_MONTSERRAT_32 1 -#define LV_FONT_MONTSERRAT_34 1 -#define LV_FONT_MONTSERRAT_36 1 -#define LV_FONT_MONTSERRAT_38 1 -#define LV_FONT_MONTSERRAT_40 1 -#define LV_FONT_MONTSERRAT_42 1 -#define LV_FONT_MONTSERRAT_44 1 -#define LV_FONT_MONTSERRAT_46 1 -#define LV_FONT_MONTSERRAT_48 1 -#define LV_FONT_MONTSERRAT_28_COMPRESSED 1 -#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1 -#define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 1 -#define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 1 -#define LV_FONT_UNSCII_8 1 -#define LV_FONT_UNSCII_16 1 -#define LV_FONT_DEFAULT &lv_font_montserrat_14 -#define LV_FONT_FMT_TXT_LARGE 1 -#define LV_USE_FONT_COMPRESSED 1 -#define LV_USE_BIDI 1 -#define LV_USE_ARABIC_PERSIAN_CHARS 1 -#define LV_USE_SYSMON 1 -#define LV_USE_PERF_MONITOR 1 -#define LV_LABEL_TEXT_SELECTION 1 - -#define LV_USE_CALENDAR_CHINESE 1 -#define LV_USE_LOTTIE 1 - -#define LV_USE_FLEX 1 -#define LV_USE_GRID 1 - -#define LV_USE_FS_STDIO 1 -#define LV_FS_STDIO_LETTER 'A' -#define LV_FS_STDIO_CACHE_SIZE 512 -#ifndef _WIN32 - #define LV_USE_FS_POSIX 1 - #define LV_FS_POSIX_LETTER 'B' -#else - #define LV_USE_FS_WIN32 1 - #define LV_FS_WIN32_LETTER 'C' -#endif -#define LV_USE_FS_MEMFS 1 -#define LV_FS_MEMFS_LETTER 'M' - -#define LV_FS_DEFAULT_DRIVER_LETTER 'A' - -#define LV_USE_MONKEY 1 -#define LV_USE_RLE 1 -#define LV_USE_LODEPNG 1 -#define LV_USE_LIBPNG 1 -#define LV_USE_BMP 1 -#define LV_USE_TJPGD 1 -#ifndef _WIN32 - #define LV_USE_LIBJPEG_TURBO 1 - #ifndef LV_USE_LIBWEBP /* If WebP library is not found, defaulting to 0 in CMakeLists.txt */ - #define LV_USE_LIBWEBP 1 - #endif -#endif -#ifndef LV_USE_FFMPEG - #define LV_USE_FFMPEG 1 - #define LV_FFMPEG_DUMP_FORMAT 1 - #define LV_FFMPEG_PLAYER_USE_LV_FS 1 -#endif -#define LV_USE_GIF 1 -#define LV_USE_QRCODE 1 -#define LV_USE_BARCODE 1 -#define LV_USE_FRAGMENT 1 -#define LV_USE_IMGFONT 1 -#define LV_USE_IME_PINYIN 1 -#define LV_USE_OBSERVER 1 -#define LV_USE_FILE_EXPLORER 1 -#define LV_USE_TINY_TTF 1 -#define LV_TINY_TTF_FILE_SUPPORT 1 -#define LV_USE_SNAPSHOT 1 -#define LV_USE_THORVG 1 -#define LV_USE_THORVG_INTERNAL 1 -#define LV_USE_LZ4 1 -#define LV_USE_LZ4_INTERNAL 1 -#define LV_USE_VECTOR_GRAPHIC 1 -#define LV_USE_SVG 1 -#define LV_USE_SVG_ANIMATION 1 -#define LV_USE_SVG_DEBUG 1 -#define LV_USE_PROFILER 1 -#define LV_PROFILER_INCLUDE "lv_profiler_builtin.h" -#define LV_USE_PROFILER_BUILTIN 1 -#define LV_USE_PROFILER_BUILTIN_POSIX 1 -#define LV_USE_GRIDNAV 1 -#define LV_USE_XML 1 -#define LV_USE_TRANSLATION 1 -#define LV_USE_TEST 1 -#define LV_USE_TEST_SCREENSHOT_COMPARE 1 -#define LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE 1 - -#define LV_BUILD_EXAMPLES 1 -#define LV_USE_DEMO_WIDGETS 1 -#define LV_USE_DEMO_KEYPAD_AND_ENCODER 1 -#define LV_USE_DEMO_FLEX_LAYOUT 1 -#define LV_USE_DEMO_STRESS 1 -#define LV_USE_DEMO_MULTILANG 1 -#define LV_USE_DEMO_RENDER 1 -#define LV_USE_DEMO_MUSIC 1 -#define LV_USE_DEMO_BENCHMARK 1 -#define LV_USE_DEMO_EBIKE 1 -#define LV_USE_DEMO_VECTOR_GRAPHIC 1 -#define LV_USE_DEMO_HIGH_RES 1 -#define LV_USE_DEMO_SMARTWATCH 1 - -#define LV_USE_OBJ_ID 1 -#define LV_OBJ_ID_AUTO_ASSIGN 1 -#define LV_USE_OBJ_ID_BUILTIN 1 - -#define LV_USE_OBJ_NAME 1 - -#define LV_CACHE_DEF_SIZE (10 * 1024 * 1024) - -#ifndef LV_USE_LINUX_DRM - #define LV_USE_LINUX_DRM 1 - #define LV_LINUX_DRM_AUTO_BACKEND 0 - #define LV_LINUX_DRM_BACKEND LV_LINUX_DRM_BACKEND_FBDEV -#endif - -#ifndef LV_USE_LINUX_FBDEV - #define LV_USE_LINUX_FBDEV 1 -#endif - -#ifndef LV_USE_NUTTX - #define LV_USE_NUTTX 0 -#endif -#if defined(_WIN32) && LV_USE_NUTTX - #undef LV_USE_NUTTX /* Disable NuttX build on Windows */ - #define LV_USE_NUTTX 0 -#endif -#if LV_USE_NUTTX - #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 1 - #define LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP 1 - #define LV_USE_NUTTX_LIBUV 1 - #define LV_USE_NUTTX_CUSTOM_INIT 0 - #define LV_USE_NUTTX_LCD 1 - #define LV_NUTTX_LCD_BUFFER_COUNT 2 - #define LV_NUTTX_LCD_BUFFER_SIZE 60 - #define LV_USE_NUTTX_TOUCHSCREEN 1 - #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 20 - #define LV_USE_NUTTX_MOUSE 1 - #define LV_USE_NUTTX_MOUSE_MOVE_STEP 1 - #define LV_USE_NUTTX_TRACE_FILE 1 - #define LV_NUTTX_TRACE_FILE_PATH "/data/lvgl-trace.log" -#endif - -#ifndef LV_USE_WAYLAND - #define LV_USE_WAYLAND 1 - #define LV_WAYLAND_AUTO_BACKEND 0 - #define LV_WAYLAND_BACKEND LV_WAYLAND_BACKEND_SHM -#endif - -#define LV_USE_GENERIC_MIPI 1 -#define LV_USE_ILI9341 1 -#define LV_USE_ST7735 1 -#define LV_USE_ST7789 1 -#define LV_USE_ST7796 1 -#define LV_USE_FT81X 1 - -#ifndef LV_USE_LIBINPUT - #define LV_USE_LIBINPUT 1 -#endif - -#ifndef LV_LIBINPUT_XKB - #define LV_LIBINPUT_XKB 1 -#endif - -#ifndef LV_USE_OPENGLES - #if !defined(NON_AMD64_BUILD) && !defined(_MSC_VER) && !defined(_WIN32) - #define LV_USE_OPENGLES 1 - #endif -#endif - -#define LV_USE_FREETYPE 1 -#define LV_FREETYPE_USE_LVGL_PORT 0 -#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 64 - -#define LV_USE_FONT_MANAGER 1 - -#define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 1 - -#define LV_USE_GESTURE_RECOGNITION 1 - -#define LV_DISABLE_API_MAPPING 1 - -#endif /* LV_TEST_CONF_FULL_H */ diff --git a/tests/src/lv_test_conf_minimal.h b/tests/src/lv_test_conf_minimal.h deleted file mode 100644 index c4848a2880..0000000000 --- a/tests/src/lv_test_conf_minimal.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LV_TEST_CONF_MINIMAL_H -#define LV_TEST_CONF_MINIMAL_H - -#define LV_MEM_SIZE 65535 -#define LV_USE_LOG 1 -#define LV_USE_ASSERT_NULL 0 -#define LV_USE_ASSERT_MALLOC 0 -#define LV_USE_ASSERT_MEM_INTEGRITY 0 -#define LV_USE_ASSERT_OBJ 0 -#define LV_USE_ASSERT_STYLE 0 -#define LV_USE_TEST 1 -#define LV_USE_TEST_SCREENSHOT_COMPARE 1 - -#define LV_USE_BIDI 0 -#define LV_USE_ARABIC_PERSIAN_CHARS 0 - -#define LV_BUILD_EXAMPLES 1 - -#define LV_USE_THEME_SIMPLE 1 -#define LV_USE_THEME_DEFAULT 0 - -#define LV_USE_LODEPNG 1 -#define LV_USE_BMP 1 -#define LV_USE_RLE 1 -#define LV_USE_GIF 1 -#define LV_USE_QRCODE 1 - -#endif /* LV_TEST_CONF_MINIMAL_H */ diff --git a/tests/src/lv_test_conf_vg_lite.h b/tests/src/lv_test_conf_vg_lite.h deleted file mode 100644 index 0e20c98310..0000000000 --- a/tests/src/lv_test_conf_vg_lite.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef LV_TEST_CONF_VG_LITE_H -#define LV_TEST_CONF_VG_LITE_H - -/* Use VG-Lite GPU. */ -#define LV_USE_DRAW_VG_LITE 1 - -/* Enable VG-Lite custom external 'gpu_init()' function */ -#define LV_VG_LITE_USE_GPU_INIT 1 - -/* Enable VG-Lite assert. */ -#define LV_VG_LITE_USE_ASSERT 1 - -/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ -#define LV_VG_LITE_FLUSH_MAX_COUNT 0 - -/* Enable border to simulate shadow - * NOTE: which usually improves performance, - * but does not guarantee the same rendering quality as the software. */ -#define LV_VG_LITE_USE_BOX_SHADOW 1 - -/* VG-Lite gradient maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ -#define LV_VG_LITE_GRAD_CACHE_CNT 32 - -/* Disable 16 pixels alignment */ -#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0 - -/* Enable ThorVG internal rendering engine */ -#define LV_USE_THORVG_INTERNAL 1 - -/* Simulate VG-Lite hardware using ThorVG */ -#define LV_USE_VG_LITE_THORVG 1 - -/* Enable performance monitor log mode for build test */ -#define LV_USE_PERF_MONITOR_LOG_MODE 1 - -/*Using matrix for transformations. - *Requirements: - `LV_USE_MATRIX = 1`. - The rendering engine needs to support 3x3 matrix transformations.*/ -#define LV_DRAW_TRANSFORM_USE_MATRIX 1 - -/* Used to test coverage of different configuration combinations */ -#ifdef NON_AMD64_BUILD - #define LV_VG_LITE_DISABLE_BLIT_RECT_OFFSET 1 -#else - #define LV_VG_LITE_DISABLE_BLIT_RECT_OFFSET 0 -#endif - -#endif /* LV_TEST_CONF_VG_LITE_H */ diff --git a/tests/src/lv_test_init.c b/tests/src/lv_test_init.c index c0590aa7bf..e2992c46bd 100644 --- a/tests/src/lv_test_init.c +++ b/tests/src/lv_test_init.c @@ -18,7 +18,7 @@ void lv_test_init(void) lv_profiler_builtin_set_enable(false); #endif -#if defined(LV_USE_DRAW_NANOVG) && LV_USE_DRAW_NANOVG && defined(LV_USE_NANOVG_TEST_HEADLESS) && LV_USE_NANOVG_TEST_HEADLESS +#if LV_USE_DRAW_NANOVG && LV_USE_NANOVG_TEST_HEADLESS lv_display_t * egl_disp = lv_test_display_egl_create(LV_TEST_DISPLAY_HOR_RES, LV_TEST_DISPLAY_VER_RES); /* LV_ASSERT_MSG is always compiled in (unlike assert() under NDEBUG) and * triggers LV_ASSERT_HANDLER, so a fatal setup failure is reported reliably. */ @@ -50,7 +50,7 @@ void lv_test_deinit(void) #endif lv_test_indev_delete_all(); -#if defined(LV_USE_DRAW_NANOVG) && LV_USE_DRAW_NANOVG && defined(LV_USE_NANOVG_TEST_HEADLESS) && LV_USE_NANOVG_TEST_HEADLESS +#if LV_USE_DRAW_NANOVG && LV_USE_NANOVG_TEST_HEADLESS /* Capture the EGL context before lv_deinit() deletes the display, then release * the EGL/GL resources after lv_deinit() has destroyed the NanoVG draw unit. */ void * egl_ctx = lv_display_get_driver_data(lv_display_get_default()); diff --git a/tests/src/test_cases/test_check_obj.c b/tests/src/test_cases/test_check_obj.c index e01d035eb2..27bda1394e 100644 --- a/tests/src/test_cases/test_check_obj.c +++ b/tests/src/test_cases/test_check_obj.c @@ -1,9 +1,5 @@ #if LV_BUILD_TEST /* Variant: default — LV_USE_CHECK_ARG=1, LV_USE_CHECK_OBJ_CLASSTYPE=1, LV_USE_CHECK_OBJ_VALIDITY=1 */ -/* 1. Include the test conf manually so we can add overrides before lvgl.h */ -#include "lv_test_conf.h" -/* 2. Prevent lv_conf_internal.h from re-including the conf */ -#define LV_CONF_SKIP #include "../lvgl.h" #include "test_cases/test_check_obj_impl.h" diff --git a/tests/src/test_cases/test_check_obj_cls_no_vld.c b/tests/src/test_cases/test_check_obj_cls_no_vld.c index 00469e69c9..91014427da 100644 --- a/tests/src/test_cases/test_check_obj_cls_no_vld.c +++ b/tests/src/test_cases/test_check_obj_cls_no_vld.c @@ -1,8 +1,6 @@ #if LV_BUILD_TEST /* Variant: LV_USE_CHECK_ARG=1, LV_USE_CHECK_OBJ_CLASSTYPE=1, LV_USE_CHECK_OBJ_VALIDITY=0 */ -#include "lv_test_conf.h" #define LV_USE_CHECK_OBJ_VALIDITY 0 -#define LV_CONF_SKIP #include "../lvgl.h" #include "test_cases/test_check_obj_impl.h" diff --git a/tests/src/test_cases/test_check_obj_no_arg.c b/tests/src/test_cases/test_check_obj_no_arg.c index fe63daf6c8..9f94448177 100644 --- a/tests/src/test_cases/test_check_obj_no_arg.c +++ b/tests/src/test_cases/test_check_obj_no_arg.c @@ -1,8 +1,6 @@ #if LV_BUILD_TEST /* Variant: LV_USE_CHECK_ARG=0 */ -#include "lv_test_conf.h" #define LV_USE_CHECK_ARG 0 -#define LV_CONF_SKIP #include "../lvgl.h" #include "test_cases/test_check_obj_impl.h" diff --git a/tests/src/test_cases/test_check_obj_no_cls_no_vld.c b/tests/src/test_cases/test_check_obj_no_cls_no_vld.c index ff84da17ad..cc2441ae56 100644 --- a/tests/src/test_cases/test_check_obj_no_cls_no_vld.c +++ b/tests/src/test_cases/test_check_obj_no_cls_no_vld.c @@ -1,9 +1,7 @@ #if LV_BUILD_TEST /* Variant: LV_USE_CHECK_ARG=1, LV_USE_CHECK_OBJ_CLASSTYPE=0, LV_USE_CHECK_OBJ_VALIDITY=0 */ -#include "lv_test_conf.h" #define LV_USE_CHECK_OBJ_CLASSTYPE 0 #define LV_USE_CHECK_OBJ_VALIDITY 0 -#define LV_CONF_SKIP #include "../lvgl.h" #include "test_cases/test_check_obj_impl.h" diff --git a/tests/src/test_cases/test_check_obj_no_cls_vld.c b/tests/src/test_cases/test_check_obj_no_cls_vld.c index af849b058d..4fe85e68c9 100644 --- a/tests/src/test_cases/test_check_obj_no_cls_vld.c +++ b/tests/src/test_cases/test_check_obj_no_cls_vld.c @@ -1,8 +1,6 @@ #if LV_BUILD_TEST /* Variant: LV_USE_CHECK_ARG=1, LV_USE_CHECK_OBJ_CLASSTYPE=0, LV_USE_CHECK_OBJ_VALIDITY=1 */ -#include "lv_test_conf.h" #define LV_USE_CHECK_OBJ_CLASSTYPE 0 -#define LV_CONF_SKIP #include "../lvgl.h" #include "test_cases/test_check_obj_impl.h" diff --git a/tests/src/test_cases/test_mem.c b/tests/src/test_cases/test_mem.c index a15c1c834b..a4f1e9bd89 100644 --- a/tests/src/test_cases/test_mem.c +++ b/tests/src/test_cases/test_mem.c @@ -87,7 +87,7 @@ void test_realloc(void) /* #3324 */ void test_realloc_failed(void) { -#ifdef LVGL_CI_USING_DEF_HEAP +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN uint32_t mem = lv_test_get_free_mem(); void * buf1 = lv_malloc(20); @@ -109,7 +109,7 @@ void test_realloc_failed(void) void test_malloc_failed(void) { -#ifdef LVGL_CI_USING_DEF_HEAP +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN uint32_t mem = lv_test_get_free_mem(); TEST_ASSERT_NULL(lv_malloc(LV_MEM_SIZE + 1)); TEST_ASSERT_NULL(lv_malloc_zeroed(LV_MEM_SIZE + 1)); @@ -199,7 +199,7 @@ void test_mem_add_pool_size_limits(void) void test_mem_test(void) { -#ifdef LVGL_CI_USING_DEF_HEAP +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN uint32_t mem = lv_test_get_free_mem(); uint32_t * zero_mem = lv_malloc_zeroed(0); TEST_ASSERT_NOT_NULL(zero_mem);