Build System Comparison | CMake vs Make vs Ninja vs Meson Complete Guide

Build System Comparison | CMake vs Make vs Ninja vs Meson Complete Guide

이 글의 핵심

Build system comparison guide presenting features and practical selection criteria for CMake, Make, Ninja, and Meson.

Introduction: What is a Build System?

”Why Are There So Many Build Tools?”

When starting a C++ project, you encounter various build systems like CMake, Make, Ninja, and Meson. What role does each play, and when should you choose which?

What This Guide Covers:

  • Role and necessity of build systems
  • Comparison of CMake, Make, Ninja, and Meson
  • Practical selection criteria
  • Pros and cons of each tool

Table of Contents

  1. What is a Build System?
  2. Make
  3. CMake
  4. Ninja
  5. Meson
  6. Comparison and Selection Guide
  7. Summary

1. What is a Build System?

Role of Build System

A Build System is a tool that automates the process of converting source code into executable files.

Build Process:

flowchart LR
    A[Source Code] --> B[Preprocessing]
    B --> C[Compilation]
    C --> D[Linking]
    D --> E[Executable]
    
    F[Build System] -.Manages.-> A
    F -.Manages.-> B
    F -.Manages.-> C
    F -.Manages.-> D

What Build Systems Do:

  1. Dependency Management: Track which files changed
  2. Incremental Build: Recompile only changed files
  3. Parallel Build: Compile multiple files simultaneously
  4. Cross-Platform: Use same build script on Windows, macOS, Linux

Build Tool vs Build File Generator

Build Tool:

  • Actually calls compiler and performs build
  • Examples: Make, Ninja

Build File Generator:

  • Generates build files for build tools to use
  • Examples: CMake, Meson

Relationship:

CMakeLists.txt (CMake script)
    ↓ Run CMake
Makefile or build.ninja (build file)
    ↓ Run Make or Ninja
Executable

2. Make

What is Make?

Make is the oldest build tool, created in 1976. Used as standard on Unix/Linux systems.

Makefile Example

# Makefile
CXX = g++
CXXFLAGS = -std=c++17 -Wall -Wextra -O2

# Target: Dependencies
#     Command

all: main

main: main.o utils.o
	$(CXX) $(CXXFLAGS) -o main main.o utils.o

main.o: main.cpp utils.h
	$(CXX) $(CXXFLAGS) -c main.cpp

utils.o: utils.cpp utils.h
	$(CXX) $(CXXFLAGS) -c utils.cpp

clean:
	rm -f *.o main

.PHONY: all clean

Usage:

# Build
make

# Parallel build (4 jobs simultaneously)
make -j4

# Clean build
make clean && make

Make Pros and Cons

Pros:

  • Simplicity: Basic concepts intuitive
  • Universality: Pre-installed on all Unix/Linux
  • Flexibility: Can use shell commands directly

Cons:

  • Cross-platform difficulty: Limited Windows support
  • Manual dependency management: Write header file dependencies manually
  • Tricky syntax: Tab/space distinction, complex variable syntax

3. CMake

What is CMake?

CMake is a cross-platform build file generator. Can generate Makefiles, Visual Studio projects, Ninja build files, etc.

CMakeLists.txt Example

cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.0)

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Create executable
add_executable(main
    main.cpp
    utils.cpp
)

# Header file path
target_include_directories(main PRIVATE include)

# Compile options
target_compile_options(main PRIVATE
    -Wall -Wextra -O2
)

# Link library
find_package(Boost REQUIRED)
target_link_libraries(main PRIVATE Boost::boost)

Usage:

# Create build directory
mkdir build && cd build

# Run CMake (generate Makefile)
cmake ..

# Build
cmake --build .

# Or use Ninja
cmake -G Ninja ..
ninja

CMake Pros and Cons

Pros:

  • Cross-platform: Supports Windows, macOS, Linux
  • Auto dependency: Automatically tracks header file dependencies
  • Ecosystem: Most C++ libraries support CMake
  • IDE integration: Integrates with Visual Studio, CLion, etc.

Cons:

  • Complex syntax: High learning curve
  • Slow configuration: Long CMake execution time on large projects
  • Debugging difficulty: Unfriendly error messages

CMake Build Flow

flowchart LR
    A[CMakeLists.txt] --> B[Run cmake]
    B --> C{Select Generator}
    C -->|Unix Makefiles| D[Makefile]
    C -->|Ninja| E[build.ninja]
    C -->|Visual Studio| F[.sln/.vcxproj]
    D --> G[make]
    E --> H[ninja]
    F --> I[msbuild]
    G --> J[Executable]
    H --> J
    I --> J

4. Ninja

What is Ninja?

Ninja is a build tool optimized for build speed. Often used as CMake’s backend.

build.ninja Example

# build.ninja (usually auto-generated by CMake)
cxx = g++
cxxflags = -std=c++17 -Wall -Wextra -O2

rule cxx
  command = $cxx $cxxflags -c $in -o $out
  description = CXX $out

rule link
  command = $cxx $in -o $out
  description = LINK $out

build main.o: cxx main.cpp
build utils.o: cxx utils.cpp
build main: link main.o utils.o

Usage:

# Generate Ninja build files with CMake
cmake -G Ninja ..

# Build with Ninja
ninja

# Parallel build (automatic)
ninja -j 8

Ninja Pros and Cons

Pros:

  • Fast speed: 2-3x faster than Make
  • Parallel build: Automatic optimization
  • Minimal features: Focuses only on building

Cons:

  • Difficult manual writing: Complex to write directly
  • Limited features: No advanced Make features
  • CMake dependency: Usually used with CMake

Make vs Ninja Speed Comparison

Project size: 1000 files

Make:
- Clean build: 120 seconds
- Incremental build: 15 seconds

Ninja:
- Clean build: 45 seconds (2.7x faster)
- Incremental build: 5 seconds (3x faster)

5. Meson

What is Meson?

Meson is a modern build system written in Python. Gaining attention as CMake alternative.

meson.build Example

# meson.build
project('myproject', 'cpp',
  version: '1.0',
  default_options: ['cpp_std=c++17']
)

# Executable
executable('main',
  'main.cpp',
  'utils.cpp',
  include_directories: include_directories('include')
)

# Library
boost_dep = dependency('boost')
executable('main',
  'main.cpp',
  dependencies: boost_dep
)

Usage:

# Setup build directory
meson setup build

# Build
meson compile -C build

# Or
cd build
ninja

Meson Pros and Cons

Pros:

  • Fast speed: Uses Ninja backend
  • Concise syntax: Python style, easy to read
  • Modern: Supports latest C++ standards
  • Cross-compilation: Easy setup

Cons:

  • Small ecosystem: Less library support than CMake
  • Lack of learning materials: Fewer docs/examples vs CMake
  • Weak legacy support: Difficult to migrate old projects

6. Comparison and Selection Guide

Comprehensive Comparison Table

FeatureMakeCMakeNinjaMeson
TypeBuild toolGeneratorBuild toolGenerator
Cross-platform
Build SpeedMediumMediumFastFast
Learning CurveLowHighMediumLow
EcosystemLargeVery largeMediumSmall
IDE IntegrationLimitedExcellentExcellentMedium
Setup TimeFastSlowFastFast

Build Speed Benchmark

Test Environment: 1000 C++ files, 8-core CPU

Clean Build (compile all files):
1. Ninja:     45 seconds  ⭐
2. Make -j8:  120 seconds
3. CMake:     Setup 10s + Build 60s = 70 seconds

Incremental Build (1 file changed):
1. Ninja:     2 seconds   ⭐
2. Make:      8 seconds
3. CMake:     Setup 3s + Build 3s = 6 seconds

Selection Flowchart

flowchart TD
    A[Start Project] --> B{Cross-platform?}
    B -->|Yes| C{Build Speed Important?}
    B -->|No| D[Make]
    
    C -->|Yes| E[CMake + Ninja]
    C -->|No| F[CMake + Make]
    
    G[New Project?] --> H{Prefer Modern Syntax?}
    H -->|Yes| I[Meson + Ninja]
    H -->|No| F

1. Simple Project (Less than 10 files)

  • Make: Simple and sufficient
  • Example: Algorithm practice, small utilities

2. Cross-platform Library

  • CMake: Industry standard, best compatibility
  • Example: Open-source libraries, commercial products

3. Large Project (Build Time Important)

  • CMake + Ninja: Fast build
  • Example: Game engines, browsers, large servers

4. New Project (No Legacy)

  • Meson + Ninja: Modern syntax, fast build
  • Example: New projects, startups

5. Windows Only

  • Visual Studio Project: Best IDE integration
  • Or CMake: Can transition to cross-platform later

Real-World Examples

Large Projects Using CMake:

  • LLVM/Clang
  • Qt Framework
  • OpenCV
  • Unreal Engine

Projects Using Ninja:

  • Chromium
  • Android (AOSP)
  • LLVM (with CMake)

Projects Using Meson:

  • systemd
  • GStreamer
  • Mesa 3D

7. Summary

Key Summary

Make:

  • Oldest and simplest build tool
  • Standard on Unix/Linux
  • Weak cross-platform support

CMake:

  • Cross-platform build file generator
  • De facto standard for C++ projects
  • Complex but powerful

Ninja:

  • Fast build tool
  • Often used as CMake backend
  • Difficult to write manually

Meson:

  • Modern build system
  • Concise syntax, fast speed
  • Small ecosystem

Beginner:

# CMake + Make (safest)
cmake ..
make

Intermediate:

# CMake + Ninja (fast build)
cmake -G Ninja ..
ninja

Advanced:

# Meson + Ninja (modern)
meson setup build
meson compile -C build

Next Steps

After choosing build system, learn detailed usage of each tool:

  • CMake Introduction Guide
  • CMake Advanced Techniques
  • CI/CD and Build Automation

Related Topics:

  • C++ Compiler Comparison
  • Cross-Platform Development
  • Build System Comparison

Additional Learning Resources

Official Documentation:

Practical Examples:

Quick Decision Guide

Simple project? → Make
Cross-platform C++? → CMake
Build speed critical? → CMake + Ninja
New project, modern syntax? → Meson + Ninja
Windows only? → Visual Studio or CMake
Large codebase? → CMake + Ninja

Keywords

Build System, CMake, Make, Ninja, Meson, C++, Cross-Platform, Build Tools, Compilation, Makefile, build.ninja