makefile中=,:=,+=,?=使用方法
shell编程
目录
makefile中的=,:=,+=,?=
在makeflie中=,:=,+=,?=的概念。
在makeflie中"="和":="是变量的定义有两种方式。
-
递归展开式变量:"="定义的变量是递归方式扩展的变量,在引用的地方是严格的文本替换过程,但在出现该变量的时候才会将他替换。
-
直接展开式变量:在使用“:=”定义变量时,变量值中对其他量或者函数的引用在定义变量时被展开(对变量进行替换)。
-
追加变量值:"+="是一个通用变量,在定义之后的其他地方对其值进行追加。当使用这种方式后,新赋值的变量值会添加到原有变量值的后面并用空格隔开。
eg. A = hello A += wolrd
在进行这两个操作后变量"A"的值会变成:"hello world"
4.条件赋值操作符:"?="只有此变量在之前没有赋值的情况下,才会对这个变量进行赋值。
makefile中"="和":="的使用上的区别
递归展开式变量"="
eg.
A = $(B)
B = $(C)
C = hello
#在这里定义一个target伪目标
target:
echo $(A)
.PHONY:target
当执行make target时,会进行递归展开(一步步执行),步骤如下:
- 将$(A)替换成$(B),
- 将$(B)替换成$(C),
- 将$(C)替换成hello,
- 打印出"hello"。
直接展开式变量":=”
这种风格的变量使用“:=”定义后被展开(对变量进行替换),变量被定义后就是一个实际需要的文本串,其中不再包含任何变量的引用,如下面例子所示,
这里我们还是使用上面的例子来执行,步骤如下:
- A = $(B)
B = $(C)
C = hello - A = $(B)
B = hello - A = hello
- 打印出"hello"。
当使用直接展开式变量的定义后:
A = $(B)
B = $(C) 等价于 A = hello
C = hello
使用"="的注意事项
"="在使用时存在两种缺点
因为出现变量的递归定义而导致 make 陷入到无限的变量展开过程中。
- 给变量赋值后,又对此变量进行追加。
- 在赋值时使用了嵌套语句。
eg.
A = $(B)
B = $(A) $(C)
变量定义中如果使用了函数,会使 make 的执行效率降低或者无法确定它在何时会被展开,出现不可控制或者难以预料的错误
因此应尽量避免和减少递归式变量的使用。
使用"+="的注意事项
-
如果被追加值的变量之前没有定义,那么,“+=”会自动变成“=”。
-
直接展开式变量的追加过程,变量使用“:=”定义之后,“+=”操作将会使用“:=”给此变量替换成展开之前此变量的值,并将需要追加的值写在末尾。
eg. A := B A += C 变成 A := B #应写成A展开之前此变量的值B A := B C -
递归展开式变量的追加过程,一个变量使用“=”定义之后,“+=”操作时不对之前此变量值中的任何引用进行替换展开,并在末尾添加需要追加的值。
eg. A := B A += C 变成 A := B #不会对其值中的引用进行展开,应写成$(A) A := $(A) C
参考手册:https://www.gnu.org/software/make/manual/make.html#Immediate-Assignment

浙公网安备 33010602011771号