一. 简介
前一篇文章从函数作用域方面学习了 变量的作用域。文章如下:
cmake进阶:变量的作用域说明一(从函数作用域方面)-CSDN博客
cmake进阶:变量的作用域说明二(从函数作用域方面)-CSDN博客
本文继续从函数作用域方面学习了 变量的作用域。
二. 变量的作用域
1. 函数内如何设置外部定义的变量
那如果需要在函数内修改外部定义的变量,该如何做呢?
譬如下面这段代码:
# 函数 xyz
function(xyz)
set(ABC "Hello China!")
endfunction()
set(ABC "Hello World!")
xyz() # 调用函数
message("${ABC}")
通过前面的介绍可知,xyz()函数内通过 set 只是创建了一个在函数内部使用的变量 ABC,而并非是去修改外部定义的变量 ABC,那如何能使得函数内可以去修改外部定义的变量呢?
其实也非常简单,set 命令提供了一个可选选项 PARENT_SCOPE,只需在调用 set 命令时在参数列表末尾加上 PARENT_SCOPE 关键字即可。如下所示:
# 函数 xyz
function(xyz)
set(ABC "Hello China!" PARENT_SCOPE) #加上 PARENT_SCOPE
endfunction()
set(ABC "Hello World!")
xyz() # 调用函数
message("${ABC}")
将上面代码添加到 工程的顶层 CMakeLists.txt文件,进入 build目录下,执行 "cmake .."命令后打印如下信息:
打印信息证明,加上 PARENT_SCOPE 之后确实可以,那 PARENT_SCOPE 选项究竟是什么?
官方给出的解释是这样的:
如果添加了 PARENT_SCOPE 选项,则变量将设置在当前作用域范围之上 的作用域范围内,每个目录(在这里“目录”指的是包含了 CMakeLists.txt 的目录)或函数都会创建一个新作用域,此命令会将变量的值设置到父目录或上层调用函数中(函数嵌套的情况下)。
其实就是说,如果 set 命令添加了 PARENT_SCOPE 选项,那就意味着并不是在当前作用域(set 命令所在作用域)内设置这个变量,而是在当前作用域的上一层作用域(父作用域)中设置该变量;
三. 举例说明 “当前作用域的上一层作用域 ”
1. 示例代码 1
示例代码如下:
# 函数 xyz
function(xyz)
set(ABC "Hello China!" PARENT_SCOPE) #加上 PARENT_SCOPE
endfunction()
set(ABC "Hello World!")
xyz() # 调用函数
message("${ABC}")
2. 示例代码 2
示例代码如下:
# 函数 func2
function(func2)
set(ABC "Hello People!" PARENT_SCOPE)
endfunction()
# 函数 func1
function(func1)
set(ABC "Hello China!")
func2()
endfunction()
set(ABC "Hello World!")
func1()
message("${ABC}")
3. 示例代码 3
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(TEST)
add_subdirectory(src)
xyz()
message("${ABC}")
# src 下的 CMakeLists.txt
function(xyz)
set(ABC "Hello World!" PARENT_SCOPE)
endfunction()
在这种情况下,函数 xyz 的上一层作用域便是顶层目录作用域(顶层源码作用域),关键是看“谁”调用该函数。
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(TEST)
add_subdirectory(src)
message("${ABC}")
# src 下的 CMakeLists.txt
set(ABC "Hello World!" PARENT_SCOPE)