按照什么顺序先决条件将通过GNU作出做什么呢?(In what order prerequisite

2019-09-02 10:24发布

假设我们的规则:

a: b c d e

bcde是相互独立的。

正在顺序bcde界定? 看来,通常他们会为了进行bcde ,但可能它有时会发生,该命令会有所不同?

Answer 1:

当然,如果我用make -ja ,他们可能都得到在同一时间(取决于是否建立bcd ,或e又将有其他/相互依存关系)。



Answer 2:

没有,订单没有定义。 这是在使用声明面向依赖编程整 :计算机可以挑选最佳评价顺序,或事实上,即使是在同一时间进行评估。



Answer 3:

按照什么顺序先决条件将通过GNU作出做什么呢?

这取决于先决条件的类型。 据寿GNU Make使用手册 ,第4.2节:

实际上有两种不同类型的GNU理解先决条件使:如前一节中描述的正常的先决条件,和订单仅先决条件。 一个正常的先决条件,使两种说法:第一,它规定在配方就会被调用的顺序:食谱为目标的所有前提条件是运行为目标的配方前完成。 其次,它规定的依赖关系:如果任何先决条件是比目标新,则目标都被认为是过期的,必须重建。

通常情况下,这正是你想要什么:如果目标的先决条件被更新,则目标也应该进行更新。

然而,有时候,你必须要强加给被调用的规则特定顺序强制目标如果执行这些规则之一被更新的情况。 在这种情况下,要定义订单仅先决条件。 (|)仅订单的先决条件可以通过将管道符号来指定在先决条件列表:任何先决条件管道符号的左边是正常; 任何先决条件的权利是顺序只:

  targets: normal-prerequisites | order-only-prerequisites 

当然正常的先决条件部分可以是空的。 此外,仍然可以声明的先决条件对同一目标的多行:它们被适当地追加(正常前提条件附加到正常的先决条件的列表;顺序仅前提条件附加到订单仅先决条件的列表)。 请注意,如果您声明相同的文件既正常和订单唯一前提,正常条件优先(因为它们有一个订单唯一前提的行为的严格超)。

考虑一个例子,其中你的目标是被放置在一个单独的目录,在这之前的目录可能不存在make运行。 在这种情况下,任何你想要的目标被放置到它,但之前创建的目录,因为目录上的时间戳改变,只要文件被添加,删除或重命名,我们当然不希望重建所有目标每当目录的时间戳的变化。 管理的一种方式是与订单仅先决条件:使目录的顺序,仅在所有目标的前提条件:

 OBJDIR := objdir OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o) $(OBJDIR)/%.o : %.c $(COMPILE.c) $(OUTPUT_OPTION) $< all: $(OBJS) $(OBJS): | $(OBJDIR) $(OBJDIR): mkdir $(OBJDIR) 

现在的规则创建“objdir”目录将被运行,如果需要的话,任何“的.o”建造之前,但没有“的.o”将建成因为‘objdir’目录时间戳改变。



Answer 4:

正确的顺序,根据您提供的规则。 为了您的具体的例子,这可能意味着许多不同的任何一个(4!= 24,从内存中)的订单。

所有make程序可自由选择,只要依赖很荣幸自己喜欢的顺序。 如果有在你的榜样其他规则,比如c: b ,然后c会前提出b (但事实并非如此,因为你所指出的)。

如果你需要依靠特定的顺序,你需要更多的规则来执行它。 否则make能做的事它为所欲为。 该文档为GNU只作规定如何处理规则 ,而不是顺序依赖关系中的规则进行处理。 最合理的顺序(对我来说,反正)将是它们所列出但是这不能保证的顺序。



Answer 5:

不,你不能在排序时,有没有依赖关系计数。

  • 做需要做一个拓扑排序 ,因为依赖可能有额外的和多重关系。 使所做的排序是有可能相当复杂,因为图中的节点可以在不同级别上相关多次
  • 在一般的排序算法不自然稳定 ,即使是简单的基于密钥的种类


Answer 6:

如果订单的问题,您可以选择性地使用强制执行递归化妆 。 例如,假设你不在乎是由什么样的顺序B和C,只要他们两个之前d制成,d为E之前进行。 然后,你可以写你的规则为:

a: b c
    $(MAKE) d
    $(MAKE) e
    # Additional steps to make a

要注意的是,根据d和e的复杂性,这种做法可能会做坏事到您的构建时间:见递归制作是有害的 (PDF)针对做这样的论点。



文章来源: In what order prerequisites will be made by the GNU make?