mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
Merge branch 'esp8266-native-pch' into esp32-idf-pch
This commit is contained in:
@@ -36,6 +36,7 @@ from esphome.build_helpers.ninja import (
|
||||
from esphome.build_helpers.pch import (
|
||||
PCH_CORE_HEADER,
|
||||
PCH_HEADER_NAME,
|
||||
mark_pch_emitted,
|
||||
pch_checksum,
|
||||
pch_enabled,
|
||||
pch_header_text,
|
||||
@@ -1284,6 +1285,7 @@ def write_project(paths: InstalledPaths, ccache: str | None) -> bool:
|
||||
]
|
||||
lines.append(f"srccxxflags = {' '.join(cxx_parts)}")
|
||||
src_cxx_override = ("$srccxxflags", gch)
|
||||
mark_pch_emitted()
|
||||
src_objs = _ninja_compile_edges(
|
||||
lines,
|
||||
_collect_sources(src_dir),
|
||||
|
||||
@@ -8,6 +8,7 @@ it too; Arduino.h visibility there is intended (esphome#8693).
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
@@ -25,6 +26,27 @@ from esphome.build_helpers.idedata import (
|
||||
split_command,
|
||||
)
|
||||
|
||||
_DOMAIN = "pch"
|
||||
|
||||
|
||||
@dataclass
|
||||
class _PCHData:
|
||||
emitted: bool = False
|
||||
|
||||
|
||||
def _pch_data() -> _PCHData:
|
||||
from esphome.core import CORE
|
||||
|
||||
if _DOMAIN not in CORE.data:
|
||||
CORE.data[_DOMAIN] = _PCHData()
|
||||
return CORE.data[_DOMAIN]
|
||||
|
||||
|
||||
def mark_pch_emitted() -> None:
|
||||
"""Record that this build's consumers reference the pch."""
|
||||
_pch_data().emitted = True
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# The header and its .gch/.sum sidecars live in the build directory.
|
||||
@@ -81,9 +103,10 @@ def pch_enabled() -> bool:
|
||||
|
||||
def ccache_pch_env() -> dict[str, str]:
|
||||
"""Settings ccache needs to cache compiles that consume the .gch;
|
||||
empty when the pch is disabled. User-set values win. Native backends
|
||||
export these process-wide; only time_macros affects non-pch TUs."""
|
||||
if not pch_enabled():
|
||||
empty unless this build actually emitted one. User-set values win.
|
||||
Native backends export these process-wide; only time_macros affects
|
||||
non-pch TUs."""
|
||||
if not (pch_enabled() and _pch_data().emitted):
|
||||
return {}
|
||||
env = {k: v for k, v in _CCACHE_PCH_ENV.items() if k not in os.environ}
|
||||
user_sloppiness = os.environ.get("CCACHE_SLOPPINESS")
|
||||
|
||||
@@ -386,6 +386,10 @@ def test_write_project_pch(tmp_path: Path) -> None:
|
||||
'#include "esphome/core/defines.h"',
|
||||
]
|
||||
assert (build_dir / "esphome_pch.h.gch.sum").read_text().strip()
|
||||
# Emission recorded so the framework env exports the ccache settings
|
||||
from esphome.build_helpers.pch import ccache_pch_env
|
||||
|
||||
assert "CCACHE_PCH_EXTSUM" in ccache_pch_env()
|
||||
|
||||
|
||||
def test_write_project_pch_sum_only_with_ccache(tmp_path: Path) -> None:
|
||||
@@ -456,6 +460,10 @@ def test_write_project_pch_skipped_when_user_force_include_precedes(
|
||||
assert "esphome_pch" not in content
|
||||
assert "srccxxflags" not in content
|
||||
assert "prevents the precompiled header" in caplog.text
|
||||
# No pch emitted: the ccache relaxation must stay off
|
||||
from esphome.build_helpers.pch import ccache_pch_env
|
||||
|
||||
assert ccache_pch_env() == {}
|
||||
|
||||
|
||||
def test_write_project_pch_disabled(
|
||||
|
||||
@@ -33,7 +33,14 @@ def test_pch_enabled(value: str | None, expected: bool) -> None:
|
||||
assert pch.pch_enabled() is expected
|
||||
|
||||
|
||||
def test_ccache_pch_env_empty_until_emitted() -> None:
|
||||
"""No sloppiness relaxation for a build that skipped the pch."""
|
||||
with patch.dict(os.environ, {}, clear=True):
|
||||
assert pch.ccache_pch_env() == {}
|
||||
|
||||
|
||||
def test_ccache_pch_env_enabled() -> None:
|
||||
pch.mark_pch_emitted()
|
||||
with patch.dict(os.environ, {}, clear=True):
|
||||
env = pch.ccache_pch_env()
|
||||
assert env["CCACHE_SLOPPINESS"] == "pch_defines,time_macros"
|
||||
@@ -48,6 +55,7 @@ def test_ccache_pch_env_disabled() -> None:
|
||||
def test_ccache_pch_env_token_check_is_membership_not_substring(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
pch.mark_pch_emitted()
|
||||
"""A token merely containing ours must not suppress the union."""
|
||||
with patch.dict(os.environ, {"CCACHE_SLOPPINESS": "pch_defines_extra"}, clear=True):
|
||||
env = pch.ccache_pch_env()
|
||||
@@ -57,6 +65,7 @@ def test_ccache_pch_env_token_check_is_membership_not_substring(
|
||||
def test_ccache_pch_env_unions_user_sloppiness(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
pch.mark_pch_emitted()
|
||||
"""Without pch_defines/time_macros ccache declines every pch-consuming
|
||||
compile, so missing tokens are unioned onto the user's value."""
|
||||
with patch.dict(os.environ, {"CCACHE_SLOPPINESS": "locale"}, clear=True):
|
||||
|
||||
@@ -9,6 +9,7 @@ from unittest.mock import MagicMock, patch
|
||||
import pytest
|
||||
|
||||
from esphome.arduino8266 import framework, toolchain
|
||||
from esphome.build_helpers.pch import mark_pch_emitted
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_COMPILE_PROCESS_LIMIT,
|
||||
@@ -632,6 +633,7 @@ def test_get_idedata_accepts_preresolved_ccache() -> None:
|
||||
|
||||
|
||||
def test_ccache_env_includes_pch_settings() -> None:
|
||||
mark_pch_emitted()
|
||||
"""The native build exports the ccache settings the pch needs."""
|
||||
with patch.dict(os.environ, {}, clear=True):
|
||||
env = framework.ccache_env("/usr/bin/ccache")
|
||||
@@ -647,6 +649,7 @@ def test_ccache_env_pch_disabled() -> None:
|
||||
|
||||
|
||||
def test_ccache_env_respects_user_sloppiness() -> None:
|
||||
mark_pch_emitted()
|
||||
with patch.dict(os.environ, {"CCACHE_SLOPPINESS": "locale"}, clear=True):
|
||||
env = framework.ccache_env("/usr/bin/ccache")
|
||||
# The user's tokens survive; the ones the pch needs are unioned on
|
||||
|
||||
Reference in New Issue
Block a user