【问题标题】:Order of processing components in makefilemakefile 中处理组件的顺序
【发布时间】:2012-02-27 22:03:24
【问题描述】:

在makefile中,依赖行的形式是-

abc: x y z

所有三个组件 (x,y,z) 本身都是 makefile 中更靠下的依赖行中的目标。

如果调用make abc,x,y,z这三个目标会按什么顺序执行?

【问题讨论】:

标签: makefile gnu-make


【解决方案1】:

默认情况下,执行顺序与先决条件列表中指定的顺序相同,除非这些先决条件之间定义了任何依赖关系。

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

【讨论】:

  • @Shailesh,不客气。我已经添加了UPD。发布主要答案后的部分。
  • @EldarAbusalimov:没必要——有修订历史。只需将答案写成一篇连贯的散文即可。
【解决方案2】:

您真的不应该依赖它们的执行顺序 - 在其他条件相同的情况下,这些先决条件的所有三个配方都可以并行运行。

唯一的硬性规则是在运行目标配方之前必须满足所有先决条件。

如果xyz 之间没有依赖关系,并且没有并行执行,GNU make 似乎会按照您指定的顺序运行它们,但在文档中并不能保证这一点。

【讨论】:

  • 简短而明确的答案。我现在不能+1,但我会尽量不要忘记明天回来投票。
  • 另一种说法:只要有一个顺序依赖,就让它显式地作为Makefile规则。
  • 'recipe' 是用来表示依赖行下的命令列表的术语?
  • 是的,这就是术语(无论如何在 GNU make 文档中)。
【解决方案3】:

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.oy.tab.o 的拼写错误,但这就是基本原理的实际含义。

因此,观察到的先决条件从左到右处理的行为在这里得到了验证,尽管它只在“基本原理”部分,而不是在主要描述中。理由还提到了并行 make 等问题。

【讨论】:

  • +1 用于 POSIX 描述和关于并行 make 作业的重要警告。 IMO 选择不允许对并行作业执行任何命令是一个错误。 eg 我很高兴我的.objects 可以按任何顺序编译,但是我需要在编译和链接之前和之后分别发生一堆其他事情,这比它困难得多应该是……
【解决方案4】:

来自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,不是最清晰的。
  • @PhilP 我不是母语人士,但我建议您的意思是“考虑过时”(因此需要运行),不是吗?
  • 我无法对其进行编辑以修复,但是是的,您是对的。我想我改写了几次并丢失了一些东西。 “被视为需要更新”也有效。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 2021-12-24
  • 1970-01-01
相关资源
最近更新 更多