Можно ли использовать make для удаления устаревших целей

Я использую make для создания эскизов из файлов изображений, которые, в свою очередь, будут использоваться для создания веб-страниц.

Иногда я удаляю исходное изображение и хочу, чтобы миниатюра удалялась автоматически. Очевидным способом сделать это было бы просто добавить правило, в котором цель и предпосылка меняются местами, но это вызывает циклическую ссылку и сообщения, подобные этому:

make[2]: Circular image123.jpg ‹- thumbnails/image123.jpg зависимость удалена.

Есть ли способ сделать это или я должен использовать отдельный make-файл? На самом деле пытался, но у меня тоже не получается. Я пробовал это:

# -*- 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 "$<"

Он ничего не сделал, кроме как напечатал одну строку, относящуюся к изображению, которое нужно сохранить.

Подводя итог: есть ли способ использовать make для удаления целей, которые не были бы созданы, если бы они отсутствовали?


person Kevin Whitefoot    schedule 27.06.2020    source источник


Ответы (1)


Во-первых, давайте настроим правило для создания миниатюр:

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

.PHONY: all
all : $(TARGETS)

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

Затем добавьте код для поиска устаревших эскизов:

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

Затем напишите правило для их удаления:

.PHONY: purge
purge:
    rm $(OBSOLETE)

Это вызовет проблемы, если нет устаревших эскизов, поэтому давайте обернем рецепт в условное выражение:

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

И, наконец, сделайте purge необходимым условием для all:

all : $(TARGETS) purge
person Beta    schedule 27.06.2020
comment
Спасибо, это работает отлично, но у меня есть вопрос: имеет ли значение использование := вместо =? Я пробовал с двоеточием и без него и не вижу никакой разницы в поведении. Какой из них следует использовать по умолчанию? - person Kevin Whitefoot; 27.06.2020
comment
О разнице читайте здесь: gnu.org/software/make/manual/ html_node/Flavors.html Короче говоря, в этой конкретной ситуации поведение такое же, но = версия работает лучше. Однако в небольшом примере, подобном этому, разница не будет измерима. - person MadScientist; 28.06.2020