CMake Primer

IXM is a CMake library and thus knowing how to use CMake is imperative. A lot has changed in the CMake command line interface in recent years, and this chapter can act as a bit of a refresher.

Choosing a Build Tool

CMake provides a large set of possible build tools. The fastest and most useful however is the ninja build tool. IXM works best with ninja, though it will always work with any Makefile based generator.

While the authors of CMake recommend against this use of CONFIGURE_DEPENDS, the ability to glob files in practice has been more useful for automatic project generation and it is inherent to some of the behavior found in IXM

Using CMake On the Command Line

Until recently, CMake could not easily handle all aspects of the build process. This has, however, changed. These are the most common flags you’ll use when working with CMake.

-B <directory>
This option declares the build directory where CMake will generate all its files. CMake will generate the build directory for you, though nothing stops you from creating the directory first. For your sanity, it is recommended you give this a name in a different location, such as either build or target. CMake works best when it treats the source directory and build directory as separate locations. Weird things can (and will) happen otherwise. In some extreme cases, code generation might overwrite existing files.
-S <directory>
This option declares the source directory where CMake will read from the root CMakeLists.txt file. When configuring from the same directory as the CMakeLists.txt directory, you can simply pass in . as the <directory> parameter.
-G <generator>
As mentioned above, while we cannot dictate the build tool you use, the author of IXM highly recommends you use the ninja build tool. Thus, you will most likely pass this flag as -G Ninja to CMake’s command line arguments.
-D <var>[:type][=<value>]
This option is used to set variables into the CMake cache. These can be values used by CMake itself, or even variables expected for use with IXM.
-U <var>
This option is used to unset variables inside the CMake cache. This can be used to “reset” part of the configuration process and require some parts of CMake to be reconfigured.
--build <directory>
Takes the same directory named used by -B and will execute the build with the correct build tool. It is used in tandem with --target and will remove any concern over what build tool was used to generate the build directory. This is most useful when writing generic scripts, or wrapper Makefiles.
--target <name>
Requires that you also pass --build. Takes the name of some target generated by your project. CMake will then only build that target and its dependencies. When this flag is not passed, CMake will build the all target. This option is used to also run custom targets within CMake, such as clang-format targets, or static analyzers, as long as they have been configured correctly.

Generating The Build

Configuring (and regenerating) a CMake build is simple. Run the following command in the same directory as your CMakeLists.txt:

cmake -B build -S. -G Ninja -DCMAKE_BUILD_TYPE=Debug

Assuming everything is setup correctly, your build will be ready to run inside the build directory.


On occasion, it might be necessary to regenerate your build. To do this, simply use the -B option with the build directory location. This is also where you can add or change additional settings with -D or remove them with -U.

A example of this can be seen when wanting to switch to clang from gcc in a C++ project

cmake -Bbuild -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang

Running the Build

CMake provides the --build command to execute the correct build tool The parameter passed to this must be the location of the build directory.

cmake --build build

With the exception of errors in your actual code or project setup (incorrectly setting directories or flags, invalid code, etc.) your project will build.

Cross Compiling

In recent years, cross compiling has gotten simpler under CMake. In many cases, a toolchain file is needed. However, in the case of some systems such as Android or iOS, all that is needed is the toolchain to be installed, and then to configure CMake’s “system name”:

cmake -Bbuild -DCMAKE_SYSTEM_NAME=Android

This solves most problems for users, and doesn’t require the acquisition of several different toolchain files