-
Notifications
You must be signed in to change notification settings - Fork 980
Introduction to CMake
CMake is a meta build system: it generates configuration files for an actual build system to use.
Historically, that second tool has been make
; we now encourage using ninja
or your IDE's internal.
CMake configuration files are always named "CMakeLists.txt" (case-sensitively). They should be put along the actual source files of the project to build, and treated in the same way.
CMake also handles modules, whose name end in ".cmake"; these are usually put in a separate folder, often /cmake
at the root of the project.
They do not describe the build, but provide additional functionalities to be used in the build description.
Both these kinds of files are written using CMake's own language; cf. below.
Whatever the user interface (system shell, cmake-gui, IDE, ...), there always are two main steps: configuration and build.
- In the configuration step, CMake reads the build description (CMakeLists.txt) and generates files for the build tool to use (e.g.,
Makefile
orbuild.ninja
). - In the build step, the build tool is called, either directly or indirectly, to perform the build and generate the required build artifacts. In case CMake needs to be re-run (maybe because one of the CMakeLists.txt has been edited), this is handled automatically without requiring the user to go through another configuration step. This means the configuration step needs only to be invoked once explicitly, even when rebuilding an updated project.
CMake projects are usually built "out-of-source", meaning the build artifacts end up in a parallel directory tree, as opposed to "in-source" builds, where they are mixed with the source files.
Using a system shell, the full process looks like the following :
# configuration step
cmake -S /path_to_source/ -B /path_to_source/build -G Ninja # -G denotes the build tool, default to `make`
# build step
cmake --build /path_to_source/build
# Alternatively, cd /path_to_source/build, then:
make # if you are using `make`
ninja # if you are using `ninja`
The syntax of the CMake language is very simple: the only statement is the function call, the only value type is the string. You may want to read the CMake tutorial to get a comprehensive overview of the features CMake offers.
For a detailed list of the functions this project provides, please refer to Functions reference. Below is an introduction to general-purpose CMake; most of it is abstracted away in said functions.
Here are some key points about the structure of a CMakeLists.txt
(Also read the documentation):
-
The main file must start with a call to
cmake_minimum_required()
, to make sure the version of CMake meets the expectations; -
A call to
project()
must occur before tackling any file or target; -
You can include a subpart of your project by calling
add_subdirectory()
. This will run theCMakeLists.txt
in the target subdirectory. Modularizing your project in this way is highly encouraged! -
Projects are structured into logical "targets":
- executables;
- static libraries;
- shared libraries;
- object libraries;
- interface libraries;
- custom targets;
These logical targets can have dependencies on one another. Except for the interface libraries, they are visible to the build tool, and can be build independently. (Illustration: when running
make clean ; make all ; make install
,clean
,all
,install
are targets)All these targets have build settings that can, optionally, be propagated to the targets depending on them:
-
compiler definitions (e.g.,
-Dxxx
flags for GCC) -
#include
search paths (e.g.,-Ixxx
flags for GCC) - compiler options (generic compiler flags: warnings, optimizations, ...)
-
linker options (
-Wl,xxx
for GCC) -
link search paths (
-Lxxx
for gcc) -
dependencies (
-lxxx
for GCC)
These commands make use of the
PUBLIC
,INTERFACE
orPRIVATE
keywords.-
PUBLIC
andINTERFACE
will apply the setting to all the dependers of the target in question; -
INTERFACE
andPRIVATE
also apply the setting to the target itself.
The links below are not endorsed by STMicroelectonics nor Kitware, but have proven useful in practice for users learning to use CMake "sanely".
-
Advanced usages