我有一个makefile规则来生成antlr解析器的输出文件:
XLexer.c XLexer.h XParser.c XParser.h X.tokens: X.g
$(ANTLR) $(ANTLRFLAGS) X.g
这可以正常工作,并在X.g更改时重建所有生成的文件,如预期的那样。但是当我使用-j标志运行并行make时,上述规则对每个文件运行一次,因此在这种情况下,antlr调用将并行运行5次。
有没有办法做这种类型的规则,但只运行一次命令?我知道.NOPARALLEL:规则,但这违背了目的。我试图使用一个锁定文件来导致多次运行退出,如果一个已经运行但没有成功。
答案 0 :(得分:4)
除非所有输出文件共享一个公共词干(例如,“XLexer.c”和“XLexer.h”具有词干“XLexer”),否则在GNU make中没有干净的方法。有各种解决方法,例如使用sentinel文件:
XLexer.c XLexer.h XParser.c XParser.h X.tokens: dummy
@
dummy: X.g
$(ANTLR) $(ANTLRFLAGS) X.g && touch dummy
在CMCrossroads的Mr. Make专栏的Rules with Multiple Outputs in GNU Make文章中详细介绍了这些选项。
(“@”行是一个“no-op”命令,但重要的是:没有它,GNU make会认为XLexer.c
和朋友永远不会通过增量重建来更新,所以你必须运行make两次以使Xg中的任何更改生效)
或者,您可以使用更智能的make版本,例如ElectricAccelerator,它会自动为您解决此问题(免责声明:我是ElectricAccelerator的架构师。)
答案 1 :(得分:0)
模式规则的行为与普通规则不同; the manual说:
模式规则可能有多个目标。与普通规则不同,这并不会使用相同的先决条件和配方来执行许多不同的规则。如果模式规则有多个目标,
make
知道规则的配方负责制作所有目标。配方只执行一次以制作所有目标。
这适用于您的情况,因为您有一个共同的词干(X
):
all: XLexer.c XLexer.h XParser.c XParser.h X.tokens
# (or more realistically, several targets that depend on the above)
%Lexer.c %Lexer.h %Parser.c %Parser.h %.tokens: %.g
$(ANTLR) $(ANTLRFLAGS) $<