Makefile: порядок оценки зависимостей - PullRequest
1 голос
/ 23 января 2011

Предположим цель 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?

Ответы [ 3 ]

4 голосов
/ 23 января 2011

Ваши оригинальные правила верны.Поскольку обновление foo.files приводит к тому, что значение FOO_FILES становится устаревшим, вам просто нужно убедиться, что ваш Makefile переоценен gnu make после обновления foo.files, так как ваш Makefile зависит от foo.files:

Makefile : foo.files
0 голосов
/ 23 января 2011

Итак, я нашел ответ о Advanced Auto-Dependency Generation на mad-scientist.net . По сути, можно переоценить make-файл с помощью функции GNU / Make. Когда есть правило для создания включенного make-файла, весь 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.

0 голосов
/ 23 января 2011

Это невозможно сделать за один проход; Make определяет, какие цели должны быть перестроены, прежде чем оно фактически выполнит какое-либо правило, и в этом случае полный список целей не существует, пока не будет выполнено одно из правил.

Это должно сделать это:

FOO_FILES := $(shell cat foo.files)

foo.tar: foo.files
    $(MAKE) foo-tarball

.PHONY: foo-tarball
foo-tarball: $(FOO_FILES)
    tar -cf foo $^

EDIT:
Как указывает ОП, это не будет работать так, как написано; Я оставил обязательное условие:

foo.tar: foo.files $(FOO_FILES)
    ...

Обратите внимание, что это будет повторяться, даже если foo.files не изменился, что не является строго необходимым; это можно исправить, но не элегантно. (Для сравнения, выбранное решение, которое, я признаю, чище моего, повторяется, даже если цель не имеет ничего общего с foo.tar.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...