[lvgl] Keep LV_CONF_PATH one argument when the build path has a space (#20758)

This commit is contained in:
Jonathan Swoboda
2026-10-14 08:36:17 -10:00
committed by GitHub
parent 7f144365ba
commit a1f740b71b
2 changed files with 50 additions and 3 deletions
+11 -3
View File
@@ -335,6 +335,16 @@ def final_validation(config_list):
widget_type.final_validate(name, conf, widget_conf, path[1:])
def lv_conf_path_flag(lv_conf_h_file: Path) -> str:
"""The ``-DLV_CONF_PATH`` build flag, decoded identically by the shell
lexers (PlatformIO, host, ESP8266) and the quoted CMake arguments
(ESP-IDF, Zephyr) the build flags pass through."""
# forward slashes for Windows, then escape what shlex or a quoted CMake
# argument would not pass through literally
path = re.sub(r"[^\w/.:+=,-]", r"\\\g<0>", Path(lv_conf_h_file).as_posix())
return f'-DLV_CONF_PATH=\\"{path}\\"'
async def to_code(configs):
config_0 = configs[0]
# Global configuration
@@ -563,9 +573,7 @@ async def to_code(configs):
if write_file_if_changed(lv_conf_h_file, generate_lv_conf_h()):
clean_build(clear_pio_cache=False)
cg.add_build_flag("-DLV_CONF_H=1")
# handle windows paths in a way that doesn't break the generated C++
lv_conf_h_path = Path(lv_conf_h_file).as_posix()
cg.add_build_flag(f'-DLV_CONF_PATH=\\"{lv_conf_h_path}\\"')
cg.add_build_flag(lv_conf_path_flag(lv_conf_h_file))
cg.add_build_flag("-DLV_KCONFIG_IGNORE")
for prop in df.get_remapped_uses():
@@ -0,0 +1,39 @@
"""The ``-DLV_CONF_PATH`` build flag carries a path. PlatformIO, the host
build and the native ESP8266 build shell-lex build flags, while the ESP-IDF
and Zephyr builds write each flag into a quoted CMake argument; both must
decode it to one ``-DLV_CONF_PATH="..."`` argument, including when the
project path contains a space."""
from __future__ import annotations
from pathlib import Path
import re
import shlex
import pytest
from esphome.components.lvgl import lv_conf_path_flag
def _cmake_quoted_argument(flag: str) -> str:
"""Decode ``flag`` as CMake decodes a quoted argument: a backslash escapes the next character."""
return re.sub(r"\\(.)", r"\1", flag)
@pytest.mark.parametrize(
"build_path",
[
"/home/user/.esphome/build/node",
"/Users/me/with space/.esphome/build/node",
"/srv/odd 'quote' $(and)/build",
"C:/Users/Kris Maddens/esphome/.esphome/build/node",
],
ids=["plain", "space", "shell-specials", "windows"],
)
def test_flag_is_one_argument_everywhere(build_path: str) -> None:
lv_conf_h_file = Path(build_path) / "src" / "lv_conf.h"
flag = lv_conf_path_flag(lv_conf_h_file)
expected = f'-DLV_CONF_PATH="{lv_conf_h_file.as_posix()}"'
assert shlex.split(flag) == [expected]
assert _cmake_quoted_argument(flag) == expected