我们也说说Android.mk(3) - 宏

我们也说说Android.mk(3) - 宏

传统上我们一直称这种东西为makefile中的变量,其实本质上就是一个宏,只是做的是字符串替换。我们何如就把它叫做宏呢。

宏的命名

makefile的宏可以包含字符、数字、下划线。需要注意的一点是,宏就是宏,反正是要做字符串替换的,所以名字以数字开头是没问题的。makefile本身也不是用于数值处理的,以字符串为主。

使用一个宏的时候需要使用$符号,所以如果字符串中要使用shell变量,需要用$$。
从中可以看到,我们前面学到的函数,其实本质上也就是宏,只不过是带有了参数的宏。

宏的赋值

= 和 :=

宏可以用其他宏的值来定义自己。最强大的是用=运算符。makefile是定义式的语言,不是按顺序一条一条执行的,所以,可以使用在这一行还没有定义的宏来为当前宏赋值,反正就是个宏展开么。

但是,这样如果造成的循环引用,就会引发意想不到的错误。在这种情况下,使用:=运算符,它是只允许引用在它之前定义的变量的。

?=

如果不知道定义没定义,可以使用?=来赋值,如果未定义,则定义。如果已经定义了,就什么也不做。

+=

如果之前未定义,则相当于=。如果之前有:=定义,则将新值按:=的规则添加到原值后面。

对宏进行比较

有4个关键字用于对宏的比较:

  • ifeq:判断相等
  • ifneq:判断不相等
  • ifdef:判断非空,相当于ifneq(<参数>,)
  • ifndef:如果为空,相当于ifeq(<参数>,)

例:

.PHONY : all7
ifeq ($(DEX2OAT_HOST_INSTRUCTION_SET_FEATURES),)
DEX2OAT_HOST_INSTRUCTION_SET_FEATURES := default
endif
all7 :
    @echo $(DEX2OAT_HOST_INSTRUCTION_SET_FEATURES)

输出:

$ make all7
default

请注意,ifeq, else, endif这些语句之前不能有Tab。

上面的例子是从Android.oat.mk中改造的。其实,跟下面的是等价的:

ifndef DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
DEX2OAT_HOST_INSTRUCTION_SET_FEATURES := default
endif

定义多行的宏

可以通过使用define / endef来定义多行的大宏。

我们看一个例子:

 # $(1): compiler - default, optimizing, jit or interpreter.
 # $(2): wrapper.
 # $(3): dex2oat suffix.
define create-core-oat-host-rule-combination
  $(call create-core-oat-host-rules,$(1),no-pic,,$(2),$(3))
  $(call create-core-oat-host-rules,$(1),pic,,$(2),$(3))

  ifneq ($(HOST_PREFER_32_BIT),true)
    $(call create-core-oat-host-rules,$(1),no-pic,2ND_,$(2),$(3))
    $(call create-core-oat-host-rules,$(1),pic,2ND_,$(2),$(3))
  endif
endef

这个宏其实是个函数了。

eval函数

eval函数用于在宏定义或者是分支、循环结构中使用其他makefile语句时。

我们看一个在foreach中使用eval的例子:

$(foreach m,$(ALL_MODULES), \
  $(eval r := $(ALL_MODULES.$(m).REQUIRED)) \
  $(if $(r), \
    $(eval r := $(call module-installed-files,$(r))) \
    $(eval t_m := $(filter $(TARGET_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
    $(eval h_m := $(filter $(HOST_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
    $(eval t_r := $(filter $(TARGET_OUT_ROOT)/%, $(r))) \
    $(eval h_r := $(filter $(HOST_OUT_ROOT)/%, $(r))) \
    $(eval t_m := $(filter-out $(t_r), $(t_m))) \
    $(eval h_m := $(filter-out $(h_r), $(h_m))) \
    $(if $(t_m), $(eval $(call add-required-deps, $(t_m),$(t_r)))) \
    $(if $(h_m), $(eval $(call add-required-deps, $(h_m),$(h_r)))) \
   ) \
 )

vpath宏

vpath宏用于指定makefile搜索源文件的目录,这个倒是有点变量的意思了

引用其他makefile

makefile基本上就是字符串替换,我们当然也可以通过include命令将一系列的其他makefile引用进当前的makefile.

例:

include art/build/Android.common_build.mk

自动宏

自动宏就是由make工具已经定义好的变量。

$@ 目标文件集

$@是指整个目标的文件集

例:

$(built_odex) : $(dir $(LOCAL_BUILT_MODULE))% : $(built_dex)
    $(hide) mkdir -p $(dir $@) && rm -f $@
    $(add-dex-to-package)
    $(hide) mv $@ $@.input
    $(call dexpreopt-one-file,$@.input,$@)
    $(hide) rm $@.input
endif

$<

依赖的第一个文件名,可以和$@一起共用。

例:

$(built_odex) : $(my_prebuilt_src_file)
    $(call dexpreopt-one-file,$<,$@)

调试与错误处理

输出消息

makefile的命令,默认都会输出出来。可以用@来隐藏显示。
通过echo命令,可以输出消息。一般都是用@echo,免得看见两次。

几条命令一起执行

如果这条命令用到上条命令的结果,需要在上条命令后面加分号

错误处理

如果makefile遇到命令出错,就会中止当前的依赖执行。可以通过在命令之前加上“-”来忽略错误。
我们也可以将忽略错误的目标以.IGNORE来声明。

如:

.IGNORE : all7
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容