- Autoformatting
- Static analysis
- Testing
- CMake tips
- Doxygen tips
- Adding libraries
- Windows XP
- GitHub Actions tips
- GitLab tips
- Tutorial links
Some IDEs recognize the .clang-format
file located in the root directory of the project and autoformat the code upon saving, according to the style and rules specified in the file. However, the clang-format tool is also integrated in the CMake script of this project, in the module cmake/clang-format.cmake
, so it is possible to autoformat the entire source code by calling the format
target, such as:
cmake --build . --target format
# or, if using make:
make format
The current script is set to format all the source files with the following extensions: .h
, .hpp
, .c
, .cpp
.
With Clang Static Analyzer:
scan-build cmake .. -G "Ninja"
scan-build ninja
With clang-tidy
:
# Using a CMake preset:
cmake .. --preset tidy
# Uses a CMake variable and the .clang-tidy file:
cmake .. -DCMAKE_CXX_CLANG_TIDY="clang-tidy"
# Appends globs to the 'Checks' option in the .clang-tidy file:
cmake .. -DCMAKE_CXX_CLANG_TIDY="clang-tidy;-checks=cppcore*,-cppcoreguidelines-owning-memory"
cmake --build .
With cppcheck
:
# Using a CMake preset:
cmake .. --preset cppcheck
# Using a CMake variable:
cmake .. -DCMAKE_CXX_CPPCHECK="cppcheck;--enable=all;--force;--inline-suppr;--suppressions-list=../CppCheckSuppressions.txt;--library=wxwidgets"
cmake --build .
Using a multi-config generator:
cd build
cmake .. -G "Ninja Multi-Config"
cmake --build . --config Debug
ctest -C Debug #-j10
ctest -C Debug -T memcheck
cd build
cmake .. -G "Ninja" -DCMAKE_BUILD_TYPE=Coverage
cmake --build .
ctest
ctest -T coverage
# or,
# ctest -T Test -T Coverage
Coverage info can be found in cpp-project-template/build/Testing/
.
You can also use your IDE's viewer. For VSCode I found the Gcov Viewer extension to be quite good. After running CTest, press Ctrl+Shift+P and type "GCov Viewer: Load" to load the report. Then press Ctrl+Shift+P and type "GCov Viewer: Show" to show the result.
Generate lcov HTML report:
cmake --build .
cmake --build . --target lcov_html
Report can be found in cpp-project-template/build/lcov/
.
Generate gcovr HTML report:
After running CTest, do:
cmake --build .
cmake --build . --target gcovr_html
Report can be found in cpp-project-template/build/gcovr/
.
cd build
cmake .. -DCMAKE_BUILD_TYPE:STRING=Coverage -DCMAKE_TOOLCHAIN_FILE=<project_root>/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows -DVCPKG_HOST_TRIPLET=x64-windows
cmake --build . --config Debug
ctest -C Debug
cmake --build . --target projectlib_gtest_coverage
ctest -T memcheck
# or
cmake --build . --target test_memcheck
# or, if using make
make test_memcheck
If using Clang, customize SanitizerBlacklist.txt
at your will.
# Using gcc:
cmake .. -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer"
# Using clang:
cmake .. -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -fsanitize-blacklist=/full/path/to/SanitizerBlacklist.txt"
# Executing wxWidgets project with lsan suppressions:
ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=suppressions=../src/projectwx/wx_lsan_suppressions.txt ./bin/projectwx
More about sanitizers:
- https://hpc-wiki.info/hpc/Compiler_Sanitizers
- https://developers.redhat.com/blog/2021/05/05/memory-error-checking-in-c-and-c-comparing-sanitizers-and-valgrind
CDash Dashboard: https://my.cdash.org/index.php?project=cpp-project-template
cmake -S . -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Coverage
cmake --build build
ctest --test-dir build -D Experimental -T Test -T Coverage -T memcheck
- Check the available targets with:
cmake --build . --target help
- List available presets with:
cmake .. --list-presets
- Files are considered private by default. Having a file command will have documentation be generated for it. See: https://linux.m2osw.com/doxygen-does-not-generate-documentation-my-c-functions-or-any-global-function
- Documenting the namespace is necessary for references to work. See: https://stackoverflow.com/q/46845369/3049315
- The main page of doxygen is set with the
\mainpage
command. See: https://www.doxygen.nl/manual/commands.html#cmdmainpage
But it is possible to set an MD file as the main page. See: https://stackoverflow.com/a/26244558/3049315
Adding libraries to the project requires modifying the vcpkg.json
file if you use one, the CI/CD workflow files, the docs/install.md
file, the CMakeLists.txt
file of the project that you are adding the library to, and the .devcontainer/Dockerfile
.
For MSVC see here. For MinGW see here. For Clang see here.
Naturally, the Windows API has evolved since Windows XP and modern features will not work with this OS.
- GitHub Actions uses the latest runners available and for this reason may need maintenance.
- CI/CD scripts should be made executable, like so:
git update-index --chmod=+x ./.github/scripts/*.cmake
- virustotal.com shows that more security vendors flag the program as malicious when compiled with LLVM, few security vendors flag the program as malicious when compiled with MinGW, and no security vendors flag the program as malicious when compiled with MSVC. Using the latest version of some compilers (e.g. LLVM) can make Windows Defender flag the program as malicious and remove it from the user's file system.
A release is created when creating and pushing a tag that starts with v
. For example:
git add .
git commit -m "Ready for release."
# Create an annotated tag:
git tag -a v0.0.1 -m "release v0.0.1"
# Push to branch main and to tag simultaneously:
git push --atomic origin main v0.0.1
Deleting a tag in case of mistake:
# Delete locally:
git tag -d v0.0.1
# Delete remotely:
git push --delete origin v0.0.1
The release can be deleted manually or with GitHub CLI.
Change the path of the CI/CD configuration file in your GitLab project's Settings -> CI/CD
to .gitlab/.gitlab-ci.yml
.
Tutorial: https://cylab.be/blog/8/using-custom-docker-images-with-gitlab
With the GitLab Container Registry, every project can have its own space to store its Docker images. More Information
This project's container registry: https://gitlab.com/MangaD/cpp-project-template/container_registry
You can manually add an image to your registry with the following commands:
sudo systemctl start docker
# If you are not already logged in, you need to authenticate to the
# Container Registry by using your GitLab username and password.
# If you have Two-Factor Authentication enabled, use a Personal Access
# Token instead of a password.
sudo docker login registry.gitlab.com
# Run the following commands in the directory where the Dockerfile is
# located. Replace the registry url with your own.
sudo docker build -t registry.gitlab.com/mangad/cpp-project-template .
# Replace the registry url with your own.
sudo docker push registry.gitlab.com/mangad/cpp-project-template
- Mastering CMake
- CMake Reference Documentation
- CMake Presets
- VS Code with CMake
- Installing & Testing
- CTest
- CTest tutorial and options
- CDash
- Codecov example
- GCov: How to Set Up Codecov with C and GitHub Actions
- OpenCppCoverage: How to Set Up Codecov with C++ and GitHub Actions
- coveralls and gcovr
- How to use gcov
- VSCode Gcov Viewer
- OpenCppCoverage Wiki
- llvm-cov
- For Sphinx instructions, see:
- GitHub Actions documentation
- GitHub Codespaces
- GitHub Sponsorship
- Code owners
- About CITATION files
- GitHub CLI