Makefile中我们经常看到 = ,:=, ?=, +=这几个赋值运算符,特别是Android系统开发时,在mk文件中这个几个赋值运算都有着不同的意思,以前自己也有点疑惑,今天就干脆写了个小例子,来具体看看每个赋值运算的含义
先来看看对这几个基本赋值运算的定义,如下:
= :基本的赋值
:= :覆盖之前的值
?= :如果没有被赋值过就赋予=后面的值
+= :添加等号后面的值,等价于字符串添加,中间以空格分开
在makefile中输出信息的方法有:$(warning xxx) 或 $(error xxx),下面就以这种方式随便找了个系统apk的mk文件为例,添加测试代码如下:
//Android.mk文件,有省略
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
...
#“=”测试
$(warning 'makefile = test start **********************************')
x=test
y=makefile $x
x=test1
$(warning $y)
$(warning 'makefile = test end*************************************')
#“:=”测试
$(warning 'makefile := test start*********************************')
x1:=test
y1:=makefile $(x1)
x1:=test1
$(warning $(y1))
$(warning 'makefile := test end************************************')
#“+=”测试
$(warning 'makefile += test start************************************')
y2+=test
y2+=makefile
$(warning $(y2))
$(warning 'makefile += test end*************************************')
#“?=”测试
$(warning 'makefile ?= test start******************************')
y3?=test
y3?=makefile
$(warning $(y3))
$(warning 'makefile ?= test end***********************************')
include $(BUILD_PACKAGE)
...
include $(call all-makefiles-under,$(LOCAL_PATH))
修改完成后,在对应mk文件目录执行"mm -B",可以看到输出的log如下
Android.mk:10: 'makefile = test start **********************************'
Android.mk:14: makefile test1
Android.mk:15: 'makefile = test end*************************************'
make会将整个makefile展开后,再决定变量的值,变量的值将会是整个makefile中最后被指定的值
Android.mk:17: 'makefile := test start*********************************'
Android.mk:21: makefile test
Android.mk:22: 'makefile := test end************************************'
表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值
Android.mk:24: 'makefile += test start************************************'
Android.mk:27: test makefile
Android.mk:28: 'makefile += test end*************************************'
字符串拼接,以空格分开
Android.mk:30: 'makefile ?= test start******************************'
Android.mk:33: test
Android.mk:34: 'makefile ?= test end***********************************'
先判断是否被赋值过,如果没有被赋值过就赋予=后面的值
另外经常看到下面这种配置,其实这两种配置是一个意思
①x += aa bb cc
②y += \
aa \
bb \
cc
其实②配置中的\其实就是换行符,需要注意的是换行符之前有个空格哈