在下面的Makefile中,我想当最终文件:checksums.md5已经存在时,不要重新制作所有md5文件:
SOURCEDIR := .
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
STAGES := .md5
CAT := checksums.md5
ALL := $(foreach I, $(STAGES), $(addsuffix $I, $(SOURCES)))
all : ${CAT}
%.md5: %
md5sum $< > $@
${CAT} : ${ALL}
cat $^ >> $@
rm *gz.md5
答案 0 :(得分:2)
您可以使用条件。例如:
SOURCEDIR := .
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
STAGES := .md5
CAT := checksums.md5
ALL := $(foreach I,$(STAGES),$(addsuffix $(I),$(SOURCES)))
ifeq ($(wildcard $(CAT)),)
all: $(CAT)
%.md5: %
md5sum $< > $@
$(CAT): $(ALL)
cat $^ >> $@
rm $(ALL)
else
all:
@echo "Nothing to be done"
endif
说明:如果checksums.md5
存在,$(wildcard $(CAT))
将展开为checksums.md5
(不是空字符串),ifeq
条件将实例化else
之间的内容和endif
。如果checksums.md5
不存在,$(wildcard $(CAT))
将展开为空字符串,ifeq
条件将实例化ifeq
和else
之间的内容。有点像两种情况下你有两个不同的Makefile。
注意:
foreach
调用中抑制了无用的空格(避免使用make无用的空格,它们可能会对其行为产生影响)。ifeq
和($(wildcard...
之间的空格,这是必需的。$I
=&gt; $(I)
),因为强烈建议这样做。rm *gz.md5
替换为rm $(ALL)
,如果您在子目录中有一些来源,这似乎更好。一般评论:你所做的并不符合make哲学。根据文件的最后修改时间和一组目标先决条件依赖性规范,决定应该做什么和不应该做什么。如果你不使用make的这个功能,你根本不应该使用它。任何脚本语言(bash,python,perl ......)可能会更好。
如果您不想要这些部分md5文件,为什么不直接将这些总和放在checksums.md5
中?例如:
SOURCEDIR := .
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
CAT := checksums.md5
all: $(CAT)
$(CAT): $(SOURCES)
md5sum $^ > $@
clean:
rm -f $(CAT)
如果checksums.md5
存在并且是最新的(比源更新),则不会执行任何操作。否则,所有md5sums都将重新计算并存储在checksums.md5
。
如果您的问题是要避免重新计算未更改的md5sums文件,则需要跟踪上次计算它们的时间,并且没有比保留这些中间md5sum文件更好的方法了。但如果您愿意,可以将它们全部放在一个单独的目录中:
SOURCEDIR := .
MD5DIR := .md5sums
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
CAT := checksums.md5
ALL := $(addprefix $(MD5DIR)/,$(patsubst %,%.md5,$(SOURCES)))
all: $(CAT)
$(MD5DIR)/%.md5: %
mkdir -p $(dir $@) && \
md5sum $< > $@
$(CAT): $(ALL)
cat $^ > $@
clean:
rm -rf $(MD5DIR) $(CAT)
注意:
$(ALL)
和addprefix
以不同的方式计算md5sum文件名(patsubst
)。mkdir -p
配方中的$(MD5DIR)/%.md5: %
来创建目标目录。$(MD5DIR)
这些目标子目录。