Development/CMake/Building

From KDE TechBase

CMake works by generating a build system for another tool to use. By default, it will generate makefiles for use with Make. However, it can also generate files for other systems, including Visual Studio and XCode. As such, building a project is a two-step process: configuring, then building.

Preparing directories for a CMake build

The first step to building a project is configuring it. This involves running CMake, which will determine the necessary information about your system and, if it finds everything it needs, generate the build system. CMake does a similar job to Autotools but with a more user friendly interface and greater emphasis on cross-platform support.

Unless you have a very good reason to do otherwise, you should to create a build directory separate from your source file directory. The next section goes into more detail.

CMake has three different interfaces. You can run the command-line tool directly (cmake), run a terminal-based GUI version (ccmake), or run a Qt-based GUI version (cmake-gui). With the command line version, cd to your intended build directory and pass the source directory as an argument. For example,

 cd /path/to/build/directory
 cmake /path/to/source/directory  -Additional -Arguments

cmake-gui can be run from anywhere; both the source and build directories need to be provided in the widgets at the top of the interface.

Why out-of-source builds are important

With modern toolkits creating separate build and source directories is recommended practice for any development project using a compiler. The result is that the outputs of your configuration and compiling are are not mixed up with the files generated by the build system. There are many advantages to doing this.

  • If your build is corrupted, you can revert to the state you started with simply by deleting this directory.
  • When using a version control system like git, only the source code matters. You do not want to have to tell Git to exclude all the makefiles, objects, libraries, configured headers, binaries and random things that fly around in a build directory.
  • It is possible to have different builds with the same source code, or with different branches of the same repository. For example, you may create a build-debug folder for a debug configuration and a build-release folder for a release configuration and test both at once.
  • Cleanly separated directories are easier to manage: tools like grep and sed are faster and give better results when the directories are more focused.
  • As a particular example of the last point, David Faure's build scripts can be used to make development easier. With its recommended directory structure, "make" can be typed in the source directory and the compilation will take place in the build directory automatically.

Most KDE projects take the additional step of enforcing out-of-source builds with a CMake directive; if you maintain a project based on Frameworks you should consider doing so by adding the line set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) to CMakeLists.txt in your project root.

Build system (generators)

As noted above, CMake just generates configuration files the tell another tool how to build the project. You can specify this to cmake and ccmake using the -G argument (use cmake --help to get a list of possible generators, and see the CMake generators documentation for more information about them).

For example, you could run

 cmake -G "Unix Makefiles" /path/to/source/directory

to generate files that can be used with the make command, or

 cmake -G "Kate - Ninja" /path/to/source/directory

to generate Kate project files in combination with files for Ninja.

cmake-gui will ask you to choose a generator when you first press the Configure button.

Depending on the generator (and the version of CMake you are using), you can also specify a toolset to use or a platform name, to further control how the build is performed. We won't cover this in detail, except to note that with the Visual Studio generators in CMake 3.0 or later, you probably want to set the platform name in order to choose between 32-bit and 64-bit builds. For example:

 cmake -G "Visual Studio 10 2010" -A x64 c:\path\to\source\directory

Cache Variables

CMake stores settings mostly in the form of variables. These range from the location of a library the project depends on to whether unit tests should be built. When you run CMake, you can provide default values for some of these by setting cache variables. There is more detailed information in the CMake documentation, but this is mostly only important if you are writing a CMake-based project.

The variable you are mostly likely to want to change is the installation location, which is named CMAKE_INSTALL_PREFIX. You might want to set this to /usr on a Linux system, or to C:\Program Files\Project Name on a Windows system. cmake can be passed a value for this using the -D argument:

 cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr /path/to/source/directory

In the case of ccmake and cmake-gui, you will need to first configure the project. Then you will be presented with a list of available variables you can change. Some of these ("advanced" variables) will be hidden initially - these should be variables you don't normally need to change because CMake should detect the correct values automatically (such as the location of a particular library). If you do need to change them, there is an option to show the advanced variables.

You may notice that the above command included :PATH just after the name of the variable we wanted to set. This is optional extra information about the variable type that helps cmake-gui decide how to let the user edit the variable (in this case, it will show a dialog that allows the user to choose a directory). Other options are BOOL (which can be set to ON or OFF), FILEPATH (like PATH but for files instead of directories) and STRING (any other value). Omitting this information is safe, though:

 cmake -DCMAKE_INSTALL_PREFIX=/usr /path/to/source/directory

will work just as well if you do not intend to use cmake-gui. As well as CMAKE_INSTALL_PREFIX, there are several other variables that CMake provides that will affect how any CMake project will build; they can be found in the CMake documentation under "Variables that Change Behaviour". The most common variables to set are:

  • CMAKE_INSTALL_PREFIX
  • CMAKE_BUILD_TYPE (although beware that projects can change what values are accepted for this option - see #KDELibs4-based projects in particular)
  • CMAKE_PREFIX_PATH for if dependencies are in a non-standard location (note that you can set this as an environment variable instead of passing it on the command line)

Projects may provide other variables you can set to configure them; for these, you will need to consult the documentation of the project you are building. A common setting is whether to build tests:

 cmake -DBUILD_TESTING:BOOL=OFF /path/to/source/directory

KDE Frameworks-based projects

Any project that makes use of the KDEInstallDirs module, which includes most KDE projects that are based on KDE Frameworks, will allow you to control the installation location of particular files using the variables listed in that module. For example:

 cmake -DCMAKE_INSTALL_PREFIX=/usr -DKDE_INSTALL_SYSCONFDIR=/etc -DKDE_INSTALL_QTPLUGINDIR=lib/qt5/plugins /path/to/source/directory

Similarly, most of these projects will use the KDECMakeSettings, which will allow you to use the BUILD_TESTING option mentioned above.

KDELibs4-based projects

See Development/CMake/Addons_for_KDE.

Building

Building is done using whatever build system you asked CMake to generate configuration files for. For example, with the "Unix Makefiles" generator, you would run

 make
 make install

from the build directory. With one of the Visual Studio generators, you would either run msbuild from the build directory or open the generated solution file in Visual Studio and build as normal.