#makefile #gnu-make
#makefile #gnu-make
Вопрос:
#!make
.PRECIOUS: a/b/c/%_pqr
a/b/c/%_pqr:
echo $@
touch $@
.PRECIOUS: a/b/c/%_abc
a/b/c/%_abc: a/b/c/pqr_pqr
echo $@
touch $@
Когда я запускаю первый раз, он учитывает свою зависимость:
make a/b/c/pqr_abc -f 1.mk
echo a/b/c/pqr_pqr
a/b/c/pqr_pqr
touch a/b/c/pqr_pqr
echo a/b/c/pqr_abc
a/b/c/pqr_abc
touch a/b/c/pqr_abc
Но если я удалю файл «a / b / c / pqr_pqr», а затем снова запущу эту цель, это не приведет к необходимому:
rm -f a/b/c/pqr_pqr; make a/b/c/pqr_abc -f 1.mk
make: `a/b/c/pqr_abc' is up to date.
Насколько я понимаю, он должен снова запустить обе цели.
Пожалуйста, кто-нибудь, помогите мне.
Ответ №1:
Обе ваши цели являются неявными и, следовательно, промежуточными. Согласно документации:
Первое отличие заключается в том, что происходит, если промежуточный файл не существует. […] Но если b является промежуточным файлом, то make можно оставить в покое. Это не будет беспокоить обновление b или конечной цели, если только какое-либо предварительное условие b не является более новым, чем эта цель, или нет какой-либо другой причины для обновления этой цели.
Следовательно, поскольку pqr_abc уже существует, а pqr_pqr является промежуточным файлом и не имеет предварительных условий (поэтому предварительные условия не изменились), он не будет восстановлен.
Согласно пониманию make, pqr_pqr необходимо будет создать только для генерации из него pqr_abc (это определение промежуточного файла), и поскольку pqr_abc уже существует, нет необходимости его регенерировать.
Если вы хотите, чтобы файл каждый раз обновлялся заново, это должно быть указано явно, чтобы он больше не считался промежуточным файлом, т.е.:
$ cat Makefile
a/b/c/%_pqr:
touch $@
a/b/c/%_abc: a/b/c/pqr_pqr
touch $@
a/b/c/pqr_pqr:
Последняя строка определяет явную цель, но не определяет рецепт, который все равно будет вызываться из неявного правила. Обратите внимание, что она больше не будет считаться промежуточной и не будет автоматически удаляться, поэтому .PRECIOUS
директивы также не нужны.
Вывод:
$ make a/b/c/pqr_abc
touch a/b/c/pqr_pqr
touch a/b/c/pqr_abc
$ make a/b/c/pqr_abc
make: 'a/b/c/pqr_abc' is up to date.
$ rm a/b/c/pqr_pqr
$ make a/b/c/pqr_abc
touch a/b/c/pqr_pqr
touch a/b/c/pqr_abc