Оба %
и *
в GNU Make можно рассматривать как подстановочные знаки, но совершенно по-другому.
*
характер what the GNU Make manual calls a wildcard: он представляет собой Глоб матч, матч против шаблона файлов, присутствующих в файловой системе. Например. *.a
расширяет список файлов, присутствующих в текущем каталоге, чьи имена заканчиваются на .a
, или на литерал *.a
, если таких файлов нет.
Например:
sh> rm -f *.a *.b *.c
sh> cat Makefile
all: *.a
*.a : *.b *.c
@echo $+ > [email protected]
sh> make
make: *** No rule to make target '*.b', needed by '*.a'. Stop.
sh> touch x.a
sh> make
make: *** No rule to make target '*.b', needed by 'x.a'. Stop.
sh> touch y.b
sh> make
make: *** No rule to make target '*.c', needed by 'x.a'. Stop.
sh> touch z1.c z2.c
sh> make
sh> cat x.a
y.b z2.c z1.c
Как вы можете видеть, *
интерпретируется путем сопоставления его с файлами, которые происходят, существуют в файловой системе. Например, make
интерпретирует *.a
как литерал filename *.a
до тех пор, пока я не создам файлы с именами, заканчивающимися на .a
, и в этот момент он расширяется до имен этих файлов; то же самое для *.b
и *.c
.
Так что используйте *
, только если вы действительно хотите указать набор файлов, уже присутствующих в вашей файловой системе. Это является общим для исходных файлов (предпосылки в правилах), но это действительно странно использовать в целевых целях, как в этом примере.
%
персонаж также выполняет поиск по шаблону, но совсем по-другому: при использовании на обеих сторонах :
, она является частью pattern rule, и она устанавливает связь между именами целевого файла (ов) и имена зависимостей.
Например:
sh> rm -f *.a *.b *.c
sh> cat Makefile
all: %.a
%.a : %.b %.c
@echo $+ > [email protected]
sh> make
make: *** No rule to make target '%.a', needed by 'all'. Stop.
sh> touch x.a y.b z1.c z2.c
sh> make
make: *** No rule to make target '%.a', needed by 'all'. Stop.
sh> make x.a
make: Nothing to be done for 'x.a'.
sh> make y.a
make: *** No rule to make target 'y.a'. Stop.
sh> touch y.c
sh> make y.a
sh> cat y.a
y.b y.c
%
характера никогда не сопоставляются с файлами в файловой системе, но вместо этого выражает соответствие между мишенью и предварительными именами файлами: %.a: %.b %.c
означает: вы можете использовать это правило, чтобы сделать любой файл, чье имя заканчивается в .c
из файлов, имена которых совпадают, за исключением того, что они заканчиваются на .a
и .b
. Таким образом, мы можем сделать x.a
, используя это правило из x.b
и x.c
, но никогда от y.b
или z1.c
, и это верно даже тогда, когда x.b
и x.b
еще не существует, до тех пор, как они тоже могут быть сделаны (хотя этот пример Безразлично» t показать, что). Если нет, GNU Make будет (смущающе) вести себя так, как будто правило не существует, как вы можете видеть в примере.
Возможный дубликат [Что делает символ процента в make-файле?] (Http://stackoverflow.com/questions/7404444/what-does-a-percent-symbol-do-in-a-makefile) – Alexander
Различные функции Make используют разные символы подстановочных знаков. Директива 'vpath' использует'% ', функция' wildcard' использует '*'. Существует не так много, кроме того, что это * не * самый большой недостаток Make-подстановок. – Beta
Чтобы быть более понятным, функция '$ (wildcard ...)' использует shell globbing (как если бы вы запускали 'ls * .c'). Сделать сам использует только простую комбинацию шаблонов (с '%'). – MadScientist