<<Modern CMake>> 翻译 2.1 变量和缓存

<<Modern CMake>> 翻译 2.1 变量和缓存

局部变量

我们首先来看变量。局部变量通常这样设置:

set(MY_VARIABLE "value")

变量的名称通常使用全大写字母,后面紧跟变量的值。您可以使用 ${} 来获取变量的值,例如,${MY_VARIABLE}1 CMake 具有作用范围的概念:在设置变量后,只要在同一范围内,你都可以存取该变量的值。 离开函数或子目录中的一个文件,变量也随之消失。 您可以在 PARENT_SCOPE 的尾部设置变量用于子作用域。

你可以设置多个值形成一个列表:

set(MY_LIST "one" "two")

这相当于多个值之间用 ; 隔开。所以以下声明和上面的效果相同:

set(MY_LIST "one;two")

list( 命令有一些实用方法来处理列表,separate_arguments 能够将一个空格分隔的字符串转为一个列表(直接修改变量值)。 请注意,CMake 中如果没有空格,值也可以不用引号引起来。 这允许您大多数时候都可以不把值用引号引起来。

使用 ${} 语法扩展变量时,对于空格的相关规则是一样的。对于文件和目录路径处理要特别小心。 因为路径可以随时包含空格,因此当它们是变量时应该始终用引号引起来(即永远不要写${MY_PATH},总是应该写为"${MY_PATH}")。

缓存变量

如果你想从命令行设置变量,CMake 会提供变量缓存。 有些变量已经内置了,比如CMAKE_BUILD_TYPE。 这种如果变量尚未(从命令行)设置,则设置变量值的语法如下:

set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "Description")

这将不会取代已经设置的变量值,因此您可以在命令行上设置它们,而不会在执行 CMake 文件时被覆盖。 如果要将这些变量作为全局变量,你可以这样书写:

set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "" FORCE)
mark_as_advanced(MY_CACHE_VARIABLE) 

第一行将导致无论如何都对变量进行设置。 第二行使你运行 cmake -L ..或使用 GUI时,变量将不会显示在列表中。 这很常见的,因此你也可以使用 INTERNAL 类型来达到同样的效果(虽然从技术上来说它强制为 STRING 类型,但不会影响任何依赖于变量的 CMake 代码):

set(MY_CACHE_VARIABLE "VALUE" CACHE INTERNAL "")

由于 BOOL 类型非常常见,您也可以使用 option 指令简洁地设置它:

 option(MY_OPTION "This is settable from the command line" OFF)

对于 BOOL 数据类型值 ON 和 OFF,有几种不同语境。

有关 CMake 中内置变量列表,请参阅 cmake-variables

环境变量

你也可以用 set(ENV{variable_name} value) 设置,用 $ENV{variable_name} 获取环境变量值, 但通常最好避免环境变量。

缓存

缓存实际上就是一个文本文件,CMakeCache.txt。CMake 运行时会在构建目录中创建这个文件。 这就是 CMake 记住你设置的任何内容的方式,因此每次重新运行 CMake 时你不必重新(在命令行上)列上这些选项。

属性

CMake 存储信息的另一种方式是使用属性。 这类似于变量,但它只能附加到其他条目上,例如目录或目标。 全局属性可以作为无缓存全局变量。 许多目标属性通过从 CMAKE_ 打头的相匹配的变量初始化而来。 例如,设置 CMAKE_CXX_STANDARD 意味着所有的新目标创建时都将把 CXX_STANDARD 设置为 CMAKE_CXX_STANDARD 变量的值。 设置属性有两种方法:

set_property(TARGET TargetName
             PROPERTY CXX_STANDARD 11)

set_target_properties(TargetName PROPERTIES
                      CXX_STANDARD 11)

第一种形式更通用,可以一次设置多个目标/文件/测试,并提供有用的选项。 第二个是在一个目标上设置多个属性的快捷方式。 你可以这样获取目标属性:

get_property(ResultVariable TARGET TargetName PROPERTY CXX_STANDARD)

有关所有内置属性的列表,请参阅 cmake-properties。 在某些情况下,您也可以定义你自己的属性。2

1.  if 语句有点奇怪,因为它可以使用也可以不使用包围语法来获取变量; 这是历史原因造成的: if出现在  ${} 语法出现之前。  ↩
2. 例如, Interface 目标对允许的自定义属性有一些限制。  ↩

猜你喜欢

转载自www.cnblogs.com/hejiang/p/11247678.html
2.1
今日推荐