Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multi-wildcard pattern rules of GNU Make

I want to write something like regex:

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

so that a.dat.1 and a.dat.2 will give a.rlt.1 and a.rlt.2.

In GNU Make info page, it says "the % can be used only once".

Is there some trick to achieve this in GNU Make?

like image 835
heroxbd Avatar asked Sep 19 '10 09:09

heroxbd


People also ask

How to use wildcard in makefile?

The Function wildcard If you want to do wildcard expansion in such places, you need to use the wildcard function, like this: $(wildcard pattern ...) This string, used anywhere in a makefile, is replaced by a space-separated list of names of existing files that match one of the given file name patterns.

What is pattern rule in makefile?

A pattern rule looks like an ordinary rule, except that its target contains the character ' % ' (exactly one of them). The target is considered a pattern for matching file names; the ' % ' can match any nonempty substring, while other characters match only themselves.


2 Answers

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)))))) 
like image 178
Paljas Avatar answered Sep 24 '22 00:09

Paljas


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.

like image 36
Erzsébet Frigó Avatar answered Sep 23 '22 00:09

Erzsébet Frigó