CMake构建实战读书笔记03-CMake常用命令
CMake提供了很多很多命令,这么命令可以先做个大致了解,在需要用到的时候,可以单独研究完整的用法细节。# 1 数值操作命令math
数值操作,即进行算术运算,CMake中不能直接使用运算符运算,需要通过math这个指令来实现运算,例如:
```cmake
math(EXPR a 10*10 OUTPUT_FORMAT DECIMAL) #计算10*10
math(EXPR b "16" OUTPUT_FORMAT HEXADECIMAL) #数字16转为Hex格式
```
# 2 字符串操作命令string
list类似于C++中的字符串,下面介绍它的相关指令
## 2.1 搜索和替换
测试代码:
- 找出aba字符串中第一个a的位置
- 反向找出aba字符串中第一个a的位置
- 找出aba字符串中第一个c的位置
```cmake
string(FIND aba a res)
message("${res}")
string(FIND aba a res REVERSE)
message("${res}")
string(FIND aba cres)
message("${res}")
```
运行结果如下:
## 2.2 正则匹配和替换
CMake中也支持正则表达式。
测试代码如下:
- 定义一个正则表达式"+",表示匹配a、b、c中的任意字符,并且可匹配多次
- 依次测试各个字符串是否满足匹配规则,匹配则会输出
```cmake
set(regex "+")
string(REGEX MATCH ${regex} res aaa)
message("${res}")
string(REGEX MATCH ${regex} res aaa bbb ccc abc)
message("${res}")
string(REGEX MATCH ${regex} res aaad)
message("${res}")
```
## 2.3 取字符串长度
这个比较容易理解,就是获取字符串的长度
```cmake
string(LENGTH "abcde" res)
message("${res}")
```
## 2.4 字符串变换
CONCAT可用于将字符串连接起来
```cmake
set(res "123")
string(CONCAT res a b c)
message("${res}")
```
## 2.5 比较字符串
COMPARE可用于比较字符串,按照字典顺序比较
```cmake
string(COMPARE LESS a abc res)
message("${res}")
string(COMPARE GREATER a abc res)
message("${res}")
```
## 2.6 取哈希值
MD5可以获取字符串的哈希值
```cmake
string(MD5 res "abcde")
message("${res}")
```
## 2.7 字符串生成
ASCII可将对应的ASCII值转换为对应的字符展示
```cmake
string(ASCII 65 66 67 res)
message("${res}")
string(ASCII 228 189 160 res)
message("${res}")
```
## 2.8 字符串模板
template_define.cmake
```cmake
set(template [=[
替换变量a: ${a}
替换变量b: @b@
定义宏C
#cmakedefine C
定义0/1宏D
#cmakedefine01 C
定义值e的宏E
#cmakedefine E e
定义值为F的变量的值的宏E
#cmakedefine F @F@
]=])
```
test8_1.cmake
```cmake
include(template_define.cmake)
set(a "a的值")
set(b "b的值")
set(C "C的值")
set(D "D的值")
set(E "E的值")
set(F "F的值")
string(CONFIGURE ${template} res)
message("${res}")
```
运行结果如下
# 3 列表操作命令list
list类似于C++中的列表,下面介绍它的相关指令
## 3.1 列表
列表可以通过set命令来创建,通过分号来分隔元素
```cmake
set(x "a;b;c")
foreach(i 0 1 2 -1 -2 -3)
list(GET x ${i} res)
message("x[${i}] = ${res}")
endforeach()
```
结果如下:
## 3.2 访问列表元素
通过GET可以获取列表中指定索引的元素,例如,访问第0个,以及访问第0个和第2个
```cmake
set(x "a;b;c")
list(GET x 0 res)
message("${res}")
list(GET x 0 2 res)
message("${res}")
```
## 3.3 获取列表长度
获取长度,也比较好理解
```cmake
set(x a;b;c)
list(LENGTH x res)
message("${res}")
```
## 3.4 列表元素增删
通过INSERT,可以在指定索引位置之后插入元素到列表中,可一次插入多个元素
```cmake
set(x "a;d;e")
list(INSERT x 1 b c)
message("${x}")
```
## 3.5 列表变换
通过JOIN可以实现列表元素的连接,该命令于string中的连接功能类似
```cmake
set(x "a;b;c")
list(JOIN x "-" res)
message("${res}")
string(JOIN "-" res ${x})
message("${res}")
```
## 3.6 列表重排
通过SORT可实现列表中元素的排序
```cmake
set(x "a;b;c;D;e")
list(SORT x)
message("${x}")
```
## 3.7 列表元素变换
通过TRANSFORM,可以实现在元素之前或之后添加自定义的字符串,例如,给每个元素加上括号的代码如下
```cmake
set(x "x a b c d e")
list(TRANSFORM x PREPEND "(")
list(TRANSFORM x AEPEND ")")
message("${x}")
```
# 4 文件操作命令file
文件操作命令的内容有很多,这里仅介绍下文件的读取和遍历
## 4.1 读取文件
读取文件中的内容,可以指定读取的长度
```cmake
file(READ example.txt res)
message("${res}")
file(READ example.txt res LIMIT 6)
message("${res}")
```
## 4.2 遍历路径
可以遍历指定目录下的文件
```cmake
file(GLOB res
RELATIVE "${CMAKE_CURRNT_LIST_DIR}"
*)
message("${res}")
```
# 5 路径操作命令cmake_path
追加路径
```cmake
cmake_path(APPEND res a b c)
message("${res}")
cmake_path(APPEND_STRING res a b c)
message("${res}")
cmake_path(APPEND res d e)
message("${res}")
```
cmake_path指令需要CMake3.20以上的版本,否则会提示不支持cmake_path指令
# 6 路径操作命令get_filename_component
get_filename_component命令也用于路径相关的操作,但其绝大多数功能已被cmake_path命令取代
```cmake
function(f mode)
get_filename_component(res "a/b.c.txt" ${mode})
message("${res}")
endfunction()
f(DIRECTORY)
f(NAME)
f(EXT)
f(NAME_WE)
f(LIST_EXT)
f(NAME_WLE)
```
# 7 配置模板文件configure_file
test471.cmake
```cmake
set(a "a的值")
set(b "b的值")
set(C "C的值")
set(D "D的值")
set(E "E的值")
set(F "F的值")
configure_file(template.h.in res1.h)
configure_file(template.h.in res2.h @ONLY)
configure_file(template.h.in res3.h COPYONLY)
```
template.h.in
```cmake
// 替换变量a:${a}
// 替换变量b:@b@
// 定义宏C
#cmakedefine C
// 定义0/1宏D
#cmakedefine01 D
// 定义值为e的宏E
#cmakedefine E e
// 定义值为F变量的值的宏F
#cmakedefine F @F @
```
# 8 日志输出命令message
类似与C/C++中的printf,用来输出信息。
```cmake
message("hello")
message(WARNING "一般警告")
message(AUTHOR_WARNING "开发警告")
message(SEND_ERROR "一般错误")
message(FATAL_ERROE "致命错误")
message("这条消息不会被输出")
```
除了基础的打印功能,还可以输出不同级别的警告和错误
FATAL_ERROE这种错误输出后,程序应该会退出的,但实际最后一句的输出也打印了出来,没看出哪里问题。
# 9 执行程序execute_process
创建一个脚本,execute_process使其输出两次变量text的值,并且第2次要延迟1s再输出
delay_message.cmake
```cmake
message("${text}")
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
message("${text}")
```
创建另一个脚本,通过execute_process可以并行执行上述的脚本
test491.cmake
```cmake
execute_process(
COMMAND ${CMAKE_COMMAND} -Dtext=1 -P delay_message.cmake
COMMAND ${CMAKE_COMMAND} -Dtext=2 -P delay_message.cmake
COMMAND ${CMAKE_COMMAND} -Dtext=3 -P delay_message.cmake
)
```
# 10 引用CMake程序include
类似与C/C++中的#inclue,用来引入其它文件中的内容。
test_a.cmake
```cmake
message("模块被执行")
set(a "变量a")
```
test410_1.cmake,主要功能为:
- 先引入test_a.cmake,这种带扩展名的,可以是绝对路径,也可以是相对路径
- 然后引入test_a,这种不带扩展名的,会被当做CMake模块,只能是相对路径(但并非当前目录,而是CMAKE_MODULE_PATH变量中的目录),若模块不存在,则会报错,但加上OPTIONAL参数后,则会忽略错误
- 设置CMAKE_MODULE_PATH变量,再次执行include
```cmake
include(test_a.cmake)
message("a: ${a}")
include(test_a OPTIONAL RESULT_VARIABLE out)
message("include(test_a): ${out}")
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
include(test_a RESULT_VARIABLE out)
message("${out}")
```
## 11 总结
本篇介绍了CMake构建实战中的CMake常用命令的相关内容,由于CMake的命令非常多,全部学会也很耗时间,因此可以先对CMake的命令有个大致了解,后续用到哪个再单独查阅对应命令的详细介绍。
<p>以实践出发,进行命令的测试可以说非常直观有效 </p>
认真学习
页:
[1]