当前位置: 首页 > news >正文

CMake变量作用域

如果你想在 CMake 中既能在当前作用域使用一个变量,又能让父作用域也同时知道这个值,可以采取以下几种方法:

方法 1:直接在子作用域设置变量,并同步到父作用域

你可以先在当前作用域中设置变量值,然后再用 PARENT_SCOPE 将值同步到父作用域。这种方式可以让你在当前作用域正常使用变量的同时,确保父作用域也能接收到该值。

# 在当前作用域设置变量
set(DATA_A "data a")# 打印当前作用域的值
message(STATUS "before I am A ----> ${DATA_A}")# 更新变量值
list(APPEND DATA_A a.c b.c)# 打印更新后的值
message(STATUS "after I am A ----> ${DATA_A}")# 同时将更新后的值传递到父作用域
set(DATA_A "${DATA_A}" PARENT_SCOPE)

这种方式的好处是:

  • 当前作用域可以立即使用 DATA_A
  • 父作用域在子 CMakeLists.txt 执行结束后,会获得最新的 DATA_A 值。

方法 2:在函数中使用 CACHE 变量

如果你希望一个变量在所有 CMakeLists.txt 文件(即全局)中都能使用,可以将该变量设置为 CACHE 变量。CACHE 变量是在全局范围内可见的,并且即使在不同的子 CMakeLists.txt 文件中也能访问。

# 将变量存储在缓存中,供全局使用
set(DATA_A "data a" CACHE STRING "Description")message(STATUS "before I am A ----> ${DATA_A}")# 更新缓存中的变量
list(APPEND DATA_A a.c b.c)# 更新到缓存中
set(DATA_A "${DATA_A}" CACHE STRING "Description")message(STATUS "after I am A ----> ${DATA_A}")

这里的 CACHE 变量可以被子、父作用域访问并修改。适合在多个子项目或者顶层项目中需要共享某些变量的场景。不过,需要注意的是,CACHE 变量适用于全局的配置,所以要慎重使用,以避免变量污染。

方法 3:通过函数传递

如果你在 CMake 函数内定义了变量并希望传递给父作用域,可以通过返回变量或者将变量作为参数传递。

function(my_function)set(DATA_A "data a")message(STATUS "before I am A ----> ${DATA_A}")list(APPEND DATA_A a.c b.c)message(STATUS "after I am A ----> ${DATA_A}")# 将变量返回到调用函数的父作用域set(DATA_A "${DATA_A}" PARENT_SCOPE)
endfunction()my_function()message(STATUS "In parent scope ----> ${DATA_A}")

这种方式比较适合封装逻辑,确保变量的值只通过函数进行修改,同时传递给父作用域。

总结

  1. PARENT_SCOPE:在当前作用域设置并同步给父作用域,适合局部需要传递的场景。
  2. CACHE:用于全局变量,适合多个子项目共享数据。
  3. 函数传递:通过函数来封装变量传递的逻辑。

没错,PARENT_SCOPE 只能将变量在 set() 调用时的值传递给父作用域,它不会持续同步变量的后续修改。也就是说,当你使用 set(VAR value PARENT_SCOPE) 时,只有该行代码执行时,value 会传递给父作用域,后续的任何对 VAR 的修改在子作用域中都不会再自动反映到父作用域中。

例子:

# 子作用域中的代码# 第一次设置 DATA_A,并将其传递给父作用域
set(DATA_A "initial value" PARENT_SCOPE)# 在当前作用域中修改 DATA_A
set(DATA_A "modified in child scope")# 打印子作用域中的 DATA_A
message(STATUS "In child scope: ${DATA_A}")

在这个例子中:

  • PARENT_SCOPE 只将 "initial value" 传递给父作用域。
  • 后续修改的 "modified in child scope" 不会传递给父作用域,父作用域仍然只会知道 "initial value"

因此,如果你希望修改后的值也能够传递给父作用域,需要再一次显式地调用 set(DATA_A "${DATA_A}" PARENT_SCOPE),将更新后的值同步给父作用域。

如何解决这个问题?

你可以在每次修改变量后,通过 set() 带上 PARENT_SCOPE 参数将最新的值同步到父作用域。例如:

# 子作用域中的代码# 第一次设置 DATA_A,并传递给父作用域
set(DATA_A "initial value" PARENT_SCOPE)# 修改变量并再次同步到父作用域
set(DATA_A "modified in child scope")
set(DATA_A "${DATA_A}" PARENT_SCOPE)# 打印子作用域中的 DATA_A
message(STATUS "In child scope: ${DATA_A}")

这样,父作用域就能获得最新的 DATA_A 值。


http://www.mrgr.cn/news/52571.html

相关文章:

  • 从零开始的LeetCode刷题日记:199. 二叉树的右视图
  • 极氪7X路上能见度越来越高,就连小猎豹都被折服成为第10000号车主
  • openpose二维骨架搭建介绍及代码撰写详解(总结4)
  • 【python实操】python小程序之TestSuite和TestRunner
  • C语言二维数组的遍历 Java的强制转换和隐形转换
  • 人脸识别之疲劳检测
  • 集合框架11:泛型集合
  • 忙碌的工作和生活,地平线8号探界者商务背包伴左右
  • 【CAN 应用编程】SocketCan实战
  • Halcon基础-二维码识别
  • Java:类和对象
  • 【前端】Matter:基础概念与入门
  • 双指针 — 复写零
  • Java集合(2 :List)
  • 【工具变量】上市公司当年是否发生财务重述指标整理Stata代码(2000-2023年)
  • 【即见未来,为何不拜】聊聊分布式系统中的故障监测机制——Phi Accrual failure detector
  • [0633].第3-3节:@SentinueResource注解
  • nequip代码
  • 第二十三节 视频处理与保存
  • 初尝类型萃取--typename、模板偏特化、和traits之(三)类型萃取