mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
Split multi-token build.flags entries when generating ESP-IDF component CMakeLists (#17649)
This commit is contained in:
@@ -83,6 +83,10 @@ def generate_cmakelists_txt(component: IDFComponent) -> str:
|
||||
Returns:
|
||||
str: The complete CMakeLists.txt content as a string
|
||||
"""
|
||||
# Late import: this module loads with the esp32 platform on every
|
||||
# validate/compile, but shlex is only needed when generating component
|
||||
# CMakeLists.
|
||||
import shlex
|
||||
|
||||
def escape_entry(p: PathType) -> str:
|
||||
# In CMakeLists.txt, backslashes need to be escaped
|
||||
@@ -105,6 +109,23 @@ def generate_cmakelists_txt(component: IDFComponent) -> str:
|
||||
build_flags = ensure_list(
|
||||
component.data.get("build", {}).get("flags", DEFAULT_BUILD_FLAGS)
|
||||
)
|
||||
# PlatformIO shell-lexes each build.flags entry, so one entry can carry a
|
||||
# flag and its argument (e.g. "-include cp_custom_alloc.h"). Split the
|
||||
# same way; emitting such an entry as a single quoted compile option
|
||||
# hands the compiler one argv with an embedded space.
|
||||
build_flags = [token for entry in build_flags for token in shlex.split(entry)]
|
||||
# Re-glue bare -I/-L/-l tokens to their argument ("-I foo" -> "-Ifoo") so
|
||||
# the prefix classifiers below still route them to INCLUDE_DIRS and the
|
||||
# link handling.
|
||||
tokens, build_flags = build_flags, []
|
||||
i = 0
|
||||
while i < len(tokens):
|
||||
if tokens[i] in ("-I", "-L", "-l") and i + 1 < len(tokens):
|
||||
build_flags.append(tokens[i] + tokens[i + 1])
|
||||
i += 2
|
||||
else:
|
||||
build_flags.append(tokens[i])
|
||||
i += 1
|
||||
|
||||
# List all sources files
|
||||
build_src_files = collect_filtered_files(
|
||||
|
||||
@@ -193,6 +193,47 @@ target_link_libraries(${{COMPONENT_LIB}} INTERFACE
|
||||
)
|
||||
|
||||
|
||||
def test_generate_cmakelists_txt_multi_token_flag(tmp_component):
|
||||
# PlatformIO shell-lexes each build.flags entry, so a single entry can
|
||||
# carry a flag and its argument. The generated CMakeLists must emit them
|
||||
# as separate compile options, not one argument with an embedded space.
|
||||
src_dir = tmp_component.path / "src"
|
||||
src_dir.mkdir()
|
||||
(src_dir / "main.c").write_text("int main() {}")
|
||||
|
||||
tmp_component.data = {"build": {"flags": ["-include cp_custom_alloc.h", "-DTEST"]}}
|
||||
|
||||
content = generate_cmakelists_txt(tmp_component)
|
||||
assert '"-include cp_custom_alloc.h"' not in content
|
||||
assert ' "-include"\n "cp_custom_alloc.h"\n' in content
|
||||
|
||||
|
||||
def test_generate_cmakelists_txt_space_separated_classified_flags(tmp_component):
|
||||
# Space-separated -I/-L/-l entries routed to INCLUDE_DIRS and the link
|
||||
# handling before the shlex split was added; splitting must not leak
|
||||
# them into raw compile options.
|
||||
src_dir = tmp_component.path / "src"
|
||||
src_dir.mkdir()
|
||||
(src_dir / "main.c").write_text("int main() {}")
|
||||
(tmp_component.path / "extra_inc").mkdir()
|
||||
|
||||
tmp_component.data = {
|
||||
"build": {"flags": ["-I extra_inc", "-L extra_lib", "-l extralib", "-DTEST"]}
|
||||
}
|
||||
|
||||
content = generate_cmakelists_txt(tmp_component)
|
||||
assert 'INCLUDE_DIRS "src" "extra_inc"' in content
|
||||
assert 'target_link_directories(${COMPONENT_LIB} INTERFACE\n "extra_lib"\n)' in (
|
||||
content
|
||||
)
|
||||
assert 'target_link_libraries(${COMPONENT_LIB} INTERFACE\n "extralib"\n)' in (
|
||||
content
|
||||
)
|
||||
assert '"-I"' not in content
|
||||
assert '"-L"' not in content
|
||||
assert '"-l"' not in content
|
||||
|
||||
|
||||
def test_generate_cmakelists_txt_references_project_managed_components_variable(
|
||||
tmp_component: IDFComponent,
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user