cmake进阶:变量的作用域说明三(从函数作用域方面)

 一.  简介

前一篇文章从函数作用域方面学习了 变量的作用域。文章如下:

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}")
在这个例子中,函数 xyz 中调用 set 时添加了 PARENT_SCOPE 选项,意味着会在函数 xyz 的上一层作 用域中设置 ABC 变量,函数的上一层作用域也就是调用 xyz() 函数时所在的作用域,也就是当前源码对应 的作用域(当前目录作用域)。

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}")
在这个示例中,函数 func1 中调用了 func2 ,那么函数 func2 的上一层作用域就是 func1 函数对应的作用域。

3. 示例代码 3

有如下工程目录结构:

顶层 CMakeLists.txt 文件内容如下:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(TEST)add_subdirectory(src)
xyz()message("${ABC}")

顶层源码调用 src 目录下的子源码,子源码下定义了一个函数 xyz ,如下所示:

# src 下的 CMakeLists.txt
function(xyz)set(ABC "Hello World!" PARENT_SCOPE)
endfunction()

在这种情况下,函数 xyz 的上一层作用域便是顶层目录作用域(顶层源码作用域),关键是看“谁”调用该函数。

同理下面这种情况也是如此,顶层 CMakeLists.txt 文件:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(TEST)
add_subdirectory(src)
message("${ABC}")

src 目录下的 CMakeLists.txt 文件:
# src 下的 CMakeLists.txt
set(ABC "Hello World!" PARENT_SCOPE)
变量 ABC 会在顶层源码中被设置,而不是 set 命令所在的作用域中。
下一篇文章来学习 函数的返回值是如何实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/671908.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VTK —— 三、简单操作 - 示例3 - 将点投影到平面上(附完整源码)

代码效果 本代码编译运行均在如下链接文章生成的库执行成功,若无VTK库则请先参考如下链接编译vtk源码: VTK —— 一、Windows10下编译VTK源码,并用Vs2017代码测试(附编译流程、附编译好的库、vtk测试源码) 教程描述 本…

leetcode-没有重复项的全排列-97

题目要求 思路 1.递归,如果num和n的元素个数一样就可以插入res中了,这个作为递归的结束条件 2.因为这个题是属于排列,并非组合,两者的区别是排列需要把之前插入的元素在回退会去,而组合不需要,因此会存在一…

【操作指南】银河麒麟高级服务器操作系统内核升级——基于4.19.90-17升级

1. 升级清单 升级包及依赖包清单如下。 kernel ARM架构 kernel-core-4.19.90-23.18.v2101.ky10.aarch64.rpm kernel-modules-4.19.90-23.18.v2101.ky10.aarch64.rpm kernel-4.19.90-23.18.v2101.ky10.aarch64.rpm kernel-modules-extra-4.19.90-23.18.v2101.ky10.aarch64.r…

【docker】常用的把springboot打包为docker镜像的maven插件

Spring Boot Maven Plugin: Spring Boot 自带的 Maven 插件 (spring-boot-maven-plugin) 支持直接生成 Docker 镜像。通过配置,可以在 Maven 构建过程中自动构建 Docker 镜像,而无需单独编写 Dockerfile。这种方法简化了将应用打包为 Docker 镜像的过程。…

设备树与/sys/bus/platform/devices与/sys/devices目录关系

设备树与sys/bus/platform/devices sysfs文件系统中/sys/bus/platform/devices下的设备是由设备树生成, 根节点下有compatible的子节点都会在/bus/platform/devices生成节点 总线 I2C、SPI 等控制器会在/bus/platform/devices生成节点 总线 I2C、SPI 节点下的子节点…

权益商城系统源码,支持多种支付方式

权益商城系统源码,支持多种支付方式,后台商品管理,订单管理,串货管理,分站管理, 会员列表,分销日志,应用配置。 上传到服务器,修改数据库信息,导入数据库&a…

LeetCode:滑动窗口最大值

文章收录于LeetCode专栏 LeetCode地址 滑动窗口最大值 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。   返回 滑动窗口中的最大值 。   示例 1…

秋招后端开发面试题 - JVM运行时数据区

目录 运行时数据区前言面试题JVM 内存区域 / 运行时数据区?说一下 JDK1.6、1.7、1.8 内存区域的变化?为什么使用元空间替代永久代作为方法区的实现?Java 堆的内存分区了解吗?运行时常量池?字符串常量池了解吗&#xff…

【Unity】如何获得TMP Button下的text内容

【背景】 unity项目中使用了TMP命名空间的Button UI组件。脚本中需要获得Button下Text的内容,但是发现用TextMeshPro仍然无法获得button下的text对象。 【分析】 Hierarchy结构上看明确Button下是有Text组件的: 括号里是TMP,所以理论上用TextMeshPro类型去FindComponent…

限量背包问题

问题描述 限量背包问题:从m个物品中挑选出最多v个物品放入容量为n的背包。 问题分析 限量背包问题,可以用来解决许多问题,例如要求从n个物品中挑选出最多v个物品放入容量为m的背包使得背包最后的价值最大,或者总共有多少种放法…

这是用VS写的一个tcp客户端和服务端的demo

服务端: 客户端: 其实这里面的核心代码就两行。 客户端的核心代码: //套接字连接服务端 m_tcpSocket->connectToHost(_ip,_port);//通过套接字发送数据m_tcpSocket->write(ui.textEditSend->toPlainText().toUtf8());//如果收到信…

【LLM第四篇】名词解释:SFT

看到京东的一段开场白,觉得很有道理: 2023年,大语言模型以前所未有的速度和能力改变我们对智能系统的认知,成为技术圈最被热议的话题。但“百模大战”终将走向“落地为王”,如何将大语言模型的强大能力融入实际业务、…