这里介绍两种变量的高级使用方法,第一种是变量值的替换。
我们可以替换变量中的共有的部分,其格式是“$(var:a=b)”或是“${var:a=b}”,其意思是,把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。
还是看一个示例吧:
foo
:=
a.o
b.o
c.o
bar
:=
$(foo:.o=.c)
这个示例中,我们先定义了一个“$(foo)”变量,而第二行的意思是把“$(foo)”中所有以“.o”字串“结尾”全部替换成“.c”,所以我们的“$(bar)”的值就是“a.c b.c
c.c”。
另外一种变量替换的技术是以“静态模式”(参见前面章节)定义的,如:
foo
:=
a.o
b.o
c.o
bar
:=
$(foo:%.o=%.c)
这依赖于被替换字串中的有相同的模式,模式中必须包含一个“%”字符,这个例子同样让$(bar)变量的值为“a.c b.c
c.c”。
第二种高级用法是——“把变量的值再当成变量”。先看一个例子:
x
=
y
y
=
z
a
:=
$($(x))
在这个例子中,$(x)的值是“y”,所以$($(x))就是$(y),于是$(a)的值就是“z”。(注意,是“x=y”,而不是“x=$(y)”)
我们还可以使用更多的层次:
x
=
y
y
=
z
z
=
u
a
:=
$($($(x)))
这里的$(a)的值是“u”,相关的推导留给读者自己去做吧。
让我们再复杂一点,使用上“在变量定义中使用变量”的第一个方式,来看一个例子:
x
=
$(y)
y
=
z
z
=
Hello
a
:=
$($(x))
这里的$($(x))被替换成了$($(y)),因为$(y)值是“z”,所以,最终结果是:a:=$(z),也就是“Hello”。
再复杂一点,我们再加上函数:
x
=
variable1
variable2
:=
Hello
y
=
$(subst
1,2,$(x))
z
=
y
a
:=
$($($(z)))
这个例子中,“$($($(z)))”扩展为“$($(y))”,而其再次被扩展为“$($(subst 1,2,$(x)))”。$(x)的值是“variable1”,subst函数把“variable1”中的所有“1”字串替换成“2”字串,于是,“variable1”变成“variable2”,再取其值,所以,最终,$(a)的值就是$(variable2)的值——“Hello”。(喔,好不容易)
在这种方式中,或要可以使用多个变量来组成一个变量的名字,然后再取其值:
first_second
=
Hello
a
=
first
b
=
second
all
=
$($a_$b)
这里的“$a_$b”组成了“first_second”,于是,$(all)的值就是“Hello”。
再来看看结合第一种技术的例子:
a_objects
:=
a.o
b.o
c.o
1_objects
:=
1.o
2.o
3.o
sources
:=
$($(a1)_objects:.o=.c)
这个例子中,如果$(a1)的值是“a”的话,那么,$(sources)的值就是“a.c b.c
c.c”;如果$(a1)的值是“1”,那么$(sources)的值是“1.c
2.c
3.c”。
再来看一个这种技术和“函数”与“条件语句”一同使用的例子:
ifdef
do_sort
func
:=
sort
else
func
:=
strip
endif
bar
:=
a
d
b
g
q
c
foo
:=
$($(func)
$(bar))
这个示例中,如果定义了“do_sort”,那么:foo :=
$(sort
a
d
b
g
q
c),于是$(foo)的值就是“a
b
c
d
g
q”,而如果没有定义“do_sort”,那么:foo
:=
$(sort
a
d
b
g
q
c),调用的就是strip函数。
当然,“把变量的值再当成变量”这种技术,同样可以用在操作符的左边:
dir
=
foo
$(dir)_sources
:=
$(wildcard
$(dir)/*.c)
define
$(dir)_print
lpr
$($(dir)_sources)
endef
这个例子中定义了三个变量:“dir”,“foo_sources”和“foo_print”。
四、追加变量值
我们可以使用“+=”操作符给变量追加值,如:
objects
=
main.o
foo.o
bar.o
utils.o
objects
+=
another.o
于是,我们的$(objects)值变成:“main.o foo.o
bar.o
utils.o
another.o”(another.o被追加进去了)
使用“+=”操作符,可以模拟为下面的这种例子:
objects
=
main.o
foo.o
bar.o
utils.o
objects
:=
$(objects)
another.o
所不同的是,用“+=”更为简洁。
如果变量之前没有定义过,那么,“+=”会自动变成“=”,如果前面有变量定义,那么“+=”会继承于前次操作的赋值符。如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符,如:
variable
:=
value
variable
+=
more
等价于:
variable
:=
value
variable
:=
$(variable)
more
但如果是这种情况:
variable
=
value
variable
+=
more
由于前次的赋值符是“=”,所以“+=”也会以“=”来做为赋值,那么岂不会发生变量的递补归定义,这是很不好的,所以make会自动为我们解决这个问题,我们不必担心这个问题。
五、override 指示符
如果有变量是通常make的命令行参数设置的,那么Makefile中对这个变量的赋值会被忽略。如果你想在Makefile中设置这类参数的值,那么,你可以使用“override”指示符。其语法是:
override
<variable>;
=
<value>;
override
<variable>;
:=
<value>;
当然,你还可以追加:
override
<variable>;
+=
<more
text>;
对于多行的变量定义,我们用define指示符,在define指示符前,也同样可以使用ovveride指示符,如:
override
define
foo
bar
endef
我们可以替换变量中的共有的部分,其格式是“$(var:a=b)”或是“${var:a=b}”,其意思是,把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。
还是看一个示例吧:
这个示例中,我们先定义了一个“$(foo)”变量,而第二行的意思是把“$(foo)”中所有以“.o”字串“结尾”全部替换成“.c”,所以我们的“$(bar)”的值就是“a.c
另外一种变量替换的技术是以“静态模式”(参见前面章节)定义的,如:
这依赖于被替换字串中的有相同的模式,模式中必须包含一个“%”字符,这个例子同样让$(bar)变量的值为“a.c
第二种高级用法是——“把变量的值再当成变量”。先看一个例子:
在这个例子中,$(x)的值是“y”,所以$($(x))就是$(y),于是$(a)的值就是“z”。(注意,是“x=y”,而不是“x=$(y)”)
我们还可以使用更多的层次:
这里的$(a)的值是“u”,相关的推导留给读者自己去做吧。
让我们再复杂一点,使用上“在变量定义中使用变量”的第一个方式,来看一个例子:
这里的$($(x))被替换成了$($(y)),因为$(y)值是“z”,所以,最终结果是:a:=$(z),也就是“Hello”。
再复杂一点,我们再加上函数:
这个例子中,“$($($(z)))”扩展为“$($(y))”,而其再次被扩展为“$($(subst
在这种方式中,或要可以使用多个变量来组成一个变量的名字,然后再取其值:
这里的“$a_$b”组成了“first_second”,于是,$(all)的值就是“Hello”。
再来看看结合第一种技术的例子:
这个例子中,如果$(a1)的值是“a”的话,那么,$(sources)的值就是“a.c
再来看一个这种技术和“函数”与“条件语句”一同使用的例子:
这个示例中,如果定义了“do_sort”,那么:foo
当然,“把变量的值再当成变量”这种技术,同样可以用在操作符的左边:
这个例子中定义了三个变量:“dir”,“foo_sources”和“foo_print”。
四、追加变量值
我们可以使用“+=”操作符给变量追加值,如:
于是,我们的$(objects)值变成:“main.o
使用“+=”操作符,可以模拟为下面的这种例子:
所不同的是,用“+=”更为简洁。
如果变量之前没有定义过,那么,“+=”会自动变成“=”,如果前面有变量定义,那么“+=”会继承于前次操作的赋值符。如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符,如:
等价于:
但如果是这种情况:
由于前次的赋值符是“=”,所以“+=”也会以“=”来做为赋值,那么岂不会发生变量的递补归定义,这是很不好的,所以make会自动为我们解决这个问题,我们不必担心这个问题。
五、override
如果有变量是通常make的命令行参数设置的,那么Makefile中对这个变量的赋值会被忽略。如果你想在Makefile中设置这类参数的值,那么,你可以使用“override”指示符。其语法是:
当然,你还可以追加:
对于多行的变量定义,我们用define指示符,在define指示符前,也同样可以使用ovveride指示符,如: