Repository navigation
CI: cache UT C++ objects and scope the axis check to one platform - #2616
Conversation
The no-hardware UT job compiles 1290 translation units from scratch on every run and then reads every one of their include trees twice, once per platform. On macOS that is 434 s of compilation and 175 s of axis check inside a 20-minute budget, and four runs have been stopped at the limit. Configure the C++ unit-test build with ccache as its compiler launcher, restoring and saving the directory through a new cache-ccache composite action. The launcher is passed only when ccache is on PATH, so a runner whose package manager cannot serve it configures and builds as before, and the step prints the hit rate because a restored-but-unusable cache and a cold one otherwise produce the same full-length build. Run check_ut_cpp_axis.py on the Linux leg alone. Which configurations a case is built for follows from the include paths the CMakeLists compose, so it is the same answer on every host, and the Linux build graph is the superset: a non-Linux configure drops test_thread_scheduling.cpp, whose wrapped sched_* symbols are a GNU ld feature. check_ut_cpp_stub_linkage.py keeps running everywhere, because which archive member resolves a symbol, and whether a weak definition wins, is the platform linker's answer. Measured on this aarch64 host: a full build with an empty cache takes 381 s and leaves 567 MB (84 MB compressed); a fresh build directory against that warm cache takes 16 s at a 100% hit rate, and an edit to chip_worker.h recompiles 8 of the 1290 units. ctest reports 327/327 on the cached objects. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Problem and behavior
The no-hardware
utjob carries a 20-minute budget. Over the last 40 PR runs its macOS leg has a median of 991 s and a p90 of 1187 s — 13 seconds of headroom — and four runs were stopped at the limit (1202/1217/1223/1223 s). GitHub records atimeout-minutesexpiry asconclusion: cancelled, sogh pr checksrenders these asfailand they read as flaky infrastructure rather than as a job that ran out of time.Phase breakdown of the 1202 s run on #2614's head (
bc46b441), from its own log timestamps:check_ut_cpp_axis.pycheck_ut_cpp_stub_linkage.py+ swimlaneTwo of those are avoidable: the compilation is cold on every run, and the axis check is run once per platform to establish an answer that does not vary by platform.
Implementation
Configure the C++ unit-test build with
ccacheas its compiler launcher, restoring and saving the directory through a newcache-ccachecomposite action modelled on the existingcache-pip. The launcher is passed only whenccacheis onPATH, so a runner whose package manager could not serve it configures and builds exactly as before;ccacheitself is an optional package on Linux and a non-fatalbrew installon macOS. The step printsccache --show-statsafter the build, because a restored-but-unusable cache and a cold one otherwise produce an identical full-length build.Run
check_ut_cpp_axis.pyon the Linux leg only. Which configurations a case is built for follows from the include paths this repository's CMakeLists compose, so the answer is the same on every host — and Linux is the leg that can establish it, because its build graph is the superset: a non-Linux configure dropstest_thread_scheduling.cpp, whose wrappedsched_*symbols are a GNU ld feature (326 targets on macOS against 327 on Linux). The non-Linux branch prints why it skipped rather than passing silently.check_ut_cpp_stub_linkage.pykeeps running on every leg. Which archive member resolves a symbol, and whether a weak definition wins, is decided by the platform's linker rather than by this repository, so it is genuinely per-platform — and at ~14 s it is not a cost.No timeout is raised and no step is split; #2588 already carries both.
Validation
Measured on an aarch64 Linux host with
--parallel 4:src/common/worker/chip_worker.hrecompiles 8 of 1290 units in 9 s.ctest -LE requires_hardwareon the cached objects: 327/327 passed.The compiler-launcher/axis-check interaction was the risk worth checking, since the axis check re-executes each
compile_commands.jsonline with-E -H: both the ccache-wrapper form and theccache /usr/bin/c++launcher form return rc=0 with identical 37-line-Houtput, so the recorded command stays usable as a preprocess command.The edited step body was executed verbatim: configure with the launcher succeeds,
RUNNER_OS=Linuxruns the axis check (38.9 s),RUNNER_OS=macOStakes the skip branch, stub linkage runs in 6.8 s, swimlane reports 12 passed.pre-commit run --all-filesexits 0.Real per-step costs for the two checks come from #2588's six split-step runs, which already report them separately: axis averages 175 s on macOS against 44 s on Linux (max 229 s), while stub linkage is ~14 s on both.
What to expect in CI
The first run on this branch writes a cache entry and will not be faster — the gain appears on the second run.
ccache --show-statsin the build step is the acceptance signal: a hit rate near zero on a re-run means the key stopped matching.🤖 Generated with Claude Code