Switching generators

Posted by phjung1 on January 9, 2022

Switching generators

The code for this recipe is available at cmake-cookbook/chapter-01/recipe-02 at v1.0 · dev-cafe/cmake-cookbook · GitHub and has a C++, C, and Fortran example. The recipe is valid with CMake version 3.5 (and higher) and has been tested on GNU/Linux, macOS, and Windows.

CMake is a build system generator and a single CMakeLists.txt can be used to configure projects for different toolstacks on different platforms. You describe in CMakeLists.txt the operations the build system will have to run to get your code configured and compiled. Based on these instructions, CMake will generate the corresponding instructions for the chosen build system (Unix Makefiles, Ninja, Visual Studio, and so on). We will revisit generators in Chapter 13, Alternative Generators and Cross-compilation.

Getting ready

CMake supports an extensive list of native build tools for different platforms. Both command-line tools, such as Unix Makefiles and Ninja, and integrated development environment (IDE) tools are supported. You can find an up-to-date list of the generators available on your platform and for your installed version of CMake by running the following:

1
$ cmake --help

The output of this command will list all options to the CMake command-line interface. At the bottom, you will find the list of available generators. For example, this is the output on a GNU/Linux machine with CMake 3.11.2 installed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Generators

The following generators are available on this platform:
  Unix Makefiles = Generates standard UNIX makefiles.
  Ninja = Generates build.ninja files.
  Watcom WMake = Generates Watcom WMake makefiles.
  CodeBlocks - Ninja = Generates CodeBlocks project files.

  CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
  CodeLite - Ninja = Generates CodeLite project files.
  CodeLite - Unix Makefiles = Generates CodeLite project files.
  Sublime Text 2 - Ninja = Generates Sublime Text 2 project files.
  Sublime Text 2 - Unix Makefiles = Generates Sublime Text 2 project files.
  Kate - Ninja = Generates Kate project files.
  Kate - Unix Makefiles = Generates Kate project files.
  Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files.
  Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files.

With this recipe, we will show how easy it is to switch generators for the same project.

How to do it

We will reuse hello-world.cpp and CMakeLists.txt from the previous recipe. The only difference is in the invocation of CMake, since we will now have to pass the generator explicitly with the -G CLI switch.

  1. First, we configure the project using the following:

    $ mkdir -p build $ cd build $ cmake -G Ninja ..

    – The CXX compiler identification is GNU 8.1.0 – Check for working CXX compiler: /usr/bin/c++ – Check for working CXX compiler: /usr/bin/c++ – works – Detecting CXX compiler ABI info – Detecting CXX compiler ABI info - done – Detecting CXX compile features – Detecting CXX compile features - done – Configuring done – Generating done – Build files have been written to: /home/user/cmake-cookbook/chapter-01/recipe-02/cxx-example/build

  2. In the second step, we build the proejct:

    $ cmake – build .

    [2/2] Linking CXX executable hello-world

We have seen that the output of the configuration step was unchanged compared to the previous recipe. The output of the compilation step and the contents of the build directory will however be different, as every generator has its own specific set of files:

  • build.ninja and rules.ninja: Contain all the build statements and build rules for Ninja.
  • CMakeCache.txt: CMake always generates its own cache in this file, regardless of the chosen generator.
  • CMakeFiles: Contains temporary files generated by CMake during configuration.
  • cmake_install.cmake: CMake script handling install rules and which is used at install time.

Note how cmake –build . wrapped the ninja command in a unified, cross-platform interface.