我正在试图弄清楚以下行为是否是Make中的错误,或故意是设计的一部分(如果是这样,我无法在任何地方找到它)。它出现在GNU Make的旧版本和新版本中,我尝试过。
简而言之,行为是评估配方中的计算名称变量是在调用配方时发生的,而不是定义配方的文件中的位置,即使变量只是简单扩展(“:=”,而不是递归扩展“=”)(不是我希望这很重要)。
Repro代码:
a_name := alpha
b_name := beta
AB := a
target1 : $($(AB)_name)
echo $^
echo $($(AB)_name)
alpha : ;
beta : ;
AB := b
target2 : target1 ;
调用make target2
输出我期望:
阿尔法
阿尔法
实际输出:
阿尔法
测试
答案 0 :(得分:1)
您需要阅读3.7 How make Reads a Makefile以了解您所看到的内容。
阅读完毕后,您会发现关键部分是:
Rule Definition
A rule is always expanded the same way, regardless of the form:
immediate : immediate ; deferred
deferred
从那个角度来看,你看到了:
target1 : $($(AB)_name)
在第1阶段读取时,makefile中的会立即展开。
此时,AB
的定义为a
,因此$($(AB)_name)
展开
到$(a_name)
,然后到alpha
。
这个alpha
一劳永逸地成为$^
的先决条件
在第2阶段,在配方中扩展,推迟,所以:
echo $^
食谱中的将回显alpha
。
食谱中的下一行:
echo $($(AB)_name)
在整个makefile之后,也在阶段2中延迟延迟
已被阅读。此时AB
拥有其最终定义
第1阶段,即b
,因此此处$($(AB)_name)
扩展为$(b_name)
,
然后到beta
。所以食谱的这一行回应beta
。