mirror of
https://github.com/esphome/esphome.git
synced 2026-08-29 09:13:28 +00:00
Preserve d1_wroom_02's shipped flash layout, refuse plain linker unflags, pin the real spaced-override outcome
This commit is contained in:
@@ -456,7 +456,12 @@ def _flash_ld_name(board: str) -> str:
|
||||
"""
|
||||
override = _pio_option("board_build.ldscript", "")
|
||||
if not override:
|
||||
return ESP8266_LD_SCRIPTS[BOARDS[board][KEY_FLASH_SIZE]][1]
|
||||
# The same per-board override the PlatformIO path pins (layout
|
||||
# preservation, see boards.py)
|
||||
board_data = BOARDS[board]
|
||||
return board_data.get(
|
||||
"ldscript", ESP8266_LD_SCRIPTS[board_data[KEY_FLASH_SIZE]][1]
|
||||
)
|
||||
if Path(override).name != override:
|
||||
raise EsphomeError(
|
||||
f"board_build.ldscript must be a bare script name, got {override!r}"
|
||||
@@ -893,6 +898,18 @@ def write_project(paths: InstalledPaths, ccache: str | None) -> bool:
|
||||
_LOGGER.warning(
|
||||
"build_unflags entries matched no build flag: %s", ", ".join(unmatched)
|
||||
)
|
||||
# _LINKFLAGS stores -u and its operand as two tokens; unflagging the
|
||||
# bare -u would strip all seven and leave the operands as ld "input
|
||||
# files" with an error pointing nowhere near build_unflags
|
||||
if plain := sorted(
|
||||
u
|
||||
for u in unflags
|
||||
if u in _PLAIN_LINKER_FLAGS or u.startswith(_PLAIN_LINKER_PREFIXES)
|
||||
):
|
||||
raise EsphomeError(
|
||||
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)
|
||||
|
||||
@@ -409,8 +409,8 @@ async def to_code(config: ConfigType) -> None:
|
||||
)
|
||||
|
||||
if config[CONF_BOARD] in BOARDS:
|
||||
flash_size = BOARDS[config[CONF_BOARD]][KEY_FLASH_SIZE]
|
||||
ld_scripts = ESP8266_LD_SCRIPTS[flash_size]
|
||||
board_data = BOARDS[config[CONF_BOARD]]
|
||||
ld_scripts = ESP8266_LD_SCRIPTS[board_data[KEY_FLASH_SIZE]]
|
||||
|
||||
if ver <= cv.Version(2, 3, 0):
|
||||
# No ld script support
|
||||
@@ -419,7 +419,9 @@ async def to_code(config: ConfigType) -> None:
|
||||
# Old ld script path
|
||||
ld_script = ld_scripts[0]
|
||||
else:
|
||||
ld_script = ld_scripts[1]
|
||||
# A per-board override preserves a layout the board shipped
|
||||
# with (see d1_wroom_02 in boards.py)
|
||||
ld_script = board_data.get("ldscript", ld_scripts[1])
|
||||
|
||||
if ld_script is not None:
|
||||
cg.add_platformio_option("board_build.ldscript", ld_script)
|
||||
|
||||
@@ -202,6 +202,11 @@ BOARDS = {
|
||||
"d1_wroom_02": {
|
||||
"name": "WeMos D1 ESP-WROOM-02",
|
||||
"flash_size": FLASH_SIZE_2_MB,
|
||||
# This board joined BOARDS after shipping with the manifest default
|
||||
# (64 KB filesystem region); the flash-size default (2m.ld) would
|
||||
# move _FS_end and with it the preferences sector, wiping existing
|
||||
# devices' flash-backed state on update.
|
||||
"ldscript": "eagle.flash.2m64.ld",
|
||||
},
|
||||
"d1": {
|
||||
"name": "WEMOS D1 R1",
|
||||
|
||||
@@ -1447,12 +1447,29 @@ def test_flash_ld_name_honors_ldscript_override(tmp_path: Path) -> None:
|
||||
arduino8266._flash_ld_name("nodemcuv2")
|
||||
|
||||
|
||||
def test_write_project_quotes_spaced_ldscript_override(tmp_path: Path) -> None:
|
||||
"""An overridden script name re-quotes on the link line like every other
|
||||
user token (a space would otherwise split into two argv elements)."""
|
||||
def test_unflagging_a_plain_linker_flag_raises(tmp_path: Path) -> None:
|
||||
"""build_unflags: -u would strip all seven -u tokens and leave the
|
||||
operands as ld input files; refuse by name instead."""
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags()
|
||||
CORE.build_unflags = {"-u _printf_float"}
|
||||
with pytest.raises(EsphomeError, match="cannot remove plain linker"):
|
||||
_write_ninja(paths)
|
||||
|
||||
|
||||
def test_d1_wroom_02_keeps_its_shipped_flash_layout() -> None:
|
||||
"""The board joined BOARDS late; the flash-size default (2m.ld) would
|
||||
move _FS_end and the preferences sector on existing devices."""
|
||||
assert arduino8266._flash_ld_name("d1_wroom_02") == "eagle.flash.2m64.ld"
|
||||
assert arduino8266._flash_ld_name("nodemcuv2") == "eagle.flash.4m.ld"
|
||||
|
||||
|
||||
def test_write_project_rejects_spaced_ldscript_override(tmp_path: Path) -> None:
|
||||
"""A spaced override never reaches the link line: generate_ld_scripts
|
||||
rejects the name first (the -T _shell_token quoting behind it is
|
||||
defence-in-depth)."""
|
||||
CORE.platformio_options = {"board_build.ldscript": "my script.ld"}
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags()
|
||||
content = _write_ninja(paths)
|
||||
assert "'my script.ld'" in content or '"my script.ld"' in content
|
||||
assert "-T my script.ld" not in content
|
||||
with pytest.raises(EsphomeError, match="Invalid flash linker script name"):
|
||||
arduino8266.write_project(paths, None)
|
||||
|
||||
Reference in New Issue
Block a user