CMake语法
CMake项目是基于 CMakeLists.txt
构建的,在 CMakeLists.txt
中(或 *.cmake
中)我们用到的就是CMake Language。
CMake Language的语法非常像一些命令式编程语言。
执行从源树(CMakeLists.txt)的跟文件开始。
CMake命令行工具是由五个可执行文件构成
cmake
ctest
cpack
cmake-gui
ccmake
如何不通过CMakeLists.txt,运行CMake
shell
cmake -P *.cmake
这种用法很少在项目中用到,但适合学习CMake的语法
如何打印
使用message
cmake
message("can you see
something?")
message(------------------------)
message([[can you see
something?]])
message(------------------------)
message(can you see
something?)
message(------------------------)
# 获取CMake中的信息 打印CMake版本信息
message(${CMAKE_VERSION})
$ ls
message.cmake
$ cmake -P message.cmake
can you see
something?
------------------------
can you see
something?
------------------------
canyouseesomething?
------------------------
3.25.1
变量操作set、list
CMake中的变量分为两种
- CMake提供的变量
- 自定义的变量
注意
- CMake变量的
- CMake中的变量在
- CMake获取变量
${变量名}
- 变量的基础操作是
set()
与unset()
,但你也可以用list
或string
操作变
set方法
cmake
set(<variable> <value> ... [PARENT_SCOPE])
- set可以给一个变量设置多个值
- 变量内部存储时使用
;
分割,但显示时只进行连接处理
进行实际使用测试
cmakecmake_minimum_required(VERSION 3.20.0) set(var1 test 1) set(var2 "test 2") set("test spaces" "The variable name has Spaces in it.") message(${var1}) message(${var2}) message((${test\ spaces})) message(-------------------------------------) # 设置多个值 set(multipleVar value1 value2) message(${multipleVar}) message(-------------------------------------) # 给一个变量重复设置值 set(multipleVar value3 value4) message(${multipleVar}) set(multipleVar value5;value6) message(${multipleVar}) message(-------------------------------------) # 获取环境变量 message($ENV{PATH}) message(-------------------------------------) # 往环境变量中添加变量 set(ENV{CXX} g++) message($ENV{CXX}) message(-------------------------------------) # unset unset(ENV{CXX}) message($ENV{CXX}) $ cmake -P set.cmake test1 test 2 (The variable name has Spaces in it.) ------------------------------------- value1value2 ------------------------------------- value3value4 value5value6 ------------------------------------- /home/zm/.vscode-server/bin/8b3775030ed1a69b13e4f4c628c612102e30a681/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/mysql/bin:/usr/local/mysql/bin ------------------------------------- g++ ------------------------------------- CMake Error at set.cmake:41 (message): message called with incorrect number of arguments
list方法
cmake
list(APPEND <list> [<element> ...]) # 向列表中添加元素
list(REMOVE_ITEM <list> <value> [value...]) # 从列表中删除元素
list(LENGTH <list> <output variable>) # 获取列表元素个数
list(FIND <list> <value> <out-variable>) # 在列表中查找元素返回索引
list(INSERT <list> <index> [<element> ...]) # 在index位置插入元素
list(REVERSE <list>) # 反转list
list(SORT <list> [...]) # 排序list
流程控制
条件流程控制if
cmake
if(<condition>)
<commands>
elseif(<condition>)
<commands>
else()
<commands>
endif()
循环流程控制foreach、while
break
continue
cmake
foreach(<loop_variable> RANGE <max>)
<commands>
endforeach()
foreach(<loop_variable> RANGE <min> <max> [<step>])
foreach(<loop_variable> IN [LISTS <lists>] [ITEMS <items>])
while(<condition>)
<commands>
endwhile()
函数
定义函数的语法
cmake
function(<name> [<argument> ...])
<commands>
endfunction()
实例测试
cmakecmake_minimum_required(VERSION 3.20.0) function(test arg1) message("function name:" ${CMAKE_CURRENT_FUNCTION}) message("function argv[0]:" ${arg1}) message("function argv[0]:" ${ARGV0}) message("function argv[1]:" ${ARGV1}) message("function argv[2]:" ${ARGV2}) set(arg1 "Testing changes") message("function argv[0]:" ${arg1}) message("function argv[0]:" ${ARGV0}) endfunction(test arg1) set(a "value1") message(${a}) test(${a} "value2") message(${a}) $ cmake -P function.cmake value1 function name:test function argv[0]:value1 function argv[0]:value1 function argv[1]:value2 function argv[2]: function argv[0]:Testing changes function argv[0]:value1 value1
通过测试我们可以看出,传入的参数在函数内被修改掉了,但是在函数外边的变量不受影响
作用域
CMake有两种作用域
- function scope 函数作用域
- directory scope 当从
add_subdirectory()
命令执行嵌套目录中的CMakeLists.txt列表文件时,注意父CMakeLists.txt中的变量可以被子CMakeLists.txt使用
构建项目测试
shell$ tree . ├── CMakeLists.txt └── test └── CMakeLists.txt 2 directories, 2 files $ cat CMakeLists.txt cmake_minimum_required(VERSION 3.20.0) project(scope) set(hello "hello world") add_subdirectory(test) $ cat test/CMakeLists.txt message("subdirectory:" ${hello}) $ cmake -B build -- The C compiler identification is GNU 12.3.0 -- The CXX compiler identification is GNU 12.3.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done subdirectory:hello world -- Configuring done -- Generating done -- Build files have been written to: /media/psf/code/cmake/scope/build
宏
宏定义在CMake中尽量不要使用,使用宏定义无疑会增加CMake的阅读难度
cmake
macro(<macro_name> [<arg> ...])
<commands>
endmacro()
实例测试
cmakecmake_minimum_required(VERSION 3.20.0) macro(test arg1) message("arg1:" ${arg1}) set(arg1 "Testing changes") set(a "Testing changes") message("arg1:" ${arg1}) endmacro(test arg1) set(a "This is a") message("a:" ${a}) test(${a}) message("a:" ${a}) $ cmake -P macro.cmake a:This is a arg1:This is a arg1:This is a a:Testing changes