My CMake Cheat Sheet (Updated Regularly)

Minimal Project

cmake_minimum_required(VERSION 3.2)
project(MyApp)
add_executable(myExe main.cpp)

Comments are # python style.

Outputs

Executables are added with add_executable (see above).

Libraries with

add_library(targetName [STATIC | SHARED | MODULE]
  [EXCLUDE_FROM_ALL]
  source1 [source2 ...]
)

STATIC

Specifies a static library or archive. On Windows, the default library name would be targetName.lib, while on Unix-like platforms, it would typically be libtargetName.a.

SHARED

Specifies a shared or dynamically linked library. On Windows, the default library name would be targetName.dll, on Apple platforms it would be libtargetName.dylib and on other Unix-like platforms it would typically be libtargetName.so. On Apple platforms, shared libraries can also be marked as frameworks, a topic covered in Section 22.3, “Frameworks”.

MODULE Specifies a library that is somewhat like a shared library, but is intended to be loaded dynamically at run-time rather than being linked directly to a library or executable. These are 16 typically plugins or optional components the user may choose to be loaded or not. On Windows platforms, no import library is created for the DLL.

Linking Targets

target_link_libraries(targetName
  <PRIVATE|PUBLIC|INTERFACE> item1 [item2 ...]
  [<PRIVATE|PUBLIC|INTERFACE> item3 [item4 ...]]
  ...
)

PRIVATE

Private dependencies specify that library A uses library B in its own internal implementation. Anything else that links to library A doesn’t need to know about B because it is an internal implementation detail of A.

PUBLIC

Public dependencies specify that not only does library A use library B internally, it also uses B in its interface. This means that A cannot be used without B, so anything that uses A will also have a direct dependency on B. An example of this would be a function defined in library A which has at least one parameter of a type defined and implemented in library B, so code cannot call the function from A without providing a parameter whose type comes from B.

INTERFACE

Interface dependencies specify that in order to use library A, parts of library B must also be used. This differs from a public dependency in that library A doesn’t require B internally, it only uses B in its interface. An example of where this is useful is when working with library targets defined using the INTERFACE form of add_library(), such as when using a target to represent a header-only library’s dependencies.

Variables

Syntax for declaring a variables:

set(varName value... [PARENT_SCOPE])

varName is case sensitive. Values are all strings, optionally quoted (like when they contain spaces). Lists can be defined by separating with spaces or ;:

set(myVar a b c) # myVar = "a;b;c"
set(myVar a;b;c) # myVar = "a;b;c"
set(myVar "a b c") # myVar = "a b c"
set(myVar a b;c) # myVar = "a;b;c"
set(myVar a "b c") # myVar = "a;b c

To refer, use ${varName}.

Environment

Refer using syntax $ENV{varName}. Set using set(ENV{PATH} "/opt/my_dir").

Cache

Laters!

Files

Common operations (executed during configure stage):

file(RENAME source destination)
file(REMOVE files...)
file(REMOVE_RECURSE filesOrDirs...)
file(MAKE_DIRECTORY dirs...)

Listing

file(GLOB outVar
  [LIST_DIRECTORIES true|false]
  [RELATIVE path]
  [CONFIGURE_DEPENDS] # Requires CMake 3.12 or later
  expressions...
)

or

file(GLOB_RECURSE outVar
  [LIST_DIRECTORIES true|false]
  [RELATIVE path]
  [FOLLOW_SYMLINKS]
  [CONFIGURE_DEPENDS] # Requires CMake 3.12 or later
  expressions...
)

The difference between two above is recursive and non-recursive. Normal wildcards (*, ?) are supported.

CONFIGURE_DEPENDS forces list on every build which may be a performance penalty. It also doesn’t work with all generators.

[ more ]

Organisation

Debugging

message([mode] msg1 [msg2]...) can be used to display diagnostic messages in cmake console. [mode] is like log level i.e. STATUS, WARNING and is optional.

MSVC

Link statically to msvc runtime (note that it requires at least CMake 3.15):

cmake_minimum_required (VERSION 3.15)
...
set_property(TARGET project PROPERTY
  MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

Thanks! You can always email me or use contact form for more questions/comments etc.