考虑以下GNU makefile片段:
# 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
但不是一个选项,因为它将在一个包含文件中,并且被多次使用(在非递归make系统的上下文中)。所以TMP
每次都会遭到破坏。
更新
多一点理由。这是一个非递归构建,变量d
包含正在处理的目录的名称。为每个子目录调用一个包含文件,设置一些变量。例如:
$d.LIBS += $($d.target_dir)/lib.a
LD_FLAGS += $($d.LIBS)
这里的问题是d
是短暂的,一旦处理完下一个目录,其值就会改变。 LD_FLAGS
,就此问题而言,$d.LIBS
可能需要保留为延迟变量,但此处需要立即评估d
。
答案 0 :(得分:3)
如果您不介意A
立即行动,那么您可以使用它:
A := $A $B
如果您希望A
继续延期,但要立即展开$B
,则可以使用eval
,因为eval
扩展了其参数:
$(eval A += $B)
这将首先展开$B
,因此您获得A += bbb
,然后对其进行评估。
如果您希望扩展价值的某些方面而不是其他方面,请逃避不要扩展的内容:
$(eval LD_FLAGS += $$($d.LIBS))
我应该说,通常情况下,您尝试做的事情更多是基于目标名称构造的变量名来处理的,所以类似于:
LD_FLAGS += $($@_LDFLAGS)
或其他什么。