mirror of
https://github.com/esphome/esphome.git
synced 2026-08-25 23:56:19 +00:00
Lex build flags once in write_project, warn on unflags that match nothing
The pre-lexed tokens feed both _flag_defines and _project_flags so a malformed entry warns once per generation. An unflag that hits nothing in the user flags or any framework set (a typo, or -DUSE_FOO against -DUSE_FOO=1) is named instead of silently leaving the flag in force.
This commit is contained in:
@@ -591,7 +591,9 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
mkdir_p(build_dir)
|
||||
|
||||
unflags = _unflag_tokens()
|
||||
flag_defines = _flag_defines(unflags)
|
||||
# Lexed once so a malformed entry warns once, not per consumer
|
||||
build_tokens = _lexed_build_flags()
|
||||
flag_defines = _flag_defines(unflags, build_tokens)
|
||||
config = _resolve_build_config(flag_defines)
|
||||
esp8266_data = CORE.data[KEY_ESP8266]
|
||||
board = esp8266_data[KEY_BOARD]
|
||||
@@ -652,7 +654,7 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
project_link_flags,
|
||||
project_lib_dirs,
|
||||
project_libs,
|
||||
) = _project_flags(unflags)
|
||||
) = _project_flags(unflags, build_tokens)
|
||||
defines = _defines_flags(
|
||||
config, esp8266_data[KEY_FLASH_MODE], board, board_build["defines"]
|
||||
)
|
||||
@@ -681,6 +683,17 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
# build_unflags applies to the framework flag sets too (compile and link),
|
||||
# as under PlatformIO (a silently ignored ``build_unflags: -Os`` would
|
||||
# diverge between the toolchains).
|
||||
# Matching is whole-token, so an unflag that hits nothing in the user
|
||||
# flags or any framework set (a typo, or -DUSE_FOO against -DUSE_FOO=1)
|
||||
# must be visible: the user believes the flag is gone while it still
|
||||
# drives the compile line and the knob selection
|
||||
flag_universe = set(build_tokens)
|
||||
for flags in (cflags, cxxflags, asflags, _LINKFLAGS):
|
||||
flag_universe.update(flags)
|
||||
if unmatched := sorted(unflags - flag_universe):
|
||||
_LOGGER.warning(
|
||||
"build_unflags entries matched no build flag: %s", ", ".join(unmatched)
|
||||
)
|
||||
cflags, cxxflags, asflags, link_flags = (
|
||||
[f for f in flags if f not in unflags]
|
||||
for flags in (cflags, cxxflags, asflags, _LINKFLAGS)
|
||||
|
||||
@@ -1074,3 +1074,28 @@ def test_generate_ld_scripts_surgery_failure_is_named(tmp_path: Path) -> None:
|
||||
pytest.raises(EsphomeError, match="anchor not found"),
|
||||
):
|
||||
_run_generate_ld_scripts(paths)
|
||||
|
||||
|
||||
def test_write_project_unmatched_unflag_warns(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""An unflag that removes nothing is named; a matching one is silent."""
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags("-DUSE_FOO=1")
|
||||
CORE.build_unflags = {"-DUSE_FOO", "-Os"}
|
||||
content = _write_ninja(paths)
|
||||
assert "matched no build flag: -DUSE_FOO" in caplog.text
|
||||
assert "-Os" not in caplog.text.split("matched no build flag")[-1].splitlines()[0]
|
||||
# The matching -Os unflag really removed the framework flag
|
||||
cflags = next(line for line in content.splitlines() if line.startswith("cflags"))
|
||||
assert " -Os " not in cflags
|
||||
|
||||
|
||||
def test_write_project_lexes_build_flags_once(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""A malformed build_flags entry warns once per generation."""
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags("-DFOO=1 -l")
|
||||
_write_ninja(paths)
|
||||
assert caplog.text.count("Ignoring trailing '-l'") == 1
|
||||
|
||||
Reference in New Issue
Block a user