mirror of
https://github.com/esphome/esphome.git
synced 2026-08-23 06:36:23 +00:00
Match ASPPCOM flag routing, quote manifest link tokens, split the src-dir error, pin the change contract
This commit is contained in:
@@ -495,6 +495,9 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
cache_key="arduino8266",
|
||||
)
|
||||
|
||||
if not src_dir.is_dir():
|
||||
# Generated project state, not install state: clean-all would not help
|
||||
raise EsphomeError(f"Generated source directory {src_dir} is missing")
|
||||
# A missing install directory would otherwise surface as a wall of
|
||||
# include errors; failing here names the path instead.
|
||||
include_dirs = [
|
||||
@@ -505,7 +508,7 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
sdk / "lwip2" / "include",
|
||||
variant_dir,
|
||||
]
|
||||
for required in include_dirs:
|
||||
for required in include_dirs[1:]:
|
||||
if not required.is_dir():
|
||||
raise EsphomeError(
|
||||
f"{_INCOMPLETE_INSTALL}: missing {required}; {_CLEAN_HINT}"
|
||||
@@ -534,7 +537,14 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
+ common
|
||||
+ get_project_cxx_compile_flags()
|
||||
)
|
||||
asflags = _ASFLAGS + defines + includes + project_compile_flags
|
||||
# PlatformIO's ASPPCOM carries defines and includes but not CCFLAGS,
|
||||
# so only -D/-I user flags reach assembly there; match it.
|
||||
asflags = (
|
||||
_ASFLAGS
|
||||
+ defines
|
||||
+ includes
|
||||
+ [f for f in project_compile_flags if f.startswith(("-D", "-I"))]
|
||||
)
|
||||
|
||||
# build_unflags applies to the framework flag sets too (compile and link),
|
||||
# as under PlatformIO (a silently ignored ``build_unflags: -Os`` would
|
||||
@@ -546,7 +556,7 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
if esp8266_data[KEY_SCANF_FLOAT]:
|
||||
link_flags += ["-u", "_scanf_float"]
|
||||
link_flags += project_link_flags
|
||||
link_flags += [flag for lib in libraries for flag in lib.link_flags]
|
||||
link_flags += [_shell_token(flag) for lib in libraries for flag in lib.link_flags]
|
||||
flash_ld = _active_flash_ld_name(flash_ld_name)
|
||||
link_flags += ["-T", flash_ld]
|
||||
|
||||
@@ -616,7 +626,7 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
f"asflags = {' '.join(asflags)}",
|
||||
f"linkflags = {' '.join(link_flags)}",
|
||||
f"libdirflags = {' '.join(f'-L{_q(d)}' for d in lib_dirs)}",
|
||||
f"libflags = {' '.join(f'-l{lib}' for lib in system_libs)}",
|
||||
f"libflags = {' '.join(_shell_token(f'-l{lib}') for lib in system_libs)}",
|
||||
"",
|
||||
]
|
||||
|
||||
@@ -625,7 +635,8 @@ def write_project(paths: InstalledPaths) -> bool:
|
||||
core_exclude |= _CORE_EXCLUDE_WAVEFORM
|
||||
|
||||
archives = []
|
||||
variant_sources = _collect_sources(variant_dir) if variant_dir.is_dir() else []
|
||||
# variant_dir existence was already enforced with the include dirs
|
||||
variant_sources = _collect_sources(variant_dir)
|
||||
if variant_sources:
|
||||
objs = _ninja_compile_edges(lines, variant_sources, variant_dir, "variant")
|
||||
lines.append(f"build libFrameworkArduinoVariant.a: ar {' '.join(objs)}")
|
||||
|
||||
@@ -676,3 +676,50 @@ def test_ninja_path_escaping() -> None:
|
||||
"""Build-statement paths and command-line paths escape differently."""
|
||||
assert arduino8266._e("a b:$c") == "a$ b$:$$c"
|
||||
assert arduino8266._q("/a b/$x") == '"/a b/$$x"'
|
||||
|
||||
|
||||
def test_write_project_asm_excludes_non_define_user_flags(tmp_path: Path) -> None:
|
||||
"""The ASPPCOM command under PlatformIO never sees CCFLAGS, so only -D/-I user flags
|
||||
reach assembly compiles."""
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags("-DUSER_KNOB=1", "-Wno-volatile")
|
||||
content = _write_ninja(paths)
|
||||
asflags = next(line for line in content.splitlines() if line.startswith("asflags"))
|
||||
assert "-DUSER_KNOB=1" in asflags
|
||||
assert "-Wno-volatile" not in asflags
|
||||
cxxflags = next(
|
||||
line for line in content.splitlines() if line.startswith("cxxflags")
|
||||
)
|
||||
assert "-Wno-volatile" in cxxflags
|
||||
|
||||
|
||||
def test_write_project_returns_changed(tmp_path: Path) -> None:
|
||||
"""The documented contract: True when build.ninja changed, False on an
|
||||
identical regeneration (pins byte-stable output too)."""
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags()
|
||||
src = CORE.relative_src_path()
|
||||
(src / "esphome" / "components" / "esp8266").mkdir(parents=True, exist_ok=True)
|
||||
(src / "main.cpp").write_text("")
|
||||
with (
|
||||
patch.object(arduino8266, "generate_ld_scripts"),
|
||||
patch("esphome.arduino.library.resolve_libraries", return_value=[]),
|
||||
patch("esphome.arduino8266.framework.ccache_path", return_value=None),
|
||||
):
|
||||
assert arduino8266.write_project(paths) is True
|
||||
assert arduino8266.write_project(paths) is False
|
||||
|
||||
|
||||
def test_write_project_missing_src_dir_raises(tmp_path: Path) -> None:
|
||||
"""A missing generated source tree is its own error, not an install one."""
|
||||
paths = _make_framework(tmp_path)
|
||||
_set_flags()
|
||||
with (
|
||||
patch.object(arduino8266, "generate_ld_scripts"),
|
||||
patch("esphome.arduino.library.resolve_libraries", return_value=[]),
|
||||
patch.object(
|
||||
arduino8266.CORE, "relative_src_path", return_value=tmp_path / "nope"
|
||||
),
|
||||
pytest.raises(EsphomeError, match="source directory"),
|
||||
):
|
||||
arduino8266.write_project(paths)
|
||||
|
||||
Reference in New Issue
Block a user