2016-03-26 2 views
1

Я следующий пример Makefile:Как адресовать несколько целей из списка зависимостей по одному правилу?

all: foo1.gz foo2.gz bar1.gz bar2.gz 
    @echo Done. 

foo1.gz: 
    touch foo1 && gzip foo1 

foo2.gz: 
    touch foo2 && gzip foo2 

bar1.gz: 
    touch bar1 && gzip bar1 

bar2.gz: 
    touch bar2 && gzip bar2 

, которая направлена ​​на создание и GZIP определенные файлы. Это не проблема для небольшого количества файлов, но когда у вас их сотни, вы не хотите указывать каждый файл как зависимость для данной цели.

Поэтому я хотел бы упростить приведенный выше синтаксис, указав только одну зависимость, а не для каждого файла.

Поэтому я ожидал бы синтаксис вроде:

all: %.gz 

который должен соответствовать нескольким целям, однако он не работает, и он терпит неудачу с:

марка: *** Нет правила для make target %.gz, необходимый `all '. Стоп.

Любая идея, как этого достичь?

ответ

2

Вы хотите сделать некоторые файлы и закрепить их. Так или иначе, у вас есть , чтобы сообщить make, что они собой представляют, или как выработать то, что они есть.

Правило шаблона не может этого сделать. Правило является правилом шаблона тогда и только тогда, когда имеет ровно один % в своей целевой точке . См. 10.5 Defining and Redefining Pattern Rules. Так

%.o: %.c 
    $(CC) -c -o [email protected] $< 

это шаблонное правило, и так

%.xyz: foobar 
    cp -f $< [email protected] 

Они говорят, что если какая-то цель соответствует левой стороне% -wise с части сопоставления %, то эта цель имеет предварительные условия, возникающие в результате замены % на часть по всей правой стороне, , и рецепт для этой цели является рецептом в правиле шаблона.

Они не вам сказать, что все является цель, и так или иначе:

all: %.gz 

не шаблонное правило, по определению. Без % слева, это просто обычное правило , в котором говорится, что цель all имеет необходимое условие: %.gz.

В широком смысле у вас есть два способа позволяют make знать некоторые список имен файлов, которые вы хотите его сделку с:

Назови их, например:

files = foo1 foo2 bar1 bar2 ... 

Или сказать make каким-то образом вычислить их, например

files = $(wildcard ...) # `make` globbing 
files = $(shell ....) # shell filter 

См 8.2 Functions for String Substitution and Analysis и 8.3 Functions for File Names для документирования make сек встроенных ресурсов для вычисления списков имен файлов (или списков строк, в более общем случае).

После того, как вы выбрали путь make определить вы хотите, созданных файлов и застегнул, затем вы можете сэкономить код шаблонного правила, например:

Makefile

zips := foo1.gz foo2.gz bar1.gz bar2.gz 

.PHONY: all clean 

all: $(zips) 
    @echo Done. 

%.gz: 
    touch $(basename [email protected]) && gzip $(basename [email protected]) 

clean: 
    rm -f $(zips)