Demote invalid-pch under user -Werror, catch the joined -include spelling, treat resource exhaustion as transient

This commit is contained in:
J. Nick Koston
2026-08-26 08:39:27 -05:00
parent f5593deb38
commit 7417dcdd7b
4 changed files with 54 additions and 8 deletions
+17 -1
View File
@@ -416,6 +416,19 @@ def test_write_project_pch_identity_unknown_skips_pch(
assert "Could not establish the pch identity" in caplog.text
def test_write_project_pch_skipped_for_joined_force_include_spelling(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
"""GCC also accepts -includefoo.h as one token; the guard must see it."""
paths = _make_framework(tmp_path)
_set_flags(
"-DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH", "-includefoo.h"
)
content = _write_ninja(paths, ccache="/usr/bin/ccache")
assert "esphome_pch" not in content
assert "prevents the precompiled header" in caplog.text
def test_write_project_pch_skipped_when_user_force_include_precedes(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
@@ -1799,7 +1812,10 @@ def test_write_project_pch_no_device_path_poison(tmp_path: Path) -> None:
CORE.build_path = tmp_path / name
_set_flags("-DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH")
content = _write_ninja(paths, ccache="/usr/bin/ccache")
assert "srccxxflags = -Winvalid-pch -include esphome_pch.h" in content
assert (
"srccxxflags = -Winvalid-pch -Wno-error=invalid-pch "
"-include esphome_pch.h" in content
)
sums.append(
(CORE.relative_pioenvs_path(name) / "esphome_pch.h.gch.sum").read_text()
)
+20 -2
View File
@@ -82,6 +82,7 @@ class _FakeSConsEnv(dict):
def _fake_cxx(
tmp_path: Path,
fail: bool = False,
fail_msg: str | None = None,
reject_pch: bool = False,
probe_exit: int = 0,
) -> Path:
@@ -96,7 +97,7 @@ def _fake_cxx(
'printf -- ---call---\\\\n >> "$0.argv"; printf \'%s\\n\' "$@" >> "$0.argv"\n'
)
if fail:
body += "echo boom >&2\nexit 1\n"
body += f"echo {fail_msg or 'boom'} >&2\nexit 1\n"
else:
# Only the c++-header compile has a -o; the load probe has none
body += 'out=""; prev=""\nfor a in "$@"; do [ "$prev" = "-o" ] && out="$a"; prev="$a"; done\n'
@@ -113,6 +114,7 @@ def _run_script(
tmp_path: Path,
flags: list[str] | None = None,
fail: bool = False,
fail_msg: str | None = None,
reject_pch: bool = False,
probe_exit: int = 0,
missing_cxx: bool = False,
@@ -124,7 +126,13 @@ def _run_script(
src = proj / "src"
(src / "esphome" / "core").mkdir(parents=True, exist_ok=True)
(src / "esphome" / "core" / "defines.h").write_text("#define USE_X\n")
cxx = _fake_cxx(tmp_path, fail=fail, reject_pch=reject_pch, probe_exit=probe_exit)
cxx = _fake_cxx(
tmp_path,
fail=fail,
fail_msg=fail_msg,
reject_pch=reject_pch,
probe_exit=probe_exit,
)
if missing_cxx:
cxx = tmp_path / "no-such-gxx"
args = (proj, src, str(cxx), flags or ["-DX=1"], platform_cls)
@@ -217,6 +225,16 @@ def test_pch_script_sum_is_device_independent(tmp_path: Path) -> None:
assert sums[0] == sums[1]
def test_pch_script_transient_compiler_failure_does_not_latch(
tmp_path: Path,
) -> None:
"""ENOSPC-style failures clear on their own; no .failed marker."""
scons_env = _run_script(tmp_path, fail=True, fail_msg="No space left on device")
proj = tmp_path / "dev"
assert not (proj / "esphome_pch.h.gch.failed").exists()
assert scons_env.prepended == []
def test_pch_script_failure_marker_suppresses_retry(
tmp_path: Path, capsys: pytest.CaptureFixture[str]
) -> None: