对于Antlr解析器生成文件,并行GNU Make运行命令多次

时间:2012-04-26 16:51:05

标签: build makefile parallel-processing antlr gnu

我有一个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:规则,但这违背了目的。我试图使用一个锁定文件来导致多次运行退出,如果一个已经运行但没有成功。

2 个答案:

答案 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) $<