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>")
To contact me, send an email anytime or leave a comment below.