Make symbol unflags pair-aware on the link line, drop the dead KEY_FLASH_MODE

This commit is contained in:
J. Nick Koston
2026-08-23 18:03:15 -05:00
parent e902d8d1fc
commit 73fd512a25
3 changed files with 36 additions and 4 deletions
+19 -3
View File
@@ -446,6 +446,22 @@ def _resolve_build_config(defines: dict[str, str]) -> _BuildConfig:
_INCOMPLETE_INSTALL = "Arduino toolchain install is incomplete"
def _filter_link_flags(unflags: set[str]) -> list[str]:
"""_LINKFLAGS minus ``unflags``, pair-aware: unflagging a symbol also
drops the ``-u`` that carried it, so no dangling operand-less flag
reaches ld as the next token's consumer."""
out: list[str] = []
it = iter(_LINKFLAGS)
for tok in it:
if tok == "-u":
symbol = next(it)
if symbol not in unflags:
out += [tok, symbol]
elif tok not in unflags:
out.append(tok)
return out
def _active_flash_ld_name(flash_ld_name: str) -> str:
"""The flash linker-script filename the link uses (testing mode renames
the surgically patched copy)."""
@@ -979,10 +995,10 @@ def write_project(paths: InstalledPaths, ccache: str | None) -> bool:
f"build_unflags cannot remove plain linker flag(s) "
f"{', '.join(plain)}; unflag the full -Wl, form or the symbol"
)
cflags, cxxflags, asflags, link_flags = (
[f for f in flags if f not in unflags]
for flags in (cflags, cxxflags, asflags, _LINKFLAGS)
cflags, cxxflags, asflags = (
[f for f in flags if f not in unflags] for flags in (cflags, cxxflags, asflags)
)
link_flags = _filter_link_flags(unflags)
if esp8266_data[KEY_SCANF_FLOAT]:
link_flags += ["-u", "_scanf_float"]
link_flags += project_link_flags
-1
View File
@@ -16,7 +16,6 @@ KEY_WAVEFORM_REQUIRED = "waveform_required"
KEY_SERIAL_REQUIRED = "serial_required"
KEY_SERIAL1_REQUIRED = "serial1_required"
# Set for the native (non-PlatformIO) toolchain's build generator
KEY_FLASH_MODE = "flash_mode"
KEY_SCANF_FLOAT = "scanf_float"
# esp8266 namespace is already defined by arduino, manually prefix esphome
@@ -688,6 +688,23 @@ def test_build_config_nonosdk_precedence() -> None:
assert _resolve_build_config(_defines()).nonosdk == "NONOSDK221"
def test_write_project_unflagged_symbol_takes_its_dash_u(tmp_path: Path) -> None:
"""Unflagging a -u symbol drops the -u that carried it; a dangling -u
would consume the next token and hand ld a symbol as an input file."""
paths = _make_framework(tmp_path)
_set_flags()
CORE.build_unflags = {"_printf_float"}
content = _write_ninja(paths)
link_line = next(
line for line in content.splitlines() if line.startswith("linkflags = ")
)
assert "_printf_float" not in link_line
assert "-u -u" not in link_line
# The neighbors survive as intact pairs
assert "-u app_entry" in link_line
assert "-u _DebugExceptionVector" in link_line
def test_write_project_build_unflags_apply_to_framework_flags(tmp_path: Path) -> None:
"""build_unflags removes flags from the framework sets, as PlatformIO does."""
paths = _make_framework(tmp_path)