This repository provides Dockerized C++ development helpers that:
- Configures and builds a CMake project with coverage flags.
- Runs tests with
ctest. - Generates HTML coverage using compiler-appropriate backends (
llvm-cov,gcovr, orfastcov). - Serves coverage on localhost (default
8080) with a tabbed dashboard. - Runs SonarQube static analysis and shows results on localhost (default
9000). - Runs valgrind/cachegrind/callgrind in Docker and serves a tabbed localhost dashboard.
- Runs CPU profiling with
perfin Docker and serves a localhost dashboard with flamegraph/report tabs.
- Docker with permission to run containers
- Internet access (container image pulls / dependency installs)
./tools/run-cpp-coverage.sh --cmake-root /absolute/path/to/project-c, --cmake-root <path>: CMake project root (must containCMakeLists.txt).
-o, --os <image>: Base image (defaultubuntu:24.04)--compiler <name>:g++|gcc|clang(defaultg++)-v, --compiler-version <major>: compiler major version (example14,18)-p, --port <port>: coverage web port (default8080)--build-type <type>: CMake build type (defaultDebug)--coverage-tool <name>:auto|gcovr|fastcov(defaultauto)
./tools/run-cpp-coverage.sh \
--cmake-root ../FixDecoder \
--os ubuntu:24.04 \
--compiler clang \
--compiler-version 18 \
--port 8080
# GCC + fastcov/genhtml backend
./tools/run-cpp-coverage.sh \
--cmake-root ../FixDecoder \
--compiler g++ \
--coverage-tool fastcov \
--port 8080Coverage URLs:
- Dashboard (default landing page):
http://localhost:<port>/index.html - Raw main report:
http://localhost:<port>/coverage_main.html - Header inventory:
http://localhost:<port>/header_inventory.html
Run analysis for a source tree:
./tools/run-sonarqube-analysis.sh --source-root ../FixDecoderUseful options:
-s, --source-root <path>: project/source root to scan-p, --port <port>: SonarQube web port (default9000)-k, --project-key <key>: Sonar project key-n, --project-name <name>: Sonar project name--project-version <version>: project version string--sonar-token <token>: auth token (or setSONAR_TOKEN; on SonarQube 9.9 this is sent assonar.login)--sonar-login <user>: auth login/user (or setSONAR_LOGIN)--sonar-password <pass>: auth password (or setSONAR_PASSWORD)--compile-commands <path>:compile_commands.json(for C/C++ analyzer support)--sonar-image <image>: override image tag (default nowsonarqube:community)--start-only: start SonarQube only--stop: stop/remove SonarQube container for the selected port
If no auth options are provided, the script tries local default credentials admin/admin.
If neither flags nor env auth is provided, the script also checks sonar.token or sonar.login + sonar.password files in --source-root.
Notes:
sonarqube:communitydoes not include the Sonar CFamily analyzer, so C/C++ rules will not run there.- For C/C++ static analysis, use a SonarQube edition/plugin that provides CFamily and pass
--compile-commands.
Examples:
# Start SonarQube + run scan
./tools/run-sonarqube-analysis.sh \
--source-root ../FixDecoder \
--project-key fixdecoder \
--project-name FixDecoder
# Run with compile_commands.json for C/C++
./tools/run-sonarqube-analysis.sh \
--source-root ../FixDecoder \
--compile-commands ../FixDecoder/build/compile_commands.json
# Stop SonarQube container on port 9000
./tools/run-sonarqube-analysis.sh --stop --port 9000SonarQube URLs:
- Home:
http://localhost:<port> - Project dashboard:
http://localhost:<port>/dashboard?id=<project-key>
For GitHub C++ repositories, use SonarQube Cloud with CI-based analysis (CFamily).
Template workflow:
templates/github-actions/sonarcloud-cpp.yml
Setup per repo:
- Copy template to
.github/workflows/sonarcloud-cpp.yml - In GitHub repo settings, add secret:
SONAR_TOKEN - In GitHub repo settings, add variables:
SONAR_ORG(your SonarQube Cloud organization key)SONAR_PROJECT_KEY(your SonarQube Cloud project key)
- Push to
main/masteror open a PR to trigger analysis
Run valgrind/cachegrind/callgrind on an executable and open a tabbed web dashboard:
./tools/run-grind-analysis.sh --executable ../FixDecoder/build/Debug/bin/run_testsOptions:
-e, --executable <path>: executable to run (required)-t, --tools <list>: comma-separated list fromcache,val,call(default runs all)-s, --source-root <path>: source tree for file/line links (default current directory)-w, --workdir <path>: runtime working directory for executable (default current directory)-p, --port <port>: web dashboard port (default8070)-- <exe args...>: pass remaining args to the executable
Examples:
# run all tools (default)
./tools/run-grind-analysis.sh -e ../FixDecoder/build/Debug/bin/run_tests
# run only cachegrind + callgrind
./tools/run-grind-analysis.sh -e ../FixDecoder/build/Debug/bin/run_tests -t cache,call
# pass executable args
./tools/run-grind-analysis.sh -e ./build/my_app -t val -- --scenario perf --size 1000Grind dashboard URL:
http://localhost:<port>/index.html
Run perf profiling on an executable and open a localhost dashboard:
./tools/run-cpp-profiler.sh --executable ../FixDecoder/build/Debug/bin/run_testsOptions:
-e, --executable <path>: executable to run (required)-s, --source-root <path>: source tree context (default current directory)-w, --workdir <path>: runtime working directory for executable (default current directory)-p, --port <port>: web dashboard port (default8060)-f, --frequency <hz>: perf sample frequency (default99)-- <exe args...>: pass remaining args to the executable
Examples:
# profile test binary with defaults
./tools/run-cpp-profiler.sh -e ../FixDecoder/build/Debug/bin/run_tests
# custom sample frequency and executable args
./tools/run-cpp-profiler.sh -e ./build/my_app -f 199 -- --scenario perf --size 1000Profiler dashboard URL:
http://localhost:<port>/index.html
Note:
- This tool uses Linux
perffrom inside Docker and starts the container with added capabilities (SYS_ADMIN,SYS_PTRACE) plusseccomp=unconfined. - Some host environments still restrict perf events (
perf_event_paranoid); if profiling fails, check diagnostics in the dashboard overview tab.