为了解决这些问题,GNU定义了另一中其它风格的变量,叫做简单扩展变量(Simply Expanded Variables)
简单扩展变量用符号:=来定义,用这种方式定义的变量,会在变量的定义点,按照被引用的变量的当前值
进行展开。同样写个例子,测试一下,这东西用文字表达太困难了
[code:1]m := mm
x := $(m)
y := $(x) bar
x := later
all:;echo $(x) $(y)[/code:1]
这种定义变量的方式更适合在大的编程项目中使用,因为它更像我们一般的编程语言。
其实,GNU还对makefile中定义变量的方式进行了第三种扩展,用?=定义变量,它的含义是如果变量还没定义
就定义它,例如 FOO ?= Am I defined?,那么,它相当于下面的代码片断
[code:1]ifeq ($(origin FOO), undefined)
FOO = Am I defined?
endif[/code:1]
这种写法可以用于为用户提供默认的选项,即如果用户不定义,就提供给他默认的。另外,要说明的是把变量
定义成NULl,也是定义了变量,此时?=将不再起作用。
注意:
最后要说的是,无论我们使用那种风格定义变量,都不要在定义变量的行后面加上随机数目的空格,之后写注释,
这个我们想象的是不一样的,例如
ml = magic_linux
和
ml = magic_linux # My favourite linux distribution
这是两个完全不同的变量,其中第一个ml的值是magic_linux,而后一个的值是‘magic_linux ’,所以除非
你有意要定义末尾带有空格的变量,否则不要在定义变量行末尾随便添加空格和注释。
第二种
这是一种高级的makefile编程技术,一般我们很少使用它,但是它并不难,先看个例子
[code:1]x = y
y = z
a := $($(x))[/code:1]
此时,a的值是什么呢?答案是z。因为内层的$(x)=y,而外层的$(y)=z,也就是说a的值是通过$(x)计算出来的,所以
叫做计算变量的值。当然嵌套可是有很多层,自己试试吧,不多说了。在嵌套变量引用的时候,还可以包含函数调用,
例如:
[code:1]x = variable1
variable2 := Hello
y = $(subst 1,2,$(x))
z = y
a := $($($(z)))[/code:1]
一番推导,a的值等于Hello
整个变量的推导过程中可以涉及到多个变量,这样,一个变量就可以有多个字面值,例如:
[code:1]a_dirs := dira dirb
1_dirs := dir1 dir2