From 14bb5f2e6bff8f26296a32b401191cba621080a9 Mon Sep 17 00:00:00 2001 From: Erik Tagirov <162967732+etag4048@users.noreply.github.com> Date: Mon, 28 Apr 2025 22:15:23 +0200 Subject: [PATCH] feat(cmake): disable PCPP by default (#8126) --- .../details/integration/building/cmake.rst | 7 +- env_support/cmake/custom.cmake | 67 +++++++++++-------- scripts/generate_cmake_variables.py | 37 +++++++--- 3 files changed, 72 insertions(+), 39 deletions(-) diff --git a/docs/src/details/integration/building/cmake.rst b/docs/src/details/integration/building/cmake.rst index 6dc8fc4d12..534515da2b 100644 --- a/docs/src/details/integration/building/cmake.rst +++ b/docs/src/details/integration/building/cmake.rst @@ -26,6 +26,7 @@ You need to install - CMake - Ninja (for Linux builds). Be sure to Add ninja to your PATH! - The prerequisites listed in ``scripts/install-prerequisites.sh/bat`` +- A python3 interpreter if you wish to use KConfig. How to build this project using cmake @@ -87,7 +88,7 @@ Here is how to build using the presets: Build with IDE ~~~~~~~~~~~~~~ -The recommend way for consuming CMakePresets is a CMakePresets aware IDE such as +The recommended way for consuming CMakePresets is a CMakePresets aware IDE such as - VS 2022 - VS Code @@ -183,4 +184,6 @@ These cmake options are available to configure LVGL: - ``LV_DEFCONFIG_PATH`` (STRING): Specify to use a defconfig file instead of the current .config in a Kconfig setup. - ``LV_CONF_BUILD_DISABLE_EXAMPLES`` (BOOLEAN): Disable building the examples if set. - ``LV_CONF_BUILD_DISABLE_DEMOS`` (BOOLEAN): Disable building the demos if set. -- ``LV_CONF_BUILD_DISABLE_THORVG_INTERNAL``: Disable the internal compilation of ThorVG. \ No newline at end of file +- ``LV_CONF_BUILD_DISABLE_THORVG_INTERNAL``: Disable the internal compilation of ThorVG. +- ``LV_CMAKE_CREATE_CONF_VARS`` (BOOLEAN) : Disable the creation of variables from ``lv_conf_internal.h`` this feature is disabled by default. + It is enabled automatically if ``LV_USE_KCONFIG`` is enabled. This feature requires a python3 interpreter with support for the *pip* and *venv* modules diff --git a/env_support/cmake/custom.cmake b/env_support/cmake/custom.cmake index f8dd3ede9d..3bc5c3f26d 100644 --- a/env_support/cmake/custom.cmake +++ b/env_support/cmake/custom.cmake @@ -14,6 +14,7 @@ find_package(Python REQUIRED) option(LV_CONF_SKIP "Skip including lv_conf.h during configuration" OFF) option(LV_USE_KCONFIG "Use Kconfig to configure LVGL" OFF) +option(LV_CMAKE_CREATE_CONF_VARS "Create variables from the options defined in lv_conf_internal.h - required for KConfig" OFF) # Option LV_CONF_PATH, which should be the path for lv_conf.h # If set parent path LV_CONF_DIR is added to includes @@ -41,10 +42,15 @@ if ( LV_USE_KCONFIG ) # and autoconf.h, which will be used by lv_conf_kconfig.h include(${CMAKE_CURRENT_LIST_DIR}/kconfig.cmake) - set(LV_KCONFIG_IGNORE OFF) + # If KConfig is used - creating CMAKE variables from lv_conf_internal.h is required, + # so PCPP is used to pre-process lv_conf_internal.h + set(LV_CMAKE_CREATE_CONF_VARS TRUE) + # Set the flag to specify we are using kconfig, needed for the # generate_cmake_variables.py script + set(LV_KCONFIG_IGNORE OFF) set(KCONFIG_FLAG --kconfig) + # If using Kconfig, we need to define additional definitions list(APPEND PCPP_DEFINITIONS_LIST "LV_CONF_SKIP" "LV_CONF_KCONFIG_EXTERNAL_INCLUDE=\"${LV_CONF_KCONFIG_EXTERNAL_INCLUDE}\"") else() @@ -75,36 +81,39 @@ target_compile_definitions( $<$:LV_CONF_SKIP> ) -# Use the portable pcpp to preprocess lv_conf_internal.h -execute_process( - COMMAND ${Python_EXECUTABLE} ${LVGL_ROOT_DIR}/scripts/preprocess_lv_conf_internal.py - --input ${LVGL_ROOT_DIR}/src/lv_conf_internal.h - --tmp_file ${CMAKE_CURRENT_BINARY_DIR}/tmp.h - --output ${CMAKE_CURRENT_BINARY_DIR}/lv_conf_expanded.h - --workfolder ${CMAKE_CURRENT_BINARY_DIR} - ${PCPP_ADDITIONAL_DEFS} - --include ${LVGL_ROOT_DIR} ${LVGL_ROOT_DIR}/.. ${LVGL_ROOT_DIR}/src ${LV_CONF_DIR} - RESULT_VARIABLE ret -) -if(NOT "${ret}" STREQUAL "0") - message(FATAL_ERROR "preprocess_lv_conf_internal.py failed with return code: ${ret}") -endif() +if ( LV_CMAKE_CREATE_CONF_VARS ) + # Use the portable pcpp to preprocess lv_conf_internal.h + execute_process( + COMMAND ${Python_EXECUTABLE} ${LVGL_ROOT_DIR}/scripts/preprocess_lv_conf_internal.py + --input ${LVGL_ROOT_DIR}/src/lv_conf_internal.h + --tmp_file ${CMAKE_CURRENT_BINARY_DIR}/tmp.h + --output ${CMAKE_CURRENT_BINARY_DIR}/lv_conf_expanded.h + --workfolder ${CMAKE_CURRENT_BINARY_DIR} + ${PCPP_ADDITIONAL_DEFS} + --include ${LVGL_ROOT_DIR} ${LVGL_ROOT_DIR}/.. ${LVGL_ROOT_DIR}/src ${LV_CONF_DIR} + RESULT_VARIABLE ret + ) + if(NOT "${ret}" STREQUAL "0") + message(FATAL_ERROR "preprocess_lv_conf_internal.py failed with return code: ${ret}") + endif() -# Convert the expanded lv_conf_expanded.h to cmake variables -execute_process( - COMMAND ${Python_EXECUTABLE} - ${LVGL_ROOT_DIR}/scripts/generate_cmake_variables.py - --input ${CMAKE_CURRENT_BINARY_DIR}/lv_conf_expanded.h - --output ${CMAKE_CURRENT_BINARY_DIR}/lv_conf.cmake - ${KCONFIG_FLAG} - RESULT_VARIABLE ret -) -if(NOT "${ret}" STREQUAL "0") - message(FATAL_ERROR "generate_cmake_variables.py command failed with return code: ${ret}") -endif() + # Convert the expanded lv_conf_expanded.h to cmake variables + execute_process( + COMMAND ${Python_EXECUTABLE} + ${LVGL_ROOT_DIR}/scripts/generate_cmake_variables.py + --input ${CMAKE_CURRENT_BINARY_DIR}/lv_conf_expanded.h + --output ${CMAKE_CURRENT_BINARY_DIR}/lv_conf.cmake + --parentscope + ${KCONFIG_FLAG} + RESULT_VARIABLE ret + ) + if(NOT "${ret}" STREQUAL "0") + message(FATAL_ERROR "generate_cmake_variables.py command failed with return code: ${ret}") + endif() -# This will set all CONFIG_LV_USE_* variables in cmake -include(${CMAKE_CURRENT_BINARY_DIR}/lv_conf.cmake) + # This will set all CONFIG_LV_USE_* variables in cmake + include(${CMAKE_CURRENT_BINARY_DIR}/lv_conf.cmake) +endif() # Add definition of LV_CONF_PATH only if needed # Do not redefine it if already defined in tests/CMakeLists.txt diff --git a/scripts/generate_cmake_variables.py b/scripts/generate_cmake_variables.py index 33a230c86c..766856f711 100755 --- a/scripts/generate_cmake_variables.py +++ b/scripts/generate_cmake_variables.py @@ -5,10 +5,12 @@ # preprocessed lv_conf_internal.h # # Author: David TRUAN (david.truan@edgemtech.ch) +# Author: Erik Tagirov (erik.tagirov@edgemtech.ch) # import os import argparse +import re def fatal(msg): print() @@ -29,6 +31,10 @@ def get_args(): parser.add_argument("--kconfig", action="store_true", help="Enable kconfig flag") + parser.add_argument("--debug", action="store_true", required=False, help="Show unhandled expressions") + + parser.add_argument("--parentscope", action="store_true", required=False, help="Additionaly set the variables in the parent scope") + args = parser.parse_args() # The input must exist @@ -37,7 +43,15 @@ def get_args(): return args -def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool): +def write_set_cmd(fout, expr, is_parent_scope): + + fout.write(f'set({expr})\n') + + # This makes the variable usable from the top level directory + if is_parent_scope == True: + fout.write(f'set({expr} PARENT_SCOPE)\n') + +def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool, debug: bool, is_parent_scope: bool): fin = open(path_input) fout = open(path_output, "w", newline='') @@ -70,7 +84,7 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool): name = name.replace("STDLIB", type) - fout.write(f'set({CONFIG_PREFIX}{name} 1)\n') + write_set_cmd(fout, f'{CONFIG_PREFIX}{name} 1', is_parent_scope) # Treat the LV_USE_OS config in a special way, as we need # to convert the define to full config with 1 value when enabled @@ -87,11 +101,12 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool): name += type - fout.write(f'set({CONFIG_PREFIX}{name} 1)\n') + write_set_cmd(fout, f'{CONFIG_PREFIX}{name} 1', is_parent_scope) - # For the rest of config, simply add CONFIG_ and write - # all LV_USE_* configs, as these are the one needed in cmake - elif line.startswith(f'{CONFIG_PATTERN}'): + # For the rest of the configs, simply add CONFIG_ and write the name of the define + # all LV_USE_* configs where the value is 0 or 1, as these are the one needed in cmake + # To detect the configuration of LVGL to perform conditional compilation/linking + elif re.search(f'{CONFIG_PATTERN}.* +[01] *$', line): parts = line.split() if len(parts) < 3: @@ -100,10 +115,16 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool): name = parts[1] value = parts[2].strip() - fout.write(f'set({CONFIG_PREFIX}{name} {value})\n') + write_set_cmd(fout, f'{CONFIG_PREFIX}{name} {value}', is_parent_scope) + + else: + # Useful for debugging expressions that are unhandled, + # if the script fails in 'unexpected ways' + if debug == True: + print(f"DBG: Skipping expression: '{line} - not handled'") if __name__ == '__main__': args = get_args() - generate_cmake_variables(args.input, args.output, args.kconfig) \ No newline at end of file + generate_cmake_variables(args.input, args.output, args.kconfig, args.debug, args.parentscope)