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