规则先决条件中缺乏递归扩展

时间:2016-04-15 15:50:37

标签: makefile

我有一个基本上看起来像这样的makefile:

DIRS = a
all : $(DIRS)
DIRS += b
a b:
    @ echo $@

我惊讶地发现只有a被打印出来。为什么?我认为递归扩展的全部优点是我可以为了方便而以任意顺序扩展我的变量。有没有办法让我想要的行为符合all的先决条件?

1 个答案:

答案 0 :(得分:1)

问题在于,当您添加时,展开$(DIRS)

来自3.7 How make Reads a Makefile

  

GNU make在两个不同的阶段开展工作。在第一阶段,它读取所有makefile,包括makefile等,并内化所有变量及其值,隐式和显式规则,并构建所有目标及其先决条件的依赖关系图。在第二阶段,make使用这些内部结构来确定需要重建的目标,并调用必要的规则。

     

理解这种两阶段方法很重要,因为它直接影响变量和函数扩展的发生方式;在编写makefile时,这往往是一些混乱的根源。在这里,我们将展示makefile中不同结构的扩展发生阶段的摘要。我们说如果在第一阶段发生扩展是立即的:在这种情况下,make将扩展构造的该部分中的任何变量或函数,因为解析了makefile。我们说如果不立即进行扩展,则推迟扩展。在构造稍后出现在直接上下文中或直到第二阶段之前,不会执行延迟构造的扩展。

     

...

     

规则定义

     

规则总是以相同的方式扩展,无论形式如何:

immediate : immediate ; deferred
    deferred
     

也就是说,目标和先决条件部分会立即展开,并且用于构造目标的配方始终是延迟的。对于显式规则,模式规则,后缀规则,静态模式规则和简单的先决条件定义,此一般规则适用。

您始终可以向目标添加先决条件。

因此,当您知道将all: b添加到b的先决条件列表中时,您可以添加all

您也可以将all:置于顶部(默认目标选择),然后将all: $(DIRS)放在底部,以使用完整的DIRS值作为先决条件。

最后,您可以使用Secondary Expansion强制执行额外的扩展阶段,该阶段应该在此处执行。

.SECONDEXPANSION:
all: $$(DIRS)