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:
|
Returns:
|
||||||
str: The complete CMakeLists.txt content as a string
|
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:
|
def escape_entry(p: PathType) -> str:
|
||||||
# In CMakeLists.txt, backslashes need to be escaped
|
# In CMakeLists.txt, backslashes need to be escaped
|
||||||
@@ -105,6 +109,23 @@ def generate_cmakelists_txt(component: IDFComponent) -> str:
|
|||||||
build_flags = ensure_list(
|
build_flags = ensure_list(
|
||||||
component.data.get("build", {}).get("flags", DEFAULT_BUILD_FLAGS)
|
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
|
# List all sources files
|
||||||
build_src_files = collect_filtered_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(
|
def test_generate_cmakelists_txt_references_project_managed_components_variable(
|
||||||
tmp_component: IDFComponent,
|
tmp_component: IDFComponent,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user