A template for a modern C++ project that follows good practices such as:
- checking for memory leaks (
valgrind
) - static analysis (
clang-tidy
) - code formatting (
clang-format
) - unit testing (
googletest
) - code coverage statistics (
gcov/lcov
) - build visualization (
graphviz
)
Continuous integration is handled automatically by:
Github
actions (upon pushing to the repo), orJenkins
automation server (running locally)
Documentation is generated using doxygen
, hosted by Github pages.
Tested on Ubuntu.
- Configure, build and run executable:
cd build
cmake ..
cmake --build . --target main
./app/main
- Unit testing (
googletest
)
cd build
rm CMakeCache.txt
cmake -DENABLE_TESTING=ON ..
cmake --build . --target unit_tests
./tests/unit_tests
- Code coverage (
gcov
)
cd build
rm CMakeCache.txt
cmake -DENABLE_TESTING=ON -DENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . --target coverage
- Check for memory leaks (
valgrind
)
cd build/app
valgrind --tool=memcheck ./main 6 3
- Static analysis (
clang-tidy
)
cd build
rm CMakeCache.txt
cmake -DENABLE_CLANG_TIDY=ON ..
cmake --build . --target main
- Formatting code (
clang-format
)
cd build
rm CMakeCache.txt
cmake -DENABLE_CLANG_FORMAT=ON ..
cmake --build . --target clang-format
In case you want to preserve the special formatting of a particular code block such as a matrix initialization, add the following directives around the block:
// clang-format off
Mat4<Scalar> m;
m(0, 0) = x[0]; m(0, 1) = x[1]; m(0, 2) = x[2]; m(0, 3) = -dot(x, eye);
m(1, 0) = y[0]; m(1, 1) = y[1]; m(1, 2) = y[2]; m(1, 3) = -dot(y, eye);
m(2, 0) = z[0]; m(2, 1) = z[1]; m(2, 2) = z[2]; m(2, 3) = -dot(z, eye);
m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0;
// clang-format on
- Build visualization (
graphviz
)
cd build
rm CMakeCache.txt
cmake --graphviz=build.dot ..
cmake --build . --target main
dot -Tpng -o build.png build.dot #convert to png image
- Valgrind
- Memory profiling: collect information about how your program uses memory
valgrind --tool=massif program_name
- Threading errors: detect and diagnose errors related to the use of threads
valgrind --tool=helgrind program_name
- IO errors: detect and diagnose errors related to input/output operations
valgrind --tool=lackey program_name
- Cachegrind: collect detailed information about the use of the cache memory
valgrind --tool=cachegrind program_name
- Massif: collect detailed information about the memory usage of your program over time
valgrind --tool=massif --time-unit=ms program_name
Upon installing Jenkins (inside a Docker container):
- Install Docker plugin
- Dashboard -> Manage Jenkins -> Configure Clouds
- Add a new cloud: Docker
- Docker cloud details
- Docker Host URL:
tcp://172.18.0.3:2375
- Enabled: Turn on
- Docker Host URL:
- Create a job
- Pipeline
- General
- GitHub project:
https://github.com/maksimdrachov/cpp-project-template
- Build Triggers - Poll SCM:
* * * * *
(Poll every minute)
- GitHub project:
- Pipeline
- Definition: Pipeline script from SCM
- SCM: Git
- Repository URL:
https://github.com/maksimdrachov/cpp-project-template
- Repository URL:
- Script Path: Jenkinsfile
kigster/cmake-project-template
An Introduction to Modern CMake
A very clean example of a C++ library
- Add doc/doxygen
- Add GitHub actions
- Add badges
docker build -t ubuntu-cpp .
docker run -v ~/cpp-project-template:/root/cpp-project-template -it ubuntu-cpp