CMakeLists.txt
lastmod 2021-01-02created 2016-02-1980 edits
Notes on the CMakeList.txt file, the build script of CMake.
Category
- CMake
- CMake:Variables
- CMake:Modules
- CMake:Test (CTest)
- CMake:Pack (CPack)
- CMake:Policies
- CMake:Example
- CMake:Troubleshooting
Commands
- if: conditional statement.
add_definitions(-DFOO -DBAR ...).) FIND_PACKAGE
Load settings for an external project.
How package finding works
The find_package() command will look in the module path for Find<name>.cmake, which is the typical way for finding libraries. First CMake checks all directories in ${CMAKE_MODULE_PATH}, then it looks in its own module directory <CMAKE_ROOT>/share/cmake-x.y/Modules/.
If no such file is found, it looks for <Name>Config.cmake or <lower-case-name>-config.cmake, which are supposed to be installed by libraries (but there are currently not yet many libraries which install them) and that don't do detection, but rather just contain hardcoded values for the installed library.
The former is called module mode and the latter is called config mode. Creation of config mode files is documented here. You may also need the documentation for importing and exporting targets.
For the module system there seems to be no documentation elsewhere, so this article concentrates on it.
No matter which mode is used, if the package has been found, a set of variables will be defined:
- <NAME>_FOUND
- <NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
- <NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS
- <NAME>_DEFINITIONS
All this takes place in the Find<name>.cmake file.
Now, in the CMakeLists.txt file in the top level directory of your code (the client code that is actually going to make use of the library <name>, we check for the variable <NAME>_FOUND to see whether the package has been found or not. For most packages the resulting variables use the name of the package all uppercased, e.g. LIBFOO_FOUND, for some packages the exact case of the package is used, e.g. LibFoo_FOUND. If this variable is found, then, we pass the<NAME>_INCLUDE_DIRS to the include_directories() command and <NAME>_LIBRARIES to the target_link_libraries() command of CMake.
These conventions are documented in the file readme.txt in the CMake module directory.
The "REQUIRED" and other optional find_package arguments are forwarded to the module by find_package and the module should affect its operation based on them.
STRING
Command for manipulating strings. Regular expressions (REGEX), TIMESTAMP, RANDOM, and more are available.
Windows path caution
MESSAGE
You can create a debugging macro as follows.
macro(DBG_MSG _MSG)
message(STATUS
"${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}")
endmacro()
MATH
Arithmetic expressions can be evaluated as follows.
INSTALL
# Install ${CMAKE_INSTALL_PREFIX} settings.
install (TARGETS ${MAIN_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
install (DIRECTORY ${MAIN_NAME}/
DESTINATION include/${MAIN_NAME}
FILES_MATCHING PATTERN "*.h")
TARGET~
- Stackoverflow: how to add linker or compile flag in cmake file
- Stackoverflow: In CMake, how can I find the directory of an included file?
The TARGET family of commands is as follows.
- target_compile_definitions
- target_compile_options
- target_include_directories
- target_link_libraries
get_property
get_source_file_property
set_property
The set_*_properties() functions are shorthands for basic usage. For "advanced" cases, it's better to use the full power of set_property():
set_property(
SOURCE a.cpp
APPEND
PROPERTY COMPILE_DEFINITIONS
DIR1="/home/xxx/b.i" DIR2="/home/xxx/c.i" DIR3="/home/xxx/d.i"
)
set_source_files_properties
- set_source_files_properties — CMake 3.3.2 Documentation
- Stackoverflow: Changing CMAKE_CXX_FLAGS in project
It can be replaced with #set_property. For reference, the getter commands are #get_source_file_property or #get_property.
Properties
The list of properties is as follows:
- ABSTRACT
- AUTOUIC_OPTIONS
- AUTORCC_OPTIONS
- COMPILE_DEFINITIONS
- COMPILE_FLAGS
- EXTERNAL_OBJECT
- Fortran_FORMAT
- GENERATED
- HEADER_FILE_ONLY
- KEEP_EXTENSION
- LABELS
- LANGUAGE
- LOCATION
- MACOSX_PACKAGE_LOCATION
- OBJECT_DEPENDS
- OBJECT_OUTPUTS
- SYMBOLIC
- VS_DEPLOYMENT_CONTENT
- VS_DEPLOYMENT_LOCATION
- VS_SHADER_ENTRYPOINT
- VS_SHADER_FLAGS
- VS_SHADER_MODEL
- VS_SHADER_TYPE
- VS_XAML_TYPE
- WRAP_EXCLUDE
- XCODE_EXPLICIT_FILE_TYPE
- XCODE_LAST_KNOWN_FILE_TYPE
set_target_properties
Targets can have properties that affect how they are built.
mark_as_advanced
Adds to the GUI's advanced (advanced) options.
Object Library
Starting with CMake 2.8.8, the OBJECT type was added to the add_library command.
First, create the OBJECTs.
# A/CMakeLists.txt
add_library(A OBJECT ${A_srcs})
# B/CMakeLists.txt
add_library(B OBJECT ${B_srcs})
To apply the OBJECTs to a project target, do the following.
# CMakeLists.txt
add_subdirectory(A)
add_subdirectory(B)
add_library(big STATIC ${other_srcs} $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
Favorite site
- CMake Useful Variables
- CMake coding guide
- How to use CMake variables
- CMake/Examples
- CMake/Language Syntax
- Building External Projects with CMake 2.8
- CMake:How To Process Lots Of Input Files