Я боюсь, что вы не можете сделать это напрямую, и вам придется помочь себе с промежуточной целью, которая делает связь между целью и ее выходом ясной (и, следовательно, дает возможность решить, когда она нужна или не нужна быть переделанным:
0_target_a: file.txt
echo "this is target_a"
touch $@
target_b: 0_target_a
echo "executing target_b"
touch 0_$@
т.е. определение правила для цели 0_target_a
и обновление touch
соответственно даст вам поведение, которое вы хотели, так как make теперь понимает правило, связывающее цель и файл 0_target_a
, и знает, когда его не нужно переделывать как зависимость target_b
. Теперь, если вы все еще хотите иметь автономный target_a
, который бы генерировал файл 0_target_a
, вы можете определить его следующим образом:
target_a: 0_target_a
Поскольку мы знаем, что эта цель на самом деле не создает сам файл, мы можем приложить немного усилий, чтобы найти его результат (target_a
), а также предотвратить конфликты, если такой файл будет создан, объявив его фальшивым.
На самом деле вы можете захотеть дать вашему target_b
такое же лечение, как и в противном случае (опять же, make не обладает достаточной информацией, чтобы понять связь между target_b
и 0_target_b
) make target_b
всегда переделывается даже если файл уже создан.
Весь файл make будет выглядеть так:
.PHONY: target_a target_b
target_a: 0_target_a
target_b: 0_target_b
0_target_a: file.txt
echo "this is target_a"
touch $@
0_target_b: 0_target_a
echo "executing target_b"
touch $@
Если это повторяющаяся тема по всему файлу, вы также можете выразить отношение во второй и третьей строке, задав правило статического шаблона:
target_a target_b: %: 0_%
Это определяет правило, согласно которому любая цель (первый «%» без чего-либо еще) имеет обязательное условие префикса 0_
, за которым следует имя цели (0_%
, 0_
плюс ствол, который в данном случае является целью название полностью соответствует предыдущему %
). и делает это правило применимым к целям target_a
и target_a
. Это правило не имеет рецепта и, следовательно, описывает только целевые / обязательные отношения между ними.
Другими словами, это означает то же самое, что и строки 2 и 3 полного примера.