one target for one dependency in makefile

2019-08-15 03:49发布

I am trying to use make to generate thumbnails of photos by typing "make all". If the thumbnails are not yet generated make all generates them, else make all just generate the thumbnails of modified photos. For this I need one target (thumbnail) for each dependency (photo) . My code is like this :

input = pictures/*.jpg
output = $(subst pictures,thumbs,$(wildcard $(input)))
all : $(output)
    echo "Thumbnails generated !"

$(output) : $(input)
    echo "Converting ..."
    convert -thumbnail 100 $(subst thumbs,pictures,$@) $@

How can I modify it to get the desired result ?

1条回答
Juvenile、少年°
2楼-- · 2019-08-15 04:31

Your problem is this line

$(output) : $(input)

The output variable is the list of every output file.

The input variable is the wildcard pattern.

This sets the prerequisites of every output target as the wildcard pattern which means if any file changes every output file will be seen as needing to be rebuilt.

The fix for this is to either use a static pattern rule like this

$(output) : thumbs/% : pictures/%

which says to build all the files in $(output) by matching them against the pattern thumbs/% and using the part that matches % (called the stem) in the prerequisite pattern (pictures/%).

Alternatively, you could construct a set of specific input/output matches for each file with something like

infiles = $(wildcard pictures/*.jpg)
$(foreach file,$(infiles),$(eval $(subst pictures/,thumbs/,$(file)): $(file)))

$(output):
    echo "Converting ..."
    convert -thumbnail 100 $(subst thumbs,pictures,$@) $@

Which uses the eval function to create explicit thumbs/file.jpg: pictures/file.jpg target/prerequisite pairs for each input file.

查看更多
登录 后发表回答