makefile中=,:=,+=,?=使用方法

shell编程

makefile中的=,:=,+=,?=

在makeflie中=,:=,+=,?=的概念。

在makeflie中"="和":="是变量的定义有两种方式。

  1. 递归展开式变量:"="定义的变量是递归方式扩展的变量,在引用的地方是严格的文本替换过程,但在出现该变量的时候才会将他替换。

  2. 直接展开式变量:在使用“:=”定义变量时,变量值中对其他量或者函数的引用在定义变量时被展开(对变量进行替换)。

  3. 追加变量值:"+="是一个通用变量,在定义之后的其他地方对其值进行追加。当使用这种方式后,新赋值的变量值会添加到原有变量值的后面并用空格隔开。

    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 陷入到无限的变量展开过程中。
  1. 给变量赋值后,又对此变量进行追加。
  2. 在赋值时使用了嵌套语句。
eg.
A = $(B)
B = $(A) $(C)
变量定义中如果使用了函数,会使 make 的执行效率降低或者无法确定它在何时会被展开,出现不可控制或者难以预料的错误

因此应尽量避免和减少递归式变量的使用。

使用"+="的注意事项
  1. 如果被追加值的变量之前没有定义,那么,“+=”会自动变成“=”。

  2. 直接展开式变量的追加过程,变量使用“:=”定义之后,“+=”操作将会使用“:=”给此变量替换成展开之前此变量的值,并将需要追加的值写在末尾。

    eg.
    A := B
    A += C
    变成
    A := B
    #应写成A展开之前此变量的值B
    A := B C 
    
  3. 递归展开式变量的追加过程,一个变量使用“=”定义之后,“+=”操作时不对之前此变量值中的任何引用进行替换展开,并在末尾添加需要追加的值。

    eg.
    A := B
    A += C
    变成
    A := B
    #不会对其值中的引用进行展开,应写成$(A)
    A := $(A) C 
    

参考手册:https://www.gnu.org/software/make/manual/make.html#Immediate-Assignment

posted @ 2024-06-15 02:00  luxiaolim  阅读(213)  评论(0)    收藏  举报