2
votes

I have a command that can take multiple types of input files and generate relevant output. IT does something similar to producing thumbnails from images. I want to write the recipe once and have a list of implicit rules that each call the recipe, e.g.:

%.png : %.jpg
%.png : %.jpeg
%.png : %.svg
%.png : %.gif
        convert $< -resize 100x100 $@

This works for .gif but for the other file types I get "No rule to make target".

Is there a way to express this set of rules without duplicating the recipe?

2
Wonder what is expected to happen if there's two files with the same stem but different file extension like picture.svg and picture.jpeg? - Joerg S
Same as what would happen if two rules match a target: the first one wins. - iter

2 Answers

2
votes

The following should be close to what you want:

PICTURES   := $(wildcard *.jpg *.jpeg *.svg *.gif)
THUMBNAILS := $(addsuffix .png,$(basename $(PICTURES)))

.PHONY: all

all: $(THUMBNAILS)

$(THUMBNAILS):
    convert $< -resize 100x100 $@

%.png: %.jpg
%.png: %.jpeg
%.png: %.svg
%.png: %.gif
2
votes

You could add one rule with no prerequisites:

%.png : %.jpg
%.png : %.jpeg
%.png : %.svg
%.png : %.gif
%.png :
        convert $< -resize 100x100 $@

THE DRAWBACK is that if you try to build foo.png when none of the prereqs exist, Make will gamely attempt to build it with no input file. You could put a test in the recipe, to get a more graceful exit in that case, but it wouldn't be very elegant.