cmake

Overview

cmake is a cross-platform tool for building applications. It is commonly used with C and C++. The program is configured through CMakeLists.txt files, which reside in the source directories of the corresponding code.

The CMake logo.

The output of cmake is standard build/project files (e.g. Makefiles if targeting GNU make). These build files are then run using the standard build command to generate the final build files.

Child Pages

A Modular, Scaleable Way Of Using CMake
ContentsOverviewOverview Each sub-project should be treated like a proper project, with it’s own build and install step. find_package() should be the preferred way of declaring and finding dependencies between packages. In a way, this method is quite similar to how the Linux package system works, and how you would add dependencies into your projects such as … Continue reading A Modular, Scaleable Way Of Using CMake
cmake Cheat Sheet
A cmake cheat sheet! Quick, short explanations on the most common statements/functions that you would use inside a CMakeLists.txt file.
External Projects
Information on the concept of an external project in a CMake system, including use of the function ExternalProject_Add().
Finding Packages
How to use the find_package() command in a cmake file.
Generating A FindMyPackage.cmake From A .in File
ContentsOverviewOverview As a code library maintainer, if you want your users to be able to use find_package(MyPackage) in CMake files, you have to know how to create FindMyPackage.cmake files. Like this:Like Loading...
How To Automatically Run Unit Tests Using CMake
ContentsOverviewOverview Unit tests are a great way to make sure your code is working, drive development (TDD, a.k.a Test Driven Development) and prevent regression. However, it is very easy to forget to run your unit tests regularly. CI (continuous integration) tools may help here, running unit tests on every commit that is pushed to the … Continue reading How To Automatically Run Unit Tests Using CMake
How To Install Your Program Using CMake
A tutorial (with code examples) on configuring CMakeLists.txt files to install your project on the target system using CMake.

Quick Syntax Overview

One thing that cmake does different from other “languages” is enforce that all variables passed into a function are linked by naming, rather than their order.

Popular Generators (Build Systems)

cmake is commonly used to generate build files for:

  • make
  • Apple’s XCode
  • Eclipse
  • Microsoft Visual Studio
  • Ninja

cmake calls it’s specific modules that convert cmake code into these various build systems generators.

Setting Variables

Variables can be created and assigned in cmake with the set() function. e.g.

This created a new variable called SOURCES .

set() may also be used to make a list variable. Each element in the list should be separated with a space.

set() can make normal, cache or environment variables. All the above examples are setting normal variables (this is the default).

Normal variables are visible to the CMakeLists.txt file they are set in, and also everything called from there ( add_subdirectory(), include(), macro() and function()).

You can also set properties.

Adding Sub-directories

Use add_subdirectory() to add a directory which contains another CMakeLists.txt and code that requires building. It has the following syntax:

If <folder_path> is relative, it will be relative to the CMakeLists.txt file which called this function. But, it can also be absolute (in which case add_subdirectory() is somewhat of a misnomer).

Adding Libraries

Libraries can be added with:

For example, the following command creates a static library called my_library from the source file src.cpp.

The library name must be a new name which is unique in the project. target_link_libraries() can be used after add_library() to specify what other libraries this newly created library needs linking to.

Linking Libraries

Once libraries have been added with add_library(), they need to be linked. This is normally done with target_link_libraries() or just link_libraries() (the former option is preferred).

link_libraries() causes all proceeding targets in the CMakeLists.txt to be linked to this library.

Copying Files

Files can be copied as part of the build process using the following syntax:

You can specify glob or regex patterns to copy only certain files. The following example will only copy header files (.h):

Adding Preprocessor Definitions

Preprocessor definitions can be added by using the following cmake command:

The add_definitions command can actually be used to add any compiler flags, but is intended for adding definitions (flags that begin with -D) only.

This command add the flags to all sources in the current directory and below.

add_custom_target()

Custom targets are always built. Because there is no output file, they are considered always out-of-date, and are always re-built.

add_custom_command()

add_custom_command() is used specify how to make the defined OUTPUT files, based on command-line(s) COMMAND.

add_custom_target() is commonly used at the same time as add_custom_command().

The .stamp file extension is commonly used to create empty placeholder files as the OUTPUT of add_custom_command(). These files can then be used as dependents for other build targets.

Cache

cmake creates a global cache called CMakeCache.txt which is created at root level of the build folder.

The cache can be used to create and store variables which have global and persistent scope. This means they can be read/set by any CMakeLists.txt file in the project, and they keep their previous value between successive cmake calls.

Maths

Basic maths (addition, subtraction, e.t.c) can be done in a CMakeLists.txt file via the math() function. e.g. to increment a counter we would use the syntax:

EXPR is to tell cmake you wish to evaluate the expression. It is currently the only supported mathematical operation.

Adding .cmake Files

You can use the include() function to include .cmake file code into your CMakeLists.txt file. cmake will scan CMAKE_MODULE_PATH to look for .cmake files.

Running cmake

This completely depends on the structure of the source code you are building, but in general, something close to the example below will be followed.

This is of course assuming an out-of-source build setup (the recommended approach!). This standard way of building is used by OpenCV.