CMake
is an open-source, cross-platform family of tools designed to build, test and package software.
第一个例子:
1 | cmake_minimum_required (VERSION 3.12.2) |
cmake_minimum_required
CMake 最低版本号要求。
project
指定项目信息。
add_executable
指定生成目标,将名为 main.cc 的源文件编译成名称为 Demo 的可执行文件。
1 | -- The C compiler identification is AppleClang 9.1.0.9020039 |
当前目录执行 cmake .
,得到 Makefile
后再使用 make
命令编译得到 Demo1 可执行文件。
1 | Scanning dependencies of target Demo |
aux_source_directory
会查找指定目录下的所有源文件,然后将结果存进指定变量名。
1 | aux_source_directory(<dir> <variable>) |
The ctest
is the CMake test driver program. CMake-generated build trees created for projects that use the ENABLE_TESTING and ADD_TEST commands have testing support.
基本语法规则
- 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
- 指令(参数 1 参数 2…) 参数之间使用空格或分号分开
- 指令是大小写无关的,参数和变量是大小写相关的。
指令 | 语法 | 介绍 |
---|---|---|
PROJECT | PROJECT(projectname [CXX] [C] [Java]) | 定义工程名称,并可指定工程支持的语言。 |
SET | SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) | 显式定义变量 |
MESSAGE | MESSAGE(STATUS “message to display”…) | 向终端输出信息 |
ADD_EXECUTABLE | ADD_EXECUTABLE(hello ${SRC_LIST} ) |
生成一个可执行文件 |
ADD_SUBDIRECTORY | ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) | 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放位置 |
SUBDIRS | SUBDIRS(dir1 dir2…) 不推荐 | 一次添加多个子目录 |
set( CMAKE_BUILD_TYPE "Debug" )
设置Debug模式。
STREQUAL
是 CMAKE 的关键字,用于字符串比较,相同返回 true。
include(CMakeParseArguments) 使用 cmake_parse_arguments(),是用来解析输入参数的。
变量
CMake基本数据类型是字符串,一组字符串在一起称为列表。
1, ON, YES, TRUE, Y, 非0的数为 真
0, OFF, NO, FALSE, N, IGNORE, 空字符串,以-NOTFOUND结尾的字符串为 假
变量显式定义 :
1 | set(VAR a b c) |
指令 | 语法 |
---|---|
CMAKE_C_COMPILER |
指定C编译器 |
CMAKE_CXX_COMPILER |
指定C++编译器 |
CMAKE_C_FLAGS |
指定编译C文件时的编译选项 |
EXECUTABLE_OUTPUT_PATH |
指定可执行文件的存放路径,最终结果的存放目录 |
LIBRARY_OUTPUT_PATH |
指定库文件存放路径,最终结果的存放目录 |
CMAKE_BUILD_TYPE |
build类型(Debug\Release) |
BUILD_SHARED_LIBS |
指定编译成静态库还是动态库 |
BUILD_LIBS |
|
CMAKE_BINARY_DIR |
工程顶层目录(内部构建),工程编译发生的目录(外部构建) |
PROJECT_BINARY_DIR |
同 CMAKE_BINARY_DIR |
CMAKE_SOURCE_DIR |
工程源代码文件所在的目录,指的是工程顶层目录 |
PROJECT_SOURCE_DIR |
工程源代码文件所在的目录,指的是工程顶层目录 |
CMAKE_CURRENT_SOURCE_DIR |
当前处理的CMakeLists.txt所在的路径 |
CMAKE_CURRRENT_BINARY_DIR |
如果是in-source编译,则跟CMAKE_CURRENT_SOURCE_DIR一致;如果是out-of-source,指的是target编译目录; |
CMAKE_CURRENT_LIST_FILE |
输出调用这个变量的CMakeLists.txt的完整路径 |
CMAKE_CURRENT_LIST_LINE |
输出这个变量所在的行 |
CMAKE_MODULE_PATH |
设置搜索CMakeModules模块(.cmake)的额外路径,用来定义自己的cmake模块所在的路径 |
EXECUTABLE_OUTPUT_PATH |
指定可执行文件的存放路径,最终结果的存放目录; |
LIBRARY_OUTPUT_PATH |
指定库文件存放路径,最终结果的存放目录; |
PROJECT_NAME |
工程名称,即使用PROJECT命令设置的名称; |
CMAKE_CXX_FLAGS_DEBUG |
用于 debug 的编译选项 |
CMAKE_C_FLAGS_DEBUG |
用于 debug 的编译选项 |
CMAKE_CXX_FLAGS_RELEASE |
用于 release 的编译选项 |
CMAKE_C_FLAGS_RELEASE |
用于 release 的编译选项 |
CMAKE_MAJOR_VERSION |
CMake主版本号 |
CMAKE_MINOR_VERSION |
CMake次版本号 |
CMAKE_PATCH_VERSION |
CMake补丁等级 |
CMAKE_SYSTEM |
系统名称,如Linux-2.6.22 |
CMAKE_SYSTEM_NAME |
不包含版本的系统名,如Linux |
CMAKE_SYSTEM_VERSION |
系统版本,如2.6.22 |
CMAKE_SYSTEM_PROCESSOR |
处理器名称,如i686 |
UNIX |
所有的类UNIX平台为TRUE,包括OS X和cygwin |
WIN32 |
所有的win32平台为TRUE,包括cygwin |
函数
1 | function(函数名 参数名) |
宏
1 | macro(宏名 参数) |
文件操作命令
FILE(WRITE filename “message towrite”… )
WRITE 将一则信息写入文件’filename’中,如果该文件存在,它会覆盖它,如果不存在,它会创建该文件。
FILE(APPEND filename “message to write”… )
APPEND 如同WRITE,区别在于它将信息内容追加到文件末尾。
FILE(READ filename variable [LIMIT numBytes] [OFFSEToffset] [HEX])
READ 会读取文件的内容并将其存入到变量中。它会在给定的偏移量处开始读取最多numBytes个字节。如果指定了HEX参数,二进制数据将会被转换成十进制表示形式并存储到变量中。
FILE(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> filenamevariable)
MD5, SHA1, SHA224, SHA256, SHA384, 和SHA512 会计算出文件内容对应的加密散列。
CTest
CMake time & configure time
CMake will process the CMakeLists.txt files in your project and
configure it.
Generation time
CMake will generate the scripts needed by the native build tools to perform subsequent steps in the project.
Build time
native build tools are invoked on the platformand tool-native build scripts previously generated by CMake.
CTest time or test time
run the test suite of the project to check whether the targets perform as intended.
CDash time or report time
results of testing the project are uploaded to a dashboard to be shared with other developers.
Install time
project’s targets, source files, executables, and libraries are installed from the build directory to an install location.
CPack time or packaging time
package our project for distribution, either as source code or binary.
Package install time
newly minted package is installed system-wide.
Cmake Cookbook
cmake --build . --target help
Discovering the operating system
1 | # print custom message depending on the operating system |
Commands
add_custom_command
添加一条自定义的构建规则 生成输出文件或是添加一条自定义命令
- PRE_BUILD 在所有其它的依赖之前执行
- PRE_LINK 在所有其它的依赖之后执行
- POST_BUILD 在目标被构建之后执行
add_custom_target
添加一个目标,它没有输出;这样它就总是会被构建
add_definitions
为源文件的编译添加由-D引入的define flag
add_dependencies
为顶层目标引入一个依赖关系
add_executable
使用给定的源文件,为工程引入一个可执行文件
add_library
使用指定的源文件向工程中添加一个库
add_subdirectory
为构建添加一个子路径
add_test
以指定的参数为工程添加一个测试
aux_source_directory
查找在某个路径下的所有源文件
break
从foreach或while循环中跳出
build_command
获取构建该工程的命令行
cmake_minimum_required
设置一个工程所需要的最低CMake版本
cmake_policy
管理CMake的策略设置
configure_file
将一份文件拷贝到另一个位置并修改它的内容
create_test_sourcelist
为构建测试程序创建一个测试驱动器和源码列表
define_property
定义并描述(Document)自定义属性
else
开始一个if语句块的else部分
elseif
开始 if 块的 elseif 部分
enable_language
支持某种语言
enable_testing
打开当前及以下目录中的测试功能
endforeach
结束foreach语句块中的一系列命令
endfunction
结束一个function语句块中的一系列命令
endif
结束一个if语句块中的一系列命令
endmacro
结束一个macro语句块中的一系列命令
endwhile
结束一个while语句块中的一系列命令
execute_process
执行一个或更多个子进程
export
从构建树中导出目标供外部使用
file
文件操作命令
find_file
查找一个文件的完整路径
find_library
查找一个库文件
find_package
为外部工程加载设置
find_path
搜索包含某个文件的路径
find_program
查找可执行程序
fltk_wrap_ui
创建FLTK用户界面包装器
find_program
查找可执行程序
fltk_wrap_ui
创建FLTK用户界面包装器
foreach
对一个list中的每一个变量执行一组命令
function
开始记录一个函数,为以后以命令的方式调用它做准备
get_cmake_property
获取一个CMake实例的属性
get_directory_property
获取DIRECTORY域中的某种属性
get_filename_component
得到一个完整文件名中的特定部分
get_property
获取一个属性值
get_source_file_property
为一个源文件获取一种属性值
get_target_property
从一个目标中获取一个属性值
get_test_property
获取一个测试的属性
if
执行一组命令
include
从给定的文件中读取CMake的列表文件
include_directories
为构建树添加包含路径
include_external_msproject
在一个workspace中包含一个外部的Microsoft工程
include_regular_expression
设置用于依赖性检查的正则表达式
install
指定在安装时要运行的规则
link_directories
指定连接器查找库的路径
list
列表操作命令
load_cache
从另一个工程的CMake cache中加载值
load_command
将一条命令加载到一个运行中的CMake
macro
为后续以命令方式调用而开始记录一组宏
mark_as_advanced
将CMake 的缓存变量标记为高级
math
数学表达式
message
为用户显示一条消息
option
为用户提供一个可选项
output_required_files
输出一个list,其中包含了一个给定源文件所需要的其他源文件
project
为整个工程设置一个工程名
qt_wrap_cpp
创建Qt包裹器
qt_wrap_ui
创建Qt的UI包裹器
remove_definitions
取消由add_definitions命令添加的-D定义标志
return
从一个文件,路径或函数内返回
separate_arguments
将空格分隔的参数解析为一个分号分隔的list
set
将一个CMAKE变量设置为给定值
set_directory_properties
设置某个路径的一种属性
set_property
在给定的作用域内设置一个命名的属性
set_source_files_properties
源文件有一些属性来可以改变它们构建的方式
set_target_properties
设置目标的一些属性来改变它们构建的方式
set_tests_properties
设置若干个测试的属性值
site_name
将给定的变量设定为计算机名
source_group
为Makefile中的源文件定义一个分组
string
字符串操作函数
target_link_libraries
将给定的库链接到一个目标上
try_compile
尝试编译一些代码
try_run
尝试编译并运行某些代码
unset
撤销对一个变量,cache变量或者环境变量的设置
variable_watch
监视CMake变量的改变
while
当条件为真时,执行一组命令
find_package
CMake本身不提供任何搜索库的便捷方法,所有搜索库并给变量赋值的操作必须由CMake代码完成。
find_package
采用两种模式搜索库:
- Module模式:搜索CMAKE_MODULE_PATH指定路径下的FindXXX.cmake文件,执行该文件从而找到XXX库。
- Config模式:搜索XXX_DIR指定路径下的XXXConfig.cmake文件,执行该文件从而找到XXX库。
CMake默认采取Module模式,如果Module模式未找到库,才会采取Config模式。
如果XXX_DIR路径下找不到XXXConfig.cmake文件,则会找/usr/local/lib/cmake/XXX/中的XXXConfig.cmake文件。
Reference: