diff --git a/esphome/components/nrf52/framework.py b/esphome/components/nrf52/framework.py index fa6f7d57ade..623cd4eef3d 100644 --- a/esphome/components/nrf52/framework.py +++ b/esphome/components/nrf52/framework.py @@ -133,7 +133,15 @@ def get_build_env() -> dict: env = os.environ.copy() env["PATH"] = str(venv_bin_dir) + os.pathsep + env.get("PATH", "") env["ZEPHYR_BASE"] = str(_get_framework_path(version) / "zephyr") - env["Zephyr-sdk_DIR"] = str(_get_toolchain_path(TOOLCHAIN_VERSION) / "cmake") + # ZEPHYR_SDK_INSTALL_DIR is the variable Zephyr documents for pointing at + # the SDK: FindZephyr-sdk.cmake reads it (from the environment, via + # zephyr_get) and passes it straight to find_package as a HINT. This + # matters because the SDK lives in the esphome cache dir, which is not on + # the module's static search path (/usr, /opt, $HOME, ...). A generic + # "Zephyr-sdk_DIR" environment hint proved unreliable here: containerized + # non-root builds failed to locate the SDK with it, while + # ZEPHYR_SDK_INSTALL_DIR fixed the same invocation. + env["ZEPHYR_SDK_INSTALL_DIR"] = str(_get_toolchain_path(TOOLCHAIN_VERSION)) return env diff --git a/tests/unit_tests/test_nrf52_framework.py b/tests/unit_tests/test_nrf52_framework.py index bb5bc8c064c..830e9efba52 100644 --- a/tests/unit_tests/test_nrf52_framework.py +++ b/tests/unit_tests/test_nrf52_framework.py @@ -1,6 +1,7 @@ """Tests for esphome.components.nrf52.framework helpers.""" import hashlib +import os from pathlib import Path from types import SimpleNamespace from unittest.mock import patch @@ -12,11 +13,13 @@ from esphome.components.nrf52.framework import ( TOOLCHAIN_VERSION, _get_toolchain_platform_info, check_and_install, + get_build_env, get_sdk_nrf_tools_path, ) from esphome.config_validation import Version from esphome.const import KEY_CORE, KEY_FRAMEWORK_VERSION from esphome.core import CORE, EsphomeError +from esphome.framework_helpers import get_python_env_executable_path @pytest.fixture(autouse=True) @@ -252,6 +255,42 @@ class TestCheckAndInstall: assert substitutions["extension"] == "tar.xz" +# --------------------------------------------------------------------------- +# get_build_env tests +# --------------------------------------------------------------------------- + + +def test_get_build_env( + nrf52_dirs: SimpleNamespace, monkeypatch: pytest.MonkeyPatch +) -> None: + """get_build_env exposes ZEPHYR_SDK_INSTALL_DIR pointing at the toolchain root. + + ZEPHYR_SDK_INSTALL_DIR is the variable Zephyr's FindZephyr-sdk.cmake + explicitly consumes (from the environment) and uses as a find_package + HINT. The old Zephyr-sdk_DIR environment hint proved unreliable in + containerized non-root builds and was removed. + """ + monkeypatch.setenv("SOME_PREEXISTING_VAR", "kept") + + env = get_build_env() + + tools = get_sdk_nrf_tools_path() + venv_bin_dir = get_python_env_executable_path( + tools / "penvs" / f"v{_TEST_SDK_VERSION}", "python" + ).parent + assert env["PATH"].startswith(str(venv_bin_dir) + os.pathsep) + assert env["ZEPHYR_BASE"] == str( + tools / "frameworks" / f"v{_TEST_SDK_VERSION}" / "zephyr" + ) + # Toolchain root, not the cmake/ subdir + assert env["ZEPHYR_SDK_INSTALL_DIR"] == str( + tools / "toolchains" / TOOLCHAIN_VERSION + ) + assert "Zephyr-sdk_DIR" not in env + # The rest of the process environment is inherited + assert env["SOME_PREEXISTING_VAR"] == "kept" + + # --------------------------------------------------------------------------- # get_sdk_nrf_tools_path tests # ---------------------------------------------------------------------------