You've heard about CMake, and want to know how it works? Great! Here's how it works at three different levels.

The Basics

At a surface level, CMake is a tool to build C/C++ software on multiple platforms using the same build script. So, you can take the same code, and build script, and build software that can run on Windows, MacOS X, Linux, and even mobile devices.

It does this by reading in its own build scripts and then generating a build script for your compiler toolchain of choice, whether that's Visual Studio, XCode, CLion, good old GNU Make. Then, your complier toolchain's build tool takes over, and performs the actual build.

Why do it this way? So that you can use one build script to build the same code on multiple platforms using the best compilers available.

Makes sense? But, how does it actually do this. To answer that question we need to look at how CMake works internally...

How it Works Internally

CMake performs its magic in two stages; three if you include the final build step:

  1. The configuration stage
  • Loads in the CMakeLists.txt script(s)
  • Executes the build logic
  • Outputs a cache of variables
  • The generator stage
  • Takes the output of the configuration stage, and generates a build script for the target "native" toolchain/build-system
  • Each toolchain/build-system has its own generator. So, if you're using Visual Studio, then CMake will use the Visual Studio generator
  • The build stage
  • The target build-system takes over, and performs the actual build

That's how it works in a nutshell.

In practise

What does it look like in practise? I demonstrated this in the video above by building one of my own projects. First, I created a build sub-directory to keep the build and source files separate:

mkdir build
cd build

Next, I start cmake from inside the build sub-directory:

cmake ..

CMake automatically selected my preferred compiler, performed some pre-configuration checks on the compiler and build envronment. Then, it performed the configuration step, which ended with  "Configuring done" message.

Finally, the generator step ran, and was done in the blink of an eye. "Generating done."

CMake stops at this point. It's done its job, and it's time for the "native" build system to take over. I start the build stage from CMake (it knows how to call the target build system):

cmake --build . --parallel

After a short wait, all the source files have been compiled and linked into a working program, which we can run (see the screenshot below).

CMake How it Works Scarfy running

Learn Modern CMake Without the Headache

CMake is a powerful tool, but it can be hard to learn how to use it. The CMake Tutorial can save you loads of time, and take the frustration and pain out of learning how to use CMake.

Click here to get The CMake Tutorial.

The CMake Tutorial