Enable code coverage on windows for C++ using clang.#26594
Enable code coverage on windows for C++ using clang.#26594KrishnaM256 wants to merge 11 commits intobazelbuild:masterfrom
Conversation
| .value(labelCache.get(toolsRepository + "//tools/test:collect_coverage"))) | ||
| .value(labelCache.get(toolsRepository + | ||
| (OS.getCurrent() == OS.WINDOWS ? | ||
| "//tools/test:collect_coverage_wrapper" : |
There was a problem hiding this comment.
It would be cleaner to keep the same label here and instead make it an alias with a select on @platforms//os:windows in the BUILD file.
There was a problem hiding this comment.
Thank you for the suggestion! That sounds like a cleaner approach. I’ll update the PR to use an alias with a select statement in the BUILD file as recommended.
| :: ============================================================================== | ||
| @echo off | ||
| setlocal | ||
| %BAZEL_SH% "%~dp0collect_coverage.sh" %* |
There was a problem hiding this comment.
Instead of crafting a custom wrapper, could you try making the collect_coverage target an sh_binary instead of a filegroup? That rule already has the necessary logic to create a launcher binary on Windows which honors BAZEL_SH etc.
There was a problem hiding this comment.
Switching the collect_coverage target to an sh_binary makes sense, and I agree it would simplify the setup on Windows. I’ll update the PR to use sh_binary instead of a filegroup and test to ensure that it works as expected with BAZEL_SH.
There was a problem hiding this comment.
If I switch from filegroup to sh_binary, I encounter the following error due to the requirement that the target must produce exactly one file:
'@bazel_tools//tools/test:collect_coverage' must produce a single file because of the singleArtifact() check.
If I remove or comment out the singleArtifact() line, Bazel crashes with a NullPointerException further down in the build.
Given these constraints, would you recommend using an alias instead, or is there another preferred approach to work around this limitation?
There was a problem hiding this comment.
For additional context:
- When collect_coverage is a filegroup, building //tools/test:collect_coverage outputs only tools/test/collect_coverage.sh.
- When I change it to an sh_binary, building the same target produces:
- tools/test/collect_coverage.sh
- bazel-out/x64_windows-fastbuild/bin/tools/test/collect_coverage
- bazel-out/x64_windows-fastbuild/bin/tools/test/collect_coverage.exe
It seems like the multiple outputs from sh_binary are conflicting with the single file requirement
tools/test/windows/tw.cc
Outdated
| } | ||
|
|
||
| (void)result->Absolutize(cwd); | ||
| if (!IsReadableFile(*result)) { |
There was a problem hiding this comment.
This fallback shouldn't be necessary - could you share the error you see if you don't add it?
There was a problem hiding this comment.
If you address the other comments and add an integration test that runs on Windows (you could also just drop the no-windows tag on the existing coverage tests), I can look into the root cause of the failure without this fallback.
There was a problem hiding this comment.
Thank you for the guidance! I’ll address the other comments and update the PR to include an integration test that runs on Windows. Once that’s done, I’ll let you know so you can investigate the root cause of the failure without the fallback.
There was a problem hiding this comment.
Hello @fmeum, I’ve removed the fallback, could you please review the changes and let me know if there are any other modifications needed?
There was a problem hiding this comment.
I started a parallel PR that adds support for multiple files in collect_coverage. There's still one issue left that I need to debug, but once that's done, you should be able to base your PR on it.
There was a problem hiding this comment.
The PR now passes CI and includes an updated integration test that you can use as the basis for getting the others to pass.
There was a problem hiding this comment.
Thanks! Great to hear the PR passes CI. I’ll use the updated integration test as a reference to get the remaining tests passing.
Summary
When running
bazel coverageon Windows, users often encounter errors as described in #18839 and #15835, including the%1 is not a valid Win32 application.message.This PR resolves those issues by:
.batwrapper for thecollect_coverage.shscript, which addresses the Win32 application error.With these changes, seamless C++ code coverage collection on Windows using Clang is now enabled.
Why is this needed?
These improvements allow Bazel to collect and generate code coverage reports inside
_cc_coverage.datfile located at COVERAGE_DIR directory for C++ targets on Windows using Clang, streamlining the workflow and reducing manual troubleshooting for users on this platform.Closes #15835 and #6374.
Implementation Details
Follow the official Windows troubleshooting guide and set the
BAZEL_SHenvironment variable as recommended.Add the following flags to your
.bazelrcto configure coverage collection with LLVM tools:Ensure that:
BAZEL_SHis set to the path of your shell (e.g., MSYS2 or Git Bash).llvm-profdata.exeandllvm-cov.exeare correct for your setup.Additional Notes
bazel coverageon C++ targets with Clang on Windows should work as expected, and coverage reports should be generated without manual intervention.