Step 2 — Install CMake and Ninja
Goal
Install CMake (build-system generator) and Ninja (fast parallel build executor). Every lab in this curriculum builds via CMake. Ninja becomes important starting at Phase 5 (LLVM) where build times grow.
Why CMake?
Because every C++ compiler project in the LLVM ecosystem — Clang, LLVM itself, MLIR, Swift, Mesa, KDE, and dozens more — uses CMake. Learning the CMake idioms here pays off in every later lab and every real LLVM contribution.
CMake is a generator, not a builder. It reads CMakeLists.txt, inspects your system (which compiler, which libs), and writes platform-appropriate build files: a Makefile (default on Unix) or a build.ninja. Then cmake --build . invokes whichever was generated.
Why Ninja?
Make is single-threaded by default and re-stats every file on every build. Ninja was designed at Google specifically for Chromium and adopted by LLVM. Differences:
| GNU Make | Ninja | |
|---|---|---|
| Designed for | hand-edited | machine-generated |
| Default parallelism | -j1 | all cores |
| Incremental rebuild speed | O(targets) | O(changed files) |
| LLVM build time (clean, 8 cores) | ~25 min | ~12 min |
For Phases 1–4 you can use either. From Phase 5 onward Ninja makes a noticeable difference.
Install
# If you don't have Homebrew, install it first:
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install cmake ninja
Verify
cmake --version | head -1
# cmake version 3.28.x or newer
ninja --version
# 1.11.x or newer
Minimum required:
- CMake ≥ 3.20 (we use modern target syntax)
- Ninja ≥ 1.10 (any recent version works)
Try It — A Tiny CMake Project
This isn't part of any lab; it's a 30-second sanity check.
mkdir -p /tmp/cmake-smoke && cd /tmp/cmake-smoke
cat > CMakeLists.txt <<'EOF'
cmake_minimum_required(VERSION 3.20)
project(smoke LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(smoke main.cpp)
EOF
cat > main.cpp <<'EOF'
#include <cstdio>
int main() { std::puts("cmake + ninja: ok"); return 0; }
EOF
cmake -B build -G Ninja
cmake --build build
./build/smoke
Expected:
cmake + ninja: ok
What Just Happened
cmake -B build -G Ninjaran the configure step. CMake inspected your system (found Clang, the SDK, ninja), wrotebuild/build.ninja, and cached the decisions inbuild/CMakeCache.txt.cmake --build buildran the build step. CMake dispatched to Ninja, which compiledmain.cppand linked the executable.- The whole thing took less than 2 seconds. Most of that was CMake's first-time configure; subsequent rebuilds are milliseconds.
Debugging Tips
cmake -B build -G Ninja --debug-findprints the resolution of everyfind_packagecall. Invaluable when LLVM can't be found in Step 3.cmake -B build --freshwipes the cache and reconfigures (useful if you changedPATHor installed a new tool).ninja -C build -vprints every command Ninja runs — see the exactclang++invocation if a build is mysteriously failing.