Cmake Cheatsheet - A Gentle Introduction To Cmake
Cmake Cheatsheet - A Gentle Introduction To Cmake
This cheatsheet will give you an idea how CMake works and how it can be used # into the executable Hello
to configure software projects. add_executable ( H e l l o s r c /main . cpp s r c / f o o . cpp )
The document and the CMake examples are available at https://github.
com/mortennobel/CMake-Cheatsheet. First, the minimum version of CMake is defined. Then the project name is
defined using the command project(). A project can contain multiple targets
CMake - Creating a simple C++ project (either executables or libraries). This project defines a single executable target
called Hello, which is created by compiling and linking the two source files
CMake is a tool for configuring how a cross-platform source code project should main.cpp and foo.cpp files.
be built on a given platform. When the two source files are compiled the compiler will search for the header
A small project could be organized like this: file foo.h since both source files depend on this using a #include "foo.hpp".
Since the file is located in the same located as the source file, the compiler will
CMakeLists.txt not have any problems finding the file.
src/main.cpp
src/foo.cpp The CMake Scripting Language
src/foo.hpp
The CMakeLists.txt describes the build process using a command based pro-
This project contains two source files located in the src directory and one header gramming language. The commands are case insensitive and take a list of
file in the include directory in the same directory. arguments.
When running CMake on this project you are asked to for a binary directory.
It is best practice to create a new directory since this directory will contain all # This i s a comment .
files related to building the project. If something goes wrong, you can delete COMMAND( arguments go h e r e )
the folder and start over. ANOTHER_COMMAND( ) # t h i s command has no arguments
Running CMake will not create the final executable, but instead, it will gener- YET_ANOTHER_COMMAND( t h e s e
ate project files for Visual Studio, XCode or makefiles. Use these tools to build arguments a r e s p r e a d # a n o t h e r comment
the project. over s e v e r a l l i n e s )
CMake script also has variables. Variables can either be defined by CMake or
Understanding CMakeLists.txt
can be defined in the CMake script. The command set(parameter value)
set a given parameter to a value. The command message(value) print out
Creating project files using CMake requires a CMakeLists.txt file, which de-
the value to the console. To get the value of a variable use ${varname}, which
scribes how the project is structured and how it should be built.
substitutes the variable name with its value.
For example 1 the file looks like this:
cmake_minimum_required (VERSION 2 . 9 ) cmake_minimum_required (VERSION 2 . 9 )
# S e t up p r o j e c t n a m e SET( x 3 ) # x = "3"
project ( HelloProject ) SET( y 1 ) # y = "1"
MESSAGE( x y ) # d i s p l a y s " xy "
# Compile and l i n k main . cpp and f o o . cpp MESSAGE( $ {x}$ {y} ) # d i s p l a y s "31"
All variable values are a text string. Text strings can be evaluated as boolean • STRING = Arbitrary string.
expressions (e.g. when used in IF() and WHILE()). The values "FALSE",
"OFF", "NO", or any string ending in "-NOTFOUND" evaluates be false - • BOOL = Boolean ON/OFF checkbox.
everything else to true.
Text strings can represent multiple values as a list by separating entities using • INTERNAL = No GUI entry (used for persistent variables).
a semicolon.
In the following example, the user can configure if "Hello" or an alterna-
cmake_minimum_required (VERSION 2 . 9 ) tive string should be printed based on the configuration variables hello and
other_msg.
SET( x 3 2 ) # x = " 3 ; 2 "
SET( y h e l l o world ! ) # y = " h e l l o ; w o r l d ; ! " cmake_minimum_required (VERSION 2 . 9 )
SET( z " h e l l o ␣ world ! " ) # y = " h e l l o w o r l d ! "
MESSAGE( ${x} ) # p r i n t s " xy " SET( h e l l o true CACHE BOOL " I f ␣ t r u e ␣ w r i t e ␣ h e l l o " )
MESSAGE( "y␣=␣${y} ␣ z ␣=␣ ${ z } " ) SET( other_msg " Hi " CACHE STRING "Not␣ h e l l o ␣ v a l u e " )
# p r i n t s y = h e l l o ; world ; ! z = h e l l o world ! IF ( ${ h e l l o } )
MESSAGE( " H e l l o " )
Lists can be iterated using the command FOREACH (var val): ELSE ( $ { h e l l o } )
cmake_minimum_required (VERSION 2 . 9 ) MESSAGE( ${ other_msg } )
ENDIF ( ${ h e l l o } )
SET( x 3 2 ) # x = " 3 ; 2 "
During configuration of the project, the CMake user gets prompted with the
FOREACH ( v a l ${x } )
exposed options.
MESSAGE( ${ v a l } )
ENDFOREACH( v a l )
# prints :
# 3
# 2
CMake allows the end user (who runs CMake) to modify some values of some
variables. This is usually used to defined properties of the build such as loca-
tions of files, machine architecture, and string values.
The command set(<variable> <value> CACHE <type> <docstring>) set
the variable to the default value - but allows the value to be changed by the
cmake user when configuring the build. The type should be one of the following:
Some project both contains multiple executables and multiple libraries. For # l i n k t o Foo l i b r a r y
instance when having both unit tests and programs. It is common to separate t a r g e t _ l i n k _ l i b r a r i e s ( H e l l o Foo )
these subprojects into subfolders. Example:
int main ( ) {
std : : fstream f ( " res . txt " ) ; set ( f o o i n c l u d e "/ u s r / l o c a l / i n c l u d e "
s t d : : c o u t << f . r d b u f ( ) ; CACHE PATH " L o c a t i o n ␣ o f ␣ f o o ␣ h e a d e r " )
return 0 ; set ( f o o l i b " / u s r / l o c a l / l i b / f o o . a"
} CACHE FILEPATH " L o c a t i o n ␣ o f ␣ f o o . a" )
This will create the symbols FOO and BAR, which can be used in the source
i n c l u d e _ d i r e c t o r i e s ( ${ f o o i n c l u d e })
code:
add_executable ( H e l l o someexe /main . cpp ) #include <i o s t r e a m >
t a r g e t _ l i n k _ l i b r a r i e s ( H e l l o ${ f o o l i b } )
using namespace s t d ;
IF (WIN32)
f i l e (COPY ${ f o o d l l } DESTINATION Debug ) int main ( ) {
f i l e (COPY ${ f o o d l l } DESTINATION R e l e a s e ) #i f d e f BAR
ENDIF(WIN32) c o u t << " Bar "<< e n d l ;
#endif
c o u t << " H e l l o ␣ world ␣"<<FOO << e n d l ;
Automatically locating libraries
return 0 ;
CMake also contains a feature to automatically find libraries (based on a num- }
ber of suggested locations) using the command find_package(). However,
this feature works best on macOS and Linux.
https://cmake.org/Wiki/CMake:How_To_Find_Libraries.
Links and information
C++ version
https://cmake.org/Wiki/CMake/Language_Syntax
The C++ version can be set using the commands: https://cmake.org/cmake/help/v3.0/command/set.html
set (CMAKE_CXX_STANDARD 1 4 )
set (CMAKE_CXX_STANDARD_REQUIRED ON) Created by Morten Nobel-Jørgensen, [email protected], ITU, 2017
set (CMAKE_CXX_EXTENSIONS OFF)
Released under the MIT license.
Use the add_definitions() to add preprocessor symbols to the project. Released under the MIT license.