mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
Union sloppiness tokens on the PlatformIO path too, survive non-UTF-8 include names
This commit is contained in:
@@ -121,7 +121,12 @@ def _include_closure(src_dir: Path, roots: Iterable[str]) -> dict[str, bytes]:
|
||||
data = f"<unreadable:{st.st_mtime_ns}:{st.st_size}>".encode()
|
||||
seen[rel] = data
|
||||
parent = posixpath.dirname(rel)
|
||||
stack.extend((inc.decode(), parent) for inc in _INCLUDE_RE.findall(data))
|
||||
stack.extend(
|
||||
# surrogateescape: a non-UTF-8 include name must not abort the
|
||||
# build; it simply will not resolve and ends the walk
|
||||
(inc.decode(errors="surrogateescape"), parent)
|
||||
for inc in _INCLUDE_RE.findall(data)
|
||||
)
|
||||
return seen
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,10 @@ def _include_closure(src_dir: Path, roots: list) -> dict:
|
||||
data = f"<unreadable:{st.st_mtime_ns}:{st.st_size}>".encode()
|
||||
seen[rel] = data
|
||||
parent = posixpath.dirname(rel)
|
||||
stack.extend((inc.decode(), parent) for inc in _INCLUDE_RE.findall(data))
|
||||
stack.extend(
|
||||
(inc.decode(errors="surrogateescape"), parent)
|
||||
for inc in _INCLUDE_RE.findall(data)
|
||||
)
|
||||
return seen
|
||||
|
||||
|
||||
@@ -264,6 +267,14 @@ def _setup_pch() -> None:
|
||||
):
|
||||
if key not in os.environ:
|
||||
projenv["ENV"][key] = value # noqa: F821
|
||||
sloppiness = os.environ.get("CCACHE_SLOPPINESS")
|
||||
if sloppiness is not None:
|
||||
missing = [t for t in ("pch_defines", "time_macros") if t not in sloppiness]
|
||||
if missing:
|
||||
# Without these ccache declines every pch-consuming compile;
|
||||
# union rather than override so the user's own tokens survive
|
||||
projenv["ENV"]["CCACHE_SLOPPINESS"] = ",".join((sloppiness, *missing)) # noqa: F821
|
||||
print(f"ESPHome: adding {','.join(missing)} to CCACHE_SLOPPINESS for the pch")
|
||||
|
||||
# Prepended so it is processed before the build_src_flags -include
|
||||
# entries: GCC only uses a .gch while no other tokens have been seen.
|
||||
|
||||
@@ -166,3 +166,12 @@ def test_include_closure_raises_when_identity_unknown(
|
||||
with pytest.raises(OSError, match="stat failed"):
|
||||
pch._include_closure(_FakeSrcDir(), ["a.h"])
|
||||
assert "Could not read a.h" in caplog.text
|
||||
|
||||
|
||||
def test_include_closure_survives_non_utf8_include_name(tmp_path: Path) -> None:
|
||||
"""A non-UTF-8 quoted include must not abort the build; it simply does
|
||||
not resolve and ends the walk."""
|
||||
(tmp_path / "a.h").write_bytes(b'#include "bad\xff.h"\n#include "b.h"\n')
|
||||
(tmp_path / "b.h").write_text("")
|
||||
closure = pch._include_closure(tmp_path, ["a.h"])
|
||||
assert set(closure) == {"a.h", "b.h"}
|
||||
|
||||
@@ -273,6 +273,16 @@ def test_copy_pch_script(tmp_path: Path) -> None:
|
||||
assert (tmp_path / "pch.py").read_text() == _SCRIPT.read_text()
|
||||
|
||||
|
||||
def test_pch_script_unions_user_sloppiness(
|
||||
tmp_path: Path, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
"""A user CCACHE_SLOPPINESS without the pch tokens gets them unioned on,
|
||||
mirroring ccache_pch_env, or every src TU is a permanent miss."""
|
||||
scons_env = _run_script(tmp_path, env_vars={"CCACHE_SLOPPINESS": "locale"})
|
||||
assert scons_env["ENV"]["CCACHE_SLOPPINESS"] == "locale,pch_defines,time_macros"
|
||||
assert "adding pch_defines,time_macros" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_pch_script_nobuild_without_projenv_is_noop(tmp_path: Path) -> None:
|
||||
"""-t nobuild never exports projenv; the script must not abort."""
|
||||
proj = tmp_path / "dev"
|
||||
|
||||
Reference in New Issue
Block a user