初探make clean-target规则

前言

在Android源码根目录下执行make,会根据编译系统的根节点Makefile文件找到一系列mk文件的引用。其中main.mk作为开始编译的入口,Android构建系统的产品配置和函数定义都可以在/build/make/core/目录下找到。

其中make clean-target是对特定目标(通常是模块名)执行清除操作。编译系统需要遵循的基础规则是定义在base_rules.mk文件里,我们可以看到关键词:make clean- targets,该规则就定义了clean-$(LOCAL_MODULE)所依赖的条件,并根据规则执行相关命令。

定义该规则的mk引用链关系如下:

include
include
include
include
include
main.mk
config.mk
package.mk
package_internal.mk
java.mk
base_rules.mk

源码分析

  • 规则定义
###########################################################
## make clean- targets
###########################################################
cleantarget := clean-$(my_register_name)
.PHONY: $(cleantarget)
$(cleantarget) : PRIVATE_MODULE := $(my_register_name)
$(cleantarget) : PRIVATE_CLEAN_FILES := \
    $(LOCAL_BUILT_MODULE) \
    $(LOCAL_INSTALLED_MODULE) \
    $(intermediates)
$(cleantarget)::
	@echo "Clean: $(PRIVATE_MODULE)"
	$(hide) rm -rf $(PRIVATE_CLEAN_FILES)

###########################################################
  • 执行流程
#定义cleantarget变量并赋值,比如clean-MtkSettings
cleantarget := clean-$(my_register_name)
#.PHONY:伪目标, 代表不是真实存在的文件target,而makefile的target默认是文件。
#含义:若当前目录存在文件名与target值一致时,普通make会把该文件当target去执行,而有了PHONY后则不会理会该文件,而是继续执行伪目标。为了防止冲突并提高编译效率,源码下定义了很多伪目标。
.PHONY: $(cleantarget)
#单冒号规则:定义target的规则,目标依赖前置条件prerequisites,通常是一系列文件或目录。指定了目标是否重新构建的判断标准,如果前置文件不存在或时间戳较早,目标就需要重新构建。
#如下cleantarget目标同时出现在两个规则中(都是同一类型:单冒号规则),依赖会被合并,但命令只会执行最后一条规则。
#定义$(cleantarget)的第一条规则,目标依赖于PRIVATE_MODULE,这里是模块名。
$(cleantarget) : PRIVATE_MODULE := $(my_register_name)
#定义$(cleantarget)的第二条规则,目标依赖于PRIVATE_CLEAN_FILES,模块编译与输出的文件路径。
$(cleantarget) : PRIVATE_CLEAN_FILES := \
    $(LOCAL_BUILT_MODULE) \
    $(LOCAL_INSTALLED_MODULE) \
    $(intermediates)
#双冒号规则:无论makefile所在目录下是否存在与target同名文件,make target都会触发commands的执行。
$(cleantarget)::
	#makefile默认会在shell中输出命令的,通过在命令前加@可以不显示命令本身而只显示它的结果。
	@echo "Clean: $(PRIVATE_MODULE)"
	@echo "Clean: $(PRIVATE_CLEAN_FILES)"
	#引用hide变量,该变量定义在同级目录下config.mk中,hide := @,与@效果一致,即关闭命令显示。
	$(hide) rm -rf $(PRIVATE_CLEAN_FILES)

编译

以命令"make clean-MtkSettings"为例,我们在mk文件加一些打印日志并编译,方便理解它的执行过程。

$(info "noah my_register_name = $(my_register_name)")
$(info "noah LOCAL_BUILT_MODULE = $(LOCAL_BUILT_MODULE)")
$(info "noah LOCAL_INSTALLED_MODULE = $(LOCAL_INSTALLED_MODULE)")
$(info "noah intermediates = $(intermediates)")
$(info "noah PRIVATE_MODULE = $(PRIVATE_MODULE)")
$(info "noah PRIVATE_CLEAN_FILES = $(PRIVATE_CLEAN_FILES)")

在源码根目录我们执行 make sys_images 2>&1 | tee build.log 使修改生效并输出日志到build.log。
然后再执行 make clean-MtkSettings 2>&1 | tee build_clean_settings.log 查看最后命令的执行输出,可见最后是对out模块输出目录下将之前生成的apk以及中间临时文件进行了递归删除。

  • 单冒号规则的输出
"noah my_register_name = MtkSettings"
"noah LOCAL_BUILT_MODULE = out/target/product/yxp_713_pad/obj/APPS/MtkSettings_intermediates/package.apk"
"noah LOCAL_INSTALLED_MODULE = out/target/product/yxp_713_pad/product/priv-app/MtkSettings/MtkSettings.apk"
"noah intermediates = out/target/product/yxp_713_pad/obj/APPS/MtkSettings_intermediates"
"noah PRIVATE_MODULE = MtkSettings"
"noah PRIVATE_CLEAN_FILES = out/target/product/yxp_713_pad/obj/APPS/MtkSettings_intermediates/package.apk out/target/product/yxp_713_pad/product/priv-app/MtkSettings/MtkSettings.apk out/target/product/yxp_713_pad/obj/APPS/MtkSettings_intermediates cleantarget := clean-MtkSettings"
  • 双冒号规则的输出
Clean: MtkSettings
Clean: out/target/product/yxp_713_pad/obj/APPS/MtkSettings_intermediates/package.apk out/target/product/yxp_713_pad/product/priv-app/MtkSettings/MtkSettings.apk out/target/product/yxp_713_pad/obj/APPS/MtkSettings_intermediates out/target/common/obj/APPS/MtkSettings_intermediates"

最后

在拆分规则定义与变量赋值的过程中,将 $(cleantarget) : PRIVATE_MODULE := $(my_register_name)拆分为两个步骤:

1PRIVATE_MODULE := $(my_register_name)
2$(cleantarget) : $(PRIVATE_MODULE )

出现编译错误:target file `clean-26.0.cil' has both : and :: entries.大致就是两种不同类型的规则同时使用导致的错误。

GNU官网上对双冒号规则的解释:
当一个目标出现在多个规则中时,所有的规则必须是相同的类型:都是普通的,或者都是双冒号。如果它们是双冒号,则它们中的每一个都是独立于其他的。如果目标早于该规则的任何先决条件,则执行每个双冒号规则的配方。如果该规则没有先决条件,则始终执行其配方(即使目标已经存在)。这可能导致不执行、不执行任何或所有双冒号规则。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值