From b8d28049fdedf1e6f2a14c1d17143560c133c737 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Wed, 24 Jan 2018 22:09:48 -0800 Subject: [PATCH] Bug 1433285: Extract classes*.dex from .ap_ --with-gradle. r=gps,snorp Right now, we only expect classes.dex, and even --with-gradle we copy it out of $topobjdir/mobile/android/base. This commit changes that for --with-gradle: we only take classes.dex from the given .ap_ file, and we also handle multiple classesN.dex files (for future multi-dex support). The moz.build system stays the same. This avoids an issue with newer Android-Gradle plugins, where the classes.dex produced could be either in dex/ or in dexMerger/, depending on whether any external libraries needed merging. By extracting classes.dex from the .ap_ file, we don't need to know what Gradle build steps actually occur. The classes.dex in the package-manifest.in has been irrelevant since Bug 1260241. MozReview-Commit-ID: FozKwjTcMzU --HG-- extra : rebase_source : 62b18c7ffe596be73cec4c9565333eac222b018e --- mobile/android/base/Makefile.in | 9 ++---- mobile/android/installer/package-manifest.in | 1 - .../mozbuild/action/package_fennec_apk.py | 31 +++++++++++++++++-- toolkit/mozapps/installer/upload-files-APK.mk | 4 +-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 289a897efbf6..07fa2925e399 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -252,17 +252,13 @@ endef # .gradle.deps: .aapt.deps FORCE $(eval $(call gradle_command,.gradle.deps,.aapt.deps FORCE)) -classes.dex: .gradle.deps - $(REPORT_BUILD) - cp $(gradle_dir)/app/intermediates/transforms/dex/officialPhoton/debug/folders/1000/1f/main/classes.dex $@ - GeneratedJNIWrappers.cpp GeneratedJNIWrappers.h GeneratedJNINatives.h : .gradle.deps $(REPORT_BUILD) FennecJNIWrappers.cpp FennecJNIWrappers.h FennecJNINatives.h: .gradle.deps $(REPORT_BUILD) -else +else # !MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE classes.dex: .proguard.deps $(REPORT_BUILD) $(DX) --dex --output=classes.dex --force-jumbo jars-proguarded @@ -501,7 +497,6 @@ $(eval $(call gradle_command,.gradle.nodeps,AndroidManifest.xml $(constants_PP_J .aapt.nodeps: .gradle.nodeps FORCE @$(TOUCH) $@ cp $(GRADLE_ANDROID_APP_APK) gecko-nodeps.ap_ - cp $(gradle_dir)/app/intermediates/transforms/dex/officialPhoton/debug/folders/1000/1f/main/classes.dex classes.dex else # .aapt.nodeps: AndroidManifest.xml FORCE $(eval $(call aapt_command,.aapt.nodeps,AndroidManifest.xml FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/)) @@ -617,8 +612,10 @@ libs:: FennecJNIWrappers.cpp echo '*****************************************************' && \ exit 1) +ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE libs:: classes.dex $(INSTALL) classes.dex $(FINAL_TARGET) +endif # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index 01c8bc32408d..eda9ee60b95c 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -81,7 +81,6 @@ [xpcom] @BINPATH@/package-name.txt -@BINPATH@/classes.dex [browser] ; [Base Browser Files] diff --git a/python/mozbuild/mozbuild/action/package_fennec_apk.py b/python/mozbuild/mozbuild/action/package_fennec_apk.py index 40b8c032bb2e..dc6a9fe3aff9 100644 --- a/python/mozbuild/mozbuild/action/package_fennec_apk.py +++ b/python/mozbuild/mozbuild/action/package_fennec_apk.py @@ -33,11 +33,34 @@ def package_fennec_apk(inputs=[], omni_ja=None, classes_dex=None, jarrer = Jarrer(optimize=False) # First, take input files. The contents of the later files overwrites the - # content of earlier files. + # content of earlier files. Multidexing requires special care: we want a + # coherent set of classesN.dex files, so we only take DEX files from a + # single input. This avoids taking, say, classes{1,2,3}.dex from the first + # input and only classes{1,2}.dex from the second input, leading to + # (potentially) duplicated symbols at runtime. + last_input_with_dex_files = None for input in inputs: jar = JarReader(input) for file in jar: path = file.filename + + if mozpath.match(path, '/classes*.dex'): + last_input_with_dex_files = input + continue + + if jarrer.contains(path): + jarrer.remove(path) + jarrer.add(path, DeflatedFile(file), compress=file.compressed) + + # If we have an input with DEX files, take them all here. + if last_input_with_dex_files: + jar = JarReader(last_input_with_dex_files) + for file in jar: + path = file.filename + + if not mozpath.match(path, '/classes*.dex'): + continue + if jarrer.contains(path): jarrer.remove(path) jarrer.add(path, DeflatedFile(file), compress=file.compressed) @@ -115,6 +138,10 @@ def package_fennec_apk(inputs=[], omni_ja=None, classes_dex=None, add(mozpath.join('assets', 'omni.ja'), File(omni_ja), compress=False) if classes_dex: + if buildconfig.substs.get('MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE'): + raise ValueError("Fennec APKs built --with-gradle " + "should never specify classes.dex") + add('classes.dex', File(classes_dex)) return jarrer @@ -143,7 +170,7 @@ def main(args): args = parser.parse_args(args) if buildconfig.substs.get('OMNIJAR_NAME') != 'assets/omni.ja': - raise ValueError("Don't know how package Fennec APKs when " + raise ValueError("Don't know how to package Fennec APKs when " " OMNIJAR_NAME is not 'assets/omni.jar'.") jarrer = package_fennec_apk(inputs=args.inputs, diff --git a/toolkit/mozapps/installer/upload-files-APK.mk b/toolkit/mozapps/installer/upload-files-APK.mk index 34a11e6d943c..074bf8440939 100644 --- a/toolkit/mozapps/installer/upload-files-APK.mk +++ b/toolkit/mozapps/installer/upload-files-APK.mk @@ -71,7 +71,7 @@ INNER_FENNEC_PACKAGE = \ --inputs \ $(GECKO_APP_AP_PATH)/gecko-nodeps.ap_ \ --omnijar $(MOZ_PKG_DIR)/$(OMNIJAR_NAME) \ - --classes-dex $(GECKO_APP_AP_PATH)/classes.dex \ + $(if $(MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE),,--classes-dex $(GECKO_APP_AP_PATH)/classes.dex) \ --lib-dirs $(MOZ_PKG_DIR)/lib \ --assets-dirs $(MOZ_PKG_DIR)/assets \ --features-dirs $(MOZ_PKG_DIR)/features \ @@ -94,7 +94,7 @@ repackage_fennec = \ $(UNPACKAGE) \ $(GECKO_APP_AP_PATH)/gecko-nodeps.ap_ \ --omnijar $(MOZ_PKG_DIR)/$(OMNIJAR_NAME) \ - --classes-dex $(GECKO_APP_AP_PATH)/classes.dex \ + $(if $(MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE),,--classes-dex $(GECKO_APP_AP_PATH)/classes.dex) \ --output $(PACKAGE:.apk=-unsigned-unaligned.apk) && \ $(call RELEASE_SIGN_ANDROID_APK,$(PACKAGE:.apk=-unsigned-unaligned.apk),$(PACKAGE))