【问题标题】:CMake argument passing, by value? by reference? or something else?CMake 参数按值传递?引用?或者是其他东西?
【发布时间】:2019-11-19 15:00:01
【问题描述】:

我有 2 个 CMake 脚本:

Script1.cmake:

cmake_minimum_required(VERSION 3.15)

macro(m1)
message("[DEBUG1] " ${var1})
m2(var1)  #<====================== HERE is different
endmacro(m1)


macro(m2 var2)
message("[DEBUG2] " ${var2})
set(${var2} "set from m2")
endmacro()


m1()
message("[DEBUG3] " ${var1})

Script2.cmake:

cmake_minimum_required(VERSION 3.15)

macro(m1)
message("[DEBUG1] " ${var1})
m2("var1")  #<====================== HERE is different
endmacro(m1)


macro(m2 var2)
message("[DEBUG2] " ${var2})
set(${var2} "set from m2")
endmacro()


m1()
message("[DEBUG3] " ${var1})

我使用cmake -P 运行它们。它们都给出相同的输出:

[DEBUG1]
[DEBUG2] var1
[DEBUG3] set from m2

对于[DEBUG1],我可以解释一下,因为var1 还没有定义。所以${var1} 解析为空。

但是对于[DEBUG2]var1"var1" 传入怎么可能一样

  • 对于通过"var1",我认为结果在逻辑上是合理的。

  • 但是为了传递var1,我实际上是将一些不存在的变量传递给宏m2。我认为应该有一些错误,因为该变量尚未定义。但实际上 CMake 工作正常。而${var2} 解析为var1 的名称。

我之前做过一些 C++ 编程,我可以理解传递参数 by reference 或传递参数 by value。但似乎这两种解释都不适合这里。似乎发生了一些隐式转换。

【问题讨论】:

  • CMake 是现存最奇怪的语言之一。在 CMake 中,一切都是字符串。 var"var" 作为参数传递时完全相同;引号只是让您在参数中放置空格等字符。当您使用${var} 扩展变量时,这就像在哈希图中查找键,即字符串var

标签: cmake cmake-language


【解决方案1】:

正如@Justin 所说,foo(a)foo("a") 是一回事。

但是当您将 list 作为参数传递时,您可以看到不同之处。当你写

foo(a b c d)

这会变成foo("a;b;c;d")。例如,当您使用源文件列表调用 add_executable 时会发生这种情况。 ; 符号是 CMake 用来分隔列表项的特殊符号。此外,CMake list() 命令基本上是对纯字符串进行操作,附加或删除 ; 以及项目本身。

现在,如果你写

foo("a b c d")

你传递一个带空格的字符串,而不是一个包含 4 个元素的列表。

【讨论】:

  • foo(a b c d) 不会变成foo("a;b;c;d")。如果你写foo("a;b;c;d")foo 的第一个参数的值是a;b;c;dfoo 是用一个参数调用的。简而言之,命令参数是存在类列表类型的特殊情况。对于变量,一切都是字符串,set(foo a b c d)set(foo "a;b;c;d")一样
猜你喜欢
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-25
  • 1970-01-01
  • 2015-10-05
  • 2018-06-13
相关资源
最近更新 更多