Skip to content

Latest commit

 

History

History
366 lines (266 loc) · 13.4 KB

development_guide.md

File metadata and controls

366 lines (266 loc) · 13.4 KB

Development Guide

Autoformatting

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.

Static analysis

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 .

Testing

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

Coverage

GCC / Clang

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/.

MSVC

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

Dynamic analysis

Valgrind

ctest -T memcheck
# or
cmake --build . --target test_memcheck
# or, if using make
make test_memcheck

Sanitizers

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:

CDash

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

CMake tips

  1. Check the available targets with:
cmake --build . --target help
  1. List available presets with:
cmake .. --list-presets

Doxygen tips

  1. 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
  2. Documenting the namespace is necessary for references to work. See: https://stackoverflow.com/q/46845369/3049315
  3. 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

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.

Windows XP

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 tips

  1. GitHub Actions uses the latest runners available and for this reason may need maintenance.
  2. CI/CD scripts should be made executable, like so:
git update-index --chmod=+x ./.github/scripts/*.cmake
  1. 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.

Releases

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.

GitLab tips

Change the path of the CI/CD configuration file in your GitLab project's Settings -> CI/CD to .gitlab/.gitlab-ci.yml.

Custom Docker images

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

Tutorial links

C++

CMake

Testing

Coverage

Profiling

Debuging

Documentation

Versioning

Licenses

Signing

GitHub

GitLab

Docker