通过计算名称的简单扩展变量的值在配方与外部配方

时间:2016-05-17 14:24:42

标签: makefile gnu-make

我正在试图弄清楚以下行为是否是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

输出我期望:

  

阿尔法
阿尔法

实际输出:

  

阿尔法
测试

1 个答案:

答案 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