Use subst
将点替换为空格,使其成为列表。然后使用word
访问特定元素:
word-dot = $(word $2,$(subst ., ,$1))
test.%:
export var1=$(call word-dot,$*,1) && export var2=$(call word-dot,$*,2) && export var3=$(call word-dot,$*,3)
哪个输出:
$ make test.foo.bar.baz
export var1=foo && export var2=bar && export var3=baz
作为旁白(这实际上占据了我的大部分答案),如果您提前知道选项是什么,您可以使用一些强大的元编程。假设你想生成test-{app}
一些人的目标APPS
:
tmpl-for = $(foreach x,$2,$(call $1,$x))
rule-for = $(foreach x,$2,$(eval $(call $1,$x)))
APPS := foo bar baz
tmpl-test = test-$1
define test-vars-rule
$(call tmpl-test,$1): APP := $1
.PHONY: $(call tmpl-test,$1)
endef
$(call rule-for,test-vars-rule,$(APPS))
$(call tmpl-for,tmpl-test,$(APPS)):
@echo Testing app: $(APP)
前两行是“库”函数,将调用“模板”(tmpl-for
)或生成规则(rule-for
) 对于您作为第二个参数提供的列表中的每个元素。我创建一个tmpl-test
它采用应用程序名称并给出test-{app}
。我定义了一个规则模板,它采用应用程序名称并设置特定于目标的APP
适当的变量test-{app}
目标(顺便说一下,它也是假的)。然后我用rule-for
创建我所有的设置规则APP
。最后,我编写了目标的实际主体,并使用以下命令获取所有可能目标的列表tmpl-for
.
$ make test-foo
Testing app: foo
$ make test-bar
Testing app: bar
$ make test-baz
Testing app: baz
$ make test-blah
make: *** No rule to make target 'test-blah'. Stop.
听起来很复杂,确实如此,但是如果您正确地抽象模板函数,它可以生成灵活且易于维护的构建系统。