GNU Make的多通配符模式规则

时间:2010-09-19 09:35:25

标签: makefile design-patterns gnu-make

我想写一些像正则表达式的东西:

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页面中,它显示“%只能使用一次”。

在GNU Make中有一些技巧可以实现吗?

3 个答案:

答案 0 :(得分:10)

我担心你想做的事情不可能像你建议的那样,因为 - 正如你已经提到的那样 - (GNU)make只允许一个词干'%&#39 ;,请参阅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 :(得分:1)

使用命名变量,我们可以编写更具可读性的代码(基于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)) \
  ) \
)

我们可以用类似的方式生成SRC。请注意,使用该方法SRC将包含所有组合。这可能是有益的,也可能不是有益的。

答案 2 :(得分:-2)

对于您提供的有限示例,您可以使用一个%的模式。

SRC := a.dat.1 a.dat.2
${SRC}: a.dat.%: a.rlt.%    
      dat2rlt $^ $@
    食谱中的
  1. $*将扩展为%匹配的任何内容。
  2. 请注意,原始宏周围的" s肯定是错误的。
  3. 请查看手册中的.SECONDEXPANSION以了解更复杂的内容(或over here)。