Guard the prefix for C edges, gate it on the pch knob, pin its resolution

This commit is contained in:
J. Nick Koston
2026-08-27 00:21:14 -05:00
parent fd871b8898
commit a0c3a010e4
3 changed files with 40 additions and 9 deletions
+11 -9
View File
@@ -1,4 +1,4 @@
from esphome.build_helpers.pch import pch_extra_scripts
from esphome.build_helpers.pch import pch_enabled, pch_extra_scripts
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import (
@@ -19,6 +19,9 @@ from .const import KEY_HOST
# force import gpio to register pin schema
from .gpio import host_pin_to_code # noqa: F401
# Guarded wrapper: build_src_flags reaches C/assembly edges too
HOST_PCH_PREFIX = "esphome/core/pch_prefix.h"
CODEOWNERS = ["@esphome/core", "@clydebarrow"]
AUTO_LOAD = ["network", "preferences"]
IS_TARGET_PLATFORM = True
@@ -57,14 +60,13 @@ async def to_code(config: ConfigType) -> None:
cg.add_platformio_option("lib_ldf_mode", "off")
cg.add_platformio_option("lib_compat_mode", "strict")
cg.add_platformio_option("extra_scripts", ["pre:ccache.py", *pch_extra_scripts()])
# Curated prefix for the pch (the script folds these plus defines.h):
# host has no framework force-includes, and the per-TU cost is the STL
# closure behind these core headers. Measured -43% compile CPU.
# macOS system clang cannot load a GCC .gch; the load probe falls back.
cg.add_platformio_option(
"build_src_flags",
"-include esphome/core/application.h -include esphome/core/automation.h",
)
if pch_enabled():
# Curated prefix for the pch (the script folds it plus defines.h):
# host has no framework force-includes, and the per-TU cost is the
# STL closure behind the core headers. Measured -43% compile CPU.
# Gated so ESPHOME_PCH_ENABLE=0 restores the strict view; a
# toolchain that cannot load its own pch hits the script's probe.
cg.add_platformio_option("build_src_flags", f"-include {HOST_PCH_PREFIX}")
# Called by writer.py
+8
View File
@@ -0,0 +1,8 @@
#pragma once
// Curated precompiled-header prefix for backends that force-include it via
// build_src_flags (the pch script folds it into the .gch). Guarded because
// build_src_flags also reaches C and assembly src edges.
#ifdef __cplusplus
#include "esphome/core/application.h"
#include "esphome/core/automation.h"
#endif
+21
View File
@@ -0,0 +1,21 @@
"""The host pch prefix must keep resolving; a rename would silently
collapse the precompiled set to defines.h with strict CI still green."""
from pathlib import Path
import re
from esphome.components.host import HOST_PCH_PREFIX
REPO = Path(__file__).parents[2]
def test_host_pch_prefix_resolves() -> None:
prefix = REPO / HOST_PCH_PREFIX
assert prefix.is_file()
body = prefix.read_text()
includes = re.findall(r'#include "([^"]+)"', body)
assert includes, "prefix wrapper folds nothing"
for name in includes:
assert (REPO / name).is_file(), f"{name} does not resolve"
# The C guard is what keeps build_src_flags safe on C/assembly edges
assert "#ifdef __cplusplus" in body