0

I use make to create thumbnails from image files that will in turn be used to create web pages.

Sometimes I delete a source image and I would like the thumbnail to be removed automatically. The obvious way to do it would be to simply add a rule where the target and prerequisite are swapped but that causes a circular reference and messages like this:

make[2]: Circular image123.jpg <- thumbnails/image123.jpg dependency dropped.

Is there a way to do it or must I use a separate makefile? Actually tried but I can't seem to make that work either. I tried this:

# -*- mode: makefile -*-

images = $(wildcard *.jpg) 
thumbnails = $(wildcard thumbnails/*.jpg) 

.PHONY: all
all : $(images)


# Delete thumbnails if source is not present.
%.jpg: thumbnails/%.jpg
    [ -f "$@" ] || rm "$<"

It didn't do anything except print one line referring to the image that is to be kept.

To summarize: is there a way to use make to remove targets that would not be built if they were missing?

Kevin Whitefoot
  • 414
  • 3
  • 15

1 Answers1

1

First, let's set up a rule to build the thumbnails:

images := $(wildcard *.jpg)
TARGETS := $(addprefix thumbnails/, $(images))

.PHONY: all
all : $(TARGETS)

thumbnails/%.jpg: %.jpg
    create the thumbnail somehow

Then add some code to find the obsolete thumbnails:

thumbnails := $(wildcard thumbnails/*.jpg)
OBSOLETE := $(filter-out $(TARGETS), $(thumbnails))

Then write a rule to remove them:

.PHONY: purge
purge:
    rm $(OBSOLETE)

This will cause trouble if there are no obsolete thumbnails, so let's wrap the recipe in a conditional:

purge:
ifneq ($(OBSOLETE),)
    rm $(OBSOLETE)
endif

And finally make purge a prerequisite of all:

all : $(TARGETS) purge
Beta
  • 96,650
  • 16
  • 149
  • 150
  • Thank you that works perfectly but I have a question: does the use of := instead of = make any difference? I tried it with and without the colon and can't see any difference in the behaviour. Which one should be used by default? – Kevin Whitefoot Jun 27 '20 at 17:17
  • 1
    Read about the difference here: https://www.gnu.org/software/make/manual/html_node/Flavors.html In short, in this specific situation the _behavior_ is the same, but the `=` version does more work. In a small example like this the difference won't be measurable however. – MadScientist Jun 27 '20 at 21:00