A C++23 project template with Conan 2.25+ dependency management, CMake presets, testing, sanitizers, coverage, CI, and IDE setup.
This repository uses:
- CMake configure, build, and test presets as the public build interface
- Conan 2 for dependency management
- spdlog via Conan as the sample compiled dependency
- CLI11 via Conan for command-line parsing
- GoogleTest via Conan
- Doxygen for generated API documentation
Outcome: a new repository with project names, targets, namespaces, include paths, and GitHub links renamed consistently.
First, create and clone a repository from this template. The rename script uses only the Python standard library.
-
Preview every change without modifying the checkout:
$ python3 scripts/rename.py my-project --github-owner your-github-user --dry-run ... Dry run: no files were changed. Re-run without --dry-run to apply.
The command must end with
Dry run: no files were changed.Review the listed rewrites, move, and removals before continuing. -
Apply the same rename without
--dry-run:$ python3 scripts/rename.py my-project --github-owner your-github-user ... Moved include/cpp_boilerplate -> include/my_project Removing scripts/rename.py Removing .github/workflows/template.yml
From my-project, the script derives my_project for CMake targets, the C++ namespace, and the
include directory. It derives MyProjectConan for the Conan recipe class. It then updates the
tracked project files and moves include/cpp_boilerplate/ to include/my_project/. Finally it
removes the three things that stop applying once the template is instantiated: itself, this section,
and .github/workflows/template.yml, the workflow that smoke-tests the rename.
The rename is complete when the command reports the rewritten files, moves
include/cpp_boilerplate/ to include/my_project/, and removes the script and template workflow.
Use --title "My Project" to override the README heading; the default is the project name in title
case.
The build is layered, and each layer owns one thing:
- Conan owns the dependency graph, the toolchain, the CMake generator, and the ABI-relevant
settings. It resolves them from
conanfile.pyand theprofiles/files;conan.lockpins the exact graph for reproducible builds. - CMake presets (
CMakePresets.json) are the public build interface: thedebug,release,sanitize*, andcoveragenames you configure, build, and test. They are checked in and are the source of truth for how the project is built. - Conan writes its toolchain details into a generated
ConanPresets.jsonthatCMakePresets.jsonincludes. That file is an implementation detail, not an interface;make bootstrapis the one-time per-clone step that materializes it. - The
Makefileis a thin convenience wrapper: each target runsconan installfor the right profile, thencmake --workflow --preset <name>. On Windows you run those two commands directly (see Windows).
When you change the Conan configuration (versions, options, or profile), rerun make bootstrap or
the matching make target and keep using the same public preset names. The preset interface is
stable across toolchain changes.
.
├── include/ public headers
├── src/ application sources
├── tests/ unit tests
├── conanfile.py Conan dependency definition
├── conan/settings_user.yml custom sanitizer setting
├── profiles/ default and sanitizer Conan profiles
└── CMakePresets.json project-owned public presets
Required:
- CMake 3.29+ (for workflow presets and
CMAKE_LINKER_TYPE) - Conan 2.25+ (for the
CMakeConfigDepsgenerator) - A compiler and standard library with C++23
std::ranges::tosupport- GCC 14+
- LLVM Clang 17+ with libc++ 17+ or libstdc++ 14+
- Apple Clang 17+ on macOS
- MSVC 2022 (17.10+) on Windows
Optional:
- Ninja for parallel, incremental Unix builds; GNU Make is used when Ninja is absent
- ccache to reuse compiler output across rebuilds; used automatically for first-party targets when on PATH, except with the Visual Studio generator, which ignores compiler launchers
- mold or LLD to reduce Linux link times; used automatically for first-party targets when on PATH, with mold preferred
- Doxygen to generate local API documentation with
make docs
The Conan recipe selects the CMake generator:
Ninjaon Unix-like systems when it is availableUnix Makefileson Unix-like systems whenninjais not installed- The Visual Studio generator matching the detected MSVC on Windows (multi-config; locates MSVC
itself, so no extra tool or
vcvarsenvironment is needed)
This boilerplate supports Linux, macOS, and Windows.
Outcome: dependencies installed, the debug preset configured and built, and the test suite passed.
git clone https://github.com/megabyde/cpp-boilerplate.git
cd cpp-boilerplate
make bootstrap # generate ConanPresets.json
make debugThe setup is complete when make debug exits successfully after running the tests.
Tip
Run make help to list the other local targets.
Outcome: dependencies installed, the release preset configured and built, and the test suite passed.
The Makefile is a Unix convenience wrapper. On Windows, run Conan and the CMake preset directly
from any shell. The Visual Studio generator locates MSVC, so no Developer PowerShell or vcvarsall
setup is required.
conan install . -pr=profiles/default -s="build_type=Release" --build=missing --lockfile=conan.lock
cmake --workflow --preset releaseThe setup is complete when the workflow exits successfully after running the tests.
cmake --workflow --preset <name> runs configure, build, and test in one step; the Unix make
targets call the same workflows. The sanitize, sanitize-asan, sanitize-ubsan, and coverage
presets are Unix-only.
For sanitizer modes, test and preset behavior, dependency updates, formatting and linting, coverage, documentation generation, build policy, and IDE setup, see Development workflows.
Outcome: the release application installed at <prefix>/bin/cpp_boilerplate. Only the executable is
installed; the static library remains an internal build artifact.
- Build and test the release preset:
cmake --workflow --preset release- Install to the selected prefix:
cmake --install build/release --prefix /path/to/prefix- Run the installed binary and verify its version:
$ /path/to/prefix/bin/cpp_boilerplate
[2026-06-30 20:46:16.431] [info] cpp-boilerplate 0.1.0 starting
[2026-06-30 20:46:16.431] [info] field 0: alpha
[2026-06-30 20:46:16.431] [info] field 1: beta
[2026-06-30 20:46:16.431] [info] field 2: gamma
[2026-06-30 20:46:16.431] [info] done
$ /path/to/prefix/bin/cpp_boilerplate --version
0.1.0The install is complete when both installed-binary commands succeed and --version prints the
expected project version.