Skip to content

ci: link the Windows OpenVMM test builds with /Brepro for sccache - #714

Merged
Pedro Henrique Penna (ppenna) merged 1 commit into
devfrom
agents/windows-sccache-misses
Oct 21, 2026
Merged

Pedro Henrique Penna (ppenna) merged 1 commit into
devfrom
agents/windows-sccache-misses

Conversation

@ppenna

@ppenna Pedro Henrique Penna (ppenna) commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #693.
Part of #430.

Summary

On Windows, every OpenVMM build relinked each proc macro into a DLL with new bytes, because MSVC's link.exe stamps the time of the link and a random PDB signature into every image. sccache keys a compilation on the contents of the libraries that it names with --extern, so each crate that uses a proc macro directly missed the cache in every build, on every runner, whatever the cache size. This PR makes test-openvmm and test-openvmm-unit append /Brepro to _LINK_ on Windows, which makes link.exe derive both from the image's contents. With it, a warm runner hits 99.7% of the WHP VMM-test compilations and 99.5% of the Windows unit-test ones, like Linux.

The investigation, the breakdown of the WHP test-openvmm step, the shared-cache evaluation, and the SCCACHE_CACHE_SIZE recommendation are recorded on #693.

Why

Constant misses. Over 13 WHP VMM-test jobs of dev pushes from October 19 to 21 (39254314492 through 39603556404), on six runners whose caches held 4 to 10 GiB, every job made 1,779 requests and had 1,174 hits and 247 misses (82.62%). The 8 Windows unit-test jobs of runners with warm caches each had 293 misses (77.77%). Linux KVM and unit-test jobs had 4 and 9 misses (99.7% and 99.3%).

Cause. A diagnostic run on a temporary branch (39616159470) built the WHP VMM tests with SCCACHE_LOG=debug:

Job (runner) Build Hits Misses Hit rate Proc-macro DLLs
Without /Brepro (azure-windows-3) 1 1,174 247 82.62%
2, same job 1,174 247 82.62% all 99 differ from build 1
With /Brepro (azure-windows-6) 1 1,183 238 83.25%
2, same job 1,417 4 99.72% all 99 identical to build 1
Unit tests with /Brepro (azure-windows-1) 1 1,025 293 77.77%
2, same job 1,311 7 99.47%
  • Between the two builds without /Brepro, 1,431 of the 1,438 cacheable compilations had identical arguments (the other 7 differ only in the order of --cfg flags, which sccache sorts), yet 244 of the 247 misses named a proc-macro DLL with --extern, and none of the 1,174 hits did.
  • The misses are 124 crates that use one of 30 proc macros directly, led by users of bitfield_struct (80 misses) and async_trait (70). flowey builds openvmm and pipette in target directories of their own, and the light, host, and target builds compile some crates separately, so zerocopy, thiserror, and futures-util each miss seven times per job.
  • The other 3 misses come from smoltcp 0.12, whose build script writes config.rs in HashMap order on every platform, so smoltcp, consomme, net_consomme (which also uses async_trait), and openvmm_resources miss in every build. They're the 4 misses that remain with /Brepro, and probably Linux's 4. smoltcp 0.14 sorts the file, so that's an OpenVMM dependency update, outside NVX.
  • A local reproduction with the pinned sccache 0.18.0 and Rust 1.95.0 shows the same: two clean builds produce different proc-macro DLLs, and only the crate that names one misses; with _LINK_=/Brepro, the DLLs are identical and every crate hits.

Changes

  • scripts/nvx_tools/ci.py: on Windows, run_openvmm_tests (through _prepare_openvmm_test_environment) and run_openvmm_unit_tests append /Brepro to _LINK_ for every command, including the flowey build and the fuzz-crate query, which builds xtask. link.exe appends _LINK_ to every command line, so it reaches the proc macros and build scripts that flowey builds with --target, which RUSTFLAGS would not. An existing _LINK_ is kept, and the option isn't added twice.
  • Docs: a new Compilation cache section in doc/ci.md describes the runner-local sccache caches and the change; doc/usage.md notes the commands' behavior on Windows.

No workflow, action, runner setting, or cache key changes. The sccache keys of crates that don't use a proc macro are unchanged, so only the affected crates miss once more on each runner, as they did in every job until now.

Tests

  • test_openvmm_windows_builds_link_reproducibly: the option's insertion into an empty, missing, or existing _LINK_, and no duplicate when /Brepro or -brepro is already present.
  • The existing run_openvmm_unit_tests, run_openvmm_tests, and _prepare_openvmm_test_environment tests now check the environment of every command: _LINK_ gets /Brepro on Windows and stays unchanged on Linux.

Validation

Expected effect

From the 13 dev pushes above to the second build with /Brepro in the diagnostic run:

WHP test-openvmm step Before (median) After
flowey's own build 111 s 34 s
VMM-test build for artifact discovery 288 s 241 s
openvmm build 366 s 299 s
pipette, guest_test_uefi, and the UEFI image 72 s 58 s
Before tests start 852 s 641 s
Test execution 280 s 268 s
Windows unit-test step Before (median, 8 warm jobs) After
xtask build for the fuzz-crate query 134 s 55 s
Test build 418 s 339 s
Doctest build 104 s 42 s
Whole step 876 s 643 s
  • The WHP VMM-test lane, which finishes last in most full runs, should start its tests about 3.5 minutes sooner, and the Windows unit tests should finish about 4 minutes sooner, once a runner has built the suites with /Brepro.
  • Each runner's first build with /Brepro still misses about 240 compilations once, because the new DLLs give the affected crates new keys, so this PR's own CI shows little of the effect.
  • The jobs also stop adding about 250-290 never-reused entries to each runner's 10-GiB cache, which evicted live entries.
  • Most of the remaining 641 s is non-cacheable: the release profile's ThinLTO codegen and link of the tests and openvmm executables take about 190 s each.

Post-merge verification

  • Over at least five comparable dev pushes or full runs that run both OpenVMM suites on runners that have already built them with /Brepro, compare with the 13 jobs above: the Windows Rust hit rates (expected about 99.7% and 99.5%), the WHP time before tests start (expected about 640 s), the Windows unit-test step (expected about 640 s), and the runners' cache sizes. Record them on ci: investigate why the Windows OpenVMM builds miss sccache #693.

Copilot AI balanced review requested due to automatic review settings October 21, 2026 15:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The narrow change preserves existing options and Linux behavior, includes regression coverage, and has no identified blocking issues.

No open issues 🎉

What changed in this PR

Improves Windows OpenVMM test-build cache reuse by making MSVC linking reproducible, supporting the CI turnaround goals in #693 and #430.

Changes:

  • Adds /Brepro to Windows test environments while preserving existing linker options and Linux behavior.
  • Adds regression coverage for option handling and environment propagation.
  • Documents compilation caching and Windows command behavior.
File Description
scripts/​test_nvx_tools.py Tests reproducible-link options and command environments.
scripts/​nvx_tools/​ci.py Enables reproducible linking for Windows OpenVMM test builds.
doc/​usage.md Documents Windows test-command behavior.
doc/​ci.md Explains runner-local caches and reproducible linking.

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The narrow Windows-only change has focused regression coverage and no identified blocking issues.

No open issues 🎉

Review effort: Balanced

The Windows OpenVMM jobs hit sccache for 82.6% of their Rust
compilations (VMM tests) and 77.8% (unit tests), against 99.3-99.7% on
Linux, and every job missed the same 247 and 293 compilations,
whatever its runner and cache size. sccache cannot cache proc macros,
so every build relinks them, and it keys each compilation on the
contents of the libraries that it names with --extern. MSVC's link.exe
stamps each DLL with the time of the link and a random PDB signature,
so every proc macro came out different in every build, and each crate
that uses one directly missed. flowey builds openvmm and pipette in
target directories of their own, so the same crates missed again
within the job. A diagnostic run with SCCACHE_LOG=debug (#693) built
the WHP VMM tests twice on one runner: both builds missed the same 247
compilations, all 99 proc-macro DLLs differed between them, 244 of the
misses named one of them, and none of the 1,174 hits did. The other
misses come from smoltcp 0.12, whose build script writes its
configuration in hash-map order on every platform.

On Windows, test-openvmm and test-openvmm-unit now append /Brepro to
_LINK_, which link.exe appends to every command line, so that it
derives the timestamp and signature from the image's contents.
RUSTFLAGS would not reach the proc macros of the builds that flowey
runs with --target. An existing _LINK_ is kept, and the option is not
added twice. In the same diagnostic run, the second build with /Brepro
on a runner hit 99.72% of the VMM-test compilations and 99.47% of the
unit-test ones. The time before the WHP VMM tests start fell from a
median of 852 seconds over 13 dev pushes to 641, and the Windows
unit-test step from 876 to 643 seconds. Every test still passed.

Tests cover the option's insertion, an existing _LINK_, and the
environments of both commands on each operating system. doc/ci.md
describes the runner compilation cache and the change, and
doc/usage.md the commands' new behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 21, 2026 17:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is narrowly scoped, consistently propagates the environment, and has focused regression coverage with no identified blocking issues.

No open issues 🎉

Review effort: Balanced

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: investigate why the Windows OpenVMM builds miss sccache

2 participants