关于调用intermediates下中间文件流程分析
最近查看安卓源码在分析其Oberlay机制,无意中发现call intermediates-dir-for 方法的调用,其后面跟了好许参数,就在这里深入的分析了解一下,原代码文件基于Mstar定制的android6.0分析
$(call intermediates-dir-for,,,,)/src
代码:build/core/definitions.mk
# $(1): target class, like "APPS" # $(2): target name, like "NotePad" # $(3): if non-empty, this is a HOST target. # $(4): if non-empty, force the intermediates to be COMMON # $(5): if non-empty, force the intermedistes to be for the 2nd arch define intermediates-dir-for $(strip \ $(eval _idfClass := $(strip $(1))) \ $(if $(_idfClass),, \ $(error $(LOCAL_PATH): Class not defined in call to intermediates-dir-for)) \ $(eval _idfName := $(strip $(2))) \ $(if $(_idfName),, \ $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \ $(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \ $(eval _idf2ndArchPrefix := $(if $(strip $(5)),$(TARGET_2ND_ARCH_VAR_PREFIX))) \ $(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \ $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \ ,$(if $(filter $(_idfClass),SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP),\ $(eval _idfIntBase := $($(_idf2ndArchPrefix)$(_idfPrefix)_OUT_INTERMEDIATES)) \ ,$(eval _idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES)) \ ) \ ) \ $(_idfIntBase)/$(_idfClass)/$(_idfName)_intermediates \ ) endef 代码中接受的几个重要参数如下: 参数1: _idfClass 参数2: _idfName 参数3: _idfPrefix 参数4: _idfIntBase 参数5:_idf2ndArchPrefix
示例:
framework_GENERATED_SOURCE_DIR := $(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)/src 示例传入参数如下: 参数1:JAVA_LIBRARIES 参数2: framework 参数3: 参数4: COMMON 参数5:
参数1赋值过程
$(eval _idfClass := $(strip $(1))) \ $(if $(_idfClass),, \ $(error $(LOCAL_PATH): Class not defined in call to intermediates-dir-for)) \ 获取第一个参数,直接赋值给_idfClass=JAVA_LIBRARIES;如果为空,直接报错
参数2赋值过程
$(eval _idfName := $(strip $(2))) \ $(if $(_idfName),, \ $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \ 获取传入的第二个参数,赋值到_idfName=framework;如果为空,直接报错
参数3赋值过程
$(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \ 获取传入的第三个参数,如果不为空,则为“HOST”,否则是“TARGET”,这里传入的为空,即_idfPrefix=TARGET
参数4赋值过程
$(if $(filter $(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \ $(eval _idfIntBase := $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \ ,$(if $(filter $(_idfClass),SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP),\ $(eval _idfIntBase := $($(_idf2ndArchPrefix)$(_idfPrefix)_OUT_INTERMEDIATES)) \ ,$(eval _idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES)) \ ) \ ) \ 判断1: 过滤在 $(_idfPrefix)-$(_idfClass) 中存在匹配条件 TARGET-NOTICE_FILES HOST-NOTICE_FILES HOST-JAVA_LIBRARIES中任意项目,如果存在不为空,直接取值$(4); 否则,_idfIntBase=(_idfPrefix)_OUT_COMMON_INTERMEDIATES 判断2: 过滤 _idfClass 中存在 SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP 中任意值,如结果不为空,_idfIntBase := $($(_idf2ndArchPrefix)$(_idfPrefix)_OUT_INTERMEDIATES)) ; 否则,_idfIntBase := $($(_idfPrefix)_OUT_INTERMEDIATES)) 此处由上此处传入的是“COMMMON”,分析得出 _idfIntBase=TARGET_OUT_COMMON_INTERMEDIATES
参数5赋值过程
$(eval _idf2ndArchPrefix := $(if $(strip $(5)),$(TARGET_2ND_ARCH_VAR_PREFIX))) \ 如果存在参数5不为空,直接取值 _idf2ndArchPrefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
具体路径查找替换
$(_idfIntBase)/$(_idfClass)/$(_idfName)_intermediates \) 由上分析这里可以替换出具体路径如下: TARGET_OUT_COMMON_INTERMEDIATES/JAVA_LIBRARIES/framework_intermediates 下面具体找到TARGET_OUT_COMMON_INTERMEDIATES的具体路径
关于TARGET_OUT_COMMON_INTERMEDIATES的具体路径
相关Makefile路径代码:build/envsetup.mk TARGET_OUT_COMMON_INTERMEDIATES := $(TARGET_COMMON_OUT_ROOT)/obj TARGET_COMMON_OUT_ROOT := $(TARGET_OUT_ROOT)/common TARGET_OUT_ROOT := $(TARGET_OUT_ROOT_$(TARGET_BUILD_TYPE)) ifneq ($(TARGET_BUILD_TYPE),debug) TARGET_BUILD_TYPE := release endif 此处默认为release TARGET_OUT_ROOT_release := $(OUT_DIR)/target TARGET_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/target ifeq (,$(strip $(OUT_DIR))) ifeq (,$(strip $(OUT_DIR_COMMON_BASE))) OUT_DIR := $(TOPDIR)out else OUT_DIR := $(OUT_DIR_COMMON_BASE)/$(notdir $(PWD)) endif endif 此处OUT_DIR为源码的根目录 因此,TARGET_OUT_COMMON_INTERMEDIATES=out/target/common/obj
综上分析得出最终的路径如下:
/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src
相关拓展