When writing C++ code, you can compile small programs directly with a compiler such as g++ or clang++. But as your project grows, managing multiple files, dependencies, and build configurations manually becomes error-prone. This is where build systems come in.

  • CMake1 is a meta-build system: it generates build configuration files (for Make, Ninja, Visual Studio, etc.), making your project portable across platforms and compilers.
  • Ninja2 is a small, fast build tool designed to replace Make. It’s optimized for speed and is widely used in large-scale C++ projects like LLVM and TensorFlow. Born on Chromium project which contains more than 30,000 source files3 which build system using Make build systems were taking 10 seconds, with Ninja it came down to under 1 second.

This guide will walk you through:

  1. Compiling a simple program with a compiler directly
  2. Automating build file creation with CMake
  3. Using Make vs Ninja backends with CMake

Step 1: A Simple C++ Program

Create a file named main.cpp:

#include <iostream>
using namespace std;

int main() {
    cout << "Hello world" << endl;
    return 0;
}

Step 2: Compile and Run Directly with a Compiler

You can use either g++ or clang++:

clang++ -o main main.cpp
./main

g++ -o main main.cpp
./main

Output:

Hello world

This works fine for small projects, but it doesn’t scale well. Let’s automate with a build system.

Step 3: Using CMake as a Build System

Create a CMakeLists.txt file:

cmake_minimum_required(VERSION 3.10)
project(demoproject)
add_executable(main main.cpp)

CMake generates build files based on the chosen build system (e.g., Make or Ninja). In this example, we’ll demonstrate how to use both generators with the same project. Keep the source file (main.cpp) and the CMakeLists.txt in the project root, and create two separate directories for the builds: one for Make (build) and one for Ninja (ninjabuild).

mkdir build
mkdir ninjabuild

Folder structure

.
├── build         # build directory for Make
├── CMakeLists.txt
├── main.cpp
├── ninjabuild    # build directory for Ninja
└── readme.md

Option A: Build with Make

cd build
cmake ..
make
./main

Here,

  • cmake .. → generates a Makefile from the top-level CMakeLists.txt.
  • make → compiles the project.
  • ./main → runs the compiled binary.

Folder structure (tree build -L 1):

build
├── CMakeCache.txt       # CMake configuration cache
├── CMakeFiles           # internal CMake files
├── Makefile             # build rules for make
├── cmake_install.cmake  # install script
└── main                 # compiled binary

Option B: Build with Ninja

cd ninjabuild
cmake -G Ninja ..
ninja
./main

Here,

  • cmake -G Ninja .. → generates a build.ninja file from CMakeLists.txt.
  • ninja → builds the project using Ninja.
  • ./main → runs the compiled binary. Folder structure (tree ninjabuild -L 1):
ninjabuild
├── build.ninja          # build rules for Ninja
├── CMakeCache.txt       # CMake configuration cache
├── CMakeFiles           # internal CMake files
├── cmake_install.cmake  # install script
└── main                 # compiled binary

Make vs. Ninja

  • Make: Widely available by default on most systems; works well for small to medium projects.
  • Ninja: Designed for speed; faster incremental builds and often preferred for large or complex projects.

Why Use CMake with Ninja?

  • CMake: CMake1 abstracts away platform/compiler differences and makes your project portable.
  • Ninja: Ninja2 is designed for speed, better parallelism, and more efficient incremental builds than Make.
  • Together, they provide a modern, cross-platform build setup widely adopted in industry.

Conclusion

  • For very small projects, compiling directly with g++/clang++ works.
  • For larger projects, use CMake to manage builds.
  • Use Ninja when you want faster builds than Make.

References:

Advertisement

Citation

Click to select citation style

Shovon, A. R. (2025, September 15). Getting Started with C++ Build Systems. Ahmedur Rahman Shovon. Retrieved September 30, 2025, from https://arshovon.com/blog/c++build/

Shovon, Ahmedur Rahman. “Getting Started with C++ Build Systems.” Ahmedur Rahman Shovon, 15 Sep. 2025. Web. 30 Sep. 2025. https://arshovon.com/blog/c++build/.

@misc{shovon_2025_getting,
    author = "Shovon, Ahmedur Rahman",
    title = "Getting Started with C++ Build Systems",
    year = "2025",
    url = "https://arshovon.com/blog/c++build/",
    note = "[Online]"
}