multi-wildcard pattern rules of GNU Make

前端 未结 3 1782
轮回少年
轮回少年 2021-01-03 23:13

I want to write something like regex:

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

so that

相关标签:
3条回答
  • 2021-01-04 00:07

    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))))))
    
    0 讨论(0)
  • 2021-01-04 00:10

    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.

    0 讨论(0)
  • 2021-01-04 00:11

    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).
    0 讨论(0)
提交回复
热议问题