2015-07-27 3 views
3

В чем разница между %.c и *.c в make-файлах. Например, мы можем иметь:В чем разница между% .c и * .c в GNU Make

vpath %.c $(BASE_DIR)platform/$(TARGET) 

и

Files += $(wildcard *.c) 

Оба включают все файлы в определенной директории, которые заканчиваются на .c будет принимать во внимание. Но когда мы используем %.c и когда *.c? Другими словами, почему я не могу использовать

vpath *.c $(BASE_DIR)platform/$(TARGET) 

вместо

vpath %.c $(BASE_DIR)platform/$(TARGET) 

?

спасибо.

+0

Возможный дубликат [Что делает символ процента в make-файле?] (Http://stackoverflow.com/questions/7404444/what-does-a-percent-symbol-do-in-a-makefile) – Alexander

+0

Различные функции Make используют разные символы подстановочных знаков. Директива 'vpath' использует'% ', функция' wildcard' использует '*'. Существует не так много, кроме того, что это * не * самый большой недостаток Make-подстановок. – Beta

+0

Чтобы быть более понятным, функция '$ (wildcard ...)' использует shell globbing (как если бы вы запускали 'ls * .c'). Сделать сам использует только простую комбинацию шаблонов (с '%'). – MadScientist

ответ

1

Оба параметра % и * в GNU Make являются подстановочными функциями. Разница между ними заключается в том, что % может использоваться как часть Text Substitution Function, тогда как * не может.

Если вы пытаетесь сделать максимально возможную Makefile, вы должны попробовать и использовать *Wildcard Function в предпочтении к % замещения функции, как не должны быть никаких ресурсов, используемых для хранения имени совпавшего элемента и заменить его в последующий вызов функции. Если вы не беспокоитесь о том, чтобы оптимизировать свою систему производства до предела, вам не нужно беспокоиться о том, какой из них вы выберете.

+0

Я не совсем уверен, почему этот ответ был отредактирован, затем неотредактирован. Кажется, что reinierpost просто расширил мой ответ примерами, а затем решил опубликовать его как свой собственный без атрибуции. Если это будет сделано регулярно, его высокий балл может быть сформирован в основном из нулевых изменений и срыгиваний. Это или он просто понял, насколько бедный мой ответ был сравнен с тем, где он хотел его принять. – TafT

+1

Прошу прощения, это была просто ошибка: я думал, что создаю свой собственный ответ, но по ошибке я нажал кнопку редактирования по вашему ответу, и я обнаружил ее только после того, как выполнил свой ответ. Как это могло случиться, я не знаю. – reinierpost

1

Оба % и * в 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 будет (смущающе) вести себя так, как будто правило не существует, как вы можете видеть в примере.

Смежные вопросы