CMAKE 变量管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 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的同名变量赋值前,当前作用域先复制一个副本,在当前作用或中输出的是本作用域的内容,所以出现如上效果。
建议:

  1. 横跨多个作用域的变量,使用使用Cache变量
  2. 子作用域访问父作用域,只允许读,不允许写

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)

总结及建议

  1. 需要全局变量或跨多个层级的变量是使用Cache变量
  2. Cache变量非常适用于用户更改自定义值
  3. Cache变量要加适当的前缀,防止在多个子目录使用同个变量名时出错
  4. 子目录只读父目录的值,不要写

参考

CMake官方set函数说明
参考1
参考2

猜你喜欢

转载自blog.csdn.net/LaineGates/article/details/89847726