SonarQube code coverage includes files not in compile_commands.json

We are using the following setup, which is getting updated soon:

  • SonarQube Server - Developer Edition v2025.2 (105476)
  • build-wrapper-linux-x86-64 v6.65 - from our sonarqube instance
  • SonarScanner CLI 7.2.0.5079
  • C and Gcov for analysis

We have a monorepo with several possible builds, each in a separate SonarQube project. There is one generic sonar-project.properties file and we want to avoid manually maintaining one for each target.

According to the documentation (and my understanding of it :grinning_face: ), we can rely on the build wrapper output to analyze only what is included in our build.

Any file that doesn’t end up in a compiled compilation unit will not be analyzed. As a consequence, source files that are not compiled and header files that are not included in any compiled source file will not be analyzed.

from Prerequisites | SonarQube Server 2025.2 | Sonar Documentation

However, some files that aren’t in the build wrapper output will show up in the code coverage analysis, most likely since they have a gcov output file due to having or being used in unit tests for other targets.

Does this mean that “compiled compilation unit” isn’t limited to the output from the build-wrapper, but also includes any gcov output?

Is there a setting that will exclude gcov output in this case?

I went through the monorepo documentation in Enterprise edition and couldn’t see something that would work around this issue.

I also went through the release notes from v2025.2 to v2026.3, but couldn’t find anything relevant, so our server version shouldn’t matter, correct?

Hello Edoardo,

Welcome to the community!

To clarify how SonarQube handles your files, here is a breakdown of how scoping works:

  • Global Analysis Scope: The scope of any analysis is primarily set by the global sonar.sources property. Any source file that matches this filter will be taken into account (see Analysis Scope Parameters).

  • Implicit Scope Tuning for C++: For accurate analysis of C++ code, the compilation commands are required, which are provided via the compile_commands.json file. Since the compile command is needed to analyze a file, the contents of this JSON file introduce an implicit scope tuning: only files that are in the sonar.sources scope and also in compile_commands.json will be analyzed (see Understanding C-Family Analysis).

  • Coverage Reports: SonarQube does not generate the coverage report itself, but relies on importing it from external tools (such as gcov in this case). The scope for this coverage is also set by sonar.sources. This is disconnected from which files actually end up being analyzed due to the implicit scope reduction from the compile commands.

If you want to define strict limits on the files included in each SonarQube project, configuring an accurate sonar.sources property is your best course of action.

Alternatively, you could ensure your gcov reports are generated specifically for that build, though I suspect you are already doing this. Is then the issue that certain files that were not analyzed because they were not in compile commands, are showing up as “uncovered”?

Regards,

Hi Guillem,

I’m sorry I wasn’t clear in what was the issue.

When browsing through the “Coverage” part of the project Measures, we would see files that aren’t used in the build and thus not in the build wrapper output. Our code coverage %, Uncovered lines and other related metrics weren’t accurate.

Our setup configures sonar.sources as any .c and .h files and relies on the build wrapper output to limit analysis to files used for the specific build. That seems to work and doesn’t require regular updates.

After some testing, I got to the conclusion that the list of files, used for code coverage measures in SonarQube, can be expanded with gcov data for files that are not in the build wrapper output.

For example, imagine a simplified project with 3 files, with sonar.sources set to include all files, relying on compile_commands.json to limit the analysis scope.

File A without any unit tests, 0% code coverage.

Files B and C with 100% code coverage.

If our build only uses files A and B, the wrapper output compile_commands.json will also include only files A and B. Those 2 would be analyzed for issues.

However, gcov will produce code coverage for B and C. We use gcovr to summarize the gcov output into a SonarQube targered XML.

The expected coverage is 50%, but the SonarQube analysis will show a 66% code coverage for the project. (50% and 6% are rough numbers to show the files covered as 1 out of 2 or 2 out of 3)

It does include File A, as it doesn’t have any gcov data, but it’s included in the scope via sonar.sources and compile_commands.json.

The issue for us was that it includes file C as well, which isn’t in compile_commands.json and thus shouldn’t be included in coverage data.
I suppose it is included in the code coverage measures as it has gcov data and therefore is in the XML report.

I haven’t made a sample project to test the exact numbers, but that is a simplified result of from our findings in our project.

We implemented a script that loads the list of files incompile_commands.json and cleans the report XML from any files that aren’t in the json file.

That seems to work - browsing through the SonarQube project coverage measures no longer includes unused files, our code coverage measures have changes and seem to be more accurate.

Hi again,

Thank you for the testing you did on your end and for the detailed report. Indeed, the conclusions you reached seem to match the expected behavior of the product, which I tried to briefly describe in my first response.

While this behavior may not be ideal, any sort of enhancement would not be easy to implement right now. The analyzer and coverage sensors are two independent subsystems that currently rely solely on the project properties.

We are glad that you were able to circumvent the issue you were facing by using a custom processing step to prune files not included in the compilation commands from the XML report.

If this becomes a significant inconvenience, please do not hesitate to reach out again so that we can register an enhancement request and review it in due time.

Best regards,