关于调用intermediates下中间文件流程分析

关于调用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. 参数1赋值过程

    $(eval _idfClass := $(strip $(1))) \
        $(if $(_idfClass),, \
            $(error $(LOCAL_PATH): Class not defined in call to intermediates-dir-for)) \
    
    获取第一个参数,直接赋值给_idfClass=JAVA_LIBRARIES;如果为空,直接报错
    
  2. 参数2赋值过程

    $(eval _idfName := $(strip $(2))) \
        $(if $(_idfName),, \
            $(error $(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \
    
    获取传入的第二个参数,赋值到_idfName=framework;如果为空,直接报错
    
  3. 参数3赋值过程

    $(eval _idfPrefix := $(if $(strip $(3)),HOST,TARGET)) \
    
    获取传入的第三个参数,如果不为空,则为“HOST”,否则是“TARGET”,这里传入的为空,即_idfPrefix=TARGET
    
  4. 参数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. 参数5赋值过程

    $(eval _idf2ndArchPrefix := $(if $(strip $(5)),$(TARGET_2ND_ARCH_VAR_PREFIX))) \
    
    如果存在参数5不为空,直接取值 _idf2ndArchPrefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
    
  6. 具体路径查找替换

    $(_idfIntBase)/$(_idfClass)/$(_idfName)_intermediates \)
    
    由上分析这里可以替换出具体路径如下:
    TARGET_OUT_COMMON_INTERMEDIATES/JAVA_LIBRARIES/framework_intermediates
    
    下面具体找到TARGET_OUT_COMMON_INTERMEDIATES的具体路径
    
  7. 关于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
    
  8. 综上分析得出最终的路径如下:

    /out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src
    
坚持原创技术分享,您的支持将鼓励我继续创作!