Phase 4 — Build, Test, Tooling (Months 6–7, Weeks 21–26)¶
Your projects look amateur without this. A senior C++ engineer is judged as much by their
CMakeLists.txt, their.github/workflows/ci.yml, and their sanitizer coverage as by the code itself. In studies, “I use CMake” means nothing — “I have a target-based CMake preset with Conan 2, sanitizer matrices in CI, and gtest+Google Benchmark wired” means you’ve done this before. Phase 4 is the boring, non-negotiable infrastructure that turns your side projects into artifacts you can put in front of a hiring committee at Meta, NVIDIA, Hudson River, Zoho ML platform, or any team that ships C++ to production.
You just spent five months getting fluent in the language and its performance model. Nothing in Phase 1–3 was “look, professional”. Everything here is. Two things happen at the end of Phase 4: (1) you own a reference C++20 project template — your personal starter kit that you’ll fork for every future project including all of Phase 5, and (2) you go back to your Phase 3 thread pool and rebuild it against that template, so you can point at one repo and say “this is how I ship C++”.
Why this phase matters more than it looks¶
Most self-taught C++ developers hit a ceiling here. They can write correct code, but they can’t:
Set up a project that a colleague can
git clone && cmake --preset default && cmake --build --preset defaultand have it Just Work on both Linux and macOS.Explain what
PUBLICvsPRIVATEvsINTERFACEactually does to the transitive property propagation graph.Run their tests under ASan+UBSan by default in CI, and know why they can’t add MSan to the same build.
Write a
benchmark::Stateloop that doesn’t get erased by the optimizer.Debug a “works on my machine, breaks in CI” toolchain drift bug.
Every one of those failures reads on your GitHub in fifteen seconds. Fix them here, once, forever.
Exit criteria — you cannot leave Phase 4 until¶
You own a public GitHub template repository (
raghul-cpp-templateor similar) that any C++ dev can fork.That template uses modern target-based CMake (CMake ≥ 3.28) with
CMakePresets.jsonfor at leastdebug,release,release-asan,release-ubsan,release-tsan.It builds cleanly with both Conan 2.x and vcpkg manifest mode on a single external dep (e.g.
fmtorspdlog) — you have written both flavors and can pick either.It ships a GoogleTest suite discovered via
gtest_discover_tests, plus one Catch2 v3 file so you know both.It ships a Google Benchmark suite with at least one meaningful
BENCHMARKthat usesbenchmark::DoNotOptimizecorrectly.All four sanitizers (ASan, UBSan, TSan, MSan) are wired as CMake options; you can produce a single command to run each locally.
.clang-tidyand.clang-formatfiles are committed with Google or LLVM base + your justified overrides.GitHub Actions matrix:
{ubuntu-24.04, macos-14} × {clang-18, gcc-13 on Linux; apple-clang on Mac} × {Debug, Release, Release+ASan+UBSan}, all green.A
Dockerfilebased on Ubuntu 24.04 with LLVM 18+, CMake 3.28+, Conan 2 produces the same green build inside a container.You have read and can navigate a real Bazel
BUILDfile (know it exists; know when Google/Databricks/Snowflake use it and why you probably don’t need to).Your Phase 3 thread pool (P3.2) is refactored on top of this template with gtest suite, benchmark suite, and sanitizers running in CI.
Onboarding time for a new contributor to your template repo (based on the README alone) is under 5 minutes to first successful test run.
If any single item above is not true, you are not done with Phase 4. Do not proceed to Phase 5.
Week-by-week breakdown¶
Week |
Focus |
Deliverable |
|---|---|---|
W21 |
Modern CMake deep dive. Targets, propagation, presets, |
Working |
W22 |
Conan 2.x + vcpkg. Do the same dep ( |
Two branches of the same repo — |
W23 |
Project P4.1: reference template. Assemble everything. gtest + Google Benchmark + sanitizers + |
Public template repo, CI green, README onboarding < 5 min. |
W24 |
Sanitizers deep dive. Read the ASan/TSan design papers/blog posts (Google, LLVM docs). Reproduce a real heap-use-after-free, data race, integer overflow, use-of-uninitialized in tiny bugs, watch each sanitizer catch it. |
Blog post or gist: “four sanitizers, four bugs, four reports.” |
W25 |
clang-tidy + IWYU + static analysis pass. Turn on |
Zero clang-tidy warnings on your template with your chosen ruleset. |
W26 |
Project P4.2: refactor P3.2 thread pool on the template. gtest suite (unit + stress under TSan). Google Benchmark (throughput at 1/4/8/16 workers). CI matrix green. |
Second polished repo referencing template patterns. |
What most people get wrong¶
They copy-paste CMake from Stack Overflow forever, and never learn the target model. They think include_directories(...) at the top of the file is normal. They set CMAKE_CXX_FLAGS globally. They use file(GLOB ...) for sources (“but the docs tell you not to”). They add -Wall -Wextra to PUBLIC and wonder why downstream consumers of their library are forced to compile with -Werror. They write one test/main.cpp that dumps a hundred assert()s instead of using a real framework. Their CI has one job on ubuntu-latest and nothing else.
You are going to be different. The rule is: every property on a target has a scope — PRIVATE (this target only), PUBLIC (this target and things that link to it), INTERFACE (only things that link to it, not this target itself). If you can’t tell me which scope to use for target_include_directories on a header-only library, come back to 01_modern_cmake.md and read again.
Bazel is worth knowing exists. You are unlikely to use it in a Zoho ML platform role. You are much more likely to use CMake + Conan or CMake + vcpkg. Learn the primary stack cold, know Bazel exists so you’re not surprised in an study.
Files in this phase¶
01_modern_cmake.md— target-based CMake, propagation model, presets, FetchContent, exporting your library.02_conan_and_vcpkg.md— both package managers, honest 2026 comparison.03_testing_and_benchmarks.md— GoogleTest, Catch2 v3, Google Benchmark, nanobench.04_sanitizers_and_static_analysis.md— ASan/UBSan/TSan/MSan + clang-tidy + clang-format + IWYU.05_ci_and_docker.md— GitHub Actions matrices, caching, Dockerfile, Bazel primer.projects.md— P4.1 (template repo), P4.2 (thread pool refactor).
Nav: ← Phase 3 · Phase 5 → · Roadmap Home