ScriptsApr 17, 2026·3 min read

CMake — Cross-Platform Build System Generator

An industry-standard tool that generates native build scripts for any platform from a single set of configuration files.

Introduction

CMake is a build system generator that produces native build files (Makefiles, Ninja files, Visual Studio projects, Xcode projects) from a platform-independent configuration language. It has become the de facto standard for C and C++ projects, used by organizations from individual developers to large companies. CMake handles dependency discovery, compiler configuration, and cross-platform builds with a single set of CMakeLists.txt files.

What CMake Does

  • Generates native build systems for Make, Ninja, Visual Studio, Xcode, and others
  • Discovers system libraries and headers with find_package() modules
  • Supports cross-compilation through toolchain files
  • Manages build configurations (Debug, Release, RelWithDebInfo) across platforms
  • Provides CTest for test execution and CPack for packaging installers

Architecture Overview

CMake runs in two phases: configure and generate. During configuration, it reads CMakeLists.txt files, evaluates variables and conditions, finds dependencies, and builds an internal representation of targets and their relationships. During generation, it writes out the native build files for the chosen generator (e.g., Unix Makefiles, Ninja). The actual compilation is then handled by the native build tool, not by CMake itself.

Self-Hosting & Configuration

  • Install via system package manager, Homebrew, pip (pip install cmake), or download from cmake.org
  • Write CMakeLists.txt at the root of your project with project(), add_executable(), and target_link_libraries()
  • Use out-of-source builds: cmake -B build -S . keeps generated files separate from source
  • Configure presets in CMakePresets.json for reproducible builds across team members
  • Set toolchain files with -DCMAKE_TOOLCHAIN_FILE=... for cross-compilation

Key Features

  • CMake Presets standardize build configurations in a shareable JSON file
  • Modern target-based approach with target_link_libraries() propagates include paths and compile flags
  • FetchContent module downloads and builds external dependencies at configure time
  • Generator expressions allow conditional logic evaluated at build time, not configure time
  • First-class support for C, C++, CUDA, Fortran, ASM, Objective-C, and Swift

Comparison with Similar Tools

  • Meson — simpler syntax and faster for smaller projects; CMake has broader IDE and ecosystem support
  • Bazel — hermetic builds for monorepos; CMake is more portable and does not require a server
  • Autotools — the traditional Unix build system; CMake is more cross-platform and easier to maintain
  • Premake — Lua-based generator; CMake has a much larger community and package ecosystem
  • xmake — newer Lua-based build system; CMake remains the most widely adopted for C/C++

FAQ

Q: What is the difference between CMake and Make? A: CMake generates Makefiles (or other build files). Make executes them. CMake is the meta-build system.

Q: Should I use CMake Presets? A: Yes. Presets (introduced in CMake 3.19) let you define configure, build, and test settings in a versioned JSON file, replacing ad-hoc command-line flags.

Q: How do I add a third-party library? A: Use find_package() for system-installed libraries or FetchContent to download and build from source during configuration.

Q: Does CMake support header-only libraries? A: Yes. Declare an INTERFACE library with add_library(mylib INTERFACE) and attach include directories to it.

Sources

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets