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_propertiesandget_target_property
commands
- generic
set|get_propertycommands - 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 listifcan 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 ()
foreachandwhileforeach (afile one two three) add_test(${afile}-test .... -D -V -A ...) endforeach (afile)macros 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)
lddcommand 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,SCRIPTandCODE - a target is coming from
add_executableoradd_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
FILESsignature - file permissions can be set using the
FILE|DIRECTORY_PERMISSIONSdirectrives
- couple of signatures defined
- prerequisite shared libraries
GetPrerequisites.cmakemodule providesget_prerequisitesfunction 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_pathandfind_libraryfind_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 inifstatements - 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_compileandtry_runcan be used to validate presence and implementation of specific libraries
- if cmake doesn’t find the files the value will be set to