mirror of
https://github.com/lvgl/lvgl.git
synced 2026-02-05 21:42:20 +08:00
arch(cmake): add native Kconfig support to cmake (#7934)
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,3 +16,6 @@ build/
|
||||
.idea
|
||||
*.bak
|
||||
.vs/
|
||||
.config*
|
||||
config.h
|
||||
defconfig
|
||||
|
||||
@@ -50,6 +50,51 @@
|
||||
"cacheVariables": {
|
||||
"BUILD_SHARED_LIBS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-kconfig",
|
||||
"inherits": "linux-base",
|
||||
"displayName": "Linux/Kconfig",
|
||||
"description": "Setup WSL or native linux, using Kconfig",
|
||||
"generator": "Ninja Multi-Config",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"installDir": "${sourceDir}/build/${presetName}",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"vendor": {
|
||||
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
|
||||
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
|
||||
}
|
||||
},
|
||||
"cacheVariables": {
|
||||
"BUILD_SHARED_LIBS": "ON",
|
||||
"LV_USE_KCONFIG": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-kconfig",
|
||||
"inherits": "_base",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"installDir": "${sourceDir}/build/install/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "cl.exe",
|
||||
"CMAKE_CXX_COMPILER": "cl.exe",
|
||||
"BUILD_SHARED_LIBS": "ON",
|
||||
"LV_USE_KCONFIG": "ON"
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
|
||||
39
Kconfig
39
Kconfig
@@ -147,17 +147,6 @@ menu "LVGL configuration"
|
||||
bool "255: CUSTOM"
|
||||
endchoice
|
||||
|
||||
config LV_USE_OS
|
||||
int
|
||||
default 0 if LV_OS_NONE
|
||||
default 1 if LV_OS_PTHREAD
|
||||
default 2 if LV_OS_FREERTOS
|
||||
default 3 if LV_OS_CMSIS_RTOS2
|
||||
default 4 if LV_OS_RTTHREAD
|
||||
default 5 if LV_OS_WINDOWS
|
||||
default 6 if LV_OS_MQX
|
||||
default 255 if LV_OS_CUSTOM
|
||||
|
||||
config LV_OS_CUSTOM_INCLUDE
|
||||
string "Custom OS include header"
|
||||
default "stdint.h"
|
||||
@@ -1077,6 +1066,34 @@ menu "LVGL configuration"
|
||||
config LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
bool "Calendar week starts monday"
|
||||
depends on LV_USE_CALENDAR
|
||||
|
||||
menu "Days name configuration"
|
||||
depends on LV_USE_CALENDAR
|
||||
|
||||
config LV_MONDAY_STR
|
||||
string "Shortened string for Monday"
|
||||
default "Mo"
|
||||
config LV_TUESDAY_STR
|
||||
string "Shortened string for Tuesday"
|
||||
default "Tu"
|
||||
config LV_WEDNESDAY_STR
|
||||
string "Shortened string for Wednesday"
|
||||
default "We"
|
||||
config LV_THURSDAY_STR
|
||||
string "Shortened string for Thursday"
|
||||
default "Th"
|
||||
config LV_FRIDAY_STR
|
||||
string "Shortened string for Friday"
|
||||
default "Fr"
|
||||
config LV_SATURDAY_STR
|
||||
string "Shortened string for Saturday"
|
||||
default "Sa"
|
||||
config LV_SUNDAY_STR
|
||||
string "Shortened string for Sunday"
|
||||
default "Su"
|
||||
|
||||
endmenu
|
||||
|
||||
config LV_USE_CALENDAR_HEADER_ARROW
|
||||
bool "Use calendar header arrow"
|
||||
depends on LV_USE_CALENDAR
|
||||
|
||||
1
configs/defconfigs/minimal_defconfig
Normal file
1
configs/defconfigs/minimal_defconfig
Normal file
@@ -0,0 +1 @@
|
||||
CONFIG_LV_CONF_MINIMAL=y
|
||||
@@ -19,7 +19,7 @@ main Makefile:
|
||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/lvgl.mk
|
||||
|
||||
For integration with CMake take a look this section of the
|
||||
:ref:`Documentation <build_cmake>`.
|
||||
:ref:`Documentation <integrating_lvgl_cmake>`.
|
||||
|
||||
|
||||
Managed builds
|
||||
|
||||
@@ -46,12 +46,6 @@ options. For example ``"-DLV_COLOR_DEPTH=32 -DLV_USE_BUTTON=1"``. Unset
|
||||
options will get a default value which is the same as the content of
|
||||
``lv_conf_template.h``.
|
||||
|
||||
LVGL also can be used via ``Kconfig`` and ``menuconfig``. You can use
|
||||
``lv_conf.h`` together with Kconfig as well, but keep in mind that the values
|
||||
from ``lv_conf.h`` or build settings (``-D...``) override the values
|
||||
set in Kconfig. To ignore the configs from ``lv_conf.h`` simply remove
|
||||
its content, or define :c:macro:`LV_CONF_SKIP`.
|
||||
|
||||
|
||||
.. _configuration_settings:
|
||||
|
||||
@@ -91,5 +85,70 @@ For example:
|
||||
|
||||
Kconfig
|
||||
*******
|
||||
TODO: Add how to use LVGL with Kconfig.
|
||||
LVGL can also be configured using Kconfig. For now, this is only available using cmake.
|
||||
Under the hood, it uses ``kconfiglib`` Kconfig python port to be able to use it across different platforms.
|
||||
The ``kconfiglib`` offers the python API and some CLI commands. Here is a list of some useful commands:
|
||||
|
||||
- ``menuconfig``: Opens a console menu interface to modify the configuration values.
|
||||
- ``guiconfig`` (needs ``tkinter``): Opens a graphical interface to modify the configuration values.
|
||||
- ``savedefconfig``: Saves the current .config as a defconfig, listing only non-default values.
|
||||
- ``alldefconfig``: Creates a .config with all default values.
|
||||
- ``genconfig``: Generates a C header from the config, following ``autoconf.h`` format.
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Install the prerequisites using ``scripts/install_prerequisites.sh/bat``.
|
||||
|
||||
|
||||
Create the configuration (.config)
|
||||
----------------------------------
|
||||
|
||||
At this point, the ``menuconfig`` command should be available:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd <lvgl_repo>
|
||||
menuconfig
|
||||
|
||||
Make changes to the config and exit using `Esc` or `Q`, and save your configuration. The ``.config`` file is
|
||||
now created and list the configuration values.
|
||||
|
||||
|
||||
Configuring with cmake
|
||||
----------------------
|
||||
|
||||
Once the ``.config`` is created, run cmake with the ``-DLV_USE_KCONFIG=ON`` flag:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd <lvgl_repo>
|
||||
cmake -B build -DLV_USE_KCONFIG=ON
|
||||
cmake --build build
|
||||
|
||||
To use a ``defconfig`` file, one can use the ``-DLV_DEFCONFIG_PATH=<path_to_defconfig>`` flag:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd <lvgl_repo>
|
||||
cmake -B build -DLV_USE_KCONFIG=ON -DLV_DEFCONFIG_PATH=<path_to_defconfig>
|
||||
cmake --build build
|
||||
|
||||
Some defconfigs are available in ``configs/defconfigs`` folder.
|
||||
|
||||
|
||||
Saving a defconfig
|
||||
------------------
|
||||
|
||||
One can save a defconfig using the ``savedefconfig`` command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd <lvgl_repo>
|
||||
menuconfig # make your changes to the default config
|
||||
savedefconfig
|
||||
cp defconfig configs/defconfigs/my_custom_defconfig # save it where you want
|
||||
# Then use it to build LVGL
|
||||
cmake -B build -DLV_USE_KCONFIG=ON -DLV_DEFCONFIG_PATH=configs/defconfigs/my_custom_defconfig
|
||||
cmake --build build
|
||||
|
||||
@@ -7,6 +7,12 @@ CMake
|
||||
|
||||
Overview
|
||||
********
|
||||
CMake is a cross-platform build system generator. It is used to easily integrate a project/library into another project.
|
||||
It also offer the possibility to configure the build with different options, to enable or disable components, or to
|
||||
integrate custom scripts executions during the configuration/build phase.
|
||||
|
||||
LVGL includes CMake natively, which means that one can use it to configure and build LVGL directly or integrate it into an higher
|
||||
level cmake build.
|
||||
|
||||
This project uses CMakePresets to ensure an easy build.
|
||||
Find out more on Cmake Presets here: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
|
||||
@@ -19,22 +25,67 @@ 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``
|
||||
|
||||
|
||||
How to build this project using cmake
|
||||
-------------------------------------
|
||||
|
||||
The recommended way to build this project is to use the provided CMakePresets.json. This file contains 2 configurations
|
||||
|
||||
- a windows (msvc) build using Visual Studio
|
||||
- a linux (gcc) build using Ninja
|
||||
Build with Command line
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The simplest way to build LVGL using cmake is to use the command line calls:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Method 1
|
||||
cd <lvgl_repo>
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. # Configure phase
|
||||
cmake --build . # Build phase
|
||||
|
||||
# Method 2
|
||||
cd <lvgl_repo>
|
||||
cmake -B build # Configure phase
|
||||
cmake --build build # build phase
|
||||
|
||||
|
||||
More configurations will be added once available.
|
||||
Build with cmake presets
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Another way to build this project is to use the provided CMakePresets.json or passing option using the command line.
|
||||
The CMakePresets.json file describes some cmake configurations and build phase. It is a way to quickly use a set of
|
||||
predefined cmake options.
|
||||
|
||||
For now, these configuration presets are available:
|
||||
|
||||
- ``windows-base``: A Windows configuration, using VS MSVC. Uses ``lv_conf.h`` as the configuration system.
|
||||
- ``windows-kconfig``: A Windows configuration, using VS MSVC. Uses Kconfig as the configuration system.
|
||||
- ``linux-base``: A Linux configuration, using Ninja and GCC. Uses ``lv_conf.h`` as the configuration system.
|
||||
- ``linux-kconfig``: A Linux configuration, using Ninja and GCC. Uses Kconfig as the configuration system.
|
||||
|
||||
|
||||
And these build presets:
|
||||
|
||||
- ``windows-base_dbg``: Windows Debug build.
|
||||
- ``windows-base_rel``: Windows Release build.
|
||||
- ``linux-base_dbg``: Linux Debug build.
|
||||
- ``linux-base_rel``: Linux Release build.
|
||||
|
||||
|
||||
Here is how to build using the presets:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cmake --preset windows-base
|
||||
cmake --build --preset windows-base_dbg
|
||||
ctest --preset windows-base_dbg
|
||||
|
||||
|
||||
Build with IDE
|
||||
--------------
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The recommend way for consuming CMakePresets is a CMakePresets aware IDE such as
|
||||
|
||||
@@ -47,7 +98,7 @@ Simply load this project into your IDE and select your desired preset and you ar
|
||||
|
||||
|
||||
Build with CMake GUI
|
||||
--------------------
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Open this project with CMake GUI and select your desired preset. When hitting the generate button,
|
||||
CMake will create solution files (for VS) or Ninja Files (for Linux Ninja Build)
|
||||
@@ -61,20 +112,75 @@ The following targets are available.
|
||||
|
||||
|
||||
All optional targets can be disabled by setting the proper cache variables.
|
||||
If you use cmake to install lvgl 3 folders will be created.
|
||||
If you use cmake to install lvgl, 3 folders will be created.
|
||||
|
||||
- include/lvgl (contains all public headers)
|
||||
- bin (contains all binaries (\*.dll))
|
||||
- lib (contains all precompiled source files (\*.lib))
|
||||
|
||||
|
||||
Build with Command line
|
||||
-----------------------
|
||||
.. _integrating_lvgl_cmake:
|
||||
|
||||
You can also build your project using the command line. Run the following commands
|
||||
Integrate LVGL to your project using cmake
|
||||
------------------------------------------
|
||||
|
||||
- ``cmake --preset windows-base``
|
||||
- ``cmake --build --preset windows-base_dbg``
|
||||
- ``ctest --preset windows-base_dbg``
|
||||
The LVGL cmake system is made to be integrated into higher level projects. To do so, simply add this to your
|
||||
project's ``CMakeLists.txt``.
|
||||
|
||||
This snippet adds LVGL and needs an ``lv_conf.h`` file present next to the lvgl folder:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
set(LV_CONF_INCLUDE_SIMPLE OFF)
|
||||
add_subdirectory(lvgl)
|
||||
|
||||
|
||||
This snippet adds LVGL and needs an ``lv_conf.h`` file present in lvgl/src folder:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
add_subdirectory(lvgl)
|
||||
|
||||
|
||||
This snippet adds LVGL and specify a ``lv_conf.h`` to use:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
set(LV_CONF_PATH path/to/my_lv_conf.h)
|
||||
add_subdirectory(lvgl)
|
||||
|
||||
|
||||
This snippet adds LVGL and specify to use Kconfig as the configuration system:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
set(LV_USE_KCONFIG ON)
|
||||
add_subdirectory(lvgl)
|
||||
|
||||
This snippet adds LVGL and specify to use Kconfig as the configuration system and to use a specific defconfig:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
set(LV_USE_KCONFIG ON)
|
||||
set(LV_DEFCONFIG_PATH path/to/my_defconfig)
|
||||
add_subdirectory(lvgl)
|
||||
|
||||
|
||||
To disable the demo/example set these options:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
set(LV_CONF_BUILD_DISABLE_EXAMPLES ON)
|
||||
set(LV_CONF_BUILD_DISABLE_DEMOS ON)
|
||||
add_subdirectory(lvgl)
|
||||
|
||||
|
||||
These cmake options are available to configure LVGL:
|
||||
|
||||
- ``LV_CONF_PATH`` (STRING): Specify a custom path for ``lv_conf.h``.
|
||||
- ``LV_CONF_INCLUDE_SIMPLE`` (BOOLEAN): Use ``#include "lv_conf.h"`` instead of ``#include "../../lv_conf.h"``
|
||||
- ``LV_USE_KCONFIG`` (BOOLEAN): Use Kconfig as the configuration source.
|
||||
- ``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.
|
||||
@@ -8,6 +8,13 @@ option(LV_LVGL_H_INCLUDE_SIMPLE
|
||||
option(LV_CONF_INCLUDE_SIMPLE
|
||||
"Use #include \"lv_conf.h\" instead of #include \"../../lv_conf.h\"" ON)
|
||||
|
||||
set(LV_KCONFIG_IGNORE "Don't use Kconfig. Kconfig is not used by default." ON)
|
||||
|
||||
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_CONF_PATH, which should be the path for lv_conf.h
|
||||
# If set parent path LV_CONF_DIR is added to includes
|
||||
if( LV_CONF_PATH )
|
||||
@@ -27,12 +34,63 @@ file(GLOB_RECURSE THORVG_SOURCES ${LVGL_ROOT_DIR}/src/libs/thorvg/*.cpp ${LVGL_R
|
||||
add_library(lvgl ${SOURCES})
|
||||
add_library(lvgl::lvgl ALIAS lvgl)
|
||||
|
||||
if ( LV_USE_KCONFIG )
|
||||
# kconfig.cmake will generate the .config
|
||||
# and autoconf.h, which will be used by lv_conf_kconfig.h
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/kconfig.cmake)
|
||||
|
||||
set(LV_KCONFIG_IGNORE OFF)
|
||||
# Set the flag to specify we are using kconfig, needed for the
|
||||
# generate_cmake_variables.py script
|
||||
set(KCONFIG_FLAG --kconfig)
|
||||
# If using Kconfig, we need to define additional definitions
|
||||
set(PCPP_ADDITIONAL_DEFS "--defs" "LV_CONF_SKIP" "LV_CONF_KCONFIG_EXTERNAL_INCLUDE=\"${LV_CONF_KCONFIG_EXTERNAL_INCLUDE}\"")
|
||||
else()
|
||||
if (LV_CONF_PATH)
|
||||
set(PCPP_ADDITIONAL_DEFS "--defs" "LV_CONF_PATH=\"${LV_CONF_PATH}\"")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(
|
||||
lvgl PUBLIC $<$<BOOL:${LV_LVGL_H_INCLUDE_SIMPLE}>:LV_LVGL_H_INCLUDE_SIMPLE>
|
||||
$<$<BOOL:${LV_CONF_INCLUDE_SIMPLE}>:LV_CONF_INCLUDE_SIMPLE>)
|
||||
$<$<BOOL:${LV_CONF_INCLUDE_SIMPLE}>:LV_CONF_INCLUDE_SIMPLE>
|
||||
$<$<BOOL:${LV_KCONFIG_IGNORE}>:LV_KCONFIG_IGNORE>
|
||||
$<$<BOOL:${LV_CONF_SKIP}>: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
|
||||
${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()
|
||||
|
||||
# This will set all CONFIG_LV_USE_* variables in cmake
|
||||
include(${CMAKE_BINARY_DIR}/lv_conf.cmake)
|
||||
|
||||
# Add definition of LV_CONF_PATH only if needed
|
||||
if(LV_CONF_PATH)
|
||||
# Do not redefine it if already defined in tests/CMakeLists.txt
|
||||
if(LV_CONF_PATH AND NOT LV_BUILD_TEST)
|
||||
target_compile_definitions(lvgl PUBLIC LV_CONF_PATH=${LV_CONF_PATH})
|
||||
endif()
|
||||
|
||||
|
||||
42
env_support/cmake/kconfig.cmake
Normal file
42
env_support/cmake/kconfig.cmake
Normal file
@@ -0,0 +1,42 @@
|
||||
set(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(KCONFIG_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/Kconfig)
|
||||
set(AUTOCONF_H ${CMAKE_CURRENT_BINARY_DIR}/autoconf.h)
|
||||
set(OUTPUT_DOTCONFIG ${CMAKE_CURRENT_SOURCE_DIR}/.config)
|
||||
set(KCONFIG_LIST_OUT ${CMAKE_CURRENT_BINARY_DIR}/kconfig_list)
|
||||
set(AUTO_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Check if the user want to use a defconfig, using the -DLV_DEFCONFIG_PATH option
|
||||
if(LV_DEFCONFIG_PATH)
|
||||
set(DOTCONFIG ${LV_DEFCONFIG_PATH})
|
||||
else()
|
||||
set(DOTCONFIG ${CMAKE_CURRENT_SOURCE_DIR}/.config)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${Python_EXECUTABLE}
|
||||
${LVGL_ROOT_DIR}/scripts/kconfig.py
|
||||
${LVGL_ROOT_DIR}/Kconfig
|
||||
${OUTPUT_DOTCONFIG}
|
||||
${AUTOCONF_H}
|
||||
${KCONFIG_LIST_OUT}
|
||||
${DOTCONFIG}
|
||||
WORKING_DIRECTORY ${LVGL_ROOT_DIR}
|
||||
# The working directory is set to the app dir such that the user
|
||||
# can use relative paths in CONF_FILE, e.g. CONF_FILE=nrf5.conf
|
||||
RESULT_VARIABLE ret
|
||||
)
|
||||
if(NOT "${ret}" STREQUAL "0")
|
||||
message(FATAL_ERROR "command failed with return code: ${ret}")
|
||||
endif()
|
||||
|
||||
# Re-configure (Re-execute all CMakeLists.txt code) when autoconf.h changes
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${AUTOCONF_H})
|
||||
|
||||
# Set compile definitions for lvgl build
|
||||
add_compile_definitions(LV_CONF_KCONFIG_EXTERNAL_INCLUDE="${AUTOCONF_H}")
|
||||
# Set the variable that can be used by the CMakeLists.txt including this file
|
||||
set(LV_CONF_KCONFIG_EXTERNAL_INCLUDE "${AUTOCONF_H}")
|
||||
|
||||
# Ensure LV_DEFCONFIG_PATH is not set in the path, to be able to call it without
|
||||
# the -DLV_DEFCONFIG_PATH after the first configuration, and to work with the .config
|
||||
unset(LV_DEFCONFIG_PATH CACHE)
|
||||
@@ -1247,7 +1247,11 @@
|
||||
#define LV_USE_ST7796 0
|
||||
#define LV_USE_ILI9341 0
|
||||
|
||||
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
#define LV_USE_GENERIC_MIPI 1
|
||||
#else
|
||||
#define LV_USE_GENERIC_MIPI 0
|
||||
#endif
|
||||
|
||||
/** Driver for Renesas GLCD */
|
||||
#define LV_USE_RENESAS_GLCDC 0
|
||||
|
||||
109
scripts/generate_cmake_variables.py
Executable file
109
scripts/generate_cmake_variables.py
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Generate the cmake variables CONFIG_LV_USE_* from the
|
||||
# preprocessed lv_conf_internal.h
|
||||
#
|
||||
# Author: David TRUAN (david.truan@edgemtech.ch)
|
||||
#
|
||||
|
||||
import os
|
||||
import argparse
|
||||
|
||||
def fatal(msg):
|
||||
print()
|
||||
print("ERROR! " + msg)
|
||||
exit(1)
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description=""
|
||||
"Convert the expanded lv_conf_internal.h to cmake variables."
|
||||
"It converts all LV_USE_* configurations."
|
||||
)
|
||||
|
||||
parser.add_argument('--input', type=str, required=True, nargs='?',
|
||||
help='Path of the macro expanded lv_conf_internal.h, which should be generated during a cmake build')
|
||||
|
||||
parser.add_argument('--output', type=str, required=True, nargs='?',
|
||||
help='Path of the output file, where the cmake variables declaration will be written (ex: build/lv_conf.cmake)')
|
||||
|
||||
parser.add_argument("--kconfig", action="store_true", help="Enable kconfig flag")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# The input must exist
|
||||
if not os.path.exists(args.input):
|
||||
fatal(f"Input {args.input} not found")
|
||||
|
||||
return args
|
||||
|
||||
def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool):
|
||||
fin = open(path_input)
|
||||
fout = open(path_output, "w", newline='')
|
||||
|
||||
# If we use Kconfig, we must check the CONFIG_LV_USE_* defines
|
||||
if kconfig:
|
||||
CONFIG_PATTERN="#define CONFIG_LV_USE"
|
||||
CONFIG_PREFIX=""
|
||||
# Otherwise check the LV_USE_* defines
|
||||
else:
|
||||
CONFIG_PATTERN="#define LV_USE"
|
||||
CONFIG_PREFIX="CONFIG_"
|
||||
|
||||
|
||||
# Using the expanded lv_conf_internal, we don't have to deal with regexp,
|
||||
# as all the #define will be aligned on the left with a single space before the value
|
||||
for line in fin.read().splitlines():
|
||||
|
||||
# Treat the LV_USE_STDLIB_* configs in a special way, as we need
|
||||
# to convert the define to full config with 1 value when enabled
|
||||
if line.startswith(f'{CONFIG_PATTERN}_STDLIB'):
|
||||
|
||||
parts = line.split()
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
|
||||
name = parts[1]
|
||||
value = parts[2].strip()
|
||||
|
||||
type = value.split("LV_STDLIB_")[1]
|
||||
|
||||
name = name.replace("STDLIB", type)
|
||||
|
||||
fout.write(f'set({CONFIG_PREFIX}{name} 1)\n')
|
||||
|
||||
# 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
|
||||
if line.startswith(f'{CONFIG_PATTERN}_OS'):
|
||||
|
||||
parts = line.split()
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
|
||||
name = parts[1]
|
||||
value = parts[2].strip()
|
||||
|
||||
type = value.split("LV_OS")[1]
|
||||
|
||||
name += type
|
||||
|
||||
fout.write(f'set({CONFIG_PREFIX}{name} 1)\n')
|
||||
|
||||
# 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}'):
|
||||
|
||||
parts = line.split()
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
|
||||
name = parts[1]
|
||||
value = parts[2].strip()
|
||||
|
||||
fout.write(f'set({CONFIG_PREFIX}{name} {value})\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = get_args()
|
||||
|
||||
generate_cmake_variables(args.input, args.output, args.kconfig)
|
||||
@@ -1,4 +1,4 @@
|
||||
vcpkg install vcpkg-tool-ninja libpng freetype opengl glfw3 glew
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
pip install pypng lz4 kconfiglib
|
||||
pip install pypng lz4 kconfiglib pcpp
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
@@ -14,4 +14,4 @@ sudo apt install gcc gcc-multilib g++-multilib ninja-build \
|
||||
ruby-full gcovr cmake python3 libinput-dev libxkbcommon-dev \
|
||||
libdrm-dev pkg-config wayland-protocols libwayland-dev libwayland-bin \
|
||||
libwayland-dev:i386 libxkbcommon-dev:i386 libudev-dev
|
||||
pip3 install pypng lz4 kconfiglib
|
||||
pip3 install pypng lz4 kconfiglib pcpp
|
||||
|
||||
346
scripts/kconfig.py
Executable file
346
scripts/kconfig.py
Executable file
@@ -0,0 +1,346 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Originally modified from:
|
||||
# https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/kconfig/kconfig.py
|
||||
|
||||
# SPDX-License-Identifier: ISC
|
||||
|
||||
# Writes/updates the lvgl/.config configuration file by merging configuration
|
||||
# files passed as arguments
|
||||
#
|
||||
# When fragments haven't changed, lvgl/.config is both the input and the
|
||||
# output, which just updates it. This is handled in the CMake files.
|
||||
#
|
||||
# Also does various checks (most via Kconfiglib warnings).
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
# Lvgl doesn't use tristate symbols. They're supported here just to make the
|
||||
# script a bit more generic.
|
||||
from kconfiglib import (
|
||||
Kconfig,
|
||||
split_expr,
|
||||
expr_value,
|
||||
expr_str,
|
||||
BOOL,
|
||||
TRISTATE,
|
||||
TRI_TO_STR,
|
||||
AND,
|
||||
OR,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
print(sys.argv)
|
||||
args = parse_args()
|
||||
|
||||
print("Parsing " + args.kconfig_file)
|
||||
kconf = Kconfig(args.kconfig_file, warn_to_stderr=False, suppress_traceback=True)
|
||||
|
||||
if args.handwritten_input_configs:
|
||||
# Warn for assignments to undefined symbols, but only for handwritten
|
||||
# fragments, to avoid warnings-turned-errors when using an old
|
||||
# configuration file together with updated Kconfig files
|
||||
kconf.warn_assign_undef = True
|
||||
|
||||
# prj.conf may override settings from the board configuration, so
|
||||
# disable warnings about symbols being assigned more than once
|
||||
kconf.warn_assign_override = False
|
||||
kconf.warn_assign_redun = False
|
||||
|
||||
if args.forced_input_configs:
|
||||
# Do not warn on a redundant config.
|
||||
# The reason is that a regular .config will be followed by the forced
|
||||
# config which under normal circumstances should be identical to the
|
||||
# configured setting.
|
||||
# Only if user has modified to a value that gets overruled by the forced
|
||||
# a warning shall be issued.
|
||||
kconf.warn_assign_redun = False
|
||||
|
||||
# Load files
|
||||
print(kconf.load_config(args.configs_in[0]))
|
||||
for config in args.configs_in[1:]:
|
||||
# replace=False creates a merged configuration
|
||||
print(kconf.load_config(config, replace=False))
|
||||
|
||||
if args.handwritten_input_configs:
|
||||
# Check that there are no assignments to promptless symbols, which
|
||||
# have no effect.
|
||||
#
|
||||
# This only makes sense when loading handwritten fragments and not when
|
||||
# loading lvgl/.config, because lvgl/.config is configuration
|
||||
# output and also assigns promptless symbols.
|
||||
check_no_promptless_assign(kconf)
|
||||
|
||||
# Print warnings for symbols that didn't get the assigned value. Only
|
||||
# do this for handwritten input too, to avoid likely unhelpful warnings
|
||||
# when using an old configuration and updating Kconfig files.
|
||||
check_assigned_sym_values(kconf)
|
||||
check_assigned_choice_values(kconf)
|
||||
|
||||
if kconf.syms.get("WARN_DEPRECATED", kconf.y).tri_value == 2:
|
||||
check_deprecated(kconf)
|
||||
|
||||
if kconf.syms.get("WARN_EXPERIMENTAL", kconf.y).tri_value == 2:
|
||||
check_experimental(kconf)
|
||||
|
||||
# Hack: Force all symbols to be evaluated, to catch warnings generated
|
||||
# during evaluation. Wait till the end to write the actual output files, so
|
||||
# that we don't generate any output if there are warnings-turned-errors.
|
||||
#
|
||||
# Kconfiglib caches calculated symbol values internally, so this is still
|
||||
# fast.
|
||||
kconf.write_config(os.devnull)
|
||||
|
||||
warn_only = r"warning:.*set more than once."
|
||||
|
||||
if kconf.warnings:
|
||||
if args.forced_input_configs:
|
||||
error_out = False
|
||||
else:
|
||||
error_out = True
|
||||
|
||||
# Put a blank line between warnings to make them easier to read
|
||||
for warning in kconf.warnings:
|
||||
print("\n" + warning, file=sys.stderr)
|
||||
|
||||
if not error_out and not re.search(warn_only, warning):
|
||||
# The warning is not a warn_only, fail the Kconfig.
|
||||
error_out = True
|
||||
|
||||
# Turn all warnings into errors, so that e.g. assignments to undefined
|
||||
# Kconfig symbols become errors.
|
||||
#
|
||||
# A warning is generated by this script whenever a symbol gets a
|
||||
# different value than the one it was assigned. Keep that one as just a
|
||||
# warning for now.
|
||||
if error_out:
|
||||
err("Aborting due to Kconfig warnings")
|
||||
|
||||
# Write the merged configuration and the C header
|
||||
print(kconf.write_config(args.config_out))
|
||||
print(kconf.write_autoconf(args.header_out))
|
||||
|
||||
# Write the list of parsed Kconfig files to a file
|
||||
write_kconfig_filenames(kconf, args.kconfig_list_out)
|
||||
|
||||
|
||||
def check_no_promptless_assign(kconf):
|
||||
# Checks that no promptless symbols are assigned
|
||||
|
||||
for sym in kconf.unique_defined_syms:
|
||||
if sym.user_value is not None and promptless(sym):
|
||||
err(
|
||||
f"""\
|
||||
{sym.name_and_loc} is assigned in a configuration file, but is not directly
|
||||
user-configurable (has no prompt). It gets its value indirectly from other
|
||||
symbols. """
|
||||
+ SYM_INFO_HINT.format(sym)
|
||||
)
|
||||
|
||||
|
||||
def check_assigned_sym_values(kconf):
|
||||
# Verifies that the values assigned to symbols "took" (matches the value
|
||||
# the symbols actually got), printing warnings otherwise. Choice symbols
|
||||
# are checked separately, in check_assigned_choice_values().
|
||||
|
||||
for sym in kconf.unique_defined_syms:
|
||||
if sym.choice:
|
||||
continue
|
||||
|
||||
user_value = sym.user_value
|
||||
if user_value is None:
|
||||
continue
|
||||
|
||||
# Tristate values are represented as 0, 1, 2. Having them as "n", "m",
|
||||
# "y" is more convenient here, so convert.
|
||||
if sym.type in (BOOL, TRISTATE):
|
||||
user_value = TRI_TO_STR[user_value]
|
||||
|
||||
if user_value != sym.str_value:
|
||||
msg = (
|
||||
f"{sym.name_and_loc} was assigned the value '{user_value}'"
|
||||
f" but got the value '{sym.str_value}'. "
|
||||
)
|
||||
|
||||
# List any unsatisfied 'depends on' dependencies in the warning
|
||||
mdeps = missing_deps(sym)
|
||||
if mdeps:
|
||||
expr_strs = []
|
||||
for expr in mdeps:
|
||||
estr = expr_str(expr)
|
||||
if isinstance(expr, tuple):
|
||||
# Add () around dependencies that aren't plain symbols.
|
||||
# Gives '(FOO || BAR) (=n)' instead of
|
||||
# 'FOO || BAR (=n)', which might be clearer.
|
||||
estr = f"({estr})"
|
||||
expr_strs.append(f"{estr} " f"(={TRI_TO_STR[expr_value(expr)]})")
|
||||
|
||||
msg += (
|
||||
"Check these unsatisfied dependencies: "
|
||||
+ ", ".join(expr_strs)
|
||||
+ ". "
|
||||
)
|
||||
|
||||
warn(msg + SYM_INFO_HINT.format(sym))
|
||||
|
||||
|
||||
def missing_deps(sym):
|
||||
# check_assigned_sym_values() helper for finding unsatisfied dependencies.
|
||||
#
|
||||
# Given direct dependencies
|
||||
#
|
||||
# depends on <expr> && <expr> && ... && <expr>
|
||||
#
|
||||
# on 'sym' (which can also come from e.g. a surrounding 'if'), returns a
|
||||
# list of all <expr>s with a value less than the value 'sym' was assigned
|
||||
# ("less" instead of "not equal" just to be general and handle tristates,
|
||||
# even though lvgl doesn't use them).
|
||||
#
|
||||
# For string/int/hex symbols, just looks for <expr> = n.
|
||||
#
|
||||
# Note that <expr>s can be something more complicated than just a symbol,
|
||||
# like 'FOO || BAR' or 'FOO = "string"'.
|
||||
|
||||
deps = split_expr(sym.direct_dep, AND)
|
||||
|
||||
if sym.type in (BOOL, TRISTATE):
|
||||
return [dep for dep in deps if expr_value(dep) < sym.user_value]
|
||||
# string/int/hex
|
||||
return [dep for dep in deps if expr_value(dep) == 0]
|
||||
|
||||
|
||||
def check_assigned_choice_values(kconf):
|
||||
# Verifies that any choice symbols that were selected (by setting them to
|
||||
# y) ended up as the selection, printing warnings otherwise.
|
||||
#
|
||||
# We check choice symbols separately to avoid warnings when two different
|
||||
# choice symbols within the same choice are set to y. This might happen if
|
||||
# a choice selection from a board defconfig is overridden in a prj.conf,
|
||||
# for example. The last choice symbol set to y becomes the selection (and
|
||||
# all other choice symbols get the value n).
|
||||
#
|
||||
# Without special-casing choices, we'd detect that the first symbol set to
|
||||
# y ended up as n, and print a spurious warning.
|
||||
|
||||
for choice in kconf.unique_choices:
|
||||
if choice.user_selection and choice.user_selection is not choice.selection:
|
||||
|
||||
warn(
|
||||
f"""\
|
||||
The choice symbol {choice.user_selection.name_and_loc} was selected (set =y),
|
||||
but {choice.selection.name_and_loc if choice.selection else "no symbol"} ended
|
||||
up as the choice selection. """
|
||||
+ SYM_INFO_HINT.format(choice.user_selection)
|
||||
)
|
||||
|
||||
|
||||
# Hint on where to find symbol information. Used like
|
||||
# SYM_INFO_HINT.format(sym).
|
||||
SYM_INFO_HINT = """\
|
||||
See https://docs.lvgl.io/master/intro/add-lvgl-to-your-project/configuration.html
|
||||
look up {0.name} in the menuconfig/guiconfig interface. The Application
|
||||
Development Primer, Setting Configuration Values, and Kconfig - Tips and Best
|
||||
Practices sections of the manual might be helpful too.\
|
||||
"""
|
||||
|
||||
|
||||
def check_deprecated(kconf):
|
||||
deprecated = kconf.syms.get("DEPRECATED")
|
||||
dep_expr = kconf.n if deprecated is None else deprecated.rev_dep
|
||||
|
||||
if dep_expr is not kconf.n:
|
||||
selectors = [s for s in split_expr(dep_expr, OR) if expr_value(s) == 2]
|
||||
for selector in selectors:
|
||||
selector_name = split_expr(selector, AND)[0].name
|
||||
warn(f"Deprecated symbol {selector_name} is enabled.")
|
||||
|
||||
|
||||
def check_experimental(kconf):
|
||||
experimental = kconf.syms.get("EXPERIMENTAL")
|
||||
dep_expr = kconf.n if experimental is None else experimental.rev_dep
|
||||
|
||||
if dep_expr is not kconf.n:
|
||||
selectors = [s for s in split_expr(dep_expr, OR) if expr_value(s) == 2]
|
||||
for selector in selectors:
|
||||
selector_name = split_expr(selector, AND)[0].name
|
||||
warn(f"Experimental symbol {selector_name} is enabled.")
|
||||
|
||||
|
||||
def promptless(sym):
|
||||
# Returns True if 'sym' has no prompt. Since the symbol might be defined in
|
||||
# multiple locations, we need to check all locations.
|
||||
|
||||
return not any(node.prompt for node in sym.nodes)
|
||||
|
||||
|
||||
def write_kconfig_filenames(kconf, kconfig_list_path):
|
||||
# Writes a sorted list with the absolute paths of all parsed Kconfig files
|
||||
# to 'kconfig_list_path'. The paths are realpath()'d, and duplicates are
|
||||
# removed. This file is used by CMake to look for changed Kconfig files. It
|
||||
# needs to be deterministic.
|
||||
|
||||
with open(kconfig_list_path, "w") as out:
|
||||
for path in sorted(
|
||||
{
|
||||
os.path.realpath(os.path.join(kconf.srctree, path))
|
||||
for path in kconf.kconfig_filenames
|
||||
}
|
||||
):
|
||||
print(path, file=out)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False)
|
||||
|
||||
parser.add_argument(
|
||||
"--handwritten-input-configs",
|
||||
action="store_true",
|
||||
help="Assume the input configuration fragments are "
|
||||
"handwritten fragments and do additional checks "
|
||||
"on them, like no promptless symbols being "
|
||||
"assigned",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--forced-input-configs",
|
||||
action="store_true",
|
||||
help="Indicate the input configuration files are "
|
||||
"followed by an forced configuration file."
|
||||
"The forced configuration is used to forcefully "
|
||||
"set specific configuration settings to a "
|
||||
"pre-defined value and thereby remove any user "
|
||||
" adjustments.",
|
||||
)
|
||||
parser.add_argument("kconfig_file", help="Top-level Kconfig file")
|
||||
parser.add_argument("config_out", help="Output configuration file")
|
||||
parser.add_argument("header_out", help="Output header file")
|
||||
parser.add_argument(
|
||||
"kconfig_list_out", help="Output file for list of parsed Kconfig files"
|
||||
)
|
||||
parser.add_argument(
|
||||
"configs_in",
|
||||
nargs="+",
|
||||
help="Input configuration fragments. Will be merged " "together.",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def warn(msg):
|
||||
# Use a large fill() width to try to avoid linebreaks in the symbol
|
||||
# reference link, and add some extra newlines to set the message off from
|
||||
# surrounding text (this usually gets printed as part of spammy CMake
|
||||
# output)
|
||||
print("\n" + textwrap.fill("warning: " + msg, 100) + "\n", file=sys.stderr)
|
||||
|
||||
|
||||
def err(msg):
|
||||
sys.exit("\n" + textwrap.fill("error: " + msg, 100) + "\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -214,12 +214,21 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#endif /*LV_USE_SYSMON*/
|
||||
|
||||
|
||||
#ifndef LV_USE_LZ4
|
||||
#define LV_USE_LZ4 (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
|
||||
#if (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
|
||||
#define LV_USE_LZ4 1
|
||||
#else
|
||||
#define LV_USE_LZ4 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_USE_THORVG
|
||||
#define LV_USE_THORVG (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL)
|
||||
#if (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL)
|
||||
#define LV_USE_THORVG 1
|
||||
#else
|
||||
#define LV_USE_THORVG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LV_USE_OS
|
||||
|
||||
96
scripts/preprocess_lv_conf_internal.py
Executable file
96
scripts/preprocess_lv_conf_internal.py
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Preprocess the lv_conf_internal.h to generate a header file
|
||||
# containing the evaluated definitions. This output will be used to
|
||||
# generate the cmake variables
|
||||
#
|
||||
# Author: David TRUAN (david.truan@edgemtech.ch)
|
||||
#
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description="Preprocess a C header file and remove indentation.")
|
||||
parser.add_argument("--input", help="Path to the input C header file", required=True)
|
||||
parser.add_argument("--tmp_file", help="Path to save the preprocessed output", required=True)
|
||||
parser.add_argument("--output", help="Path to save the cleaned output with removed indentation", required=True)
|
||||
|
||||
parser.add_argument(
|
||||
"--defs",
|
||||
nargs='+',
|
||||
default=[],
|
||||
help="Definitions to be added to pcpp (flag -D)"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--include",
|
||||
nargs='+',
|
||||
default=[],
|
||||
help="Paths to include directories for the preprocessor (flag -I)"
|
||||
)
|
||||
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def preprocess_file(input_file, tmp_file, output_file, include_dirs, defs):
|
||||
|
||||
try:
|
||||
pcpp_command = ["pcpp", "-o", tmp_file, "--passthru-defines", "--line-directive=", input_file]
|
||||
|
||||
for include_path in include_dirs:
|
||||
pcpp_command.append(f"-I{include_path}")
|
||||
|
||||
for definition in defs:
|
||||
pcpp_command.append(f"-D{definition}")
|
||||
|
||||
subprocess.run(pcpp_command, check=True)
|
||||
print(f"Preprocessing completed. Output saved to {tmp_file}")
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error during preprocessing: {e}")
|
||||
exit(1)
|
||||
|
||||
|
||||
def remove_indentation(tmp_file, output_file):
|
||||
|
||||
try:
|
||||
with open(tmp_file, "r") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
clean_lines = []
|
||||
for line in lines:
|
||||
stripped = line.lstrip()
|
||||
|
||||
# Remove extra spaces after #
|
||||
if stripped.startswith("#"):
|
||||
stripped = re.sub(r"^#\s+", "#", stripped)
|
||||
|
||||
clean_lines.append(stripped)
|
||||
|
||||
with open(output_file, "w") as f:
|
||||
f.writelines(clean_lines)
|
||||
|
||||
print(f"Indentation removed. Cleaned output saved to {output_file}")
|
||||
|
||||
os.remove(tmp_file)
|
||||
print(f"Temporary preprocessed file {tmp_file} removed.")
|
||||
except Exception as e:
|
||||
print(f"Error during indentation removal: {e}")
|
||||
exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
args = get_args()
|
||||
|
||||
preprocess_file(args.input, args.tmp_file, args.output, args.include, args.defs)
|
||||
|
||||
remove_indentation(args.tmp_file, args.output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -3994,11 +3994,25 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_USE_GENERIC_MIPI
|
||||
#ifdef CONFIG_LV_USE_GENERIC_MIPI
|
||||
#define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI
|
||||
#else
|
||||
#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)
|
||||
#ifndef LV_USE_GENERIC_MIPI
|
||||
#ifdef LV_KCONFIG_PRESENT
|
||||
#ifdef CONFIG_LV_USE_GENERIC_MIPI
|
||||
#define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI
|
||||
#else
|
||||
#define LV_USE_GENERIC_MIPI 0
|
||||
#endif
|
||||
#else
|
||||
#define LV_USE_GENERIC_MIPI 1
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#ifndef LV_USE_GENERIC_MIPI
|
||||
#ifdef CONFIG_LV_USE_GENERIC_MIPI
|
||||
#define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI
|
||||
#else
|
||||
#define LV_USE_GENERIC_MIPI 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -4337,12 +4351,21 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#endif /*LV_USE_SYSMON*/
|
||||
|
||||
|
||||
#ifndef LV_USE_LZ4
|
||||
#define LV_USE_LZ4 (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
|
||||
#if (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
|
||||
#define LV_USE_LZ4 1
|
||||
#else
|
||||
#define LV_USE_LZ4 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_USE_THORVG
|
||||
#define LV_USE_THORVG (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL)
|
||||
#if (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL)
|
||||
#define LV_USE_THORVG 1
|
||||
#else
|
||||
#define LV_USE_THORVG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LV_USE_OS
|
||||
|
||||
@@ -83,6 +83,30 @@ extern "C" {
|
||||
# define CONFIG_LV_USE_STDLIB_SPRINTF LV_STDLIB_CUSTOM
|
||||
#endif
|
||||
|
||||
/*******************
|
||||
* LV_USE_OS
|
||||
*******************/
|
||||
|
||||
#ifdef CONFIG_LV_OS_NONE
|
||||
# define CONFIG_LV_USE_OS LV_OS_NONE
|
||||
#elif defined(CONFIG_LV_OS_PTHREAD)
|
||||
# define CONFIG_LV_USE_OS LV_OS_PTHREAD
|
||||
#elif defined(CONFIG_LV_OS_FREERTOS)
|
||||
# define CONFIG_LV_USE_OS LV_OS_FREERTOS
|
||||
#elif defined(CONFIG_LV_OS_CMSIS_RTOS2)
|
||||
# define CONFIG_LV_USE_OS LV_OS_CMSIS_RTOS2
|
||||
#elif defined (CONFIG_LV_OS_RTTHREAD)
|
||||
# define CONFIG_LV_USE_OS LV_OS_RTTHREAD
|
||||
#elif defined (CONFIG_LV_OS_WINDOWS)
|
||||
# define CONFIG_LV_USE_OS LV_OS_WINDOWS
|
||||
#elif defined (CONFIG_LV_OS_MQX)
|
||||
# define CONFIG_LV_USE_OS LV_OS_MQX
|
||||
#elif defined (CONFIG_LV_OS_SDL2)
|
||||
# define CONFIG_LV_USE_OS LV_OS_SDL2
|
||||
#elif defined (CONFIG_LV_OS_CUSTOM)
|
||||
# define CONFIG_LV_USE_OS LV_OS_CUSTOM
|
||||
#endif
|
||||
|
||||
/*******************
|
||||
* LV_MEM_SIZE
|
||||
*******************/
|
||||
@@ -259,6 +283,15 @@ extern "C" {
|
||||
# define CONFIG_LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_LV_USE_CALENDAR
|
||||
# ifdef CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY
|
||||
# define CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES { CONFIG_LV_MONDAY_STR , CONFIG_LV_TUESDAY_STR, CONFIG_LV_WEDNESDAY_STR, CONFIG_LV_THURSDAY_STR, CONFIG_LV_FRIDAY_STR, CONFIG_LV_SATURDAY_STR, CONFIG_LV_SUNDAY_STR }
|
||||
# else
|
||||
# define CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES { CONFIG_LV_SUNDAY_STR, CONFIG_LV_MONDAY_STR , CONFIG_LV_TUESDAY_STR, CONFIG_LV_WEDNESDAY_STR, CONFIG_LV_THURSDAY_STR, CONFIG_LV_FRIDAY_STR, CONFIG_LV_SATURDAY_STR }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
@@ -170,6 +170,10 @@ if ($ENV{NON_AMD64_BUILD})
|
||||
set(CMAKE_LIBRARY_PATH "/usr/lib/i386-linux-gnu" CACHE PATH "search 32bit lib path firstly")
|
||||
endif()
|
||||
|
||||
# Set LV_CONF_PATH so custom.cmake knows about it before compiling lvgl
|
||||
# Used to preprocess lv_conf_internal.h with the test config
|
||||
set(LV_CONF_PATH "${LVGL_TEST_DIR}/src/lv_test_conf.h")
|
||||
set(LV_BUILD_TEST ON)
|
||||
# Options lvgl and examples are compiled with.
|
||||
set(COMPILE_OPTIONS
|
||||
-DLV_CONF_PATH="${LVGL_TEST_DIR}/src/lv_test_conf.h"
|
||||
|
||||
Reference in New Issue
Block a user