我们也说说Android.mk(5) - 案例教程

我们也说说Android.mk(5) - 案例教程

userdata是如何生成的

我们先看看userdataimage的伪目标是如何定义的:

.PHONY: userdataimage
userdataimage: $(INSTALLED_USERDATAIMAGE_TARGET)

ifneq (,$(filter userdataimage, $(MAKECMDGOALS)))
$(call dist-for-goals, userdataimage, $(BUILT_USERDATAIMAGE_TARGET))
endif

.PHONY: userdatatarball
userdatatarball: $(INSTALLED_USERDATATARBALL_TARGET)

INSTALLED_USERDATAIMAGE_TARGET

userdataimage依赖于INSTALLED_USERDATAIMAGE_TARGET,我们再看看INSTALLED_USERDATAIMAGE_TARGET是什么:

INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)

BUILT_USERDATAIMAGE_TARGET

我们再继续看BUILT_USERDATAIMAGE_TARGET:

BUILT_USERDATAIMAGE_TARGET := $(PRODUCT_OUT)/userdata.img

OK,这一支明白了,就是userdata.img嘛。

# A global variable to remember all dist'ed src:dst pairs.
# So if a src:dst is already dist'ed by another goal,
# we should just establish the dependency and don't really call the
# copy-one-dist-file to avoid multiple rules for the same target.
_all_dist_src_dst_pairs :=
# Other parts of the system should use this function to associate
# certain files with certain goals. When those goals are built
# and "dist" is specified, the marked files will be copied to DIST_DIR.
#
# $(1): a list of goals (e.g. droid, sdk, pdk, ndk)
# $(2): the dist files to add to those goals. If the file contains ':',
# the text following the colon is the name that the file is copied
# to under the dist directory. Subdirs are ok, and will be created
# at copy time if necessary.
define dist-for-goals
$(foreach file,$(2), \
  $(eval fw := $(subst :,$(space),$(file))) \
  $(eval src := $(word 1,$(fw))) \
  $(eval dst := $(word 2,$(fw))) \
  $(eval dst := $(if $(dst),$(dst),$(notdir $(src)))) \
  $(if $(filter $(_all_dist_src_dst_pairs),$(src):$(dst)),\
    $(eval $(call add-dependency,$(1),$(DIST_DIR)/$(dst))),\
    $(eval $(call copy-one-dist-file,\
      $(src),$(DIST_DIR)/$(dst),$(1)))\
      $(eval _all_dist_src_dst_pairs += $(src):$(dst))\
  )\
)
endef

userdata的中间文件

我们再来看看userdata的中间文件是如何生成的:

userdataimage_intermediates := \
    $(call intermediates-dir-for,PACKAGING,userdata)

这个好,直接调用一个函数。所谓函数,就是一个大宏,我们看看它是如何定义的:

###########################################################
## The intermediates directory. Where object files go for
## a given target. We could technically get away without
## the "_intermediates" suffix on the directory, but it's
## nice to be able to grep for that string to find out if
## anyone's abusing the system.
###########################################################

# $(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

虽然逻辑并不是一目了然,但是所用的特性,我们前面都讲过了。

你可能感兴趣的:(Android-mk)