如何在Makefile中用点分割字符串?

问题描述 投票:0回答:1

我的目标是这样的:

test.%
    export var1=$(basename $*) && export var2=$(subst .,,$(suffix $*))

我用类似

test.var1.var2

现在我想做一个像

test.var1.var2.var3
这样的关卡。我怎样才能在 Makefile 中得到它?

编辑:

我想这样做的原因是因为我正在使用 Makefile 来部署多个应用程序。我想要很多变量。这样用户就可以像这样部署

make install.{app1}.{test}.{build_number}
makefile gnu-make
1个回答
40
投票

使用

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.

这听起来很复杂,确实如此,但是如果您正确地抽象模板函数,它可以生成灵活且易于维护的构建系统。

© www.soinside.com 2019 - 2024. All rights reserved.