假设我有一个程序generator
,它接受带有后缀.source
的文件名列表,并为每个参数生成一个带有后缀.source
替换为.target
的文件。
我有一组带有后缀的文件.source
,并希望编写一个规则,对所有比目标更新的文件调用该程序一次。
我只想优化这个工作 Makefile,为每个更改的源调用generator
。
SOURCES=$(wildcard *.source)
TARGETS=$(SOURCES:%.source=%.target)
all: $(TARGETS)
%.target : %.source
./generator $<
这根据需要工作:
SOURCES=$(wildcard *.source)
all: target.timestamp
target.timestamp : $(SOURCES)
./generator $?
touch target.timestamp
我可以避免创建时间戳文件吗?
您可以通过在每个食谱的列表中收集先决条件来做到这一点然后在虚假目标中进行综述操作:
SOURCES=$(wildcard *.source)
TARGETS=$(SOURCES:%.source=%.target)
all: collective_build
%.target : %.source
$(eval collective_src += $<)
# we do a cp to update the .target files
collective_build: $(TARGETS)
$(foreach f,$(collective_src),cp $(f) $(subst source,target,$(f)); )
但是你违反了保罗规则#2"每一个非。PHONY规则必须使用其目标的确切名称更新文件",并且正在破坏制作的基础。
需要一个时间戳来知道是否运行生成器;但是你的生成器构建了一个文件列表,所以没有一个时间戳。
您编写了两个有效的生成文件,其中包含您知道的优缺点,并且别无选择。