Merge branch 'platformio-pch-rp2' into platformio-pch-libretiny

This commit is contained in:
J. Nick Koston
2026-08-25 15:05:58 -05:00
6 changed files with 58 additions and 11 deletions
+6
View File
@@ -50,6 +50,12 @@ def ccache_pch_env() -> dict[str, str]:
return {k: v for k, v in _CCACHE_PCH_ENV.items() if k not in os.environ}
def pch_extra_scripts() -> list[str]:
"""The extra_scripts entries a PlatformIO platform registers for the
pch; empty when disabled (the script itself has no enable check)."""
return ["post:pch.py"] if pch_enabled() else []
def pch_header_text(include_headers: Iterable[str]) -> str:
"""The prefix-header source: exactly these includes, in order."""
return "".join(f'#include "{name}"\n' for name in include_headers)
+2 -4
View File
@@ -6,7 +6,7 @@ import subprocess
import time
from typing import Any
from esphome.build_helpers.pch import pch_enabled
from esphome.build_helpers.pch import pch_extra_scripts
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import (
@@ -421,9 +421,7 @@ async def to_code(config: ConfigType) -> None:
]
if not enable_scanf_float:
extra_scripts.append("pre:remove_float_scanf.py")
# Generation-time gate: the script itself has no enable check
if pch_enabled():
extra_scripts.append("post:pch.py")
extra_scripts.extend(pch_extra_scripts())
extra_scripts.append("post:post_build.py")
cg.add_platformio_option("extra_scripts", extra_scripts)
+5 -7
View File
@@ -6,7 +6,7 @@ from string import ascii_letters, digits
import subprocess
from typing import Any
from esphome.build_helpers.pch import pch_enabled
from esphome.build_helpers.pch import pch_extra_scripts
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import (
@@ -341,12 +341,10 @@ async def to_code(config: ConfigType) -> None:
cg.add_define("ESPHOME_VARIANT", VARIANT_FRIENDLY[variant])
cg.add_define(ThreadModel.SINGLE)
extra_scripts = ["pre:ccache.py"]
# Generation-time gate: the script itself has no enable check
if pch_enabled():
extra_scripts.append("post:pch.py")
extra_scripts.append("post:post_build.py")
cg.add_platformio_option("extra_scripts", extra_scripts)
cg.add_platformio_option(
"extra_scripts",
["pre:ccache.py", *pch_extra_scripts(), "post:post_build.py"],
)
conf = config[CONF_FRAMEWORK]
cg.add_platformio_option("framework", "arduino")
+22
View File
@@ -115,6 +115,28 @@ def _setup_pch() -> None:
digest.update(rel.encode())
digest.update(closure[rel])
digest.update(b"\0")
# Project-local include dirs outside src (e.g. rp2's lwip_override)
# hold generated headers the src closure cannot see; hash them so an
# ESPHome-side change invalidates an existing build dir
prev = ""
for tok in flags:
inc = tok[2:] if tok.startswith("-I") and len(tok) > 2 else ""
if prev == "-I":
inc = tok
prev = tok
if not inc:
continue
inc_dir = Path(inc)
if not (
inc_dir.is_dir()
and inc_dir.is_relative_to(proj_dir)
and not inc_dir.is_relative_to(src_dir)
):
continue
for local in sorted(inc_dir.rglob("*.h")):
digest.update(str(local.relative_to(proj_dir)).encode())
digest.update(local.read_bytes())
digest.update(b"\0")
checksum = digest.hexdigest()
# The ccache .sum sidecar doubles as the freshness stamp
@@ -120,3 +120,10 @@ def test_include_closure_marks_unreadable(
locked.chmod(0o644)
assert closure["locked.h"] == b"<unreadable>"
assert "Could not read locked.h" in caplog.text
def test_pch_extra_scripts_gated(monkeypatch: pytest.MonkeyPatch) -> None:
with patch.dict(os.environ, {}, clear=True):
assert pch.pch_extra_scripts() == ["post:pch.py"]
monkeypatch.setenv("ESPHOME_PCH_ENABLE", "0")
assert pch.pch_extra_scripts() == []
@@ -165,3 +165,19 @@ def test_copy_pch_script(tmp_path: Path) -> None:
CORE.build_path = tmp_path
toolchain.copy_pch_script()
assert (tmp_path / "pch.py").read_text() == _SCRIPT.read_text()
def test_pch_script_hashes_project_local_include_dirs(tmp_path: Path) -> None:
"""Generated headers in project-local -I dirs (e.g. rp2's lwip_override)
must invalidate the checksum when they change."""
proj = tmp_path / "dev"
override = proj / "lwip_override"
override.mkdir(parents=True)
(override / "lwipopts.h").write_text("#define TCP_MSS 1460\n")
flags = ["-DX=1", "-I", str(override)]
_run_script(tmp_path, flags=flags)
first = (proj / "esphome_pch.h.gch.sum").read_text()
(override / "lwipopts.h").write_text("#define TCP_MSS 536\n")
(tmp_path / "fake-gxx.argv").unlink(missing_ok=True)
_run_script(tmp_path, flags=flags)
assert (proj / "esphome_pch.h.gch.sum").read_text() != first