Reputation: 597
In the following Makefile, I would like make not to remake the ALL md5 files when the final file: checksums.md5 already exists:
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
Upvotes: 0
Views: 57
Reputation: 29050
You can use conditionals. Example:
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
Explanation: if checksums.md5
exists, $(wildcard $(CAT))
will expand as checksums.md5
(not the empty string) and the ifeq
conditional will instantiate what is between else
and endif
. If checksums.md5
does not exist, $(wildcard $(CAT))
will expand as the empty string and the ifeq
conditional will instantiate what is between ifeq
and else
. It is a bit like if you had two different Makefiles for the two situations.
Notes:
foreach
call (avoid useless spaces with make, they may have an impact on its behavior).ifeq
and ($(wildcard...
, it is needed.$I
=> $(I)
) because it is strongly advised.rm *gz.md5
by rm $(ALL)
which seems better if you have some of your sources in sub-directories.General remark: what you do is not inline with the make philosophy. make decides what should be done and what should not, based on the last modification time of files and a set of target-prerequisites dependency specifications. If you do not use this feature of make you should probably not use it at all. Any scripting language (bash, python, perl...) would probably be better.
If you do not want these partial md5 files, why don't you directly put the sums in checksums.md5
? Example:
SOURCEDIR := .
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
CAT := checksums.md5
all: $(CAT)
$(CAT): $(SOURCES)
md5sum $^ > $@
clean:
rm -f $(CAT)
If checksums.md5
exists and is up-to-date (more recent than the sources), nothing will be done. Else, all md5sums will be recomputed and stored in checksums.md5
.
If your problem is to avoid recomputing md5sums of files that did not change, you need to keep track of the last time you computed them and there is no better way than keeping these intermediate md5sum files. But you can put them all in a separate directory, if you wish:
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)
Notes:
$(ALL)
) using addprefix
and patsubst
.mkdir -p
in the $(MD5DIR)/%.md5: %
recipe is needed to create the destination directory before storing the md5sum file in it.$(MD5DIR)
are needed if you have your sources also in sub-directories and some of them can have the same base name.Upvotes: 2