Makefile: порядок оценки зависимости
-
23-10-2019 - |
Вопрос
Предположить цель foo.tar
, это зависит от списка файлов foo.files
, например
FOO_FILES := $(shell cat foo.files)
foo.tar: foo.files $(FOO_FILES)
tar -cf foo $(FOO_FILES)
Теперь предположим, что foo.files нужно генерировать, например:
foo.files: foo.files.template
sed -e "s/@{VERSION}/$(VERSION)/" < $< > $@
Ясно, что foo.files
зависит от foo.files.template
, но как можно убедиться, что foo_files оценивается после foo.files создается?
Решение
Ваши первоначальные правила верны. Поскольку обновление foo.files приводит к устаревшему значению foo_files, вам просто нужно убедиться, что ваш make-файл переоценен с помощью GNU Make, когда foo.files обновляется, сделав ваш Makefile зависеть от foo.files:
Makefile : foo.files
Другие советы
Итак, я нашел ответ, читающий о Расширенное генерация автозависимости за Madcecentist.net. Анкет По сути, можно переоценить создание с помощью функции GNU/Make. Когда существует правило для создания включенного Makefile, весь файл Make будет перечитан после генерации включенного файла. Таким образом --
# -*- mode: make -*-
VERSION := 1.2.3
foo.tar: foo.files $(FOO_FILES)
tar cf $@ $(FOO_FILES)
clean:
rm -f foo.files foo_files.mk foo.tar
foo.files: foo.files.template
sed -e "s/@{VERSION}/$(VERSION)/" < $< > $@
# -- voodoo start here --
# This will ensure that FOO_FILES will be evaluated only
# *after* foo.files is generated.
foo_files.mk: foo.files
echo "FOO_FILES := `xargs < $<`" > $@
include foo_files.mk
# -- voodoo ends here --
.PHONY: clean
- кажется, поступает правильно.
... и только для полноты:
foo.files.template
является:
a-$(VERSION)
b-$(VERSION)
и предположим наличие a-1.2.3
а также b-1.2.3
.
Это не может быть сделано в одном проходе; Сделайте определение, какие цели должны быть перестроены до того, как оно фактически выполнит какое -либо правило, и в этом случае полный список целей не существует, пока не будет выполнено одно из правил.
Это должно это сделать:
FOO_FILES := $(shell cat foo.files)
foo.tar: foo.files
$(MAKE) foo-tarball
.PHONY: foo-tarball
foo-tarball: $(FOO_FILES)
tar -cf foo $^
РЕДАКТИРОВАТЬ:
Как указывает ОП, это не будет работать, как написано; Я оставил предпосылку:
foo.tar: foo.files $(FOO_FILES)
...
Обратите внимание, что это повторится, даже если foo.files
не изменился, что не является строго необходимым; Это возможно исправить, но не элегантно. (Для сравнения, выбранное решение, которое, как я признаю, чище, чем мое, повторяется, даже если цель не имеет ничего общего с foo.tar
.)