[core] Fix the native ESP8266 and host builds on Windows without ccache (#20468)

This commit is contained in:
J. Nick Koston
2026-10-10 07:39:49 -10:00
committed by GitHub
parent f4fbc3215d
commit 4ba0e1bfa2
6 changed files with 40 additions and 11 deletions
+1 -1
View File
@@ -1057,7 +1057,7 @@ def write_project(paths: InstalledPaths, ccache: str | None) -> bool:
cxx = (toolchain_tool(paths.toolchain, "g++"),)
lines = [
*tool_lines((toolchain_tool(paths.toolchain, "gcc"),), cxx, ccache),
*compile_rule_lines(),
*compile_rule_lines(ccache),
*ar_rule_lines(toolchain_tool(paths.toolchain, "ar")),
*pch_rule_lines(),
"rule link",
+1 -1
View File
@@ -240,7 +240,7 @@ def write_project(compilers: HostCompilers, ccache: str | None) -> bool:
lines = [
*tool_lines(compilers.cc, compilers.cxx, ccache),
*compile_rule_lines(),
*compile_rule_lines(ccache),
*pch_rule_lines(),
"rule link",
" command = $cxx -o $out $linkflags @$out.rsp $archives $libdirflags $libflags",
+14 -7
View File
@@ -74,33 +74,40 @@ def tool_lines(
# path gets
f"python = {_q(strip_win_long_path_prefix(sys.executable))}",
f"buildtool = {_q(_BUILD_TOOL)}",
f"ccache = {_q(ccache) if ccache else ''}",
*([f"ccache = {_q(ccache)}"] if ccache else []),
"",
]
def compile_rule_lines() -> list[str]:
"""The compile rules; ``$own_includes`` is empty unless an edge sets it."""
def compile_rule_lines(ccache: str | None) -> list[str]:
"""The compile rules; ``$own_includes`` is empty unless an edge sets it.
``ccache`` is the launcher ``tool_lines`` was given; the same test here
keeps the variable and the rules in step. It is spliced in rather than
left as an empty variable: a leading space on the command line makes
CreateProcess fail on Windows.
"""
launcher = "$ccache " if ccache else ""
return [
"rule c",
" command = $ccache $cc -MMD -MF $out.d $own_includes $cflags $flags -c $in -o $out",
f" command = {launcher}$cc -MMD -MF $out.d $own_includes $cflags $flags -c $in -o $out",
" depfile = $out.d",
" deps = gcc",
" description = CC $out",
"rule cxx",
" command = $ccache $cxx -MMD -MF $out.d $own_includes $cxxflags $flags -c $in -o $out",
f" command = {launcher}$cxx -MMD -MF $out.d $own_includes $cxxflags $flags -c $in -o $out",
" depfile = $out.d",
" deps = gcc",
" description = CXX $out",
"rule aspp",
" command = $ccache $cc -MMD -MF $out.d -x assembler-with-cpp $own_includes $asflags $flags -c $in -o $out",
f" command = {launcher}$cc -MMD -MF $out.d -x assembler-with-cpp $own_includes $asflags $flags -c $in -o $out",
" depfile = $out.d",
" deps = gcc",
" description = AS $out",
# Plain assembler, as SCons's ASCOM: no preprocessor, so no
# depfile and no $flags (defines/includes) either
"rule asm",
" command = $ccache $cc -x assembler $asflags -c $in -o $out",
f" command = {launcher}$cc -x assembler $asflags -c $in -o $out",
" description = AS $out",
]
@@ -888,8 +888,9 @@ def test_write_project_plain_asm_rule_skips_preprocessor(tmp_path: Path) -> None
_set_flags()
content = _write_ninja(paths)
assert "lowlevel.s.o: asm " in content
assert "rule asm\n command = $cc -x assembler $asflags -c $in -o $out" in content
assert "rule asm\n command = $ccache $cc -x assembler $asflags -c $in -o $out" in (
content
_write_ninja(paths, ccache="/cc/ccache")
)
+4 -1
View File
@@ -308,7 +308,10 @@ def test_write_project_pch_skipped_for_a_force_include_in_the_compiler(
def test_write_project_without_ccache(tmp_path: Path) -> None:
_make_src(tmp_path, "main.cpp")
_changed, ninja = _render()
assert "ccache = \n" in ninja
# No launcher variable, and no leading space on the commands either:
# CreateProcess on Windows rejects a command line that starts with one
assert "$ccache" not in ninja
assert " command = $cxx -MMD -MF $out.d" in ninja
def test_write_project_routes_user_link_flags(tmp_path: Path) -> None:
@@ -55,3 +55,21 @@ def test_collect_sources_skips_excluded_and_other_files(tmp_path: Path) -> None:
tmp_path / "b.cpp",
tmp_path / "sub" / "c.S",
]
@pytest.mark.parametrize("ccache", ["/usr/bin/ccache", None])
def test_compile_rule_lines_splice_the_launcher(ccache: str | None) -> None:
"""Without ccache no command keeps a leading space, which CreateProcess
on Windows rejects; with it every compile rule starts with the launcher."""
commands = [
line.removeprefix(" command = ")
for line in ninja_gen.compile_rule_lines(ccache)
if line.startswith(" command = ")
]
assert len(commands) == 4
for command in commands:
if ccache:
assert command.startswith("$ccache $c")
else:
assert command.startswith("$c")
assert "$ccache" not in command