правила шаблона с несколькими подстановочными знаками в GNU Make - PullRequest
16 голосов
/ 19 сентября 2010

Я хочу написать что-то вроде регулярного выражения:

SRC:="a.dat.1 a.dat.2"    
$(SRC): %.dat.%: (\\1).rlt.(\\2)    
      dat2rlt $^ $@

, чтобы a.dat.1 и a.dat.2 дало a.rlt.1 и a.rlt.2 .

В GNU Make info page говорится, что «% можно использовать только один раз».

Есть ли хитрость для достижения этой цели в GNU Make?

Ответы [ 3 ]

11 голосов
/ 21 августа 2015

Боюсь, то, что вы пытаетесь сделать, невозможно, как вы предлагаете это сделать, поскольку - как вы уже упоминали - (GNU) make допускает только один ствол "%", см. http://www.gnu.org/software/make/manual/make.html#Pattern-Rules:

Шаблонное правило выглядит как обычное правило, за исключением того, что его цель содержит символ «%» (ровно один из них).

Без этого создание таких «многомерных» целей будет громоздким.

Одним из способов решения этой проблемы является перестройка имени зависимости в команде (а не в списке зависимостей):

SRC := a.dat.1 a.dat.2

all : $(SRC:%=%.dat2rlt)

%.dat2rlt :
    dat2rtl $(word 1,$(subst ., ,$*)).rlt.$(word 2,$(subst ., ,$*)) $*

Однако, конечно, таким образом вы потеряете зависимость, она не будет перестраиваться после обновления rlt.

Единственный способ решить эту проблему - явное создание правил:

SRC := a.dat.1 a.dat.2

all : $(SRC)

define GEN_RULE
$1.dat.$2 : $1.rlt.$2
    dat2rtl $$< $$@
endef

$(foreach src,$(SRC),$(eval $(call GEN_RULE,$(word 1,$(subst ., ,$(src))),$(word 3,$(subst ., ,$(src))))))
1 голос
/ 11 января 2019

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

letters:=a b c
numbers:=1 2 3 4

define GEN_RULE
$(letter).dat.$(number) : $(letter).rlt.$(number)
    ./rlt2dat $$< $$@
endef

$(foreach number,$(numbers), \
  $(foreach letter,$(letters), \
    $(eval $(GEN_RULE)) \
  ) \
)

Мы можем сгенерировать SRC аналогичным образом. Обратите внимание, что при использовании этого метода SRC будет содержать все комбинации. Это может или не может быть полезным.

0 голосов
/ 01 октября 2010

Для ограниченного примера, который вы дали, вы можете использовать шаблон с одним %.

SRC := a.dat.1 a.dat.2
${SRC}: a.dat.%: a.rlt.%    
      dat2rlt $^ $@
  1. $* в рецепте расширится до любого% совпало.
  2. Обратите внимание, что " вокруг вашего исходного макроса определенно неверны.
  3. Посмотрите на .SECONDEXPANSION в руководстве для более сложных вещей (или здесь ).
...