Unable to upload llvm coverage to SonarQube on Bazel

Must-share information (formatted with Markdown):

  • which versions are you using (SonarQube, Scanner, Plugin, and any relevant extension)
    SonarQube is 8.5

SonarScanner is

INFO: SonarScanner 4.4.0.2170
INFO: Java 11.0.7 Debian (64-bit)
INFO: Linux 4.19.76-linuxkit amd64
  • what are you trying to achieve
    Upload coverage from llvm-cov to Sonarqube
  • what have you tried so far to achieve this
    Various permutations of:
sonar-scan-in-dev:
	@echo "==> Running SonarQube Scanner in dev container..."
	# Debug options:
	# -X -Dsonar.verbose=true
	sonar-scanner \
	  -X -Dsonar.verbose=true \
		-Dsonar.cfamily.build-wrapper-output=${DOCKER_SONARQUBE_DIR}/build-wrapper-output \
		-Dsonar.sources=${DOCKER_SRC_DIR} \
		-Dsonar.branch.name=${BRANCH_NAME} \
		-Dsonar.projectVersion=${VERSION} \
		-Dsonar.pvs-studio.reportPath=${DOCKER_PVS_STUDIO_DIR}/pvs-report.xml \
		-Dsonar.working.directory=${DOCKER_SONARQUBE_DIR}/sonarwork \
		-Dsonar.cfamily.llvm-cov.reportPath=${DOCKER_COVERAGE_DIR}/coverage.txt

Hello! Is it possible to upload the coverage report from llvm-cov to SonarQube without using the build wrapper? I’m trying to use it with Bazel in Docker, but unfortunately when I set the flags I found that are needed (--spawn_strategy=standalone --genrule_strategy=standalone) the build is just failing right after configuration. A possible reason for this is warning from Bazel ignoring LD_PRELOAD in environment which seems to be generated in current Bazel version whenever LD_PRELOAD is set.

The coverage.txt format is along the lines of:

/company/aggregation/include/aggregation/aggregation.h:
    1|       |#pragma once
    2|       |
    3|       |#include "aggregation/device_context.h"

there are some non-absolute paths though, not sure if it could be a problem:

   96|  39.1k|    }));
  ------------------
  | application.cc:_ZZN2nx11some12directory14AClass12post_trackedIZNS0_v:
  |   91|      7|                               handler(std::forward<decltype(handler)>(handler))]() mutable {

in the SonarScanner log there are no mentions of the coverage.txt file.

My goal - have the coverage % in SonarQube to make certain people happy. :slight_smile: .

Hi @LesnyRumcajs,

could you share the error you are getting?

Hi @mpaladin . There’s no meaningful error, just that the build has failed. The Bazel version I use is 1.2.1. I also tried converting the compile_commands.json with the Python script provided here: https://jira.sonarsource.com/browse/CPP-1428 . Unfortunately Sonar Scanner is still lost with the includes.

@mpaladin Just in case it’s important for Sonar technology, I’m using C++20.

@mpaladin I switched to more verbose log. It seems the build is failing on one of our rules to build librdkafka. All is fine without those --spawn_strategy=standalone --genrule_strategy=standalone.

ERROR: /tmp/dev/.cache/bazel/_bazel_nexthink/45687a9fc51e3180e3ee6f957bfa2b6a/external/librdkafka/BUILD.bazel:16:1: Executing genrule @librdkafka//:generate-config failed (Exit 1)
cp: cannot create regular file '../../bazel-out/k8-opt/bin/external/librdkafka/config.h': No such file or directory

The bazel command:

	  mkdir -p ${DOCKER_SONARQUBE_DIR}/build-wrapper-output && \
		build-wrapper-linux-x86-64 --out-dir ${DOCKER_SONARQUBE_DIR}/build-wrapper-output \
		bazel --max_idle_secs="${BAZEL_IDLE_SECS}" build \
			-s \
			--spawn_strategy=standalone --genrule_strategy=standalone \
			--verbose_failures \
			--symlink_prefix=${DOCKER_BUILD_DIR}/ \
			--compilation_mode=opt \
			--protocopt=--experimental_allow_proto3_optional \
			aggregation:${BUILD_TARGET} aggregation:${BUILD_TARGET}.stripped"

Hi @LesnyRumcajs,

What do you mean with “Sonar Scanner is still lost with the includes.” ? What is the symptom?

We don’t support C++20, the analyzer is going to fail when trying to analyze a file with -std=c++20.

This may be some configuration issue of your build after setting --spawn_strategy=standalone --genrule_strategy=standalone..

I can see that you have ${DOCKER_SONARQUBE_DIR} environment variable, are you trying to use the docker sonar-scanner image? For your information it doesn’t support C/C++ analysis, the analysis needs to run at the same layer of the build to properly resolve include files. This may explain why you see something strange when converting compile_commands.json file. You should use the normal sonar-scanner instead.

Hi @mpaladin

in Sonar-Scanner debug log there are issues with includes:

...
08:16:06.781 DEBUG: [/company/aggregation/include/aggregation/module/application_context.h:10]: cannot find include file '#include "somelib/Include/KAssert.h"'
08:16:06.783 DEBUG: [/company/aggregation/include/aggregation/module/application_context.h:11]: cannot find include file '#include "somelib/somehelpers.h"'
08:16:06.784 DEBUG: [/company/aggregation/include/aggregation/module/application_context.h:12]: cannot find include file '#include "some-proto/proto/events.pb.h"'
...

and at the end

08:16:11.583 INFO: Executing post-job 'Final report'
08:16:11.583 WARN: Preprocessor: 874 include directive error(s). This is only relevant if parser creates syntax errors. The preprocessor searches for include files in the with 'sonar.cxx.includeDirectories' defined directories and order.
08:16:11.583 WARN: Source code parser: 182 syntax error(s) detected. Syntax errors could cause invalid software metric values. Root cause are typically missing includes, missing macros or compiler specific extensions.
08:16:11.585 INFO: Analysis total time: 12.373 s
08:16:11.587 INFO: ------------------------------------------------------------------------
08:16:11.587 INFO: EXECUTION SUCCESS
08:16:11.588 INFO: ------------------------------------------------------------------------
08:16:11.588 INFO: Total time: 54.659s
08:16:11.639 INFO: Final Memory: 9M/40M
08:16:11.639 INFO: ------------------------------------------------------------------------

It will fail when encountering a C++20 feature or just every file that was compiled with this flag? More importantly in my particular case, will I be able to have the coverage % in SonarQube nevertheless or it’s a lost cause until SonarQube supports C++20?

It’s a regular sonar-scanner, not an image. Although the entire process (both Bazel and scanning) is being run inside a development container, so I guess it should be fine?

Hi @LesnyRumcajs,

are those files available after build and during the sonar-scanner analysis? Can you find them in the filesystem?

Are you sure you are using -std=c++20? You managed to get an EXECUTION SUCCESS, that means that no -std=c++20 was encountered.

All good, if both build and analysis are run inside the same docker container it is ok.

Hi @mpaladin

Yes, they are available after the compilation, though in various places around the container. But the Python script output should handle that, I guess? Some lines of build-wrapper-dump-json:

        "-I",
        "bazel-out/k8-opt/bin/external/com_github_jupp0r_prometheus_cpp/core/_virtual_includes/core",
        "-iquote",
        "external/com_github_jupp0r_prometheus_cpp",
        "-iquote",
        "bazel-out/k8-opt/bin/external/com_github_jupp0r_prometheus_cpp",
        "-I",
        "/usr/local/include",
        "-I",
        "/usr/lib/llvm-10/lib/clang/10.0.1/include",
        "-I",
        "/usr/include/x86_64-linux-gnu",
        "-I",
        "/usr/include",
        "-I",

Then I set this output for the scanner

	sonar-scanner \
	  -X -Dsonar.verbose=true \
		-Dsonar.cfamily.build-wrapper-output=${DOCKER_SRC_DIR}/cfamily-compilation-database \
.
.
.

Definitely, there are concepts in the code so it must be there. -c++20 is added to copts of cc_binary. The compiler is:

Debian clang version 10.0.1-1
Target: x86_64-pc-linux-gnu

Hi @LesnyRumcajs,

if I send you a PM would you be able to share sonar-scanner output (with sonar.verbose=true property) and the build-wrapper-dump.json file?

Hi @mpaladin, sorry for the late response. Sure, please do.

Hi @LesnyRumcajs,

PM sent to you.