一次执行多个目标的配方

时间:2014-01-15 21:23:18

标签: makefile gnu-make

我有一个项目,我需要以相同的方式处理许多文件。我的GNUMake文件如下所示:

$(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 $@,它将在所有情况下执行一次所有先决条件的构建工具,这也是不合需要的。
是否有一些方法只为所有目标执行一次配方,即在第一次构建时具有所有先决条件并且仅在后续构建中进行修改?

2 个答案:

答案 0 :(得分:4)

您无法使用模式规则。这就是为什么你看到一切都是多次建造的原因。您必须使用“sentinel”文件,该文件可用于确定自上次构建以来哪些文件已更改。

例如,类似这样的东西会起作用:

$(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 $@

答案 1 :(得分:0)

根据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 $?