版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LaineGates/article/details/89847726
变量分类
CMake的变量有其作用域,分全局作用域和局部作用域。
局部作用域变化:
1.在切换目录(即CMakeLists.txt变化)
2.调用函数时变化
3.macro不改变作用域。
局部变量
设置变量
set(<variable> <value>... [PARENT_SCOPE])
如
set(<var "ABC" PARENT_SCOPE) # PARENT_SCOPE指父作用域,使用此参数则父作用域必须有此名的变量
在处理字符串列表,set命令会自动将处理变量
set(MY_LIST "one" "two")
等同于
set(MY_LIST "one;two")
删除变量
unset(<variable>)
使用中遇到bug
项目中,CMAKE分两级目录。
在父级CMakeLists.txt中
set(ABC_Version 1.1.1)
add_subdirectory(子目录)
message(STATUS ABC_Version1 ${ABC_Version}
在子目录CMakeLists.txt中
set(ABC_Version 9.9.9 PARENT_SCOPE)
message(STATUS ABC_Version2 ${ABC_Version}
结果输出
ABC_Version2 1.1.1 !!!非常让人困惑!!!
ABC_Version1 9.9.9
我使用的Cmake版本3.13.3,我猜测在为PARENT_SCOPE的同名变量赋值前,当前作用域先复制一个副本,在当前作用或中输出的是本作用域的内容,所以出现如上效果。
建议:
- 横跨多个作用域的变量,使用使用Cache变量
- 子作用域访问父作用域,只允许读,不允许写
Cache变量
设置变量
cache变量全部是全局变量,变量的值可以在CMakeCache.txt中找到,如CMAKE_INSTALL_PREFIX
。变量设置方式如下:
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
< type >
变量说明
类型 | 内容 | cmake-gui效果 |
---|---|---|
BOOL | bool值,只有ON /OFF 两种个值 |
checkBox,等同效果于OPTION |
FILEPATH | 文件路径 | 文件对话框 |
PATH | 目录路径 | 路径对话框 |
STRING | 字符串 | 输入框或内容为string列表的comboBox |
INTERNAL | 字符串 | 不在界面显示,使用此类型,则默认FORCE |
删除变量
unset(<variable> CACHE)
特殊情况说明
变量作用时间
以下脚本,运行一次
set(abc "123" CACHE STRING "")
message("Variable from cache: ${abc}")
再修改为如下,再运行
set(abc "456" CACHE STRING "")
message("Variable from cache: ${abc}")
两次结果都是123,CACHE仍然使用之前的值
通过"-D"预定义变量
在之前脚本基础上,从命令行设定变量内容
~/dir> cmake -Dabc=444
输出结果为
Variable from cache: 444
说明,未设置FOCE的Cache变量,可通过在命令行通过-D
修改
使用FORCE的Cache变量
命令行仍然使用相同命令,但Cmake内容修改如下:
set(abc "456" CACHE STRING "")
message("Variable from cache: ${abc}")
则输出
Variable from cache: 456
说明,设置FOCE的Cache变量,命令行通过-D
无法修改
原帖作用给出建议:
使用FORCE说明编写的 CMake 代码设计不好.
枚举Cache变量
set(FOO_CRYPTO "OpenSSL" CACHE STRING "Backend for cryptography")
set_property(CACHE FOO_CRYPTO PROPERTY STRINGS "OpenSSL;Libgcrypt;WinCNG")
效果:
高级变量
使用mark_as_advanced(<variable>)
的variable,在cmake-gui中点击了"Advanced"才会出现
环境变量
设置变量
set(ENV{<variable>} [<value>])
如
set(ENV{Boost_ROOT} "/usr/include")
属性
除设置变量外,CMake可通过属性保存信息,属性保存在特定对象上,如目录或target。如下:
set_property(TARGET TargetName
PROPERTY CXX_STANDARD 11)
set_target_properties(TargetName PROPERTIES
CXX_STANDARD 11)
- 前一个更加常用,可为targets/files/tests一次设定属性
-后一个为单个target设置属性,但一次可设置多个属性
获取属性的方式
get_property(ResultVariable TARGET TargetName PROPERTY CXX_STANDARD)
总结及建议
- 需要全局变量或跨多个层级的变量是使用Cache变量
- Cache变量非常适用于用户更改自定义值
- Cache变量要加适当的前缀,防止在多个子目录使用同个变量名时出错
- 子目录只读父目录的值,不要写