2015-04-03 5 views
0

Я думаю, что есть что-то вроде элементарного, которого я пропускаю в gnu make (я использую 3.81, если это имеет значение) сопоставление статического шаблона (что, видимо, кто-то еще сделал, и где я работаю, потому что это был обнаружен, поскольку я пытался исправить правило, которое было прокомментировано). Я попытался упростить свой пример до конца (надеюсь, я не «пропустил что-то существенное в настоящем примере»).Ошибка сопоставления шаблона статического шаблона Makefile

Так это, кажется, работает, как и следовало ожидать

JUNK:=foo bar 
BINS:=$(patsubst %,bin/%,$(JUNK)) 

all : $(BINS) 
.PHONY : all 

# This works 
$(BINS) : bin/% : % 
     mkdir -p bin && cp $< [email protected] 

Но это (который ближе к тому, что я нашел в реальном Makefile) не

JUNK:=foo bar 
BINS:=$(patsubst %,bin/%,$(JUNK)) 

all : $(BINS) 
.PHONY : all 

# This doesn't work 
$(JUNK) : bin/% : % 
     mkdir -p bin && cp $< [email protected] 

# This doesn't work either 
#bin/$(JUNK) : bin/% : % 
#  mkdir -p bin && cp $< [email protected] 

Основываясь на моем понимании что должно происходить в обоих случаях, я ожидал, что оба Makefiles будут вести себя точно так же; Однако, только первый один ведет себя, как я ожидал (т.е. должным образом копирует файлы в мусорное ведро) и второй дает следующие выходные данные

Makefile:12: target `foo' doesn't match the target pattern 
Makefile:12: target `bar' doesn't match the target pattern 
make: *** No rule to make target `bin/foo', needed by `all'. Stop. 

Что более запутанным есть почти идентичные другие правила статической модели в марке файл, который я изучал, которые работали.

Поэтому я, очевидно, знаю, как «обойти» проблему, если это необходимо, но я хотел бы понять, почему вторая (и часть с комментариями во втором блоке кода) также не делает то, что я ожидаю от них к.

Заранее благодарим за любую помощь/понимание.

ответ

2

Первый не работает, потому что, после расширения переменной JUNK, сделать это видит:

foo bar : bin/% : % 

Путь статический шаблон правила работы является то, что первый образец (шаблон цели) необходимо матча каждое слово в списке целей. Это говорит о том, какая часть целевого имени - это стержень (часть, которая соответствует %). Если целевой шаблон не соответствует, make не знает, что такое стержень. Образец bin/% не соответствует тексту foo, (нет bin/ в тексте foo), чтобы вы получили сообщение об ошибке.

Второй не работает, так как результат exanding переменной JUNK в этом примере (bin/$(JUNK) : bin/% : %) выглядит следующим образом:

bin/foo bar : bin/% : % 

Здесь bin/foo соответствует шаблону, но bar не соответствует и поэтому вы получите ту же ошибку, что и в предыдущем.

Чтобы сделать его работу вы должны иметь bin/ предваряется каждый цели, а не только первая цель, следовательно, использование patsubst (или, addprefix будет работать, а).

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