Quick CMake Tutorial
This tutorial describes several most commonly used and helpful commands of CMake.
In this section you can find a brief summary on:
- Specifying/adding header search paths
- Setting compilation options
- Adding build targets
- Including libraries
- Including sub-projects
CMake commands and directives are specified in CMakeLists.txt files.
As a rule, the first command that you see there is
This command specifies the proper version of CMake.
When you create a new project in CLion, the IDE generates this file automatically and inserts there the current
bundled or custom version of CMake (if you prefer to use another version), so you don't need to specify it here.
cmake_minimum_required stays the
project() command. In most cases, it is used to
declare the project's name:
set (MY_VARIABLE example value)
MY_VARIABLEwith the value "example value".
To use the variable's value in the other commands and instructions you need to add "$" before the variable's name:
set (MY_VARIABLE "$(MY_VARIABLE) more text")
Example below illustrates, how to create the list of all project source files in the single variable:
set (PROJECT_SOURCE_FILES exampleMain.cpp exampleClass.cpp exampleLib.cpp) # creating a list of project source files
Specifying/adding header search paths
The compiler searches the headers in several predefined places, specific for each operating system. In addition to that,
you can specify the directories with the header
files of your project using CMake
include_directories ("directory_1" "directory_2")
include_directories command adds the specified directories to the
INCLUDE_DIRECTORIES directory property
and the same property for each target for the current
The directories specified in that command can be appended to the current list of directories, or vice versa, prepended.
That can be triggered by using the
Setting compilation options
Setting compilerCLion uses the
Clangcompilers, which you have to download and install prior to CLion installation on your system. So, as a rule, there is no need for you to instruct CMake about compiler to be used. Although, if you want to select the compiler explicitly, do the following:
Under CMake options filed specify the desired compiler:, in
-D CMAKE_<LANG>_COMPILER=[fully qualified compiler name]
LANGdefines a language:
Cfor pure C
Setting language standard
To enable a particular language standard, you need to add the respected flag to
set (CMAKE_CXX_FLAGS "$(CMAKE_CXX_FLAGS) -std=c++11") # enable C++11 standard
set (CMAKE_CXX_FLAGS "$(CMAKE_CXX_FLAGS) -std=c++11 -Wall")
Adding build targets
You can instruct the builder to add either the executable or library targets to your project.
To add the executable, use CMake command
add_executable (my_executable $(PROJECT_SOURCE_FILES))
PROJECT_SOURCE_FILEScontains the project sources, needed for successful compilation. If you created your project in CLion, that list of source files is created automatically by the IDE and you don't need to specify it manually.
To add the library, specify
add_library() command instead of
add_library (my_library STATIC|SHARED|MODULE $(PROJECT_SOURCE_FILES))
PROJECT_SOURCE_FILEShere has the same meaning as in the above example. The keywords
MODULEspecify the type of library to be created:
STATIC: create the static library.
SHARED: create the dynamic link library (DLL).
MODULE: create the plugin.
As the first step, you need to instruct the compiler to find a desired library and its components:
find_package (my_library COMPONENTS REQUIRED component1 component2 OPTIONAL_COMPONENTS opt_component)
component2as the mandatory components for a project. The component
opt_componentis qualified as an optional one; that means, that compilation can be proceeded anyway, even in case when the latter had not been found.
Next, link an executable to the found library:
target_link_libraries (my_target $(my_library);$(another_library))
target_link_libraries()shall be placed after
add_executable()command of CMakeLists.txt file (see below example for Boost).
Let's pass this procedure using Boost as an example and extend it with a couple of additional options.
Generally, you can begin with the
find_package() command, which instructs the compiler
to find Boost itself and include (as an example) its
However, if you'd like to configure Boost precisely, you should set up Boost variables prior to
set (Boost_USE_STATIC_LIBS OFF) # enable dynamic linking set (Boost_USE_MULTITHREAD ON) # enable multithreading find_package (Boost COMPONENTS REQUIRED chrono filesystem)
You can add Boost headers directory to the header search paths:
And finally, link your executable with the found Boost libraries:
target_link_libraries (my_target $(Boost_LIBRARIES))
Another approach is to take advantage of such a dependencies manager that can use CMake to configure and build projects, like biicode. You can find an example of how to include Boost libraries in the project using CMake and biicode in this JetBrains CLion Blog post.
Let's imagine that the project which you are working on, has dependencies on some other projects - project1 and project2. In this case you may want to organize your workspace in such a way, that:
- When opening the main project, the IDE shall open all the dependant projects as well.
- All the settings of the main project shall be applied to the dependant projects automatically.
- All the smart features (e.g refactoring, code completion, etc) shall take effect in all the projects.
You can achieve that by proper CMake configuring. Organize your projects as a tree of subdirectories with the top-level
CMakeLists.txt file in the root directory. Each subdirectory of that tree shall represent a single sub-project and contain its own
file and shall be included to the main project in the top-level
CMakeLists.txt file, as following:
add_subdirectory (project1) # including project1 into the main project add_subdirectory (project2) # including project2 into the main project