Я постараюсь подвести итоги нашего обсуждения. Возможно, кто-то все еще всплывает с другим / лучшим пониманием.
Помимо опции, также упомянутой в самом вопросе (см. Пояснение по последней итерации для этого подхода):
a:
$(error missing file "$@")
b: a
@echo MAKING B
cp a b
Теоретически должна быть возможность полностью отключить неявное правило шаблонов или для конкретного (набора) целей, либо , определяя правило цели без рецепта (% : %.c
) или , определяя a правило статического шаблона (a: % : %.c
). Тем не менее, результирующее поведение в случае наличия файла a.c
выглядит так же, как и с пустым правилом для a:
. То есть make b
просто продолжается без файла a
(и мы позже не сможем получить к нему доступ).
Поскольку, по крайней мере, некоторые из неявных правил, по-видимому, реализованы в виде суффиксных правил , можно отключить учет таких входных данных, как a.c
, путем очистки списка достаточных значений по умолчанию:
.SUFFIXES:
Или вообще запретите использование неявных встроенных правил, вызвав make с опцией -r
(или --no-builtin-rules
). Однако они довольно жесткие, поскольку они влияют на обработку всех правил в Makefile
.
Работать с комментариями в:
как уже упоминалось, отключение пары встроенных правил для компиляции C, похоже, даст желаемый результат, а именно:
% : %.c
% : %.o
В результате a.c
присутствует, а a
нет make: *** No rule to make target 'a', needed by 'b'. Stop.
Однако (как -r) это довольно навязчиво, так как это повлияет на все другие цели, на которые полагается неявное правило. Хотя в то же время это не так далеко, потому что он не охватывает другие случаи, такие как a.C
, a.cpp
, a,v
, ...
Статическое правило должно быть в состоянии заменить шаблонные правила, где это применимо (более точное правило применяется к более общему правилу при сопоставлении). Но на самом деле ограничение его одной целью в действительности ставит его в один ряд с определенным правилом a:
.
На самом деле я не уверен, как выглядит остальная часть дерева и какие могут быть все возможные этапы сборки. При существующем понимании я все же стремился бы к явной цели с проверкой существования файла, если файлы со встречными именами могут быть проблемой.
Пояснение для последней версии простого ошибочного правила:
Когда @ Stein продолжил тему, он на самом деле очень услужливо указал: простое (всегда) несоблюдение правила для "сборки" a
вполне достаточно. Если файл с таким именем (a
) существует, правило для цели a
никогда не запускает свой рецепт. В случае, если файла нет, у нас может быть просто рецепт, который завершается ошибкой с сообщением об ошибке.