【问题标题】:Execution of the recipe for multiple targets at once一次为多个目标执行配方
【发布时间】:2014-01-15 21:23:18
【问题描述】:

我有一个项目,我需要以相同的方式处理许多文件。我的 GNUMakefile 看起来像这样:

$(SOURCES) = file1.a file2.a file3.a ... fileN.a
$(TARGETS) = $(SOURCES:.a=.b)

%.b: %.a
    build-tool $?

all: $(TARGETS)

这个makefile 为每个目标执行build-tool,这很慢。所以我希望它只执行一次 build-tool 并列出所有更新的先决条件。
我尝试添加以下规则:

$(TARGETS): $(SOURCES)

它在第一次这样构建时有所帮助:

$ make all
build-tool file1.a file2.a ... fileN.a

但在随后的构建中,build-tool 的执行次数与我拥有的目标一样多:

$ touch file1.a && make all
build-tool file1.a
build-tool file1.a
...
build-tool file1.a

另一方面,如果我将配方更改为build-tool $@,它将在所有情况下执行一次构建工具并满足所有先决条件,这也是不可取的。
是否有某种方法可以对所有目标仅执行一次配方,即在第一次构建时具有所有先决条件,并且仅在后续构建时进行修改?

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    您不能为此使用模式规则。这就是为什么您会看到所有内容都多次构建。您必须使用 make 可以使用的“哨兵”文件来确定自上次构建以来哪些文件发生了更改。

    例如,这样的事情会起作用:

    $(SOURCES) = file1.a file2.a file3.a ... fileN.a
    $(TARGETS) = $(SOURCES:.a=.b)
    
    .PHONY: all
    all: .ran-build-tool
    
    .ran-build-tool: $(SOURCES)
            build-tool $?
            @touch $@
    

    ETA:如果您需要另一个级别,您可以执行以下操作:

    $(SOURCES) = file1.a file2.a file3.a ... fileN.a
    $(TARGETS) = $(SOURCES:.a=.b)
    
    .PHONY: all
    all: .ran-build-tool2
    
    .ran-build-tool2: $(TARGETS) | .ran-build-tool
            build-tool2 $?
            @touch $@
    
    .ran-build-tool: $(SOURCES)
            build-tool $?
            @touch $@
    

    【讨论】:

    • 它解决了我的问题,但我不知道如何在更复杂的情况下使用它。例如,如果我需要以与上述相同的方式从.bbuild-tools2 制作.c 文件。
    • 抱歉,除非您准确描述“更复杂的情况”,否则很难回答您的问题。在 SO 上,与任何地方一样,您会得到您所问问题的答案,而不是您想问的问题的答案。在没有详细了解 build-tool2 的工作原理的情况下,我为我的答案添加了一个可能的解决方案。
    • 如果有人触摸任何$(TARGETS),这将不起作用。 Make 不会检测这些文件是否被修改或删除。
    • 我不确定你的意思。 make 从不检测 targets 是否被触摸/修改。只要他们的时间戳更新,他们的先决条件就会得到满足。 Make 不会保留先前时间戳的数据库,因此它无法知道它是否已更改。然而,在我的第二个示例中,will 检测$(TARGETS) 是否已更改并将运行build-tool2 命令,因为一个或多个将比.ran-build-tool2 目标更新。
    • 注意如果你有clean目标,你还需要删除.ran-build-tool
    【解决方案2】:

    根据an answer to "multiple targets from one recipe and parallel execution",您可能会这样写:

    file1%b file2%b file3%b: file1%a file2%a file3%a
            build-tool $?
    

    【讨论】:

      猜你喜欢
      • 2013-11-18
      • 1970-01-01
      • 2013-11-08
      • 1970-01-01
      • 2015-08-30
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      • 1970-01-01
      相关资源
      最近更新 更多