bazel: drop coverage workarounds, bump llvm to 0.8.14 - #10986
Merged
eder-matheus merged 2 commits intoJul 27, 2026
Merged
Conversation
hermetic-llvm 0.8.14 enables the cc_toolchain coverage features and declares gcov / llvm-cov / llvm-profdata as toolchain files (hermeticbuild/hermetic-llvm The-OpenROAD-Project#675, fixed by The-OpenROAD-Project#677), so instrumentation, tool staging into the test sandbox and LLVM_COV/LLVM_PROFDATA all come from the toolchain. Remove the hand-rolled instrumentation copts/linkopts, the two --test_env paths that hardcoded the LLVM release (they broke on every module bump) and --strategy=TestRunner=local: coverage tests run sandboxed again. Add --noexperimental_fetch_all_coverage_outputs to work around a rules_cc bug (dangling `gcov` symlink in each test's raw _coverage tree in llvm mode); drop it once rules_cc >= 0.2.23 (bazelbuild/rules_cc#795) is released. 0.8.14 still pins LLVM 22.1.8, so the compiler is unchanged. Verified: `bazelisk coverage --config=coverage -- //src/utl/test:cpp_tests` passes 4/4 sandboxed, combined lcov report has 1464 DA: lines across 57 files (all under src/), genhtml renders 39.6% lines / 44.2% functions -- identical to the numbers from the original coverage config. `bazelisk build //:openroad` succeeds. Signed-off-by: SombraSoft <sombrio@sombrasoft.dev>
Keep the toolchain pin consistent across the repo: the downstream-consumer test module and the equivalent snippet in docs/user/Bazel.md tracked the version we bumped in the previous commit. Note that test/downstream currently fails analysis regardless of the llvm version -- rules_pycross rejects the module graph with "Unknown Python version: 3.8" -- so this bump is verified only through module resolution (`bazelisk mod graph` shows llvm@0.8.14). The pycross failure reproduces unchanged on master at 0.8.11 and is tracked separately. Signed-off-by: SombraSoft <sombrio@sombrasoft.dev>
Contributor
There was a problem hiding this comment.
Code Review
This pull request upgrades the llvm Bazel dependency from version 0.8.11 to 0.8.14 across the workspace, downstream tests, and documentation. It also simplifies the .bazelrc coverage configuration by removing manual instrumentation flags, local test runner strategies, and hardcoded tool paths, as these are now natively supported by the updated toolchain. Additionally, it introduces the --noexperimental_fetch_all_coverage_outputs flag to bypass a known issue with dangling symlinks in rules_cc. There are no review comments, and I have no additional feedback to provide.
eder-matheus
approved these changes
Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Bumps hermetic-llvm (
llvm) 0.8.11 → 0.8.14 and drops most of the--config=coverageworkaround that came in with #3608..bazelrcloses 5 of its 8 coverage lines:test/downstream/MODULE.bazeland thedocs/user/Bazel.mdsnippet pin the sametoolchain for downstream consumers; they move to 0.8.14 too so the repo shows
one version everywhere.
Why
#10913 landed
bazel coveragesupport against a toolchain that had no coveragesupport, so the config had to instrument by hand, point the collector at the
LLVM tools via
--test_env, and run test actions unsandboxed. Two consequenceswe called out at the time:
--test_envpaths embed the LLVM release(
llvm-toolchain-minimal-22.1.8), so everyllvmbump silently breaks thenightly coverage job;
we care about.
We filed hermeticbuild/hermetic-llvm#675 with the analysis, and it was fixed by
hermeticbuild/hermetic-llvm#677 (merged upstream, first released in v0.8.14):
coverage_stub,llvm_coverage_map_format,gcc_coverage_map_formatwere commented outbehind a
TODO: Re-enable once coverage is supported, sobazel coverageapplied zero instrumentation flags and produced a structurally empty report
(
SF:entries, noDA:lines) with no error — a silent failure;bin/gcov,bin/llvm-covandbin/llvm-profdataare now declared astoolchain files, so they are staged into the test sandbox (previously:
GCov does not exist at the given path) and Bazel exportsLLVM_COV/LLVM_PROFDATAfrom the tool paths for rules_cc'scollect_cc_coverage.sh;bazel coveragelcov e2e test to their CI on Linux andmacOS, so this path is now covered against regressions.
Instrumentation, tool staging and the env vars therefore all come from the
toolchain, and the hand-rolled flags plus the version-coupled paths go away.
The remaining two
--experimental_*flags are not workarounds: they selectclang source-based coverage instead of gcov, which is the only viable path here
(gcov-style
-fprofile-arcsobjects fail to link,ld.lld: error: .eh_frame: relocation is not in any piece, as of LLVM 22.1.8).The one new flag
--noexperimental_fetch_all_coverage_outputsis a rules_cc bug, not atoolchain one:
collect_cc_coverage.sh'sinit_gcovcreates agcovsymlinkin each test's raw
_coveragetree and only the gcov branch removes it, so inllvm mode the tree keeps a dangling link and Bazel's output validation rejects
it:
We only consume the merged lcov report, so the raw per-test outputs are skipped.
bazelbuild/rules_cc#795 fixes it upstream but is still open (latest release is
0.2.22); the flag can be dropped once rules_cc >= 0.2.23 is available.
Risk
0.8.14 still pins LLVM 22.1.8, identical to 0.8.11 — this is a module-level
bump, not a compiler bump.
MODULE.bazel.lockchurn is 4 lines. Nothing in therepo referenced the
soname→set_sonamefeature rename that also landed inthis range.
Verification
bazelisk coverage --config=coverage -- //src/utl/test:cpp_tests: 4/4 testspass, sandboxed (
processwrapper-sandbox, no--strategyoverride).Combined report: 1464
DA:lines across 57 files, 580 covered / 884uncovered, zero non-
src/entries.genhtmlrenders it: 39.6% lines, 44.2% functions — identical to the numbersrecorded in #10913, so the CI report contract is unchanged.
bazelisk build //:openroadsucceeds on 0.8.14 (clean, 6936 actions).--noexperimental_fetch_all_coverage_outputsis still required:re-running with
--experimental_fetch_all_coverage_outputsreproduces thedangling-symlink validation error above.
test/downstreamcould only be verified through module resolution(
bazelisk mod graphintest/downstreamresolvesllvm@0.8.14). Analysisin that module currently fails for an unrelated, pre-existing reason —
rules_pycross rejects the module graph with
Unknown Python version: 3.8,before any target is configured. Reproduced on a pristine
masterworktreeat 0.8.11, so it is not caused by this PR; worth a separate look.
Follow-up (not in this PR)
Drop
--noexperimental_fetch_all_coverage_outputswhen rules_cc >= 0.2.23lands.