一. 简介
前面从函数作用域方面学习了变量的作用域,本文从目录作用域方面来学习变量的作用域。
二. cmake进阶:从目录作用域方面学习变量的作用域
1. 目录作用域
什么是目录作用域?
我把这个作用域叫做目录作用域。子目录会将父目录的所有变量拷贝到当前 CMakeLists.txt 源码中,当前 CMakeLists.txt 中的变量的作用域仅在当前目录有效。
目录作用域有两个特点:向下有效(上层作用域中定义的变量在下层作用域中是有效的),值拷贝。
举个栗子来进一步阐述! 譬如目录结构如下所示:
![](https://img-blog.csdnimg.cn/direct/659bbc5e3ceb45348e7e727976e125c8.png)
父目录
CMakeLists.txt
文件内容如下:
# 父源码
cmake_minimum_required(VERSION 3.5)
project(TEST)
set(parent_var "Hello parent")
message("parent-<parent_var>: ${parent_var}")
add_subdirectory(sub_dir)
message("parent-<parent_var>: ${parent_var}")
在父源码中,我们定义了一个变量
parent_var
,并将其设置为
"Hello parent"
。
子源码
CMakeLists.txt
内容:
message("subdir-<parent_var>: ${parent_var}")
set(parent_var "Hello child")
message("变量修改之后")
message("subdir-<parent_var>: ${parent_var}")
在子源码中,第
1
行打印了
parent_var
变量,这个变量是由父源码所创建的,由于变量向下有效,所以在子源码中也可以使用;
第
2
行,我们去修改
parent_var
变量,将其设置为
"Hello child"
,但这是子源码新
建的一个变量,并没改变父源码中的
parent_var
变量。
也就是说这里的
set
并不影响父源码中的
parent_var
变量,仅仅只是改变了子源码中的
parent_var
变量,这就是值拷贝的含义(子源码从父源码中拷贝了一份变
量,副本)。
进入 build目录下,运行"cmake .."命令后,打印信息如下:
![](https://img-blog.csdnimg.cn/direct/957cd01c8f004bc3b58c9af67d73b5e5.png)
缓存变量在整个
cmake
工程的编译生命周期内都有效,所以这些变量的作用域是全局范围的,工程内
的其他任意目录都可以访问缓存变量。
注意:cmake 是从上到下来解析 CMakeLists.txt 文件的。
缓存变量可以通过
set
命令来定义,使用
set
命令时添加
CACHE
选项来实现;
除此之外,还有其它多
种方式可以定义缓存变量,譬如前面给大家介绍的
cmake -D
选项是经常用来定义缓存变量的方法,
cmake -
DXXX
,就表示创建了一个名为
XXX
的全局变量;