本文共 3707 字,大约阅读时间需要 12 分钟。
在Android的mk系统中,调用dex2oat中有几处,但是真正被调用来生成目标系统上的oat的是下面这个,位于/build/core/dex_preopt_libart.mk中:
# For a single jar or APK # $(1): the input .jar or .apk file # $(2): the output .odex filedefine dex2oat-one-file$(hide) rm -f $(2)$(hide) mkdir -p $(dir $(2))$(hide) $(DEX2OAT) \ --runtime-arg -Xms$(DEX2OAT_XMS) --runtime-arg -Xmx$(DEX2OAT_XMX) \ --boot-image=$(PRIVATE_DEX_PREOPT_IMAGE_LOCATION) \ --dex-file=$(1) \ --dex-location=$(PRIVATE_DEX_LOCATION) \ --oat-file=$(2) \ --android-root=$(PRODUCT_OUT)/system \ --instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \ --instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \ --instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \ --include-patch-information --runtime-arg -Xnorelocate --no-generate-debug-info \ --abort-on-hard-verifier-error \ $(PRIVATE_DEX_PREOPT_FLAGS)endef
这个dex2oat-one-file,是被dexpreopt-one-file调用,位于/build/core/dex_preopt.mk中:
include $(BUILD_SYSTEM)/dex_preopt_libart.mk # Define dexpreopt-one-file based on current default runtime. # $(1): the input .jar or .apk file # $(2): the output .odex filedefine dexpreopt-one-file$(call dex2oat-one-file,$(1),$(2))endef
以下根据生成的类型不同,包、库、预先编译好的应用有不同的路径。
/build/core/package_internal.mk
############################### ## Rule to build the odex fileifdef LOCAL_DEX_PREOPT$(built_odex): PRIVATE_DEX_FILE := $(built_dex) # Use pattern rule - we may have multiple built odex files.$(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 $@.inputendif
/build/core/java_library.mk
$(built_odex): PRIVATE_MODULE := $(LOCAL_MODULE) # Use pattern rule - we may have multiple built odex files.$(built_odex) : $(dir $(LOCAL_BUILT_MODULE))% : $(common_javalib.jar) @echo "Dexpreopt Jar: $(PRIVATE_MODULE) ($@)" $(call dexpreopt-one-file,$<,$@)
############################### ## Rule to build the odex fileifdef LOCAL_DEX_PREOPT$(built_odex) : $(my_prebuilt_src_file) $(call dexpreopt-one-file,$<,$@)endif
我们再来看看,odex是如何被install到system分区下面的。
# Use pattern rule - we may have multiple installed odex files. # Ugly syntax - See the definition get-odex-file-path.$(installed_odex) : $(dir $(LOCAL_INSTALLED_MODULE))%$(notdir $(word 1,$(installed_odex))) \ : $(dir $(LOCAL_BUILT_MODULE))%$(notdir $(word 1,$(built_odex))) \ | $(ACP) @echo "Install: $@" $(copy-file-to-target)endif
我们看一个实际的例子:
Install: out/target/product/6753_64_m/system/app/Note/oat/arm64/Note.odexmkdir -p out/target/product/6753_64_m/system/app/Note/oat/arm64/out/host/linux-x86/bin/acp -fp out/target/product/6753_64_m/obj/APPS/Note_intermediates/oat/arm64/package.odex out/target/product/6753_64_m/system/app/Note/oat/arm64/Note.odexInstall: out/target/product/6753_64_m/system/priv-app/Settings/oat/arm64/Settings.odexmkdir -p out/target/product/6753_64_m/system/priv-app/Settings/oat/arm64/out/host/linux-x86/bin/acp -fp out/target/product/6753_64_m/obj/APPS/Settings_intermediates/oat/arm64/package.odex out/target/product/6753_64_m/system/priv-app/Settings/oat/arm64/Settings.odex
除了编译之外,我们得先看一些预先定义好的函数。它们定义于/build/core/definitions.mk中。
将class文件压缩成classes*.dex
define add-dex-to-package$(hide) zip -qj $@ $(dir $(PRIVATE_DEX_FILE))classes*.dexendef
将依赖文件复制到目标文件
define copy-file-to-target@mkdir -p $(dir $@)$(hide) $(ACP) -fp $< $@endef
转载地址:http://yluml.baihongyu.com/