cmake指令合集
一、工程属性相关
1.1 project
指定工程的名字和支持的语言,默认支持所有语言
PROJECT(HELLO) # 指定了工程的名字, 并支持所有语言--建议 |
该指定隐式定义了两个CMake的变量
<projectname>_BINARY_DIR |
MESSAGE关键字就可以直接使用这两个变量,当前都指向当前的工作目录
- 问题:如果改了工程名,这两个变量名也会改变
- 解决:CMake有两个预定义变量:
PROJECT_BINARY_DIR
和PROJECT_SOURCE_DIR
,这两个变量和HELLO_BINARY_DIR
,HELLO_SOURCE_DIR
是一致的。所以改了工程名也没有关系
1.2 cmake_minimum_required
指定最低cmake版本
cmake_minimum_required(VERSION 3.0) |
二、变量相关
2.1 预定义变量
PROJECT_SOURCE_DIR
:工程的根目录PROJECT_BINARY_DIR
:运行 cmake 命令的目录,通常是${PROJECT_SOURCE_DIR}/build
PROJECT_NAME
:返回通过 project 命令定义的项目名称CMAKE_CURRENT_SOURCE_DIR
:当前处理的 CMakeLists.txt 所在的路径CMAKE_CURRENT_BINARY_DIR
:target 编译目录CMAKE_CURRENT_LIST_DIR
:CMakeLists.txt 的完整路径CMAKE_CURRENT_LIST_LINE
:当前所在的行CMAKE_MODULE_PATH
:定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
,然后可以用INCLUDE
命令来调用自己的模块EXECUTABLE_OUTPUT_PATH
:重新定义目标二进制可执行文件的存放位置LIBRARY_OUTPUT_PATH
:重新定义目标链接库文件的存放位置
2.2 set
显式指定变量
set(SRC_LIST main.cpp) # 令SRC_LIST变量包含main.cpp |
CMake缓存变量:
- Normal Variable 普通变量:在一个CMakeList中使用
- Cache Variable 缓存变量:在同一个CMake工程的任何地方都可以使用
定义缓存变量:
set(<variable> <value>... CACHE <type> <docstring> [FORCE]) |
variable
:变量名称value
:变量值列表CACHE
:cache变量的标志type
:变量类型,取决于变量的值。类型分为:BOOL
、FILEPATH
、PATH
、STRING
、INTERNAL
docstring
:必须是字符串,作为变量概要说明FORCE
:强制选项,强制修改变量值
2.3 set_property
在给定范围内设置一个对象的属性
set_property(<scope> [APPEND] [APPEND_STRING] PROPERTY <name> [value...]) |
scope
:属性的范围Scope Description GLOBAL 属性在全局范围内有效,属性名称需唯一 DIRECTORY 在指定目录内有效,可以是相对路径也可以是绝对路径 TARGET 设置指定 TARGET 的属性 SOURCE 属性对应零个或多个源文件。默认情况下,源文件属性仅对添加在同一目录 (CMakeLists.txt) 中的目标可见 INSTALL 属性对应零个或多个已安装的文件路径。这些可供 CPack 使用以影响部署 TEST 属性对应零个或多个现有测试 CACHE 属性对应零个或多个缓存现有条目 APPEND | APPEND_STRING
:表示属性是可扩展的列表- 如果设置了,那么后面的
<value1>...
将以列表的形式附加到指定属性的后面 APPEND_STRING
表示后面的<value1>
将以字符串的形式添加到属性的后面
- 如果设置了,那么后面的
PROPERTY
:标识name
:属性名称value
:属性的值
2.4 list
与SET命令类似,即使列表本身是在父域中定义的,LIST命令也只会在当前域创建新的变量
list(LENGTH <list> <output variable>) |
LENGTH
:返回list的长度GET
:返回list中index的element到value中APPEND
:添加新element到list中FIND
:返回list中element的index,没有找到返回-1INSERT
:将新element插入到list中index的位置REMOVE_ITEM
:从list中删除某个elementREMOVE_AT
:从list中删除指定index的elementREMOVE_DUPLICATES
:从list中删除重复的elementREVERSE
:将list的内容反转SORT
:将list按字母顺序排序
三、配置相关
3.1 add_definitions
命令原型:
add_definitions(-DFOO -DBAR ...) |
说明: 在源文件的编译中添加 -D 标志。
测试用例
- 假设代码中通过USE_MACRO 作为区分是否编译部分模块的代码。
|
可以通过项目中中的CMakeLists.txt 中添加如下代码控制代码的开启和关闭。
option(USE_MACRO "Build the project using macro" OFF) |
运行构建项目的时候可以添加参数控制宏的开启和关闭。
cmake -D USE_MACRO=on # 开启 |
说明
- 当运行
cmake -DUSE_MACRO=on
时,会编译#ifdef USE_MACRO
里的代码模块 - 当运行
cmake -DUSE_MACRO=off
时,不会编译#ifdef USE_MACRO
里的代码模块。
3.2 option
控制编译流程,相当于C语言中的宏条件编译
option(<variable> "<help_text>" [value]) |
variable
:定义选项名称help_text
:说明选项的含义value
:定义选项默认状态,一般是OFF或者ON,除去ON之外,其他所有值都为认为是OFF
四、文件结构相关
4.1 add_subdirectory
向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) |
EXCLUDE_FROM_ALL
函数是将写的目录从编译中排除,如程序中的exampleADD_SUBDIRECTORY(src bin)
- 将 src 子目录加入工程并指定编译输出(包含编译中间结果)路径为bin 目录
- 如果不进行 bin 目录的指定,那么编译结果(包括中间结果)都将存放在build/src 目录
4.2 add_library
add_library(hello SHARED ${LIBHELLO_SRC}) |
hello
:就是正常的库名,生成的名字前面会加上lib,最终产生的文件是libhello.soSHARED
,动态库STATIC
,静态库${LIBHELLO_SRC}
:源文件
4.3 set_target_properties
这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本
set(LIBHELLO_SRC hello.cpp) |
4.4 include_directores
这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割
include_directores(/usr/include/hello) |
4.5 link_directories
添加非标准的共享库搜索路径
link_directories(/home/myproject/libs) |
4.6 target_link_libraries
添加需要链接的共享库,共享库需要在标准路径下
# 链接动态库 |
五、文件操作命令
5.1 file
5.1.1 WRITE
将一则信息写入文件filename
中
file(WRITE filename "message towrite"... ) |
- 如果该文件存在,它会覆盖它
- 如果不存在,它会创建该文件
5.1.2 APPEND
如同WRITE,区别在于它将信息内容追加到文件末尾
file(APPEND filename "message to write"... ) |
5.1.3 READ
读取文件的内容并将其存入到变量中
file(READ filename variable [LIMIT numBytes] [OFFSEToffset] [HEX]) |
- 它会在给定的偏移量处开始读取最多
numBytes
个字节 - 如果指定了
HEX
参数,二进制数据将会被转换成十进制表示形式并存储到变量中
5.1.4 加密
计算出文件内容对应的加密散列
file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> filenamevariable) |
5.1.6 STRING
从文件中解析出ASCII字符串列表并存储在变量中
file(STRINGS filename variable |
- 文件中的二进制数据将被忽略。回车符(CR)也会被忽略
- 也能解析
Intel Hex
和Motorola S-record
文件- 这两种文件在读取时会自动转换为二进制格式,可以使用参数
NO_HEX_CONVERSION
禁用这种自动转换
- 这两种文件在读取时会自动转换为二进制格式,可以使用参数
LIMIT_COUNT
:设置可返回的最大数量的字符串LIMIT_INPUT
:设置从输入文件中可读取的最大字节数LIMIT_OUTPUT
:设置存储在输出变量中最大的字节数。LENGTH_MINIMUM
:设置返回的字符串的最小长度。小于这个长度的字符串将被忽略。LENGTH_MAXIMUM
:设置返回的字符串的最大长度。大于这个长度的字符串将被切分为长度不大于于最大长度值的子字符串NEWLINE_CONSUME
:允许换行符包含进字符串中而不是截断它们REGEX
:指定了返回的字符串必须匹配的正则表达式的模式典型用法
5.1.7 GLOB
会产生一个由所有匹配globbing表达式的文件组成的列表,并将其保存到变量中
file(GLOB variable [RELATIVE path] [globbingexpressions]...) |
Globbing 表达式与正则表达式类似,但更简单
如果指定了
RELATIVE
标记,返回的结果将是与指定的路径相对的路径构成的列表通常不推荐使用GLOB命令来从源码树中收集源文件列表
- 原因是:如果CMakeLists.txt文件没有改变,即便在该源码树中添加或删除文件,产生的构建系统也不会知道何时该要求CMake重新产生构建文件
globbing 表达式包括:
*.cxx // match all files with extension cxx
*.vt? // match all files with extension vta,...,vtz
f[3-5].txt // match files f3.txt,f4.txt, f5.txt
5.1.8 GLOB_RECURSE
与GLOB类似,区别在于它会遍历匹配目录的所有文件以及子目录下面的文件
- 对于属于符号链接的子目录,只有FOLLOW_SYMLINKS指定一或者cmake策略CMP0009没有设置为NEW时,才会遍历这些目录
/dir/*.py
:match all Python files in /dir and subdirectories
file(GLOB_RECURSE variable |
5.1.9 RENAME
将文件系统中的文件或目录移动到目标位置,并自动替换目标位置处的文件或目录
file(RENAME <oldname> <newname>) |
5.1.10 REMOVE
删除指定的文件以及子目录下的文件
file(REMOVE [file1 ...]) |
5.1.11 REMOVE_RECURSE
删除指定的文件及子目录,包括非空目录
file(REMOVE_RECURSE [file1 ...]) |
5.1.12 MAKE_DIRECTORY
在指定目录处创建子目录,如果它们的父目录不存在,也会创建它们的父目录
file(MAKE_DIRECTORY [directory1 directory2 ...]) |
5.1.13 RELATIVE_PATH
推断出指定文件相对于特定目录的路径
file(RELATIVE_PATH variable directory file) |
5.1.14 TO_CMAKE_PATH
将路径转换成cmake风格的路径表达形式
file(TO_CMAKE_PATH path result) |
5.1.15 TO_NATIVE_PATH
与TO_CMAKE_PATH类似,但执行反向操作,将cmake风格的路径转换为操作系统特定风格的路径表式形式
file(TO_NATIVE_PATH path result) |
5.1.16 DOWNLOAD
下载指定URL的资源到指定的文件上
file(DOWNLOAD url file |
- 如果指定了
LOG
参数,将会把下载的日志保存到相应的变量中 - 如果指定了
STATUS
变量,操作的状态信息就会保存在相应的变量中。返回的状态是一个长度为2的列表。第一个元素是操作的返回值。0表示操作过程中无错误发生 - 如果指定了
TIMEOUT
,单位为秒,且必须为整数,那么在指定的时间后,操作将会超时, INACTIVITY_TIMEOUT
指定了操作在处于活动状态超过指定的秒数后,应该停止。如果指定了EXPECTED_MD5,如果操作会检验下载后的文件的实际md5校验和是否与预期的匹配,如果不匹配,操作将会失败,并返回相应的错误码。如果指定了 SHOW_PROGRESS,那么进度的信息将会被打印成状态信息直到操作完成。
5.2 get_filename_component
获取完整文件名的特定部分
get_filename_component(<variable> <Filename> <mode> [CACHE]) |
variable
:保存获取部分的变量Filename
:完整的文件名mode
:要获取文件名的哪个部分DIRECTORY
:文件所在目录NAME
:没有目录的文件名EXT
:最长的扩展名,即第一个.
开始NAME_WE
:没有目录和扩展名的文件名LAST_EXT
:最后一个扩展名NAME_WLE
:没有目录和最后一个扩展名的文件名
CACHE
:若指定,则获取到的结果变量会放到缓存中
get_filename_component(<variable> <Filename> <mode> [BASE_DIR <dir>] [CACHE]) |
variable
:保存获取部分的变量Filename
:完整的文件名mode
:要获取文件名的哪个部分ABSOLUTE
:文件的绝对路径REALPATH
:如果为符号连接文件,取得实际的文件的绝对路径。如果不是连接文件,则与ABSOLUTE一样
BASE_DIR <dir>
:如果指定基本目录,则获取的绝对路径为基本目录+文件名。如果不指定,则基于CMAKE_CURRENT_SOURCE_DIR
目录CACHE
:若指定,则获取到的结果变量会放到缓存中
get_filename_component(<variable> <Filename> PROGRAM [PROGRAM_ARGS <arg_var>] [CACHE]) |
variable
:保存获取部分的变量Filename
:完整的文件名PROGRAM_ARGS <arg_var>
:FileName的字符串分离为程序名和参数,然后把参数保存在arg_var中CACHE
:若指定,则获取到的结果变量会放到缓存中