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 MakeNinja
Designed forhand-editedmachine-generated
Default parallelism-j1all cores
Incremental rebuild speedO(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

  1. cmake -B build -G Ninja ran the configure step. CMake inspected your system (found Clang, the SDK, ninja), wrote build/build.ninja, and cached the decisions in build/CMakeCache.txt.
  2. cmake --build build ran the build step. CMake dispatched to Ninja, which compiled main.cpp and linked the executable.
  3. 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-find prints the resolution of every find_package call. Invaluable when LLVM can't be found in Step 3.
  • cmake -B build --fresh wipes the cache and reconfigures (useful if you changed PATH or installed a new tool).
  • ninja -C build -v prints every command Ninja runs — see the exact clang++ invocation if a build is mysteriously failing.

Next

03-install-homebrew-llvm.md