⚡A clean starter for modern C++20 projects with CMake Presets, testing, benchmarking, sanitizers, coverage, and developer tooling.
- Features
- Project Structure
- Prerequisites
- Build Presets
- Workflow Presets
- Building and Testing
- Sanitizers
- Benchmarking
- Coverage
- Developer Tooling
- Installation
- Package
- Contributing
- License
- Modern C++20+: fully enabled C++20 with support for upgrading to C++23
- CMake Presets: reproducible, platform‑agnostic builds via
CMakePresets.json
- Testing: integrated with GoogleTest using
gtest_discover_tests()
- Benchmarking: optional benchmarks with Google Benchmark
- Sanitizers: ASan and UBSan runtime checks
- Coverage:
gcovr
-powered HTML reports - Developer Tooling:
clang-format
,clang-tidy
,cppcheck
custom targets - Installation: provides
find_package(...)
integration with proper exports - CI-Ready: GitHub Actions for builds, linting, testing, and formatting
modern-cpp-project-template/
├── .github/workflows/ # CI pipelines for GitHub Actions
├── .vscode/ # VS Code workspace settings
├── app/ # Optional demo application
├── benchmarks/ # Google Benchmark performance tests
├── cmake/ # Custom CMake modules (Options, Flags, Helpers, etc.)
├── include/ # Public library headers
├── src/ # Library source files
├── tests/ # Unit tests (GoogleTest)
├── .clang-format # Formatting rules
├── .clang-tidy # Static analysis configuration
├── .clangd # Clangd language server settings
├── .editorconfig # Editor consistency rules
├── .gitignore # Git ignore patterns
├── CMakeLists.txt # Top-level build configuration
├── CMakePresets.json # Build, test, and workflow presets
├── LICENSE # Apache 2.0 license
└── README.md # Project documentation
Before building the project, make sure the following tools are installed on your system:
- CMake ≥ 3.23 (tested with 3.28+)
- C++ Compiler: GCC ≥ 10 or Clang ≥ 12
- Ninja (optional; recommended), or your generator of choice
- gcovr (for code coverage reports)
- clang-format, clang-tidy, cppcheck (optional diagnostics)
Tools not found are skipped with a warning; features gated by CMake option.
This project uses CMake Presets to simplify configuration.
Preset | Notes |
---|---|
Debug |
Debugging with no optimizations |
Release |
Optimized builds without debug symbols |
RelWithDebInfo |
Optimized build with debug symbols (recommended) |
Sanitize |
Builds with runtime checks enabled (ASan/UBSan) |
Coverage |
Builds instrumented for coverage reporting |
Release-Bench |
Builds Release + benchmarks |
List available presets:
cmake --list-presets
Preset | Notes |
---|---|
check-sanitize |
Sanitize → build → run tests |
coverage-report |
Coverage → build → run tests → *(generate report) |
dist |
RelWithDebInfo → build → package via CPack |
List available workflow presets:
cmake --workflow --list-presets
Run workflows with:
cmake --workflow --preset check-sanitize
Configure and build:
cmake --preset gcc-RelWithDebInfo
cmake --build --preset gcc-RelWithDebInfo
Run unit tests:
ctest --preset gcc-RelWithDebInfo
cmake --preset gcc-Sanitize
cmake --build --preset gcc-Sanitize
ctest --preset gcc-Sanitize
or run the workflow:
cmake --workflow --preset check-sanitize
cmake --preset gcc-Release-Bench
cmake --build --preset gcc-Release-Bench --target benchmarks
./build/gcc-Release-Bench/benchmarks/benchmarks
cmake --preset gcc-Coverage
cmake --build --preset gcc-Coverage
ctest --preset gcc-Coverage
cmake --build --preset gcc-Coverage --target coverage
or run the workflow:
cmake --workflow --preset coverage-report
cmake --build --preset gcc-Coverage --target coverage
Find the report in
build/gcc-Coverage/coverage.xml
Format all C++ files using .clang-format
.
Check formatting:
cmake --preset gcc-RelWithDebInfo
cmake --build --preset gcc-RelWithDebInfo --target format-check
Reformat everything:
cmake --build --preset gcc-RelWithDebInfo --target format
Use a pre-commit hook to automatically check formatting before each commit.
Run clang-tidy
analysis:
cmake --preset gcc-RelWithDebInfo
cmake --build --preset gcc-RelWithDebInfo --target clang-tidy
Configurable via
.clang-tidy
, with selective checks enabled.
Run cppcheck
analysis:
cmake --preset gcc-RelWithDebInfo
cmake --build --preset gcc-RelWithDebInfo --target cppcheck
cmake --preset gcc-RelWithDebInfo
cmake --build --preset gcc-RelWithDebInfo
cmake --install build/gcc-RelWithDebInfo --prefix install # or /usr/local
- This installs the library to the
install/
directory. - You can also install system-wide with
--prefix /usr/local
(requiressudo
).
After installation, consume the library like this in another CMake project:
find_package(modern_cpp REQUIRED)
add_executable(my_app ...)
target_link_libraries(my_app PRIVATE modern_cpp::library)
Make sure CMake knows where to find the installed package:
cmake -DCMAKE_PREFIX_PATH=/path/to/install ..
Once you’ve built your release‐type binaries (e.g. RelWithDebInfo
), you can produce .tar.gz
and .zip
archives via CPack:
Use package presets:
cmake --preset gcc-Release
cmake --build --preset gcc-Release
cpack --preset package-gcc-Release
or workflow preset:
cmake --workflow --preset gcc-Release-dist
This generates
.tar.gz
and.zip
archives inbuild/gcc-Release
.
Pull requests are welcome. Please ensure:
- Code passes all tests
- Code is formatted and clang-tidy clean
- Commits follow clear, atomic changes
This project is licensed under the Apache License 2.0.
You are free to use, modify, distribute, and include this code in commercial or open-source projects.