CLion Help

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:


CMake commands and directives are specified in CMakeLists.txt files. As a rule, the first command that you see there is cmake_minimum_required(VERSION x.x.x). 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.

Next to cmake_minimum_required stays the project() command. In most cases, it is used to declare the project's name:

You can specify more parameters and variables by that command: source and binaries directories, project versions numbers, etc. For more information refer to CMake official documentation.

You can create text variables in CMake. For example, the following set command:
set (MY_VARIABLE example value)
creates a variable MY_VARIABLE with 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() command:

include_directories ("directory_1" "directory_2")

The include_directories command adds the specified directories to the INCLUDE_DIRECTORIES directory property and the same property for each target for the current CMakeLists.txt file.

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 AFTER or BEFORE qualifiers:

include_directories(BEFORE "directory_1/")

The default behavior is append to the current list.

Setting compilation options

Setting compiler

CLion uses the GCC or Clang compilers, 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 Settings | Build, Execution, Deployment | CMake, in CMake options filed specify the desired compiler:

-D CMAKE_<LANG>_COMPILER=[fully qualified compiler name]
where LANG defines a language:
  • C for pure C
  • CXX for C++
For example, the directive below sets your C++ compiler:

Setting language standard

To enable a particular language standard, you need to add the respected flag to CMAKE_CXX_FLAGS variable:

set (CMAKE_CXX_FLAGS "$(CMAKE_CXX_FLAGS) -std=c++11") # enable C++11 standard
Use this command to set the other flags used during the project compilation, for example:
set (CMAKE_CXX_FLAGS "$(CMAKE_CXX_FLAGS) -std=c++11 -Wall")
The above command enables the C++11 standard and instructs the compiler to show all the compiler warnings.

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():

add_executable (my_executable $(PROJECT_SOURCE_FILES))
In this example, the variable PROJECT_SOURCE_FILES contains 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_executable:

The variable PROJECT_SOURCE_FILES here has the same meaning as in the above example. The keywords STATIC, SHARED or MODULE specify the type of library to be created:
  • STATIC: create the static library.
  • SHARED: create the dynamic link library (DLL).
  • MODULE: create the plugin.

Including libraries

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)
In this example, option REQUIRED determines component1 and component2 as the mandatory components for a project. The component opt_component is 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))
Note, that 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 chrono and filesystem components. However, if you'd like to configure Boost precisely, you should set up Boost variables prior to find_package() command:

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:

include_directories ($(Boost_INCLUDE_DIRS))

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.

Including sub-projects

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 CMakeLists.txt 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

See Also



Last modified: 20 October 2015