如果在Make中存在最终目标时,如何不重新制作先决条件

时间:2017-08-04 08:57:00

标签: linux bash makefile

在下面的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

1 个答案:

答案 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条件将实例化ifeqelse之间的内容。有点像两种情况下你有两个不同的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)。
  • 在将md5sum文件存储到目标目录之前,需要mkdir -p配方中的$(MD5DIR)/%.md5: %来创建目标目录。
  • 如果您的源也在子目录中,并且其中一些源可以具有相同的基本名称,则需要$(MD5DIR)这些目标子目录。