build: restructure cmake (#8210)

Co-authored-by: Erik Tagirov <erik.tagirov@edgemtech.ch>
This commit is contained in:
André Costa
2025-05-21 13:02:26 +02:00
committed by GitHub
parent b5dc0418ea
commit 48417aef64
18 changed files with 1042 additions and 696 deletions
+2 -1
View File
@@ -335,13 +335,14 @@ def write_c_array_file(
header = f'''
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
#include "lvgl.h"
#elif defined(LV_LVGL_H_INCLUDE_SYSTEM)
#include <lvgl.h>
#elif defined(LV_BUILD_TEST)
#include "../lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef LV_ATTRIBUTE_MEM_ALIGN
#define LV_ATTRIBUTE_MEM_ALIGN
#endif
+2 -2
View File
@@ -28,7 +28,7 @@ fi
cd ..
# Generate lv_conf
LV_CONF_PATH=lvgl/configs/ci/docs/lv_conf_docs.h
LV_CONF_PATH=`pwd`/lvgl/configs/ci/docs/lv_conf_docs.h
cp lvgl/lv_conf_template.h $LV_CONF_PATH
python ./lvgl/scripts/generate_lv_conf.py \
@@ -38,7 +38,7 @@ python ./lvgl/scripts/generate_lv_conf.py \
mkdir cmbuild
cd cmbuild
emcmake cmake .. -DLV_CONF_PATH=$LV_CONF_PATH -DLVGL_CHOSEN_DEMO=lv_example_noop -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
emcmake cmake .. -DLV_BUILD_CONF_PATH=$LV_CONF_PATH -DLVGL_CHOSEN_DEMO=lv_example_noop -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
emmake make -j$(nproc)
rm -rf CMakeFiles
cd ../..
+11 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
#
# Generate the cmake variables CONFIG_LV_USE_* from the
# Generate the cmake variables CONFIG_LV_USE_* or CONFIG_LV_BUILD_* from the
# preprocessed lv_conf_internal.h
#
# Author: David TRUAN (david.truan@edgemtech.ch)
@@ -20,7 +20,7 @@ def fatal(msg):
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."
"It converts all LV_USE_*, LV_BUILD_* configurations."
)
parser.add_argument('--input', type=str, required=True, nargs='?',
@@ -55,13 +55,14 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool, d
fin = open(path_input)
fout = open(path_output, "w", newline='')
# If we use Kconfig, we must check the CONFIG_LV_USE_* defines
# If we use Kconfig, we must check the CONFIG_LV_USE_* and
# CONFIG_LV_BUILD_* defines
if kconfig:
CONFIG_PATTERN="#define CONFIG_LV_USE"
CONFIG_PATTERN="^#define +(CONFIG_LV_USE|CONFIG_LV_BUILD)"
CONFIG_PREFIX=""
# Otherwise check the LV_USE_* defines
# Otherwise check the LV_USE_* and LV_BUILD_* defines
else:
CONFIG_PATTERN="#define LV_USE"
CONFIG_PATTERN="^#define +(LV_USE|LV_BUILD)"
CONFIG_PREFIX="CONFIG_"
@@ -71,7 +72,7 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool, d
# 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'):
if re.search(f'{CONFIG_PATTERN}_STDLIB', line):
parts = line.split()
if len(parts) < 3:
@@ -88,7 +89,7 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool, d
# 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'):
if re.search(f'{CONFIG_PATTERN}_OS', line):
parts = line.split()
if len(parts) < 3:
@@ -104,7 +105,8 @@ def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool, d
write_set_cmd(fout, f'{CONFIG_PREFIX}{name} 1', is_parent_scope)
# 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
# all LV_USE_* or LV_BUILD_* configs where the value is 0 or 1,
# as these are the ones that are needed in cmake
# To detect the configuration of LVGL to perform conditional compilation/linking
elif re.search(f'{CONFIG_PATTERN}.* +[01] *$', line):
+16
View File
@@ -214,6 +214,22 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
#define LV_USE_MEM_MONITOR 0
#endif /*LV_USE_SYSMON*/
#if LV_BUILD_DEMOS == 0
#define LV_USE_DEMO_WIDGETS 0
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
#define LV_USE_DEMO_BENCHMARK 0
#define LV_USE_DEMO_RENDER 0
#define LV_USE_DEMO_STRESS 0
#define LV_USE_DEMO_MUSIC 0
#define LV_USE_DEMO_VECTOR_GRAPHIC 0
#define LV_USE_DEMO_FLEX_LAYOUT 0
#define LV_USE_DEMO_MULTILANG 0
#define LV_USE_DEMO_TRANSFORM 0
#define LV_USE_DEMO_SCROLL 0
#define LV_USE_DEMO_EBIKE 0
#define LV_USE_DEMO_HIGH_RES 0
#define LV_USE_DEMO_SMARTWATCH 0
#endif /* LV_BUILD_DEMOS */
#ifndef LV_USE_LZ4
#if (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
+96 -26
View File
@@ -6,6 +6,7 @@
# generate the cmake variables
#
# Author: David TRUAN (david.truan@edgemtech.ch)
# Author: Erik Tagirov (erik.tagirov@edgemtech.ch)
#
import sys
@@ -13,6 +14,8 @@ import subprocess
import os
import argparse
import re
import importlib.util
def get_args():
parser = argparse.ArgumentParser(description="Preprocess a C header file and remove indentation.")
@@ -57,13 +60,23 @@ def preprocess_file(pcpp_exe, input_file, tmp_file, output_file, include_dirs, d
exit(1)
def remove_indentation(tmp_file, output_file):
# Read the temporary files and return an array of lines
def read_lines(tmp_file):
try:
with open(tmp_file, "r") as f:
lines = f.readlines()
except Exception as e:
print(f"Failed to pre-process file: {e}")
exit(1)
clean_lines = []
return lines
def remove_indentation(lines):
clean_lines = []
try:
for line in lines:
stripped = line.lstrip()
@@ -73,39 +86,68 @@ def remove_indentation(tmp_file, output_file):
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 install_pcpp_in_venv(workfolder:str) -> str:
return clean_lines
# This is required - to avoid include errors when Kconfig is used and
# LVGL is installed on the system - i.e when lvgl.h is used as a system include
def add_include_guards(lines):
lines.insert(0, "#define LV_CONF_H\n\n")
lines.insert(0, "#ifndef LV_CONF_H\n")
lines.append("#endif /* END LV_CONF_H */\n")
return lines
def init_venv(venv_path):
"""
Creates a virtual env named .venv inside `workfolder`
and installs every dependecy inside `dependencies`
Returns the path to pcpp
Creates a virtual env named .venv in the `workfolder` directory
It is usually set to the path of the build directory.
If the .venv already exists it enters the venv
Returns the path to the venv
"""
venv_path = os.path.join(workfolder, ".venv")
try:
if os.path.exists(venv_path) == False:
# Create venv
subprocess.check_call([sys.executable, "-m", "venv", venv_path])
# Enter venv
venv_path = os.path.join(venv_path, ".venv")
subprocess.check_call([sys.executable, "-m", "venv", venv_path])
if sys.platform == "win32":
venv_pip = os.path.join(venv_path, "Scripts", "pip.exe")
venv_pcpp = os.path.join(venv_path, "Scripts", "pcpp.exe")
else:
venv_pip = os.path.join(venv_path, "bin", "pip")
venv_pcpp = os.path.join(venv_path, "bin", "pcpp")
subprocess.check_call([venv_pip, "install", "pcpp"])
except subprocess.CalledProcessError as e:
print(f"Error setting up environnement: {e}")
sys.exit(1)
print(f"Error during the setup of python venv: {e}")
exit(1)
return venv_path
def install_pcpp_in_venv(venv_path):
"""
Install pcpp a python implementation of the C pre-processor
On success - Returns the path to pcpp, None on failure
"""
if sys.platform == "win32":
venv_pip = os.path.join(venv_path, "Scripts", "pip.exe")
venv_pcpp = os.path.join(venv_path, "Scripts", "pcpp.exe")
else:
venv_pip = os.path.join(venv_path, "bin", "pip")
venv_pcpp = os.path.join(venv_path, "bin", "pcpp")
if os.path.exists(venv_pcpp) == False:
# Install pcpp
try:
subprocess.check_call([venv_pip, "install", "pcpp"])
except subprocess.CalledProcessError as e:
print(f"Failed to install PCPP: {e}")
return None
else:
print("PCPP is already installed in venv")
return venv_pcpp
@@ -113,10 +155,38 @@ def main():
args = get_args()
pcpp_exe = install_pcpp_in_venv(args.workfolder)
# Check if PCPP is already present on the system
# if it's not - create a python venv inside the workfolder directory
# and install it there
res = subprocess.run(["which", "pcpp"], capture_output=True)
if res.returncode == 0:
pcpp_exe = res.stdout.decode().replace("\n", "")
print(f"Found PCPP: {pcpp_exe}")
else:
print("Failed to locate pcpp - installing it")
venv_path = init_venv(args.workfolder)
pcpp_exe = install_pcpp_in_venv(venv_path)
if pcpp_exe is None:
exit(1)
preprocess_file(pcpp_exe, args.input, args.tmp_file, args.output, args.include, args.defs)
remove_indentation(args.tmp_file, args.output)
lines = read_lines(args.tmp_file)
lines = remove_indentation(lines)
lines = add_include_guards(lines)
# Write the resulting output header file with include guards and no indentation
try:
with open(args.output, "w") as f:
f.writelines(lines)
except Exception as e:
print(f"Writing resulting file failed: {e}")
exit(1)
print(f"Expanded configuration header saved to {args.output}")
os.remove(args.tmp_file)
print(f"Temporary preprocessed file {args.tmp_file} removed.")
if __name__ == "__main__":
main()