Generate the Zephyr syscall headers before compiling the pch

This commit is contained in:
J. Nick Koston
2026-08-27 10:44:38 -05:00
parent 8defc48611
commit 21c1c582b5
2 changed files with 41 additions and 14 deletions
+23 -9
View File
@@ -963,15 +963,29 @@ def run_compile(args, config: ConfigType) -> bool:
# so an existing DB is settled, and --cmake-only reconfigures.
# Sysbuild configures the app image during its own configure, so the
# app's flags and autoconf.h are settled after this phase too.
if not (
_app_build_dir(build_dir) / "compile_commands.json"
).is_file() and not run_command_ok(
west_cmd + ["--cmake-only", "--", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"],
env=env,
stream_output=True,
cwd=str(paths["framework_path"]),
):
raise EsphomeError("nRF52 native build failed")
if not (_app_build_dir(build_dir) / "compile_commands.json").is_file():
if not run_command_ok(
west_cmd + ["--cmake-only", "--", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"],
env=env,
stream_output=True,
cwd=str(paths["framework_path"]),
):
raise EsphomeError("nRF52 native build failed")
# The pch includes zephyr/kernel.h, whose syscall headers are
# generated at build time (same target the clang-tidy flow uses)
if not run_command_ok(
[
"cmake",
"--build",
str(_app_build_dir(build_dir)),
"--target",
"zephyr_generated_headers",
],
env=env,
stream_output=True,
cwd=str(paths["framework_path"]),
):
raise EsphomeError("nRF52 native build failed")
# An optional speedup must never abort the build
app_dir = _app_build_dir(build_dir)
+18 -5
View File
@@ -195,7 +195,8 @@ class TestRunCompilePhases:
def test_missing_db_runs_cmake_phase(self, compile_ctx) -> None:
run_cmd, prepare, build_dir = compile_ctx
results = iter([True, False]) # cmake-only ok, final build fails
# cmake-only ok, generated headers ok, final build fails
results = iter([True, True, False])
def west(cmd, **kwargs):
# Phase 1 configures the sysbuild app domain
@@ -208,10 +209,22 @@ class TestRunCompilePhases:
with pytest.raises(EsphomeError, match="nRF52 native build failed"):
self._run()
assert "--cmake-only" in run_cmd.call_args_list[0].args[0]
assert "--cmake-only" not in run_cmd.call_args_list[1].args[0]
# Generated syscall headers are built in the app domain pre-pch
headers_cmd = run_cmd.call_args_list[1].args[0]
assert headers_cmd[:2] == ["cmake", "--build"]
assert str(build_dir / "zephyr") in headers_cmd
assert "zephyr_generated_headers" in headers_cmd
assert "--cmake-only" not in run_cmd.call_args_list[2].args[0]
# The pch is prepared in the app domain dir, not the sysbuild root
assert prepare.call_args.args[0] == build_dir / "zephyr"
def test_generated_headers_failure_raises(self, compile_ctx) -> None:
run_cmd, prepare, _ = compile_ctx
run_cmd.side_effect = [True, False]
with pytest.raises(EsphomeError, match="nRF52 native build failed"):
self._run()
assert not prepare.called
def test_cmake_phase_failure_raises(self, compile_ctx) -> None:
run_cmd, prepare, _ = compile_ctx
run_cmd.side_effect = [False]
@@ -264,10 +277,10 @@ class TestRunCompilePhases:
) -> None:
run_cmd, prepare, _ = compile_ctx
prepare.side_effect = RuntimeError("boom")
run_cmd.side_effect = [True, False]
run_cmd.side_effect = [True, True, False]
with pytest.raises(EsphomeError, match="nRF52 native build failed"):
self._run()
assert run_cmd.call_count == 2
assert run_cmd.call_count == 3
assert "Precompiled header setup failed" in caplog.text
def test_prepare_failure_strict_raises(
@@ -276,6 +289,6 @@ class TestRunCompilePhases:
monkeypatch.setenv("ESPHOME_PCH_STRICT", "1")
run_cmd, prepare, _ = compile_ctx
prepare.side_effect = RuntimeError("boom")
run_cmd.side_effect = [True]
run_cmd.side_effect = [True, True]
with pytest.raises(RuntimeError, match="boom"):
self._run()