Makefile - Сделать зависимость только в том случае, если файл не существует
Как и в названии, я хотел бы сделать зависимость только в том случае, если определенный файл не существует, НЕ каждый раз, когда он обновляется.
У меня есть корневой каталог (тот, у которого есть файл makefile), а в нем есть подкаталог "example". В моем корневом каталоге находятся четыре файла.h(functions.h, parser.h, node.h и exception.h), которые я хотел бы скопировать в подкаталог "example", если эти.h файлы еще не существуют в "примерах".
К сожалению, я не могу просто установить стандартную зависимость для проверки файлов заголовков в "примере", потому что каждый раз, когда я копирую файлы заголовков от root до "example", заголовочные файлы в "примере" будут считаться обновленными и будут вызывать эту зависимость каждый раз, когда я запускаю make. Я хотел бы, чтобы мой makefile копировал файлы заголовков из корневого каталога в "example", только если они не существуют в "примере".
Ответы
Ответ 1
Для этого необходимы только предварительные условия/зависимости:
Однако иногда возникает ситуация, когда вы хотите ввести конкретный порядок в правилах, которые вызывают, не заставляя цель обновляться, если выполняется одно из этих правил. В этом случае вы хотите определить предварительные условия только для заказа. Предварительные требования только для заказа могут быть указаны путем помещения символа трубы (|
) в список предварительных условий: любые предпосылки слева от символа трубы являются нормальными; любые предварительные условия справа - это только порядок.
В твоем случае:
examples/%.h : | %.h
cp $| [email protected]
См. Также: Предварительные требования только для заказа не отображаются в $^
или $+
.
Ответ 2
Вы должны выражать зависимости в терминах относительного возраста файлов.
Обычно используется обходной путь - использовать фиктивный ("дозорный") файл, который обозначает завершение операции:
examples/%.h.hasbeencopied: %.h
if [ -f example/[email protected] ] || cp -p $< examples/[email protected]; \
then touch [email protected]; \
else rm -f [email protected]; \
fi
и сделать любое правило зависит от example/foo.h
также зависит от example/foo.h.hasbeencopied
.