diff --git a/core/Makefile b/core/Makefile index ad964c12e..f27b5c1a9 100644 --- a/core/Makefile +++ b/core/Makefile @@ -737,7 +737,8 @@ INSTALLED_SYSTEMIMAGE := $(PRODUCT_OUT)/system.img ifdef WITH_DEXPREOPT ifndef DISABLE_DEXPREOPT - with_dexpreopt := true +# TODO: remove the unnecessary code. +# with_dexpreopt := true endif endif ifdef with_dexpreopt diff --git a/core/base_rules.mk b/core/base_rules.mk index db05e0098..f372748a0 100644 --- a/core/base_rules.mk +++ b/core/base_rules.mk @@ -492,6 +492,16 @@ $(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE) $(copy-file-to-target-with-cp) endif +ifeq ($(LOCAL_DEX_PREOPT),true) +installed_odex := $(basename $(LOCAL_INSTALLED_MODULE)).odex +built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex +$(installed_odex) : $(built_odex) | $(ACP) + @echo "Install: $@" + $(copy-file-to-target) + +$(LOCAL_INSTALLED_MODULE): $(installed_odex) +endif + endif # !LOCAL_UNINSTALLABLE_MODULE diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk index 24a356555..dbc64ff39 100644 --- a/core/cleanbuild.mk +++ b/core/cleanbuild.mk @@ -186,7 +186,11 @@ installclean_files := \ ./$(PRODUCT_OUT)/obj/PACKAGING \ ./$(PRODUCT_OUT)/recovery \ ./$(PRODUCT_OUT)/root \ - ./$(PRODUCT_OUT)/system + ./$(PRODUCT_OUT)/system \ + ./$(PRODUCT_OUT)/dex_bootjars + +# TODO: move the dex-preopt files to a product-specific directory +installclean_files += ./$(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/*/javalib.jar # The files/dirs to delete during a dataclean, which removes any files # in the staging and emulator data partitions. diff --git a/core/clear_vars.mk b/core/clear_vars.mk index c046c69f9..968136451 100644 --- a/core/clear_vars.mk +++ b/core/clear_vars.mk @@ -97,6 +97,7 @@ LOCAL_PROGUARD_FLAGS:= LOCAL_EMMA_COVERAGE_FILTER:= LOCAL_MANIFEST_FILE:= LOCAL_BUILD_HOST_DEX:= +LOCAL_DEX_PREOPT:= # Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to # iterate over thousands of entries every time. diff --git a/core/config.mk b/core/config.mk index 897af8357..a3bcbf1ea 100644 --- a/core/config.mk +++ b/core/config.mk @@ -215,6 +215,8 @@ E2FSCK := e2fsck JARJAR := $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar PROGUARD := external/proguard/bin/proguard.sh JAVATAGS := build/tools/java-event-log-tags.py +DEXOPT := $(HOST_OUT_EXECUTABLES)/dexopt$(HOST_EXECUTABLE_SUFFIX) +DEXPREOPT := dalvik/tools/dex-preopt # ACP is always for the build OS, not for the host OS ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX) diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk new file mode 100644 index 000000000..b0364439a --- /dev/null +++ b/core/dex_preopt.mk @@ -0,0 +1,73 @@ +#################################### +# Dexpreopt on the boot jars +# +#################################### + +# TODO: replace it with device's BOOTCLASSPATH +DEXPREOPT_BOOT_JARS := core:bouncycastle:ext:framework:android.policy:services:core-junit +DEXPREOPT_BOOT_JARS_MODULES := $(subst :, ,$(DEXPREOPT_BOOT_JARS)) + +DEXPREOPT_BUILD_DIR := $(OUT_DIR) +DEXPREOPT_PRODUCT_DIR := $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(PRODUCT_OUT))/dex_bootjars +DEXPREOPT_BOOT_JAR_DIR := system/framework +DEXPREOPT_DEXOPT := $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(DEXOPT)) + +DEXPREOPT_BOOT_JAR_DIR_FULL_PATH := $(DEXPREOPT_BUILD_DIR)/$(DEXPREOPT_PRODUCT_DIR)/$(DEXPREOPT_BOOT_JAR_DIR) + +DEXPREOPT_BOOT_ODEXS := $(foreach b,$(DEXPREOPT_BOOT_JARS_MODULES),\ + $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(b).odex) + +# $(1): the .jar or .apk to remove classes.dex +define dexpreopt-remove-classes.dex +$(hide) $(AAPT) remove $(1) classes.dex +endef + +# $(1): the input .jar or .apk file +# $(2): the output .odex file +define dexpreopt-one-file +$(hide) $(DEXPREOPT) --dexopt=$(DEXPREOPT_DEXOPT) --build-dir=$(DEXPREOPT_BUILD_DIR) \ + --product-dir=$(DEXPREOPT_PRODUCT_DIR) --boot-dir=$(DEXPREOPT_BOOT_JAR_DIR) \ + --boot-jars=$(DEXPREOPT_BOOT_JARS) \ + $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(1)) \ + $(patsubst $(DEXPREOPT_BUILD_DIR)/%,%,$(2)) +endef + +# $(1): boot jar module name +define _dexpreopt-boot-jar +$(eval _dbj_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1).jar) +$(eval _dbj_odex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1).odex) +$(eval _dbj_jar_no_dex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(1)_nodex.jar) +$(eval _dbj_src_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,$(1),,COMMON)/javalib.dex.jar) +$(eval $(_dbj_odex): PRIVATE_DBJ_JAR := $(_dbj_jar)) +$(_dbj_odex) : $(_dbj_src_jar) | $(ACP) $(DEXPREOPT) $(DEXOPT) + @echo "Dexpreopt Boot Jar: $$@" + $(hide) rm -f $$@ + $(hide) mkdir -p $$(dir $$@) + $(hide) $(ACP) -fpt $$< $$(PRIVATE_DBJ_JAR) + $$(call dexpreopt-one-file,$$(PRIVATE_DBJ_JAR),$$@) + +$(_dbj_jar_no_dex) : $(_dbj_src_jar) | $(ACP) $(AAPT) + $$(call copy-file-to-target) + $$(call dexpreopt-remove-classes.dex,$$@) + +$(eval _dbj_jar :=) +$(eval _dbj_odex :=) +$(eval _dbj_src_jar :=) +endef + +$(foreach b,$(DEXPREOPT_BOOT_JARS_MODULES),$(eval $(call _dexpreopt-boot-jar,$(b)))) + +# $(1): the rest list of boot jars +define _build-dexpreopt-boot-jar-dependency-pair +$(if $(filter 1,$(words $(1)))$(filter 0,$(words $(1))),,\ + $(eval _bdbjdp_target := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(word 2,$(1)).odex) \ + $(eval _bdbjdp_dep := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(word 1,$(1)).odex) \ + $(eval $(call add-dependency,$(_bdbjdp_target),$(_bdbjdp_dep))) \ + $(eval $(call _build-dexpreopt-boot-jar-dependency-pair,$(wordlist 2,999,$(1))))) +endef + +define _build-dexpreopt-boot-jar-dependency +$(call _build-dexpreopt-boot-jar-dependency-pair,$(DEXPREOPT_BOOT_JARS_MODULES)) +endef + +$(eval $(call _build-dexpreopt-boot-jar-dependency)) diff --git a/core/java_library.mk b/core/java_library.mk index a33bf2eca..3e670a94a 100644 --- a/core/java_library.mk +++ b/core/java_library.mk @@ -23,6 +23,14 @@ all_res_assets := LOCAL_BUILT_MODULE_STEM := javalib.jar +ifndef LOCAL_IS_HOST_MODULE +ifeq (true,$(WITH_DEXPREOPT)) +ifndef LOCAL_DEX_PREOPT +LOCAL_DEX_PREOPT := true +endif +endif +endif + ################################# include $(BUILD_SYSTEM)/java.mk ################################# @@ -35,8 +43,10 @@ $(LOCAL_BUILT_MODULE): $(full_classes_jar) else # !LOCAL_IS_STATIC_JAVA_LIBRARY -$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex) -$(LOCAL_BUILT_MODULE): $(built_dex) $(java_resource_sources) | $(AAPT) +ifeq ($(LOCAL_DEX_PREOPT),true) +jar_with_dex := $(intermediates.COMMON)/javalib.dex.jar +$(jar_with_dex): PRIVATE_DEX_FILE := $(built_dex) +$(jar_with_dex) : $(built_dex) $(java_resource_sources) | $(AAPT) @echo "target Jar: $(PRIVATE_MODULE) ($@)" $(create-empty-package) $(add-dex-to-package) @@ -44,4 +54,43 @@ ifneq ($(extra_jar_args),) $(add-java-resources-to-package) endif +dexpreopt_boot_jar_module := $(filter $(LOCAL_MODULE),$(DEXPREOPT_BOOT_JARS_MODULES)) +ifneq ($(dexpreopt_boot_jar_module),) +# boot jar's rules are defined in dex_preopt.mk +dexpreopted_boot_jar := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module)_nodex.jar +$(LOCAL_BUILT_MODULE) : $(dexpreopted_boot_jar) | $(ACP) + $(call copy-file-to-target) + +dexpreopted_boot_odex := $(DEXPREOPT_BOOT_JAR_DIR_FULL_PATH)/$(dexpreopt_boot_jar_module).odex +built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex +$(built_odex) : $(dexpreopted_boot_odex) | $(ACP) + $(call copy-file-to-target) + +else # dexpreopt_boot_jar_module +built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex +$(built_odex): PRIVATE_MODULE := $(LOCAL_MODULE) +# Make sure the boot jars get dex-preopt-ed first +$(built_odex) : $(DEXPREOPT_BOOT_ODEXS) +$(built_odex) : $(jar_with_dex) | $(DEXPREOPT) $(DEXOPT) + @echo "Dexpreopt Jar: $(PRIVATE_MODULE) ($@)" + $(hide) rm -f $@ + $(call dexpreopt-one-file,$<,$@) + +$(LOCAL_BUILT_MODULE) : $(jar_with_dex) | $(ACP) $(AAPT) + $(call copy-file-to-target) + $(call dexpreopt-remove-classes.dex,$@) + +endif # dexpreopt_boot_jar_module + +else # LOCAL_DEX_PREOPT +$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex) +$(LOCAL_BUILT_MODULE) : $(built_dex) $(java_resource_sources) | $(AAPT) + @echo "target Jar: $(PRIVATE_MODULE) ($@)" + $(create-empty-package) + $(add-dex-to-package) +ifneq ($(extra_jar_args),) + $(add-java-resources-to-package) +endif +endif # LOCAL_DEX_PREOPT + endif # !LOCAL_IS_STATIC_JAVA_LIBRARY diff --git a/core/main.mk b/core/main.mk index be74e3889..8a70489a3 100644 --- a/core/main.mk +++ b/core/main.mk @@ -157,6 +157,9 @@ INTERNAL_MODIFIER_TARGETS := showcommands checkbuild # Bring in standard build system definitions. include $(BUILD_SYSTEM)/definitions.mk +# Bring in dex_preopt.mk +include $(BUILD_SYSTEM)/dex_preopt.mk + ifneq ($(filter eng user userdebug tests,$(MAKECMDGOALS)),) $(info ***************************************************************) $(info ***************************************************************) diff --git a/core/package.mk b/core/package.mk index 8254bae9d..683499551 100644 --- a/core/package.mk +++ b/core/package.mk @@ -154,6 +154,14 @@ endif # all_resources endif # !custom LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS) +ifeq (true,$(WITH_DEXPREOPT)) +ifneq (,$(LOCAL_SRC_FILES)) +ifndef LOCAL_DEX_PREOPT +LOCAL_DEX_PREOPT := true +endif +endif +endif + # The dex files go in the package, so we don't # want to install them separately for this module. old_DONT_INSTALL_DEX_FILES := $(DONT_INSTALL_DEX_FILES) @@ -314,6 +322,10 @@ PACKAGES.$(LOCAL_PACKAGE_NAME).CERTIFICATE := $(certificate) # Define the rule to build the actual package. $(LOCAL_BUILT_MODULE): $(AAPT) | $(ZIPALIGN) +ifeq ($(LOCAL_DEX_PREOPT),true) +# Make sure the boot jars get dexpreopt-ed first +$(LOCAL_BUILT_MODULE): $(DEXPREOPT_BOOT_ODEXS) | $(DEXPREOPT) $(DEXOPT) +endif $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries) ifneq ($(TARGET_BUILD_APPS),) # Include all resources for unbundled apps. @@ -332,6 +344,14 @@ endif $(sign-package) @# Alignment must happen after all other zip operations. $(align-package) +ifeq ($(LOCAL_DEX_PREOPT),true) + $(hide) rm -f $(patsubst %.apk,%.odex,$@) + $(call dexpreopt-one-file,$@,$(patsubst %.apk,%.odex,$@)) + $(call dexpreopt-remove-classes.dex,$@) + +built_odex := $(basename $(LOCAL_BUILT_MODULE)).odex +$(built_odex): $(LOCAL_BUILT_MODULE) +endif # Save information about this package PACKAGES.$(LOCAL_PACKAGE_NAME).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))