From 3b2bdf10338fb048fc749ce9f65a77f917f7d304 Mon Sep 17 00:00:00 2001 From: Ying Wang Date: Mon, 1 Feb 2010 09:51:23 -0800 Subject: [PATCH] Fix and enable proguard on packages. --- core/base_rules.mk | 3 ++- core/definitions.mk | 32 ++++++++++++++++++++++++- core/java.mk | 46 +++++++++++++++++++++++------------- core/package.mk | 13 +++++++---- core/proguard.flags | 49 ++++++++++++++++++++++++++++++++++++++- core/proguard_tests.flags | 21 +++++++++++++++++ 6 files changed, 141 insertions(+), 23 deletions(-) create mode 100644 core/proguard_tests.flags diff --git a/core/base_rules.mk b/core/base_rules.mk index 8598e7ea5..a2acb01d9 100644 --- a/core/base_rules.mk +++ b/core/base_rules.mk @@ -351,7 +351,8 @@ ifdef LOCAL_INSTRUMENTATION_FOR link_instr_intermediates_dir.COMMON := $(call intermediates-dir-for, \ APPS,$(LOCAL_INSTRUMENTATION_FOR),,COMMON) - full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes.jar + # link against the jar with full original names (before proguard processing). + full_java_libs += $(link_instr_intermediates_dir.COMMON)/classes-full-names.jar # We can't depend on the .jar file, so we depend on something that # depends on the jar file; the final built package file. diff --git a/core/definitions.mk b/core/definitions.mk index e8d05ac1d..b9845f8fe 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -1579,7 +1579,6 @@ define transform-prebuilt-to-target-strip-comments $(copy-file-to-target-strip-comments) endef - ########################################################### ## On some platforms (MacOS), after copying a static ## library, ranlib must be run to update an internal @@ -1607,6 +1606,37 @@ endef endif +########################################################### +## Commands to call Proguard +########################################################### + +# Command to copy the file with acp, if proguard is disabled. +define proguard-disabled-commands +@echo Copying: $@ +$(hide) $(ACP) $< $@ +endef + +# Command to call Proguard +# $(1): extra flags for instrumentation. +define proguard-enabled-commands +@echo Proguard: $@ +$(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS) $(1) +endef + +# Figure out the proguard dictionary file of the module that is instrumentationed for. +define get-instrumentation-proguard-flags +$(if $(PRIVATE_INSTRUMENTATION_FOR),$(if $(ALL_MODULES.$(PRIVATE_INSTRUMENTATION_FOR).PROGUARD_ENABLED),-applymapping $(call intermediates-dir-for,APPS,$(PRIVATE_INSTRUMENTATION_FOR),,COMMON)/proguard_dictionary)) +endef + +define transform-jar-to-proguard +$(eval _instrumentation_proguard_flags:=$(call get-instrumentation-proguard-flags)) +$(eval _enable_proguard:=$(PRIVATE_PROGUARD_ENABLED)$(_instrumentation_proguard_flags)) +$(if $(_enable_proguard),$(call proguard-enabled-commands,$(_instrumentation_proguard_flags)),$(call proguard-disabled-commands)) +$(eval _instrumentation_proguard_flags:=) +$(eval _enable_proguard:=) +endef + + ########################################################### ## Stuff source generated from one-off tools ########################################################### diff --git a/core/java.mk b/core/java.mk index 65c4c8a16..d57ffca9c 100644 --- a/core/java.mk +++ b/core/java.mk @@ -70,6 +70,7 @@ emma_intermediates_dir := $(intermediates.COMMON)/emma_out full_classes_emma_jar := $(emma_intermediates_dir)/lib/$(full_classes_compiled_jar_leaf) full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar full_classes_jarjar_jar := $(intermediates.COMMON)/classes-jarjar.jar +full_classes_full_names_jar := $(intermediates.COMMON)/classes-full-names.jar full_classes_proguard_jar := $(full_classes_jar) built_dex := $(intermediates.COMMON)/classes.dex @@ -193,39 +194,52 @@ $(full_classes_jarjar_jar): $(full_classes_emma_jar) | $(ACP) $(hide) $(ACP) $< $@ endif +# Keep a copy of the jar just before proguard processing. +$(full_classes_full_names_jar): $(full_classes_emma_jar) | $(ACP) + @echo Copying: $@ + $(hide) $(ACP) $< $@ + # Run proguard if necessary, otherwise just copy the file. This is the last # part of this step, so the output of this command is full_classes_jar. -ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),) proguard_dictionary := $(intermediates.COMMON)/proguard_dictionary -proguard_flags := $(addprefix -libraryjars ,$(full_java_libs)) \ +# Proguard doesn't like a class in both library and the jar to be processed. +proguard_full_java_libs := $(filter-out $(full_static_java_libs),$(full_java_libs)) +proguard_flags := $(addprefix -libraryjars ,$(proguard_full_java_libs)) \ -include $(BUILD_SYSTEM)/proguard.flags \ -forceprocessing \ -printmapping $(proguard_dictionary) -ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),full) +# If this is a test package, add proguard keep flags for tests. +ifneq ($(strip $(LOCAL_INSTRUMENTATION_FOR)$(filter tests,$(LOCAL_MODULE_TAGS))$(filter android.test.runner,$(LOCAL_JAVA_LIBRARIES))),) +proguard_flags := $(proguard_flags) -include $(BUILD_SYSTEM)/proguard_tests.flags +endif # test package + +LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED)) +ifneq ($(LOCAL_PROGUARD_ENABLED),) +ifeq ($(LOCAL_PROGUARD_ENABLED),full) # full else -ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),optonly) +ifeq ($(LOCAL_PROGUARD_ENABLED),optonly) # optonly proguard_flags += -dontobfuscate else -ifeq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom) +ifeq ($(LOCAL_PROGUARD_ENABLED),custom) # custom else $(warning while processing: $(LOCAL_MODULE)) $(error invalid value for LOCAL_PROGUARD_ENABLED: $(LOCAL_PROGUARD_ENABLED)) -endif -endif -endif +endif # custom +endif # optonly +endif # full +endif # LOCAL_PROGUARD_ENABLED +$(full_classes_proguard_jar): PRIVATE_PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED) $(full_classes_proguard_jar): PRIVATE_PROGUARD_FLAGS := $(proguard_flags) $(LOCAL_PROGUARD_FLAGS) -$(full_classes_proguard_jar): $(full_classes_emma_jar) | $(PROGUARD) - @echo Proguard: $@ - $(hide) $(PROGUARD) -injars $< -outjars $@ $(PRIVATE_PROGUARD_FLAGS) -else -$(full_classes_proguard_jar): $(full_classes_emma_jar) | $(ACP) - @echo Copying: $@ - $(hide) $(ACP) $< $@ -endif +$(full_classes_proguard_jar): PRIVATE_INSTRUMENTATION_FOR:=$(strip $(LOCAL_INSTRUMENTATION_FOR)) + +$(full_classes_proguard_jar): $(full_classes_full_names_jar) | $(ACP) $(PROGUARD) + $(call transform-jar-to-proguard) + +ALL_MODULES.$(LOCAL_MODULE).PROGUARD_ENABLED:=$(LOCAL_PROGUARD_ENABLED) # Override PRIVATE_INTERMEDIATES_DIR so that install-dex-debug # will work even when intermediates != intermediates.COMMON. diff --git a/core/package.mk b/core/package.mk index 388435a5b..07bb3f9ad 100644 --- a/core/package.mk +++ b/core/package.mk @@ -126,10 +126,15 @@ endif LOCAL_BUILT_MODULE_STEM := package.apk -proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options -ifneq ($(strip $(LOCAL_PROGUARD_ENABLED)),custom) - LOCAL_PROGUARD_FLAGS := -include $(proguard_options_file) $(LOCAL_PROGUARD_FLAGS) -endif +LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED)) + +proguard_options_file := +ifneq ($(LOCAL_PROGUARD_ENABLED),custom) +ifneq ($(all_resources),) + proguard_options_file := -include $(package_expected_intermediates_COMMON)/proguard_options +endif # all_resources +endif # !custom +LOCAL_PROGUARD_FLAGS := $(proguard_options_file) $(LOCAL_PROGUARD_FLAGS) # The dex files go in the package, so we don't # want to install them separately for this module. diff --git a/core/proguard.flags b/core/proguard.flags index afd154879..3544b9003 100644 --- a/core/proguard.flags +++ b/core/proguard.flags @@ -1,7 +1,54 @@ # see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707 -optimizations !code/simplification/arithmetic +-optimizations !code/simplification/cast -allowaccessmodification +# To prevent name conflict in incremental obfuscation. +-useuniqueclassmembernames + +# dex does not like code run through proguard optimize and preverify steps. +-dontoptimize +-dontpreverify + +# Don't obfuscate. We only need dead code striping. +-dontobfuscate + +# Add this flag in your package's own configuration if it's needed. +#-flattenpackagehierarchy + # Some classes in the libraries extend package private classes to chare common functionality # that isn't explicitly part of the API --dontskipnonpubliclibraryclasses +-dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers + +# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native +-keepclasseswithmembernames class * { + native ; +} + +# class$ methods are inserted by some compilers to implement .class construct, +# see http://proguard.sourceforge.net/manual/examples.html#library +-keepclassmembernames class * { + java.lang.Class class$(java.lang.String); + java.lang.Class class$(java.lang.String, boolean); +} + +# Please specify classes to be kept explicitly in your package's configuration. +# -keep class * extends android.app.Activity +# -keep class * extends android.view.View +# -keep class * extends android.app.Service +# -keep class * extends android.content.BroadcastReceiver +# -keep class * extends android.content.ContentProvider +# -keep class * extends android.preference.Preference +# -keep class * extends android.app.BackupAgent + +#-keep class * implements android.os.Parcelable { +# public static final android.os.Parcelable$Creator *; +#} + + diff --git a/core/proguard_tests.flags b/core/proguard_tests.flags new file mode 100644 index 000000000..f4063d668 --- /dev/null +++ b/core/proguard_tests.flags @@ -0,0 +1,21 @@ +# Keep everything for tests +-dontshrink -dontobfuscate + +#-keep class * extends junit.framework.TestCase { +# public void test*(); +#} + +#-keepclasseswithmembers class * { +# public static void run(); +# public static junit.framework.Test suite(); +#} + +# some AllTests don't include run(). +#-keepclasseswithmembers class * { +# public static junit.framework.Test suite(); +#} + +#-keep class * extends junit.framework.TestSuite +#-keep class * extends android.app.Instrumentation +#-keep class * extends android.test.TestSuiteProvider +