【发布时间】:2012-02-27 22:03:24
【问题描述】:
在makefile中,依赖行的形式是-
abc: x y z
所有三个组件 (x,y,z) 本身都是 makefile 中更靠下的依赖行中的目标。
如果调用make abc,x,y,z这三个目标会按什么顺序执行?
【问题讨论】:
在makefile中,依赖行的形式是-
abc: x y z
所有三个组件 (x,y,z) 本身都是 makefile 中更靠下的依赖行中的目标。
如果调用make abc,x,y,z这三个目标会按什么顺序执行?
【问题讨论】:
默认情况下,执行顺序与先决条件列表中指定的顺序相同,除非这些先决条件之间定义了任何依赖关系。
abc: x y z
订单是x y z。
abc: x y z
y : z
订单是x z y。
但理想情况下,您应该设计您的 Makefile,使其不依赖于指定先决条件的顺序。也就是说,如果y 应该在z 之后执行,那么必须有 y : z 依赖。
请记住,GNU Make 可以并行执行一些配方,请参阅Mat's answer。
【讨论】:
您真的不应该依赖它们的执行顺序 - 在其他条件相同的情况下,这些先决条件的所有三个配方都可以并行运行。
唯一的硬性规则是在运行目标配方之前必须满足所有先决条件。
如果x、y 和 z 之间没有依赖关系,并且没有并行执行,GNU make 似乎会按照您指定的顺序运行它们,但在文档中并不能保证这一点。
【讨论】:
+1,但我会尽量不要忘记明天回来投票。
make 的 POSIX 描述包含一个基本原理:
大多数历史实现中的
make实用程序以从左到右的顺序处理目标的先决条件,而makefile 格式需要这样做。它支持许多生成yacc程序的makefile 中使用的标准惯用语;例如:foo: y.tab.o lex.o main.o $(CC) $(CFLAGS) -o $@ t.tab.o lex.o main.o在此示例中,如果
make选择任意顺序,则lex.o可能不会使用正确的y.tab.h。尽管可能有更好的方式来表达这种关系,但它在历史上被广泛使用。如前所述,希望并行更新先决条件的实现应该需要显式扩展make或 makefile 格式来完成它。
(我认为$(CC) 行中的t.tab.o 是y.tab.o 的拼写错误,但这就是基本原理的实际含义。)
因此,观察到的先决条件从左到右处理的行为在这里得到了验证,尽管它只在“基本原理”部分,而不是在主要描述中。理由还提到了并行 make 等问题。
【讨论】:
make 作业的重要警告。 IMO 选择不允许对并行作业执行任何命令是一个错误。 eg 我很高兴我的.objects 可以按任何顺序编译,但是我需要在编译和链接之前和之后分别发生一堆其他事情,这比它困难得多应该是……
来自https://stackoverflow.com/a/22638294/636849,可以添加管道符号:
abc: | x y z
来自制作手册: 可以通过在先决条件列表中放置管道符号 (|) 来指定仅订单先决条件:管道符号左侧的任何先决条件都是正常的;右侧的任何先决条件都是仅订购的:
目标:正常的先决条件 |仅订购的先决条件
【讨论】:
foo: | bar baz 不会强制执行 bar baz ,就像没有管道字符一样。相反,管道粗略地说“当订购 foo、bar 和 baz 时,bar 和 baz 必须都在 foo 之前,但是对 bar 和 baz 的更新并不是导致 foo 被认为已更新并需要运行的充分理由”。文档位于gnu.org/software/make/manual/html_node/Prerequisite-Types.html,不是最清晰的。