удивительное (?) Поведение GNU Make при использовании `%` в качестве цели

#makefile

#makefile

Вопрос:

Рассмотрим следующий Makefile

 foo:
    @echo '$@'

test:
    @echo '$@'
    @echo '---'

# Catch-all target
%: test
    @echo '   '
    @echo '$@'
 

При выдаче make bar выводится следующее::

 $ make bar
test
---
   
Makefile
   
bar
 

Я хотел бы понять, происхождение Makefile которого показывает, что оно получено в качестве аргумента в какой-то момент, а также как избавиться от него в такой схеме. Это использование

 GNU Make 4.1
Built for x86_64-apple-darwin13.4.0
 

Ответ №1:

GNU make рассматривает сам makefile как цель, которую необходимо обновить. Посмотрите, как переделываются makefile-файлы:

… после чтения всех файлов makefile make рассмотрит каждый из них как целевую цель и попытается ее обновить. Если в makefile есть правило, в котором указано, как его обновить (найденное либо в этом самом makefile, либо в другом), или если к нему применяется неявное правило (см. Использование неявных правил), оно будет обновлено при необходимости…

Если вы знаете, что один или несколько ваших make-файлов не могут быть переделаны, и вы хотите, чтобы make не выполнял в них неявный поиск по правилам, возможно, из соображений эффективности, вы можете использовать любой обычный метод предотвращения неявного поиска правил для этого. Например, вы можете написать явное правило с makefile в качестве цели и пустым рецептом (см. раздел Использование пустых рецептов).

Следовательно, для обновления Makefile используется catch-all-target % .

Make-файлы часто не нужно обновлять, поэтому для этого обычно добавляется пустое правило:

 Makefile : ;
 

Комментарии:

1. IIRC, it must come before that catch-all-target В этом не должно быть необходимости, правила соответствия чему-либо рассматриваются только тогда, когда ни одно другое правило не соответствует.