【问题标题】:Make: how to force immediate expansion of a variable?Make:如何强制立即扩展变量?
【发布时间】:2016-10-22 03:07:05
【问题描述】:

考虑以下 GNU makefile sn-p:

# this code is not under my control
A = aaa
B = bbb

# this code is under my control
A += $B

B = ccc
# Prints "aaa ccc".  I would rather "aaa bbb".
$(info $A)

问题在于,由于A 最初是作为延迟变量创建的,因此+= 的RHS 值被视为延迟值。有没有像A += $(immediate B) 这样的东西可以使用?

以下内容有所了解:

TMP := $B
A += $TMP

but 不是一个选项,因为这将在一个包含文件中,并被多次使用(在非递归 make 系统的上下文中)。所以TMP 每次都会被破坏。

更新

多一点理由。这是一个非递归构建,变量d 保存正在处理的目录的名称。为每个子目录调用一个包含文件,设置一些变量。例如:

$d.LIBS += $($d.target_dir)/lib.a
LD_FLAGS += $($d.LIBS)

这里的问题是d 是短暂的,一旦处理下一个目录,它的值就会改变。 LD_FLAGS 和就此而言,$d.LIBS 可能需要保留为延迟变量,但 d 需要在此处立即进行评估。

【问题讨论】:

  • 请更新您的示例,以显示您在包含文件时遇到的问题,很难想象发生了什么。
  • 你不说是否需要A继续延期。如果您不介意它成为直接变量,您可以使用 A := $A $B
  • @user657267 上面的sn -p是一个完整的可运行make脚本。实际用例是一个非递归的 make,每个目录都调用一个包含文件,$B 是当前目录的名称。
  • @MadScientist 如果没有其他解决方案,这可能在实际意义上可行。但我更希望 A 保持延迟,如果它一开始就这样定义的话。

标签: makefile gnu-make


【解决方案1】:

如果你不介意 A 立即生效,那么你可以使用这个:

A := $A $B

如果您希望A 继续被延迟,但要立即扩展$B,您可以使用eval,因为eval 扩展了它的参数:

$(eval A += $B)

这将首先扩展$B,所以你得到A += bbb,然后评估它。

如果您希望扩展值的某些方面而其他方面不扩展,只需转义不可扩展的内容:

$(eval LD_FLAGS += $$($d.LIBS))

不过,我应该说,通常您尝试做的事情更多是由基于目标名称构造的变量名称来处理的,因此类似于:

LD_FLAGS += $($@_LDFLAGS)

或其他。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多