cmake 4:基本语法
指令
指令的格式:
指令名(指令参数)
- 指令名不区分大小写
- 多个指令参数用空格分隔
- 不需要在调用结束时使用分号
- 每行源代码最多可以包含一个指令调用
- 指令调用不是表达式,不能为调用指令提供另一个指令作为参数
变量
有三类变量:普通变量、缓存变量和环境变量。
定义变量
- 变量名区分大小写,可以包含任何字符
- 变量都在内部作为字符串存储
- 基本的变量操作指令是set()和unset() 建议在变量名中只使用字母数字字符、减号(-) 和下划线(_)。
引用变量
创建对已定义变量的引用,需要使用${}
语法。不同类别变量的使用:
- ${}用于引用普通变量或缓存变量。
- $ENV{}用于引用环境变量。
- $CACHE{}用于引用缓存变量。
普通变量
set(MyString1 "Text1")
message(${MyString1})
unset({MyString1})
求值时CMake将遍历作用域堆栈,并将${MyString1}替换为值,若没有找到变量则替换为空字符串。这个过程称为变量求值、展开或插值。
展开是由内而外的方式执行的,CMake将重复展开过程,直到不能再展开为止。
环境变量
CMake生成环境中用于启动CMake进程的变量的副本,并使它们在单一的全局作用域中可用。查看所有环境变量:
cmake -E environment
CMake允许设置变量(set())和取消设置变量(unset()),但更改只会在运行的CMake进程中对本地副本进行,而不会对实际的系统环境进行更改。
set(ENV{CXX} "clang++")
message("generated with " $ENV{CXX})
unset(ENV{VERBOSE})
缓存变量
缓存变量是存储在构建树中的CMakeCache.txt文件中的变量,包含在项目配置阶段收集的信息,包 括从系统(到编译器、链接器、工具和其他的路径)和通过GUI从用户收集的信息。
缓存变量在脚本中不可用(因为没有CMakeCache.txt 文件),其只存在于项目中。
set(<variable> <value> CACHE <type> <docstring> [FORCE])
set(FOO "BAR" CACHE STRING "interesting value")
set(FOO "BAR" CACHE STRING "interesting value" FORCE)
变量作用域
CMake有两个作用域:
- 函数作用域: 用于执行用function()定义的自定义函数
- 目录作用域: 当从add_subdirectory()指令执行嵌套目录中的CMakeLists.txt文件时
当创建嵌套作用域时,CMake只需用来自当前作用域的所有变量的副本填充。后续命令将影响这些副本。但若完成了嵌套作用域的执行,所有的副本都会删除,而原始的父作用域将恢复。
控制语句
条件语句
if(<condition>)
<commands>
elseif(<condition>)
<commands>
else()
<commands>
endif()
if() 条件支持NOT、AND和OR逻辑操作符:
- NOT
-
AND -
OR 条件的嵌套也可以通过匹配的括号(()) 来实现,CMake语言尊重求值的顺序,从最里面的括号开始。
if() 条件支持支持比较操作:EQUAL,LESS,LESS_EQUAL,GREATER 和GREATER_EQUAL。
循环语句
CMake中的循环可以使用while()或foreach()。这两个命令都支持循环控制机制:
- break():循环停止剩余块的执行,并从封闭循环中断开。
- continue():循环停止当前迭代的执行,并开启下一个迭代。
while
while(<condition>)
<commands>
endwhile()
foreach
foreach(<loop_var> RANGE <max>)
<commands>
endforeach()
foreach(<loop_var> RANGE <min> <max> [<step>])
<commands>
endforeach()
foreach(<loop_var> IN [LISTS <lists>] [ITEMS <items>])
<commands>
endforeach()
指令
可以使用macro()或function()定义指令。
- function() 为本地变量创建一个单独的作用域。
- macro()的工作方式更像是查找和替换指令,没有单独的作用域。
macro()不会在调用堆栈上创建单独的条目。所以宏中调用return()将比在函数中返回调用语句的级别高一级。
function(MyFunction Arg1 Arg2)
<commands>
endfunction()