В моей битве против .PHONY
целей я переписал:
# Makefile v0
tar:
tar -cf tarfile.tar dir
.PHONY: tar
быть:
# Makefile v1
tar: tarfile.tar
tarfile.tar: $(shell find dir)
tar -cf $@ dir
.PHONY: tar
Что, кажется, работает на игрушечном примере.
Тем не менее, я вижу, что это может быть неправильно, в зависимости от времени, когда $(shell find dir)
оценивается. Если есть какое-то правило, которое создает или удаляет файлы в dir
после разбора файла Makefile, это может нарушиться.
Обновление
Судя по ответу @ user562374, у меня, кажется, есть лучшее решение, но рассмотрим этот случай:
# Makefile v2
tar: tarfile.tar
tarfile.tar: dir/.dirstamp
tar --create --exclude $< --file $@ $(<D)
dir/.dirstamp: .FORCE
[ ! -e $@ -o "$(find $(@D) -newer $@ -print -quit)" ] && touch $@
dir/a: src/a
cp $< $@
.FORCE:
.PHONY: .FORCE tar
Теперь предположим, что src/a
было изменено. Поскольку между tarfile.tar
и dir/a
нет никакой зависимости (не прямой и не косвенной), цель tarfile.tar:
может быть оценена до dir/a:
, и, таким образом, tarfile.tar
не будет актуальной.
Итак, мои вопросы: какова лучшая практика работы с такими случаями? Должен ли я вести список файлов в dir
отдельно? Если так, какой самый простой способ сделать это?