我想写一些像正则表达式的东西:
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中有一些技巧可以实现吗?
答案 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 $^ $@
$*
将扩展为%
匹配的任何内容。"
s肯定是错误的。.SECONDEXPANSION
以了解更复杂的内容(或over here)。