Mastering CMake
15 Aug 2017chapters 1-2
- cmake-gui or ccmake (curses lib version) can be run to update configurations
chapter 3
generators
- global per project generator
- every folder has a local generator for creating Makefiles
- each in turn will create content based on CMakeLists
targets
- stored in cmMakefile; e.g. add_library, add_executable
add_library (foo STATIC foo.c)
: foo can be used in the CML later- can keep track of general properties w/
set_target_properties
andget_target_property
commands
- generic
set|get_property
commands - all variables defined have visibility in the following scope and well as in children of the current scope
- we can explicitly set variables with PARENT_SCOPE if required:
set (foo 1 PARENT_SCOPE)
- we can explicitly set variables with PARENT_SCOPE if required:
- user selections and options are cached
- we can explicitly define vars in the cache, but their type need to be specified:
set (USE_JPEG ON CACHE BOOL "include jpeg?")
- we can explicitly define vars in the cache, but their type need to be specified:
chapter 4
project
: if CXX enabled, C is included as wellset
/remove
/separate_arguments
- input a string containing multiple space separated values, outputs a listif
can either have the condition specified everywhere - strings must remain the same - or all others can have just empty conditions- possible operations in the check:
NOT
,AND
,OR
,DEFINED
,MATCHES
,EQUAL
,LESS
,STREQUAL
, …,VERSION_GREATER
if (FOO)
# do something
else (FOO) # or else ()
# elseif (BAR) is also supported
# something else
endif (FOO) # or endif ()
foreach
andwhile
foreach (afile one two three) add_test(${afile}-test .... -D -V -A ...) endforeach (afile)
macro
s are called similarly to functions, but its arguments are replaced prior to executing it- they can have also variable number of parameters
- we can specify minimum required version for cmake
cmake_minimum_required (VERSION 2.8)
- cmake modules are components which can be reused - they are located in the Modules subfolder
include (moduleName)
the full path to the module can as well be provided instead
- a policy (version dependent) can be set or queried, useful on cmake version upgrades
- policies can be silenced w/
cmake_policy (SET CMPXXXX OLD)
or enabled w/... NEW)
- policies can be silenced w/
- system libraries can be targeted w/ the following snippet
find_library (M_LIB m) target_link_libraries (my_executable ${M_LIB})
- shared libraries
- entire unit is the atomic unit, this can cause issues when converting from static to shared library
- the linking order needs to be taken into account, as linker do a single pass to search for symbols (pg 64)
ldd
command to see which libraries are used by a binary- the linked libraries for different “.so” versions can be set by
set_target_properties
- installing files
- couple of signatures defined
TARGETS
,FILES
,PROGRAMS
,DIRECTORY
,SCRIPT
andCODE
- a target is coming from
add_executable
oradd_library
; e.g. shared lib in /lib and static lib in project directory, same as binaryinstall (TARGETS myStaticLib DESTINATION lib/myproject)
- general purpose files to be installed, such as header files, can be installed using the
FILES
signature - file permissions can be set using the
FILE|DIRECTORY_PERMISSIONS
directrives
- couple of signatures defined
- prerequisite shared libraries
GetPrerequisites.cmake
module providesget_prerequisites
function to analyze and classify the dependent libraries - it will produce a list of the shared libraries required
- imported and exported targets
chapter 5 - system inspection
- most used are
find_path
andfind_library
find_library (SOME_LIBRARY NAMES somelib somelib2 PATHS /usr/local/lib /usr/lib) find_path (SOME_INCLUDES some.h /usr/local/include /usr/include) include_directories (${SOME_INCLUDES}) add_executable ([...]) target_link_libraries (myapp ${SOME_LIBRARY})
- all find commands will look in the $PATH variable; windows registry can be used as well
- if cmake doesn’t find the files the value will be set to
VAR-NOTFOUND
, the value will evaluate as false inif
statements - order is important, if you prefer somelib2 over somelib, you need to re-order them
- you shouldn’t code against platform-specific but against feature-specific (ifdefs)
try_compile
andtry_run
can be used to validate presence and implementation of specific libraries
- if cmake doesn’t find the files the value will be set to