multi-wildcard pattern rules of GNU Make

拟墨画扇 提交于 2019-12-04 22:46:54

I'm afraid what you are trying to do is not possible the way you suggest to do it, since - as you already mention - (GNU) make only allows a single stem '%', see http://www.gnu.org/software/make/manual/make.html#Pattern-Rules:

A pattern rule looks like an ordinary rule, except that its target contains the character ‘%’ (exactly one of them).

Without it, creating such 'multi-dimensional' targets is cumbersome.

One way around this is by rebuilding the name of the dependency in the command (rather than in the dependency list):

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

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

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

Of course, however, this way you would lose the dependency, it will not rebuild once the rlt has been updated.

The only way I can see to address that is by generating the rules explicitly:

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))))))

Using named variables, we can write more readable code (based on answer of Paljas):

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)) \
  ) \
)

We can generate SRC in a similar way. Note that using that method SRC will contain all the combinations. That may or may not be beneficial.

bobbogo

For the limited example you gave, you can use a pattern with one %.

SRC := a.dat.1 a.dat.2
${SRC}: a.dat.%: a.rlt.%    
      dat2rlt $^ $@
  1. $* in the recipe will expand to whatever the % matched.
  2. Note that the "s around your original macro are definitely wrong.
  3. Have a look at .SECONDEXPANSION in the manual for more complicated stuff (or over here).
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!