Skip to content

Commit b973cbe

Browse files
committed
feat(sonar): Add optional static analysis with sonarcube
It is part of the helper script, since the build job is done in docker (and the docker image is used for testing). So sonar setup is done in container in 1st stage of image (builder) to avoid taiting the multistage docker image small (used for testing). The analysis will be done outside the build part, since it requiere online resources (in a github action), check following commits. Origin: SiliconLabsSoftware/z-wave-engine-application-layer#73 Relate-to: #100 Last-Update: 2025-07-16 Forwarded: #134 Signed-off-by: Philippe Coval <[email protected]>
1 parent 4b3b49d commit b973cbe

File tree

3 files changed

+126
-12
lines changed

3 files changed

+126
-12
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ project(z-wave-protocol-controller)
44
# ##############################################################################
55
# Include Configurations
66
# ##############################################################################
7+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
8+
option(COVERAGE "Enable coverage reporting" OFF)
9+
if(COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
10+
message(STATUS "Building with code coverage")
11+
add_compile_options(--coverage -O0 -g)
12+
add_link_options(--coverage)
13+
endif()
714

815
include(cmake/include/version.cmake)
916
include(cmake/include/build_permutations.cmake)

helper.mk

Lines changed: 117 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ version?=$(shell git describe --tags --always 2> /dev/null || echo "0")
2323
BUILD_DEV_GUI?=OFF
2424
BUILD_IMAGE_PROVIDER?=ON
2525

26+
cmake?=cmake
2627
cmake_options?=-B ${build_dir}
2728

2829
CMAKE_GENERATOR?=Ninja
@@ -31,6 +32,8 @@ export CMAKE_GENERATOR
3132
build_dir?=build
3233
sudo?=sudo
3334

35+
default_rules?=configure prepare all test dist
36+
3437
debian_codename?=bookworm
3538

3639
packages?=cmake ninja-build build-essential python3-full ruby clang
@@ -40,6 +43,7 @@ packages+=python3-defusedxml # For extract_get.py
4043
# TODO: remove for offline build
4144
packages+=curl wget python3-pip
4245
packages+=expect
46+
packages+=gcovr
4347

4448
# For docs
4549
packages+=graphviz
@@ -62,6 +66,33 @@ rust_url?=https://sh.rustup.rs
6266
RUST_VERSION?=1.71.0
6367
export PATH := ${HOME}/.cargo/bin:${PATH}
6468

69+
app_dir?=opt
70+
71+
# To be overloaded from env
72+
BRANCH_NAME?=tmp/local/${USER}/main
73+
SONAR_HOST_URL?=https://sonarcloud.io)
74+
SONAR_TOKEN?=${USER}
75+
76+
sonar_bw_url?=${SONAR_HOST_URL}/static/cpp/build-wrapper-linux-x86.zip
77+
sonar_bw_file?=$(shell basename -- ${sonar_bw_url})
78+
sonar_bw_app?=${app_dir}/build-wrapper-linux-x86/build-wrapper-linux-x86-64
79+
sonar_bw_out_file?=${SONAR_OUT_DIR}/compile_commands.json
80+
81+
sonar_scanner_url?=https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-7.1.0.4889-linux-x64.zip
82+
sonar_scanner_file?=$(shell basename -- ${sonar_scanner_url})
83+
sonar_scanner_app?=${app_dir}/sonar-scanner-7.1.0.4889-linux-x64/bin/sonar-scanner
84+
85+
ifndef SONAR_OUT_DIR
86+
gcovr?=gcovr
87+
coverage_file?=${build_dir}/coverage.xml
88+
sonar_bw_cmdline?=
89+
else
90+
default_rules+=coverage sonar/deploy sonar/dist
91+
cmake_options+=-DCOVERAGE=ON
92+
gcovr?=gcovr --sonarqube
93+
sonar_bw_cmdline?=${sonar_bw_app} --out-dir "${SONAR_OUT_DIR}"
94+
coverage_file?=${SONAR_OUT_DIR}/coverage.xml
95+
endif
6596

6697
# Allow overloading from env if needed
6798
ifdef VERBOSE
@@ -166,7 +197,7 @@ setup/cmake:
166197
--prefix=/usr/local \
167198
--skip-license
168199
rm -v "${cmake_filename}"
169-
cmake --version
200+
${cmake} --version
170201

171202
setup-cmake: setup/cmake
172203

@@ -198,6 +229,54 @@ setup/debian/bookworm: setup/debian setup/rust setup/python setup/plantuml
198229
setup: setup/debian/${debian_codename}
199230
date -u
200231

232+
${sonar_bw_app}:
233+
@echo "${project}: log: TODO: https://community.sonarsource.com/t/are-sonar-tools-versionned-on-public-sources/144031"
234+
mkdir -p "${@D}"
235+
cd "${app_dir}" \
236+
&& wget -c "${sonar_bw_url}" \
237+
&& unzip "${sonar_bw_file}"
238+
file -E "$@"
239+
240+
${sonar_scanner_app}:
241+
mkdir -p "${@D}"
242+
cd "${app_dir}" \
243+
&& wget -c "${sonar_scanner_url}" \
244+
&& unzip "${sonar_scanner_file}"
245+
file -E "$@"
246+
247+
sonar/configure: configure
248+
ls -l ${sonar_bw_out_file}
249+
250+
sonar/setup: ${sonar_bw_app} ${sonar_scanner_app}
251+
file -E $^
252+
253+
${SONAR_OUT_DIR}/compile_commands.json: coverage
254+
ls $@
255+
256+
sonar/dist: ${coverage_file} sonar-project.properties .scannerwork/report-task.txt
257+
@echo "${project}: log: %@: Files for sonar/deploy"
258+
ls -l "${sonar_bw_out_file}"
259+
ls -l "${coverage_file}"
260+
find "${build_dir}" -iname "*.gc*" | wc -l # Can not be processed outside build env
261+
tar cvfz "${SONAR_OUT_DIR}/${@F}.tar.gz" $^
262+
263+
264+
.scannerwork/report-task.txt: ${sonar_scanner_app}
265+
ls "${sonar_bw_out_file}"
266+
ls "${coverage_file}"
267+
@echo "${project}: log: $@: Uploading data to ${SONAR_HOST_URL}"
268+
${<} \
269+
--define sonar.branch.name=${BRANCH_NAME} \
270+
--define sonar.cfamily.compile-commands="${sonar_bw_out_file}" \
271+
--define sonar.coverageReportPaths="${coverage_file}" \
272+
--define sonar.host.url="${SONAR_HOST_URL}" \
273+
--define sonar.token="${SONAR_TOKEN}" \
274+
--debug
275+
find .scannerwork -type f
276+
277+
sonar/deploy: .scannerwork/report-task.txt
278+
@echo "${project}: log: TODO: https://community.sonarsource.com/t/new-github-action-for-c-docker-project/136307/5?u=rzr"
279+
ls -l $<
201280

202281
git/lfs/prepare:
203282
[ ! -r .git/lfs/objects ] \
@@ -225,12 +304,13 @@ reconfigure: configure/clean configure
225304
@date -u
226305

227306
${build_dir}/CMakeCache.txt: CMakeLists.txt
228-
cmake ${cmake_options}
307+
${sonar_bw_cmdline} ${cmake} ${cmake_options}
229308

230309
all: ${build_dir}/CMakeCache.txt
231-
# cmake --build ${<D} \
310+
# ${sonar_bw_cmdline} ${cmake} --build ${<D} \
232311
# || cat ${build_dir}/CMakeFiles/CMakeOutput.log
233-
cmake --build ${<D}
312+
${sonar_bw_cmdline} ${cmake} --build ${<D}
313+
234314
.PHONY: all
235315

236316
${build_dir}/%: all
@@ -239,11 +319,18 @@ ${build_dir}/%: all
239319
${build_dir}: ${build_dir}/CMakeCache.txt
240320
file -E "$<"
241321

242-
test: ${build_dir}
322+
test: ${build_dir} all
243323
ctest --test-dir ${<}/${project_test_dir}
244324

245325
check: test
246326

327+
coverage: ${coverage_file}
328+
ls -l "$<"
329+
330+
${coverage_file}: test all
331+
${gcovr} --print-summary -o "$@"
332+
ls -l "$@"
333+
247334
zwa_project?=z-wave-stack-binaries
248335
zwa_ver?=25.1.0-28-g7e0b50f
249336
zwa_rev?=v${zwa_ver}
@@ -278,14 +365,14 @@ zwa/test: ./scripts/tests/z-wave-stack-binaries-test.sh ${zwa_dir}
278365
--zpc.datastore_file=${datastore_file} \
279366
--zpc.ota.cache_path=${cache_path} \
280367
--log.level=d" \
281-
time $< # Add debug=1 to begining of this line to trace
368+
time $< # Add debug=1 to begining of this line to trace
282369

283370
dist/cmake: ${build_dir}
284-
cmake --build $< --target package
285-
cmake --build $< --target package_archive
371+
${cmake} --build $< --target package
372+
${cmake} --build $< --target package_archive
286373

287374
dist/deb: ${build_dir}
288-
cmake --build $< --target package
375+
${cmake} --build $< --target package
289376
install -d $</$@
290377
cp -av ${<}/*.deb $</$@
291378

@@ -296,9 +383,9 @@ distclean:
296383

297384
prepare: git/prepare
298385
git --version
299-
cmake --version
386+
${cmake} --version
300387

301-
all/default: configure prepare all test dist
388+
all/default: ${default_rules}
302389
@date -u
303390

304391
run_args?=--help
@@ -353,6 +440,9 @@ prepare/docker: Dockerfile prepare
353440
docker_workdir?=/usr/local/opt/${project}
354441
docker_branch?=main
355442
docker_url?=${url}.git\#${docker_branch}
443+
docker_builder_target?=builder
444+
docker_builder_image?=${project}-${docker_builder_target}
445+
docker_build_args?=
356446

357447
docker/%: Dockerfile
358448
time docker run "${project}:latest" -C "${docker_workdir}" "${@F}"
@@ -363,14 +453,29 @@ test/docker: distclean prepare/docker docker/help docker/test docker/run
363453
test/docker/build:
364454
time docker build -t "${project}:${docker_branch}" ${docker_url}
365455

456+
build/docker:
457+
@echo "${project}: log: $@: Multistage build to minimize test image"
458+
docker build \
459+
--tag "${docker_builder_image}:latest" \
460+
--target ${docker_builder_target} \
461+
${docker_build_args} \
462+
.
463+
docker build --tag "${project}:latest" ${docker_build_args} .
464+
465+
dist/docker:
466+
@echo "${project}: log: $@: Extract artifacts from multistage build"
467+
docker create --name "${docker_builder_image}" "${docker_builder_image}"
468+
docker cp ${docker_builder_image}:${docker_workdir}/dist dist
469+
docker cp ${docker_builder_image}:${docker_workdir}/${SONAR_OUT_DIR} ${SONAR_OUT_DIR}
470+
366471
docs: ./scripts/build/build_documentation.py doc ${PLANTUML_JAR_PATH} configure
367472
@echo "# export PLANTUML_JAR_PATH=${plantuml_dir}/${plantuml_filename}"
368473
@echo "$@: PLANTUML_JAR_PATH=${PLANTUML_JAR_PATH}"
369474
$< --output-dir $@
370475
touch $@/.nojekyll
371476

372477
zpc/docs/api: docs
373-
cmake --build build --target zpc_doxygen
478+
${cmake} --build build --target zpc_doxygen
374479
install -d docs/doxygen_zpc
375480
cp -rfa build/zpc_doxygen_zpc/html/* docs/doxygen_zpc/
376481

sonar-project.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# https://docs.sonarsource.com/sonarqube-server/latest/project-administration/setting-analysis-scope/introduction/
2+
sonar.projectKey=z-wave-protocol-controller

0 commit comments

Comments
 (0)