mirror of
https://github.com/esphome/esphome.git
synced 2026-08-27 08:28:30 +00:00
Assemble plain .s without the preprocessor, allow unflagging operand-less linker flags
This commit is contained in:
@@ -631,6 +631,10 @@ _PLAIN_LINKER_FLAGS = (
|
||||
"-nostdlib",
|
||||
"-rdynamic",
|
||||
)
|
||||
# The subset whose next token is an operand; unflagging the bare flag
|
||||
# would strand the operand. Operand-less members of the list above filter
|
||||
# whole-token from both the compile and link lines, as PlatformIO allows.
|
||||
_PLAIN_LINKER_OPERAND_FLAGS = ("-u", "-e")
|
||||
_PLAIN_LINKER_PREFIXES = ("-T", "-Xlinker")
|
||||
# Driver options, not ld options: -Wl, has no equivalent for these
|
||||
_PLAIN_DRIVER_LINK_PREFIXES = ("-fuse-ld=", "--specs=", "-specs=")
|
||||
@@ -993,7 +997,7 @@ def write_project(paths: InstalledPaths, ccache: str | None) -> bool:
|
||||
if plain := sorted(
|
||||
u
|
||||
for u in unflags
|
||||
if u in _PLAIN_LINKER_FLAGS or u.startswith(_PLAIN_LINKER_PREFIXES)
|
||||
if u in _PLAIN_LINKER_OPERAND_FLAGS or u.startswith(_PLAIN_LINKER_PREFIXES)
|
||||
):
|
||||
raise EsphomeError(
|
||||
f"build_unflags cannot remove plain linker flag(s) "
|
||||
@@ -1040,7 +1044,7 @@ def write_project(paths: InstalledPaths, ccache: str | None) -> bool:
|
||||
f"buildtool = {_q(build_tool)}",
|
||||
f"ccache = {_q(ccache) if ccache else ''}",
|
||||
"",
|
||||
# Rule names match SOURCE_KIND_FOR_SUFFIX values (c, cxx, asm)
|
||||
# Rule names match SOURCE_KIND_FOR_SUFFIX values (c, cxx, asm, aspp)
|
||||
"rule c",
|
||||
" command = $ccache $cc -MMD -MF $out.d $cflags $flags -c $in -o $out",
|
||||
" depfile = $out.d",
|
||||
@@ -1051,11 +1055,16 @@ def write_project(paths: InstalledPaths, ccache: str | None) -> bool:
|
||||
" depfile = $out.d",
|
||||
" deps = gcc",
|
||||
" description = CXX $out",
|
||||
"rule asm",
|
||||
"rule aspp",
|
||||
" command = $ccache $cc -MMD -MF $out.d -x assembler-with-cpp $asflags $flags -c $in -o $out",
|
||||
" depfile = $out.d",
|
||||
" deps = gcc",
|
||||
" description = AS $out",
|
||||
# Plain assembler, as SCons's ASCOM: no preprocessor, so no
|
||||
# depfile and no $flags (defines/includes) either
|
||||
"rule asm",
|
||||
" command = $ccache $cc -x assembler $asflags -c $in -o $out",
|
||||
" description = AS $out",
|
||||
"rule ar",
|
||||
f" command = $python $buildtool ar {_q(toolchain_tool(paths.toolchain, 'ar'))} $out $out.rsp",
|
||||
" rspfile = $out.rsp",
|
||||
|
||||
@@ -346,7 +346,7 @@ def test_write_project_link_line_and_exclusions(tmp_path: Path) -> None:
|
||||
assert "core_esp8266_waveform_phase.cpp" not in content
|
||||
assert "core_esp8266_main.cpp.o" in content
|
||||
# Assembly and C sources compile through their own rules
|
||||
assert "cont.S.o: asm" in content
|
||||
assert "cont.S.o: aspp" in content
|
||||
assert "abi.c.o: c" in content
|
||||
# throw_stubs is force-included for ESPHome sources only, via one shared
|
||||
# srcflags variable rather than a copy of the flags line per edge
|
||||
@@ -688,6 +688,30 @@ def test_build_config_nonosdk_precedence() -> None:
|
||||
assert _resolve_build_config(_defines()).nonosdk == "NONOSDK221"
|
||||
|
||||
|
||||
def test_write_project_plain_asm_rule_skips_preprocessor(tmp_path: Path) -> None:
|
||||
"""A lowercase .s source assembles plain (SCons AS), never through the
|
||||
preprocessor rule that a .S source gets."""
|
||||
paths = _make_framework(tmp_path)
|
||||
core_dir = paths.framework / "cores" / "esp8266"
|
||||
(core_dir / "lowlevel.s").write_text("nop\n")
|
||||
_set_flags()
|
||||
content = _write_ninja(paths)
|
||||
assert "lowlevel.s.o: asm " in content
|
||||
assert "rule asm\n command = $ccache $cc -x assembler $asflags -c $in -o $out" in (
|
||||
content
|
||||
)
|
||||
|
||||
|
||||
def test_write_project_unflags_operandless_linker_flag(tmp_path: Path) -> None:
|
||||
"""build_unflags: -nostdlib filters whole-token from both lines, as
|
||||
PlatformIO allows; only operand-taking flags hard-error."""
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags()
|
||||
CORE.build_unflags = {"-nostdlib"}
|
||||
content = _write_ninja(paths)
|
||||
assert "-nostdlib" not in content
|
||||
|
||||
|
||||
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."""
|
||||
|
||||
Reference in New Issue
Block a user