Dependencies GNU制造的先决条件将按什么顺序制造?
假设我们有规则:Dependencies GNU制造的先决条件将按什么顺序制造?,dependencies,makefile,gnu,Dependencies,Makefile,Gnu,假设我们有规则: a: b c d e 和b,c,d和e是相互独立的 制定b、c、d、e的顺序是否已定义?一般来说,它们的顺序是b,c,d,e,但有时可能会出现顺序不同的情况吗?当然,如果我使用make-ja,它们可能会同时生成(取决于b、c、d或e是否依次具有其他/相关的依赖项)。根据您提供的规则,顺序正确。对于您的特定示例,这可能意味着许多不同(4!=24,来自内存)顺序中的任何一个 所有make程序都可以自由选择它们喜欢的顺序,只要依赖关系得到尊重。如果在您的示例中有其他规则,比如c:b
a: b c d e
和b
,c
,d
和e
是相互独立的
制定
b
、c
、d
、e
的顺序是否已定义?一般来说,它们的顺序是b
,c
,d
,e
,但有时可能会出现顺序不同的情况吗?当然,如果我使用make-ja
,它们可能会同时生成(取决于b
、c
、d
或e
是否依次具有其他/相关的依赖项)。根据您提供的规则,顺序正确。对于您的特定示例,这可能意味着许多不同(4!=24,来自内存)顺序中的任何一个
所有make
程序都可以自由选择它们喜欢的顺序,只要依赖关系得到尊重。如果在您的示例中有其他规则,比如c:b
,那么c
将在b
之前生成(但您指出的情况并非如此)
如果您需要依赖特定的顺序,则需要更多的规则来强制执行。否则,
make
可以随心所欲。for GNU make只说明如何处理规则,而不是规则中依赖项的处理顺序。最符合逻辑的顺序(对我来说,无论如何)将是它们列出的顺序,但这不能保证。不,顺序没有定义。这就是使用面向声明依赖性编程的要点:计算机可以选择最佳的求值顺序,或者实际上,甚至在同一时间对它们求值。不,当存在n时,您不能指望排序o依赖关系
- make需要这样做,因为依赖关系可能有额外的和多个关系。make所做的排序可能相当复杂,因为图中的节点可能在不同级别上多次相关
- 一般来说,排序算法并不自然,即使对于简单的基于键的排序也是如此
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:=OBJDIR
OBJS:=$(addprefix$(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o:%.c
$(COMPILE.c)$(输出选项)$<
全部:$(OBJS)
$(OBJS):|$(OBJDIR)
$(OBJDIR):
mkdir$(OBJDIR)
现在,如果需要,将运行创建“objdir”目录的规则,
在生成任何“.o”之前,但不会生成“.o”,因为
“objdir”目录时间戳已更改
如果顺序很重要,您可以使用有选择地强制执行。例如,假设您不关心b和c的顺序,只要它们都是在d之前生成的,d是在e之前生成的。那么您可以将规则编写为:
a: b c
$(MAKE) d
$(MAKE) e
# Additional steps to make a
请注意,根据d和e的复杂性,这种方法可能会影响构建时间:请参阅(PDF)对于反对这样做的论点。我将添加这一点以供将来参考。虽然GNU Make在处理先决条件时可能没有定义特定的顺序,但POSIX Make要求按照指定的顺序处理先决条件,即从左到右。大多数实现都遵循这一规则。POSIX甚至给出了一个例子,说明不遵循此规则的重新生成实现可能会中断程序的生成过程:
foo: y.tab.o lex.o main.o
$(CC) $(CFLAGS) -o $@ t.tab.o lex.o main.o
lex.o最终使用了一个不正确的y.tab.h。虽然这可以用GNU Make的方式重写,但我想我应该和大家分享一下关于prerequisit的一些小贴士