How to use cmake
How to use cmake
Quick CMake tutorial
This tutorial will guide you through the process of creating and developing a simple CMake project. Step by step, we will learn the basics of CMake as a build system, along with the CLion settings and actions for CMake projects.
The source code of the sample project used below is available on GitHub.
1. Basic CMake project
CMake is a meta build system that uses scripts called CMakeLists to generate build files for a specific environment (for example, makefiles on Unix machines). When you create a new CMake project in CLion, a CMakeLists.txt file is automatically generated under the project root.
By default, we get the project with a single source file main.cpp and the automatically created root CMakeLists.txt containing the following commands:
Specifies the minimum required version of CMake. It is set to the version of CMake bundled in CLion (always one of the newest versions available).
Defines the project name according to what we provided during project creation.
Sets the CMAKE_CXX_STANDARD variable to the value of 14, as we selected when creating the project.
2. Build targets and Run/Debug configurations
Target is an executable or a library to be built using a CMake script. You can define multiple build targets in a single script.
For now, our test project has only one build target, cmake_testapp. Upon the first project loading, CLion automatically adds a Run/Debug configuration associated with this target:
Click Edit Configurations in the switcher or select Run | Edit Configurations from the main menu to view the details. The target name and the executable name were taken directly from the CMakeLists.txt :
Notice the Before launch area of this dialog: Build is set as a before launch step by default. So we can use this configuration not only to debug or run our target but also to perform the build. To learn more about various build actions available in CLion, see Build actions.
3. Adding targets and reloading the project
Now let’s add another source file calc.cpp and create a new executable target from it.
Since our goal is to create a new target, we clear the Add to targets checkbox. Accordingly, CLion notifies us that the new file currently does not belong to any target:
After reloading the project, CLion adds a Run/Debug configuration for the new target:
Library targets
As well as for executables, CLion adds a Run/Debug configuration for the library target after reloading the project:
However, this is a non-executable configuration, so if we attempt to run or debug it, we will get the Executable not specified error message.
4. Build types and CMake profiles
All the Run/Debug configurations created by far were Debug configurations, which is the default build type of the CMake profile that was automatically configured for our project. CMake profile is a set of options for the project build. It specifies the toolchain, build type, CMake flags, path for storing build artifacts, make build options, and environment variables.
For example, to separate the Debug and Release builds, we can add a new CMake profile in Settings / Preferences | Build, Execution, Deployment | CMake and set its build type to Release :
Notice the Build directory field that specifies the location of build results. The default folders are cmake-build-debug for Debug profiles and cmake-build-release for Release profiles. You can always set other locations of your choice.
Now the Run/Debug configuration switcher shows two available profiles:
Switching configurations or CMake profiles may affect preprocessor definitions used while resolving the code. For example, when there are separate flags for Debug and Release builds, or when there are some variables that take different values depending on the build type. This is called resolve context.
Resolve context defines how CLion performs syntax highlighting and other code insights like Find Usages, refactorings, and code completion. When you switch between configurations, the resolve context for the current file is changed automatically. Also, you can select it manually in the context switcher ( restores the automatic selection):
5. Adding include directories
In order to use additional headers located in separate directories, we need to add them either to all the targets or to some specific ones.
Headers and sources that you add to the project will be resolved correctly only if you include them explicitly in CMakeLists.txt or if you include them in other files already belonging to the project (see Managing CMake project files).
6. Linking libraries
Static libraries
On step 3, we created a static library called test_library (the default filename is libtest_library.a ).
Let’s create a lib directory under the project root and copy libtest_library.a from its default location ( cmake-build-debug ) to this folder.
Note : make sure to place target_link_libraries after the add_executable command, so that CMake actually builds the target before linking the library.
Dynamic libraries (Boost example)
To illustrate linking dynamic libraries, we will take an example of using Boost.Test framework.
Let’s write a simple function int add_values (int a, int b) < return a+b;>in calc.cpp and create the associated header calc.h with the function declaration. We will test this function with the help of Boost.Test framework.
For details on working with Boost.Test, see Unit testing tutorial.
As our project gets more complicated, the root CMakeLists.txt file can become difficult to maintain. To avoid this, and to build a transparent project structure, we will extract the tests into a subproject.
As a result, the project structure will be updated to the following:
Adjust the inserted code to the following:
Also, we need to place the add_subdirectory(test) command in the root CMakeLists.txt to make our test target cmake_testapp_boost available for the main build.
After reloading the changes in both CMakeLists.txt files, CLion creates a Run/Debug configuration for the cmake_testapp_boost target. This is a regular CMake Application configuration which we could run/debug right away. However, to be able to use the built-in test runner, let’s create another configuration out of the Boost.Test template:
Now we can run this configuration and get test results. Test runner shows the tree of tests in the suite, their output, status, and duration:
7. Working with CTest
This chapter gives a simple example of how to use CTest, a framework for compiling and running tests as part of the CMake build process. Find general description of the framework in CTest support.
Add CTest to the sample project
Add the following lines to ctest/CMakeLists.txt :
The first line states the minimum supported version of CTest, which corresponds to the version of CMake, 3.14.
Now we can place the actual code inside the test sources:
Next, we need to enable CTest and declare the subproject in the top-level CMakeLists.txt :
The enable_testing command creates a built-in target test which will execute CTest.
Reload the project.
After the reload, CLion detects the tests and creates a ready-to-go All CTest configuration:
If we run this configuration, the results will be shown in the Test Runner window, similarly to other supported testing frameworks:
We can also use the gutter menu next to the add_test commands in ctest/CMakeLists.txt to run or debug our tests:
Let’s check the All CTest configuration. Click the pen icon next to the Test list to run field. This opens the List of Available Tests dialog, where we can change the set of tests:
For more information on the CTest Application template, see CTest run/debug configuration.
8. Learn more
To dig deeper into CMake in CLion, learn how to:
How to use cmake
Once CMake has been installed on your system using it to build a project is easy. We will cover the process for Windows and then UNIX.
Running CMake for Windows / Microsoft Visual C++ (MSVC)
Run cmake-gui.exe, which should be in your Start menu under Program Files, there may also be a shortcut on your desktop, or if you built from source, it will be in the build directory. A GUI will appear similar to what is shown below. The top two entries are the source code and binary directories. They allow you to specify where the source code is for what you want to compile and where the resulting binaries should be placed. You should set these two values first. If the binary directory you specify does not exist, it will be created for you.
Running CMake on Unix
On most unix platforms, if the curses library is supported, cmake will build an executable called ccmake. This interface is a terminal based text application that is very similar to the windows GUI. To run ccmake, change directories into the directory where you want the binaries to be placed. This can be the same directory as the source code for what we call in-place builds (the binaries are in the same place as the source code) or it can be a new directory you create. Then run ccmake with either no arguments for an in-place-build, or with the path to the source directory on the command line. This will start the text interface that looks something like this:
If you hit the “c” key, it will configure the project. You should use that as you change values in the cache. To change values, use the arrow keys to select cache entries, and the enter key to edit them. Boolean values will toggle with the enter key. Once you have set all the values as you like, you can hit the ‘G” key to generate the makefiles and exit. You can also hit “h” for help, “q” to quit, and “t” to toggle the viewing of advanced cache entries.
Two examples of CMake usage on the Unix platform follow for a hello world project called Hello. In the first example, and in-place build is performed, i.e., the binaries are placed in the same directory as the source code.
In the second example, an out-of-place build is performed, i.e., the source code, libraries, and executables are produced in a directory separate from the source code directory(ies).
Running CMake from the command line
From the command line, cmake can be run as an interactive question and answer session or as a non-interactive program. To run in interactive mode, just pass the option “-i” to cmake. This will cause cmake to ask you to enter a value for each value in the cache file for the project. The process stops when there are no longer any more questions to ask.
To build with just cmake change directory into where you want the binaries to be placed. For an in-place build you then run cmake and it will produce a CMakeCache.txt file that contains build options that you can adjust using any text editor. For non in-place builds the process is the same except you run cmake and provide the path to the source code as its argument. Once you have edited the CMakeCache.txt file you rerun cmake, repeat this process until you are happy with the cache settings. The type make and your project should compile. Some projects will have install targets as well so you can type make install to install them.
What is the CMake cache?
The cache is best thought of as a configuration file. Indeed Unix users could consider the cache as equivalent to the set of flags passed to the configure command. The first time CMake is run, it produces a CMakeCache.txt file. This file contains things like the existence and location of native JPEG library. The entries are added in response to certain CMake commands (e.g. FIND_LIBRARY) as they are processed anywhere in CMakeLists files anywhere in the source tree. After CMake has been run, and created a CMakeCache.txt file – you may edit it. The CMake GUI, will allow you to edit the options easily, or you can edit the file directly. The main reason for editing the cache would be to give CMake the location of a native library such as JPEG, or to stop it from using a native library and use a version of the library in your source tree.
CMake will not alter an existing entry in the cache file itself. If your CMakeLists.txt files change significantly, you will need to remove the relevant entries from the cache file. If you have not already hand-edited the cache file, you could just delete it before re-running CMake.
Why do I have to edit the cache more than once for some projects?
Some projects are very complex and setting one value in the cache may cause new options to appear the next time the cache is built. For example, VTK supports the use of MPI for performing distributed computing. This requires the build process to determine where the MPI libraries and header files are and to let the user adjust their values. But MPI is only available if another option VTK_USE_PARALLEL is first turned on in VTK. So to avoid confusion for people who don’t know what MPI is, we hide those options until VTK_USE_PARALLEL is turned on. So CMake shows the VTK_USE_PARALLEL option in the cache area, if the user turns that on and rebuilds the cache, new options will appear for MPI that they can then set. The rule is to keep building the cache until it doesn’t change. For most projects this will be just once. For some complicated ones it will be twice.
Utility Targets produced
In addition to the targets and rules to build object files, libraries and executables of a project, CMake creates some additional targets and rules. For Visual Studio projects, two utility projects are automatically created: ALL_BUILD and RUN_TESTS.
User Interaction GuideВ¶
IntroductionВ¶
Where a software package supplies a CMake-based buildsystem with the source of their software, the consumer of the software is required to run a CMake user interaction tool in order to build it.
Well-behaved CMake-based buildsystems do not create any output in the source directory, so typically, the user performs an out-of-source build and performs the build there. First, CMake must be instructed to generate a suitable buildsystem, then the user invokes a build tool to process that generated buildsystem. The generated buildsystem is specific to the machine used to generate it and is not redistributable. Each consumer of a provided source software package is required to use CMake to generate a buildsystem specific to their system.
Generated buildsystems should generally be treated as read-only. The CMake files as a primary artifact should completely specify the buildsystem and there should be no reason to populate properties manually in an IDE for example after generating the buildsystem. CMake will periodically rewrite the generated buildsystem, so modifications by users will be overwritten.
The features and user interfaces described in this manual are available for all CMake-based build systems by virtue of providing CMake files.
Command Line cmake toolВ¶
A simple but typical use of cmake(1) with a fresh copy of software source code is to create a build directory and invoke cmake there:
It is recommended to build in a separate directory to the source because that keeps the source directory pristine, allows for building a single source with multiple toolchains, and allows easy clearing of build artifacts by simply deleting the build directory.
cmake-gui toolВ¶
Users more accustomed to GUI interfaces may use the cmake-gui(1) tool to invoke CMake and generate a buildsystem.
The source and binary directories must first be populated. It is always advised to use different directories for the source and the build.
Generating a BuildsystemВ¶
There are several user interface tools which may be used to generate a buildsystem from CMake files. The ccmake(1) and cmake-gui(1) tools guide the user through setting the various necessary options. The cmake(1) tool can be invoked to specify options on the command line. This manual describes options which may be set using any of the user interface tools, though the mode of setting an option is different for each tool.
Command line environmentВ¶
On Linux systems, the appropriate tools are often provided in system-wide locations and may be readily installed through the system package manager. Other toolchains provided by the user or installed in non-default locations can also be used.
When cross-compiling, some platforms may require environment variables to be set or may provide scripts to set the environment.
Visual Studio ships multiple command prompts and vcvarsall.bat scripts for setting up the correct environments for command line buildsystems. While not strictly necessary to use a corresponding command line environment when using a Visual Studio generator, doing so has no disadvantages.
When using Xcode, there can be more than one Xcode version installed. Which one to use can be selected in a number of different ways, but the most common methods are:
Setting the default version in the preferences of the Xcode IDE.
Setting the default version via the xcode-select command line tool.
Overriding the default version by setting the DEVELOPER_DIR environment variable when running CMake and the build tool.
For convenience, cmake-gui(1) provides an environment variable editor.
CMake chooses a generator by default based on the platform. Usually, the default generator is sufficient to allow the user to proceed to build the software.
On Windows, cmake(1) can be used to generate solutions for the Visual Studio IDE. Visual Studio versions may be specified by the product name of the IDE, which includes a four-digit year. Aliases are provided for other means by which Visual Studio versions are sometimes referred to, such as two digits which correspond to the product version of the VisualC++ compiler, or a combination of the two:
On Apple, the Xcode generator may be used to generate project files for the Xcode IDE.
Some IDEs such as KDevelop4, QtCreator and CLion have native support for CMake-based buildsystems. Those IDEs provide user interface for selecting an underlying generator to use, typically a choice between a Makefile or a Ninja based generator.
Choosing a generator in cmake-guiВ¶
The «Configure» button triggers a new dialog to select the CMake generator to use.
When choosing a Visual Studio generator, further options are available to set an architecture to generate for.
Setting Build VariablesВ¶
Software projects often require variables to be set on the command line when invoking CMake. Some of the most commonly used CMake variables are listed in the table below:
Path to search for additional CMake modules
Location to install the software to with the install build target
Whether to build shared instead of static libraries for add_library() commands used without a type
Generate a compile_commands.json file for use with clang-based tools
Other project-specific variables may be available to control builds, such as enabling or disabling components of the project.
There is no convention provided by CMake for how such variables are named between different provided buildsystems, except that variables with the prefix CMAKE_ usually refer to options provided by CMake itself and should not be used in third-party options, which should use their own prefix instead. The cmake-gui(1) tool can display options in groups defined by their prefix, so it makes sense for third parties to ensure that they use a self-consistent prefix.
Setting variables on the command lineВ¶
CMake variables can be set on the command line either when creating the initial build:
or later on a subsequent invocation of cmake(1) :
A CMake buildsystem which was initially created on the command line can be modified using the cmake-gui(1) and vice-versa.
Setting variables with cmake-guiВ¶
Variables may be set in the cmake-gui using the «Add Entry» button. This triggers a new dialog to set the value of the variable.
The main view of the cmake-gui(1) user interface can be used to edit existing variables.
The CMake CacheВ¶
When CMake is executed, it needs to find the locations of compilers, tools and dependencies. It also needs to be able to consistently re-generate a buildsystem to use the same compile/link flags and paths to dependencies. Such parameters are also required to be configurable by the user because they are paths and options specific to the users system.
When it is first executed, CMake generates a CMakeCache.txt file in the build directory containing key-value pairs for such artifacts. The cache file can be viewed or edited by the user by running the cmake-gui(1) or ccmake(1) tool. The tools provide an interactive interface for re-configuring the provided software and re-generating the buildsystem, as is needed after editing cached values. Each cache entry may have an associated short help text which is displayed in the user interface tools.
The cache entries may also have a type to signify how it should be presented in the user interface. For example, a cache entry of type BOOL can be edited by a checkbox in a user interface, a STRING can be edited in a text field, and a FILEPATH while similar to a STRING should also provide a way to locate filesystem paths using a file dialog. An entry of type STRING may provide a restricted list of allowed values which are then provided in a drop-down menu in the cmake-gui(1) user interface (see the STRINGS cache property).
The CMake files shipped with a software package may also define boolean toggle options using the option() command. The command creates a cache entry which has a help text and a default value. Such cache entries are typically specific to the provided software and affect the configuration of the build, such as whether tests and examples are built, whether to build with exceptions enabled etc.
PresetsВ¶
Using presets on the command-lineВ¶
and you run the following:
If you want to see the list of available presets, you can run:
This will list the presets available in /path/to/source/CMakePresets.json and /path/to/source/CMakeUsersPresets.json without generating a build tree.
Using presets in cmake-guiВ¶
Invoking the BuildsystemВ¶
After generating the buildsystem, the software can be built by invoking the particular build tool. In the case of the IDE generators, this can involve loading the generated project file into the IDE to invoke the build.
CMake is aware of the specific build tool needed to invoke a build so in general, to build a buildsystem or project from the command line after generating, the following command may be invoked in the build directory:
For all generators, it is possible to run the underlying build tool after invoking CMake. For example, make may be executed after generating with the Unix Makefiles generator to invoke the build, or ninja after generating with the Ninja generator etc. The IDE buildsystems usually provide command line tooling for building a project which can also be invoked.
Selecting a TargetВ¶
Each executable and library described in the CMake files is a build target, and the buildsystem may describe custom targets, either for internal use, or for user consumption, for example to create documentation.
CMake provides some built-in targets for all buildsystems providing CMake files.
The default target used by Makefile and Ninja generators. Builds all targets in the buildsystem, except those which are excluded by their EXCLUDE_FROM_ALL target property or EXCLUDE_FROM_ALL directory property. The name ALL_BUILD is used for this purpose for the Xcode and Visual Studio generators.
Lists the targets available for build. This target is available when using the Unix Makefiles or Ninja generator, and the exact output is tool-specific.
Runs tests. This target is only automatically available if the CMake files provide CTest-based tests. See also Running Tests.
Installs the software. This target is only automatically available if the software defines install rules with the install() command. See also Software Installation.
Creates a binary package. This target is only automatically available if the CMake files provide CPack-based packages.
Creates a source package. This target is only automatically available if the CMake files provide CPack-based packages.
For Makefile based systems, /fast variants of binary build targets are provided. The /fast variants are used to build the specified target without regard for its dependencies. The dependencies are not checked and are not rebuilt if out of date. The Ninja generator is sufficiently fast at dependency checking that such targets are not provided for that generator.
Makefile based systems also provide build-targets to preprocess, assemble and compile individual files in a particular directory.
The file extension is built into the name of the target because another file with the same name but a different extension may exist. However, build-targets without the file extension are also provided.
Specifying a Build ProgramВ¶
User Interaction GuideВ¶
IntroductionВ¶
Where a software package supplies a CMake-based buildsystem with the source of their software, the consumer of the software is required to run a CMake user interaction tool in order to build it.
Well-behaved CMake-based buildsystems do not create any output in the source directory, so typically, the user performs an out-of-source build and performs the build there. First, CMake must be instructed to generate a suitable buildsystem, then the user invokes a build tool to process that generated buildsystem. The generated buildsystem is specific to the machine used to generate it and is not redistributable. Each consumer of a provided source software package is required to use CMake to generate a buildsystem specific to their system.
Generated buildsystems should generally be treated as read-only. The CMake files as a primary artifact should completely specify the buildsystem and there should be no reason to populate properties manually in an IDE for example after generating the buildsystem. CMake will periodically rewrite the generated buildsystem, so modifications by users will be overwritten.
The features and user interfaces described in this manual are available for all CMake-based build systems by virtue of providing CMake files.
Command Line cmake toolВ¶
A simple but typical use of cmake(1) with a fresh copy of software source code is to create a build directory and invoke cmake there:
It is recommended to build in a separate directory to the source because that keeps the source directory pristine, allows for building a single source with multiple toolchains, and allows easy clearing of build artifacts by simply deleting the build directory.
cmake-gui toolВ¶
Users more accustomed to GUI interfaces may use the cmake-gui(1) tool to invoke CMake and generate a buildsystem.
The source and binary directories must first be populated. It is always advised to use different directories for the source and the build.
Generating a BuildsystemВ¶
There are several user interface tools which may be used to generate a buildsystem from CMake files. The ccmake(1) and cmake-gui(1) tools guide the user through setting the various necessary options. The cmake(1) tool can be invoked to specify options on the command line. This manual describes options which may be set using any of the user interface tools, though the mode of setting an option is different for each tool.
Command line environmentВ¶
On Linux systems, the appropriate tools are often provided in system-wide locations and may be readily installed through the system package manager. Other toolchains provided by the user or installed in non-default locations can also be used.
When cross-compiling, some platforms may require environment variables to be set or may provide scripts to set the environment.
Visual Studio ships multiple command prompts and vcvarsall.bat scripts for setting up the correct environments for command line buildsystems. While not strictly necessary to use a corresponding command line environment when using a Visual Studio generator, doing so has no disadvantages.
When using Xcode, there can be more than one Xcode version installed. Which one to use can be selected in a number of different ways, but the most common methods are:
Setting the default version in the preferences of the Xcode IDE.
Setting the default version via the xcode-select command line tool.
Overriding the default version by setting the DEVELOPER_DIR environment variable when running CMake and the build tool.
For convenience, cmake-gui(1) provides an environment variable editor.
CMake chooses a generator by default based on the platform. Usually, the default generator is sufficient to allow the user to proceed to build the software.
On Windows, cmake(1) can be used to generate solutions for the Visual Studio IDE. Visual Studio versions may be specified by the product name of the IDE, which includes a four-digit year. Aliases are provided for other means by which Visual Studio versions are sometimes referred to, such as two digits which correspond to the product version of the VisualC++ compiler, or a combination of the two:
On Apple, the Xcode generator may be used to generate project files for the Xcode IDE.
Some IDEs such as KDevelop4, QtCreator and CLion have native support for CMake-based buildsystems. Those IDEs provide user interface for selecting an underlying generator to use, typically a choice between a Makefile or a Ninja based generator.
Choosing a generator in cmake-guiВ¶
The “Configure” button triggers a new dialog to select the CMake generator to use.
When choosing a Visual Studio generator, further options are available to set an architecture to generate for.
Setting Build VariablesВ¶
Software projects often require variables to be set on the command line when invoking CMake. Some of the most commonly used CMake variables are listed in the table below:
Path to search for additional CMake modules
Location to install the software to with the install build target
Whether to build shared instead of static libraries for add_library commands used without a type
Generate a compile_commands.json file for use with clang-based tools
Other project-specific variables may be available to control builds, such as enabling or disabling components of the project.
There is no convention provided by CMake for how such variables are named between different provided buildsystems, except that variables with the prefix CMAKE_ usually refer to options provided by CMake itself and should not be used in third-party options, which should use their own prefix instead. The cmake-gui(1) tool can display options in groups defined by their prefix, so it makes sense for third parties to ensure that they use a self-consistent prefix.
Setting variables on the command lineВ¶
CMake variables can be set on the command line either when creating the initial build:
or later on a subsequent invocation of cmake(1) :
A CMake buildsystem which was initially created on the command line can be modified using the cmake-gui(1) and vice-versa.
Setting variables with cmake-guiВ¶
Variables may be set in the cmake-gui using the “Add Entry” button. This triggers a new dialog to set the value of the variable.
The main view of the cmake-gui(1) user interface can be used to edit existing variables.
The CMake CacheВ¶
When CMake is executed, it needs to find the locations of compilers, tools and dependencies. It also needs to be able to consistently re-generate a buildsystem to use the same compile/link flags and paths to dependencies. Such parameters are also required to be configurable by the user because they are paths and options specific to the users system.
When it is first executed, CMake generates a CMakeCache.txt file in the build directory containing key-value pairs for such artifacts. The cache file can be viewed or edited by the user by running the cmake-gui(1) or ccmake(1) tool. The tools provide an interactive interface for re-configuring the provided software and re-generating the buildsystem, as is needed after editing cached values. Each cache entry may have an associated short help text which is displayed in the user interface tools.
The cache entries may also have a type to signify how it should be presented in the user interface. For example, a cache entry of type BOOL can be edited by a checkbox in a user interface, a STRING can be edited in a text field, and a FILEPATH while similar to a STRING should also provide a way to locate filesystem paths using a file dialog. An entry of type STRING may provide a restricted list of allowed values which are then provided in a drop-down menu in the cmake-gui(1) user interface (see the STRINGS cache property).
The CMake files shipped with a software package may also define boolean toggle options using the option command. The command creates a cache entry which has a help text and a default value. Such cache entries are typically specific to the provided software and affect the configuration of the build, such as whether tests and examples are built, whether to build with exceptions enabled etc.
PresetsВ¶
Using presets on the command-lineВ¶
and you run the following:
If you want to see the list of available presets, you can run:
This will list the presets available in /path/to/source/CMakePresets.json and /path/to/source/CMakeUsersPresets.json without generating a build tree.
Using presets in cmake-guiВ¶
Invoking the BuildsystemВ¶
After generating the buildsystem, the software can be built by invoking the particular build tool. In the case of the IDE generators, this can involve loading the generated project file into the IDE to invoke the build.
CMake is aware of the specific build tool needed to invoke a build so in general, to build a buildsystem or project from the command line after generating, the following command may be invoked in the build directory:
For all generators, it is possible to run the underlying build tool after invoking CMake. For example, make may be executed after generating with the Unix Makefiles generator to invoke the build, or ninja after generating with the Ninja generator etc. The IDE buildsystems usually provide command line tooling for building a project which can also be invoked.
Selecting a TargetВ¶
Each executable and library described in the CMake files is a build target, and the buildsystem may describe custom targets, either for internal use, or for user consumption, for example to create documentation.
CMake provides some built-in targets for all buildsystems providing CMake files.
The default target used by Makefile and Ninja generators. Builds all targets in the buildsystem, except those which are excluded by their EXCLUDE_FROM_ALL target property or EXCLUDE_FROM_ALL directory property. The name ALL_BUILD is used for this purpose for the Xcode and Visual Studio generators.
Lists the targets available for build. This target is available when using the Unix Makefiles or Ninja generator, and the exact output is tool-specific.
Runs tests. This target is only automatically available if the CMake files provide CTest-based tests. See also Running Tests.
Installs the software. This target is only automatically available if the software defines install rules with the install command. See also Software Installation.
Creates a binary package. This target is only automatically available if the CMake files provide CPack-based packages.
Creates a source package. This target is only automatically available if the CMake files provide CPack-based packages.
For Makefile based systems, /fast variants of binary build targets are provided. The /fast variants are used to build the specified target without regard for its dependencies. The dependencies are not checked and are not rebuilt if out of date. The Ninja generator is sufficiently fast at dependency checking that such targets are not provided for that generator.
Makefile based systems also provide build-targets to preprocess, assemble and compile individual files in a particular directory.
The file extension is built into the name of the target because another file with the same name but a different extension may exist. However, build-targets without the file extension are also provided.
Specifying a Build ProgramВ¶
Using Dependencies GuideВ¶
IntroductionВ¶
Projects will frequently depend on other projects, assets, and artifacts. CMake provides a number of ways to incorporate such things into the build. Projects and users have the flexibility to choose between methods that best suit their needs.
The primary methods of bringing dependencies into the build are the find_package() command and the FetchContent module. The FindPkgConfig module is also sometimes used, although it lacks some of the integration of the other two and is not discussed any further in this guide.
Using Pre-built Packages With find_package() В¶
A package needed by the project may already be built and available at some location on the user’s system. That package might have also been built by CMake, or it could have used a different build system entirely. It might even just be a collection of files that didn’t need to be built at all. CMake provides the find_package() command for these scenarios. It searches well-known locations, along with additional hints and paths provided by the project or user. It also supports package components and packages being optional. Result variables are provided to allow the project to customize its own behavior according to whether the package or specific components were found.
The find_package() command supports two main methods for carrying out the search:
Config mode
With this method, the command looks for files that are typically provided by the package itself. This is the more reliable method of the two, since the package details should always be in sync with the package.
Module mode
Not all packages are CMake-aware. Many don’t provide the files needed to support config mode. For such cases, a Find module file can be provided separately, either by the project or by CMake. A Find module is typically a heuristic implementation which knows what the package normally provides and how to present that package to the project. Since Find modules are usually distributed separately from the package, they are not as reliable. They are typically maintained separately, and they are likely to follow different release schedules, so they can easily become out-of-date.
Depending on the arguments used, find_package() may use one or both of the above methods. By restricting the options to just the basic signature, both config mode and module mode can be used to satisfy the dependency. The presence of other options may restrict the call to using only one of the two methods, potentially reducing the command’s ability to find the dependency. See the find_package() documentation for full details about this complex topic.
For both search methods, the user can also set cache variables on the cmake(1) command line or in the ccmake(1) or cmake-gui(1) UI tools to influence and override where to find packages. See the User Interaction Guide for more on how to set cache variables.
Config-file packagesВ¶
The config files can usually be found in a directory whose name matches the pattern lib/cmake/
, although they may be in other locations instead (see Config Mode Search Procedure ). The
is usually the first argument to the find_package() command, and it may even be the only argument. Alternative names can also be specified with the NAMES option:
The config file must be named either
ConfigVersion.cmake file is present.
Config.cmake file is found and any version constraint is satisfied, the find_package() command considers the package to be found, and the entire package is assumed to be complete as designed.
There may be additional files providing CMake commands or Imported Targets for you to use. CMake does not enforce any naming convention for these files. They are related to the primary
Config.cmake file by use of the CMake include() command. The
The environment variable CMAKE_PREFIX_PATH may also be populated with prefixes to search for packages. Like the PATH environment variable, this is a list, but it needs to use the platform-specific environment variable list item separator ( : on Unix and ; on Windows).
The CMAKE_PREFIX_PATH variable provides convenience in cases where multiple prefixes need to be specified, or when multiple packages are available under the same prefix. Paths to packages may also be specified by setting variables matching
Find Module FilesВ¶
Packages which do not provide config files can still be found with the find_package() command, if a FindSomePackage.cmake file is available. These Find module files are different to config files in that:
Find module files should not be provided by the package itself.
The availability of a Find
.cmake file does not indicate the availability of the package, or any particular part of the package.
CMake does not search the locations specified in the CMAKE_PREFIX_PATH variable for Find
.cmake files. Instead, CMake searches for such files in the locations given by the CMAKE_MODULE_PATH variable. It is common for users to set the CMAKE_MODULE_PATH when running CMake, and it is common for CMake projects to append to CMAKE_MODULE_PATH to allow use of local Find module files.
CMake ships Find
See Find Modules for a detailed discussion of how to write a Find module file.
Imported TargetsВ¶
Imported targets should also encapsulate any configuration-specific paths. This includes the location of binaries (libraries, executables), compiler flags, and any other configuration-dependent quantities. Find modules may be less reliable in providing these details than config files.
A complete example which finds a third party package and uses a library from it might look like the following:
Downloading And Building From Source With FetchContent В¶
Dependencies do not necessarily have to be pre-built in order to use them with CMake. They can be built from sources as part of the main project. The FetchContent module provides functionality to download content (typically sources, but can be anything) and add it to the main project if the dependency also uses CMake. The dependency’s sources will be built along with the rest of the project, just as though the sources were part of the project’s own sources.
The general pattern is that the project should first declare all the dependencies it wants to use, then ask for them to be made available. The following demonstrates the principle (see Examples for more):
Various download methods are supported, including downloading and extracting archives from a URL (a range of archive formats are supported), and a number of repository formats including Git, Subversion, and Mercurial. Custom download, update, and patch commands can also be used to support arbitrary use cases.
Not all dependencies can be brought into the project this way. Some dependencies define targets whose names clash with other targets from the project or other dependencies. Concrete executable and library targets created by add_executable() and add_library() are global, so each one must be unique across the whole build. If a dependency would add a clashing target name, it cannot be brought directly into the build with this method.
FetchContent And find_package() IntegrationВ¶
New in version 3.24.
The above example calls find_package(googletest NAMES GTest) first. CMake provides a FindGTest module, so if that finds a GTest package installed somewhere, it will make it available, and the dependency will not be built from source. If no GTest package is found, it will be built from source. In either case, the GTest::gtest_main target is expected to be defined, so we link our unit test executable to that target.
For more advanced use cases, see the CMAKE_FIND_PACKAGE_REDIRECTS_DIR variable.
Dependency ProvidersВ¶
New in version 3.24.
The preceding section discussed techniques that projects can use to specify their dependencies. Ideally, the project shouldn’t really care where a dependency comes from, as long as it provides the things it expects (often just some imported targets). The project says what it needs and may also specify where to get it from, in the absence of any other details, so that it can still be built out-of-the-box.
A dependency provider can be set to intercept find_package() and FetchContent_MakeAvailable() calls. The provider is given an opportunity to satisfy such requests before falling back to the built-in implementation if the provider doesn’t fulfill it.
Only one dependency provider can be set, and it can only be set at a very specific point early in the CMake run. The CMAKE_PROJECT_TOP_LEVEL_INCLUDES variable lists CMake files that will be read while processing the first project() call (and only that call). This is the only time a dependency provider may be set. At most, one single provider is expected to be used throughout the whole project.
For details on how to implement your own custom dependency provider, see the cmake_language(SET_DEPENDENCY_PROVIDER) command.