mirror of
https://github.com/esphome/esphome.git
synced 2026-10-01 00:40:21 +00:00
[platformio] Fix ccache path for non-root containers (#19807)
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
@@ -21,10 +21,14 @@ export PLATFORMIO_PLATFORMS_DIR="${pio_cache_base}/platforms"
|
||||
export PLATFORMIO_PACKAGES_DIR="${pio_cache_base}/packages"
|
||||
export PLATFORMIO_CACHE_DIR="${pio_cache_base}/cache"
|
||||
|
||||
# Keep the native toolchain installs on the persistent cache root, not the
|
||||
# container's ephemeral user cache dir (re-downloaded on every restart).
|
||||
# Keep the native toolchain installs and compiler caches on the persistent
|
||||
# cache root, not the container's user cache dir: it is lost on every
|
||||
# restart, and not writable when the container runs as a non-root user.
|
||||
export ESPHOME_ESP_IDF_PREFIX="$(dirname "${pio_cache_base}")/idf"
|
||||
export ESPHOME_SDK_NRF_PREFIX="$(dirname "${pio_cache_base}")/sdk-nrf"
|
||||
export ESPHOME_ARDUINO8266_PREFIX="$(dirname "${pio_cache_base}")/arduino8266"
|
||||
export ESPHOME_HOST_PREFIX="$(dirname "${pio_cache_base}")/host"
|
||||
export ESPHOME_PLATFORMIO_CCACHE_DIR="$(dirname "${pio_cache_base}")/platformio-ccache"
|
||||
|
||||
# If /build is mounted, use that as the build path
|
||||
# otherwise use path in /config (so that builds aren't lost on container restart)
|
||||
|
||||
@@ -15,10 +15,14 @@ export PLATFORMIO_PLATFORMS_DIR="${pio_cache_base}/platforms"
|
||||
export PLATFORMIO_PACKAGES_DIR="${pio_cache_base}/packages"
|
||||
export PLATFORMIO_CACHE_DIR="${pio_cache_base}/cache"
|
||||
|
||||
# Keep the native toolchain installs on the persistent /data volume, not the
|
||||
# container's ephemeral user cache dir (wiped on every add-on update/restart).
|
||||
# Keep the native toolchain installs and compiler caches on the persistent
|
||||
# /data volume, not the container's ephemeral user cache dir (wiped on every
|
||||
# add-on update/restart).
|
||||
export ESPHOME_ESP_IDF_PREFIX=/data/cache/idf
|
||||
export ESPHOME_SDK_NRF_PREFIX=/data/cache/sdk-nrf
|
||||
export ESPHOME_ARDUINO8266_PREFIX=/data/cache/arduino8266
|
||||
export ESPHOME_HOST_PREFIX=/data/cache/host
|
||||
export ESPHOME_PLATFORMIO_CCACHE_DIR=/data/cache/platformio-ccache
|
||||
|
||||
if bashio::config.true 'leave_front_door_open'; then
|
||||
export DISABLE_HA_AUTHENTICATION=true
|
||||
|
||||
@@ -35,9 +35,12 @@ SDK_NRF_TOOLS_CACHE = ("ESPHOME_SDK_NRF_PREFIX", "sdk-nrf")
|
||||
ARDUINO8266_TOOLS_CACHE = ("ESPHOME_ARDUINO8266_PREFIX", "arduino8266")
|
||||
# The host backend installs nothing; the entry only holds its ccache dir
|
||||
HOST_TOOLS_CACHE = ("ESPHOME_HOST_PREFIX", "host")
|
||||
# PlatformIO installs into its own dirs; the entry is its ccache dir itself
|
||||
PLATFORMIO_CCACHE = ("ESPHOME_PLATFORMIO_CCACHE_DIR", "platformio-ccache")
|
||||
TOOLS_CACHE_SPECS = (
|
||||
IDF_TOOLS_CACHE,
|
||||
SDK_NRF_TOOLS_CACHE,
|
||||
ARDUINO8266_TOOLS_CACHE,
|
||||
HOST_TOOLS_CACHE,
|
||||
PLATFORMIO_CCACHE,
|
||||
)
|
||||
|
||||
@@ -7,9 +7,8 @@ import re
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import platformdirs
|
||||
|
||||
from esphome.build_helpers.ccache import resolve_ccache_path
|
||||
from esphome.build_helpers.tools_cache import PLATFORMIO_CCACHE, tools_cache_path
|
||||
from esphome.const import CONF_COMPILE_PROCESS_LIMIT, CONF_ESPHOME, KEY_CORE
|
||||
from esphome.core import CORE, EsphomeError
|
||||
from esphome.framework_helpers import strip_win_long_path_prefix
|
||||
@@ -235,8 +234,9 @@ def _ccache_env() -> dict[str, str]:
|
||||
these values would hand it the wrong cache dir and a stale basedir.
|
||||
|
||||
This mirrors ``_ccache_env()`` in ``esphome/espidf/framework.py``. The
|
||||
cache lives under the machine-global ESPHome cache dir, so it is shared
|
||||
across all projects and removed by ``esphome clean-all``. Unlike the
|
||||
cache lives under the machine-global ESPHome cache dir, or where
|
||||
``ESPHOME_PLATFORMIO_CCACHE_DIR`` points (the containers set it to their
|
||||
writable cache mount), and is removed by ``esphome clean-all``. Unlike the
|
||||
ESP-IDF path, ``CCACHE_DEPEND`` is not set: SCons compiles don't emit
|
||||
the depfiles depend mode needs, so ccache's default preprocessor mode
|
||||
is used.
|
||||
@@ -264,10 +264,7 @@ def _ccache_env() -> dict[str, str]:
|
||||
)
|
||||
env["CCACHE_BASEDIR"] = str(Path(CORE.build_path).resolve())
|
||||
defaults = {
|
||||
"CCACHE_DIR": str(
|
||||
Path(platformdirs.user_cache_dir("esphome", appauthor=False))
|
||||
/ "platformio-ccache"
|
||||
),
|
||||
"CCACHE_DIR": str(tools_cache_path(*PLATFORMIO_CCACHE)),
|
||||
"CCACHE_NOHASHDIR": "true",
|
||||
}
|
||||
env.update({k: v for k, v in defaults.items() if k not in os.environ})
|
||||
|
||||
@@ -447,6 +447,47 @@ def test_ccache_env_enabled_by_default(setup_core: Path) -> None:
|
||||
assert "ESPHOME_CCACHE_ENABLE" not in os.environ
|
||||
|
||||
|
||||
def test_ccache_env_uses_cache_dir_override(setup_core: Path, tmp_path: Path) -> None:
|
||||
"""The containers point ccache at their writable cache mount."""
|
||||
CORE.build_path = setup_core / "build" / "test"
|
||||
ccache_dir = tmp_path / "cache" / "platformio-ccache"
|
||||
|
||||
with (
|
||||
patch.dict(
|
||||
os.environ,
|
||||
{"HOME": "/", "ESPHOME_PLATFORMIO_CCACHE_DIR": str(ccache_dir)},
|
||||
clear=True,
|
||||
),
|
||||
patch("shutil.which", return_value="/usr/bin/ccache"),
|
||||
patch("esphome.framework_helpers.subprocess.run"),
|
||||
):
|
||||
env = toolchain._ccache_env()
|
||||
|
||||
assert env["CCACHE_DIR"] == str(ccache_dir.resolve())
|
||||
|
||||
|
||||
def test_ccache_env_ignores_platformio_cache_dir(
|
||||
setup_core: Path, tmp_path: Path
|
||||
) -> None:
|
||||
"""PLATFORMIO_CACHE_DIR does not move ccache; only the override does."""
|
||||
CORE.build_path = setup_core / "build" / "test"
|
||||
cache_root = tmp_path / "user-cache"
|
||||
|
||||
with (
|
||||
patch.dict(
|
||||
os.environ,
|
||||
{"PLATFORMIO_CACHE_DIR": str(tmp_path / "platformio" / "cache")},
|
||||
clear=True,
|
||||
),
|
||||
patch("platformdirs.user_cache_dir", return_value=str(cache_root)),
|
||||
patch("shutil.which", return_value="/usr/bin/ccache"),
|
||||
patch("esphome.framework_helpers.subprocess.run"),
|
||||
):
|
||||
env = toolchain._ccache_env()
|
||||
|
||||
assert env["CCACHE_DIR"] == str((cache_root / "platformio-ccache").resolve())
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("env_vars", "expect_warning"),
|
||||
[
|
||||
@@ -582,6 +623,7 @@ def test_ccache_env_respects_user_values_and_refreshes_basedir(
|
||||
user_env = {
|
||||
"CCACHE_DIR": "/custom/cache",
|
||||
"CCACHE_BASEDIR": "/stale/other-device",
|
||||
"ESPHOME_PLATFORMIO_CCACHE_DIR": "/mounted/platformio-ccache",
|
||||
}
|
||||
CORE.build_path = setup_core / "build" / "test"
|
||||
|
||||
|
||||
@@ -1085,6 +1085,28 @@ def test_clean_all_removes_global_arduino8266_install(
|
||||
assert str(arduino8266_install.resolve()) in caplog.text
|
||||
|
||||
|
||||
@patch("esphome.writer.CORE")
|
||||
def test_clean_all_removes_platformio_ccache(
|
||||
mock_core: MagicMock,
|
||||
tmp_path: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""clean_all removes the PlatformIO ccache dir the containers relocate."""
|
||||
ccache_dir = tmp_path / "platformio-ccache"
|
||||
(ccache_dir / "0").mkdir(parents=True)
|
||||
monkeypatch.setenv("ESPHOME_PLATFORMIO_CCACHE_DIR", str(ccache_dir))
|
||||
|
||||
config_dir = tmp_path / "config"
|
||||
config_dir.mkdir()
|
||||
|
||||
with caplog.at_level("INFO"):
|
||||
clean_all([str(config_dir)])
|
||||
|
||||
assert not ccache_dir.exists()
|
||||
assert str(ccache_dir.resolve()) in caplog.text
|
||||
|
||||
|
||||
@patch("esphome.writer.CORE")
|
||||
def test_clean_all_removes_default_cache_root(
|
||||
mock_core: MagicMock,
|
||||
|
||||
Reference in New Issue
Block a user