变量的传播规则:父会传给子
父模块里定义的变量,会传递给子模块。
变量的传播规则:子不传给父
变量的传播规则:子不传给父

如果父模块里本来就定义了同名变量,则离开子模块后仍保持父模块原来设置的值。
如果子模块需要向父模块里传变量怎么办?
可以用 set 的 PARENT_SCOPE 选项,把一个变量传递到上一层作用域(也就是父模块)。
如果父模块里没有定义 MYVAR 的话,也可以用缓存变量向外部传变量(不推荐)。但是这样就不光父模块可见了,父模块的父模块,到处都可见。
除了父子模块之外还有哪些是带独立作用域的
include的XXX.cmake没有独立作用域add_subdirectory的CMakeLists.txt有独立作用域macro没有独立作用域function有独立作用域(因此PARENT_SCORE也可以用于function的返回值)https://cmake.org/cmake/help/v3.16/command/set.html https://blog.csdn.net/Calvin_zhou/article/details/104060927
环境变量的访问方式:$ENV{xx}
- 用
${xx}访问的是局部变量,局部变量服从刚刚所说的父子模块传播规则。 - 而还有一种特殊的方式可以访问到系统的环境变量(environment variable):
$ENV{xx}。 - 比如
$ENV{PATH}就是获取PATH这个环境变量的值。


缓存变量的访问方式:$CACHE{xx}
此外,还可以用 $CACHE{xx} 来访问缓存里的 xx 变量。缓存变量和环境变量是不论父子模块都共用的,没有作用域一说。
${xx} 找不到局部变量时,会自动去找缓存变量
${xx} 当找不到名为 xx 的局部变量时,就会去在缓存里查找名为 xx的缓存变量。因此这里 CMAKE_BUILD_TYPE 虽然在代码里没被 set,但是他被-D参数固定在缓存里了。所以 ${CMAKE_BUILD_TYPE} 自动变成 $CACHE{CMAKE_BUILD_TYPE} 从而找到变量。
if (DEFINED xx) 判断某变量是否存在
if (DEFINED MYVAR)可以判断是否存在 MYVAR 这个局部变量或缓存变量。
值得注意的是:空字符串不代表变量不存在。因此即使是空字符串 DEFINED 也认为存在。
if (xx) 就可以判断某变量是否存在且不为空字符串
可以直接用 if (xx) 来判断是否为空字符串,因为空字符串等价于 FALSE。
if (DEFINED ENV{xx}) 判断某环境变量是否存在
因为 $ENV{xx} 代表环境变量,因此在 set 和 if 中也可以用 ENV{xx}来表示环境变量。
因为 set 的第一参数和 if 的参数都是不加 $ 的,所以要设置 ${x} 就变成了 set(x ...)。而设置 $ENV{x} 自然就是 set(ENV{x} ...) 咯。同理还可以用 if (DEFINED CACHE{x}) 判断是否存在这个缓存变量,但是 set(CACHE{x} ...) 就不行。
从 bash 设置环境变量试试看


