makefile := 与 = 的区别

一、简述

1、"="赋值,这种形式是以递归的形式展开变量,及被赋值的变量只有在被引用(使用)时,才会展开,及延迟展开(不常用)

2、":="赋值,这种形式是直接展开式赋值。

二、举例

例子1:

foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo)

例子来源于GnuMake

上述例子执行结果为(其中all:;echo $(foo)等价于 将分号去掉,echo语句换行并以tab键开头)

echo Huh?
Huh?

如果将 foo = $(bar)替换成 foo:=$(bar)呢:

foo := $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo)

执行结果如下:

echo 

可以看到foo变量为空,这就印证了简述中的定义,foo直接展开式赋值时,bar变量为空(还未赋值),所以foo也为空,foo递归展开赋值时,在调用echo 语句时才被展开,所以此时bar的值为Hub?,所以foo的值也是Hub?

例子2:

网上有一种说法: "=" make会将整个makefile展开后,再决定变量的值,":="表示变量的值决定于它在makefile中的位置,而不是整个makefile展开式的最终结果

那么这句话对吗,我个人认为这种描述是不精确的,会给人带来误区,“:=” 和"="的区别还是按照例子1中的测试结果描述,我们将上例做如下添加:

foo := $(bar)
bar = $(ugh)
ugh = Huh?
all:
    echo $(foo)

foo := hello

如果按照上述网上的说法,那么你很可能认为 foo仍然为空,但实际执行结果为:

echo hello
hello

实际上一般make执行确定的目标前,会将所有的变量赋值全部读取,解析,也就是调用all目标之前,foo:=hello 已经被读取了,并且已经生效了,所以,echo $(foo)的结果会是hello,那上述网络描述是什么意思呢?其实他的本来的意思是,如果一个变量foo只在一个地方被赋值的时候 用"="和":="被赋值的区别是,如果赋值的内容中有变量,"="会等Makefile全部展开后,所有的变量值再来为foo变量赋值,而":="不会等Makefile全部展开,而是foo变量之前所有展开的变量的值来为foo进行赋值,如果foo:=$(bar),其中bar变量在foo变量之前还没有展开,则bar变量就按空处理,将空赋值为foo。所以上述网络说法可以在这种情况下可以套用。

而我们是在一个Makefile中的多个地方为同一变量赋值,所以会产生歧义,如果Makefile中在多个地方对同一变量进行赋值,无论用“=”还是":="都是按照Makefile展开的顺序,最后为变量赋值的地方是最终生效的赋值语句。

如果将上述例子中所有的 ":=" 变成 "=" 那么执行结果也是毫无疑义的,如下:

foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
    echo $(foo)
foo = hello  

执行结果:

echo hello
hello

另外,其实并不推荐 := 和= 在变量赋值中交替混合使用,其实 =并不常用。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值