Lesson 21 · Build & ship

Generators

The generator concept explained. Ninja versus Make versus Visual Studio, single-config versus multi-config, and the commands for each.

Back in lesson 1 you learned CMake is a build system generator. Now it is time to actually choose a generator, because “which one” changes how you build.

What a generator is

When you run cmake -S . -B build, the generator decides what kind of build files end up in build/:

GeneratorBuild filesTypical platform
Ninjabuild.ninjaLinux, macOS, Windows. The default choice for speed
Unix MakefilesMakefileLinux, macOS. The old default
Visual Studio 17 2022.sln plus .vcxprojWindows
Xcode.xcodeprojmacOS
Ninja Multi-Configbuild.ninja, multi-configany

You saw -G Ninja in the presets lesson. -G is how you pick. If you do not, CMake picks a default based on your platform.

Single-config versus multi-config

This is the concept that confuses everyone, so here it is plainly:

  • Single-config generators (Ninja, Makefiles). The build type, Debug, Release, is chosen at configure time with -DCMAKE_BUILD_TYPE=Debug. One build directory, one build type.
  • Multi-config generators (Visual Studio, Ninja Multi-Config, Xcode). The build type is chosen at build time with --config Debug. One build directory can hold all types.
# Single-config (Ninja)
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build

# Multi-config (Ninja Multi-Config)
cmake -S . -B build -G "Ninja Multi-Config"
cmake --build build --config Debug
cmake --build build --config Release      # same dir, both types

Why

This is why “the same command” produces different flags on different machines. On Windows with Visual Studio, CMAKE_BUILD_TYPE is ignored. It is --config that matters. On Linux with Ninja, --config is ignored. It is CMAKE_BUILD_TYPE that matters. Projects that work on both use presets (lesson 20) to define each scenario once. Exactly why that lesson exists.

Why Ninja

Ninja is the default for good reasons:

  • Fast. Built to parallelize aggressively and do minimal work on incremental builds.
  • Portable. The same build.ninja workflow on Linux, macOS and Windows.
  • Clean errors. Colors, clear formatting, deduplicated output.

It does what make does, better. Install it with apt install ninja-build, brew install ninja, or choco install ninja on Windows. Then -G Ninja, or put "generator": "Ninja" in your presets.

Visual Studio on Windows

On Windows with Visual Studio installed, cmake -S . -B build without flags picks it automatically. You get .sln files you can open in the IDE, and the IDE, with --config, handles Debug and Release switching. Ninja works too, but the VS generator gives the IDE integration.

What you actually need to remember

  1. Ninja plus presets for yourself and CI. Fast and deterministic.
  2. CMAKE_BUILD_TYPE for single-config, --config for multi-config. If a tutorial mixes them up, the tutorial is wrong.
  3. cmake --build build is generator-agnostic. It just works, whichever one you picked.

Pitfall

Switching generators on an existing build directory, for example cmake -S . -B build -G Ninja after it was configured with Makefiles, produces confusing errors. Change generators, get a fresh build directory (rm -rf build). The generator is a configure-time identity, not a runtime flag.

Read the docs