Bug 1384312 - Support generating JNI wrappers under --with-gradle, r=nalexander draft
authormaliu <max@mxli.us>
Wed, 11 Oct 2017 15:37:40 -0700
changeset 680393 5ce8c3d6c077362b1c4f172edcc3ca2981110fb6
parent 678819 2b7b1e97d89c2944886871ec09db7606687ccda3
child 735844 ba2ba65de2c8e32c97a673971258b3609fb93349
push id84491
push userbmo:max@mxli.us
push dateFri, 13 Oct 2017 23:47:00 +0000
reviewersnalexander
bugs1384312
milestone58.0a1
Bug 1384312 - Support generating JNI wrappers under --with-gradle, r=nalexander MozReview-Commit-ID: HECL60Ggeqn
mobile/android/app/build.gradle
mobile/android/base/Makefile.in
mobile/android/geckoview/build.gradle
mobile/android/gradle/with_gecko_binaries.gradle
--- a/mobile/android/app/build.gradle
+++ b/mobile/android/app/build.gradle
@@ -350,16 +350,20 @@ android.applicationVariants.all { varian
 
     // :app uses :geckoview:release and handles it's own Gecko binary inclusion,
     // even though this would be most naturally done in the :geckoview project.
     if (!audienceDimension.equals('official')) {
         configureVariantWithGeckoBinaries(variant)
     }
 }
 
+android.applicationVariants.all { variant ->
+    configureVariantWithJNIWrappers(variant, "Fennec")
+}
+
 apply plugin: 'spoon'
 
 spoon {
     // For now, let's be verbose.
     debug = true
     // It's not helpful to pass when we don't have a device connected.
     failIfNoDeviceConnected = true
 
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -20,16 +20,18 @@ GARBAGE += \
   GeneratedJNIWrappers.h \
   FennecJNINatives.h \
   FennecJNIWrappers.cpp \
   FennecJNIWrappers.h \
   $(NULL)
 
 GARBAGE_DIRS += classes db jars res sync services generated
 
+gradle_dir := $(topobjdir)/gradle/build/mobile/android
+
 # The bootclasspath is functionally identical to the classpath, but allows the
 # classes given to redefine classes in core packages, such as java.lang.
 # android.jar is here as it provides Android's definition of the Java Standard
 # Library. The compatability lib here tweaks a few of the core classes to paint
 # over changes in behaviour between versions.
 JAVA_BOOTCLASSPATH := \
     $(ANDROID_SDK)/android.jar \
     $(NULL)
@@ -136,16 +138,17 @@ endif
 # java_bundled_libs.  See the note above.
 
 # uniq purloined from http://stackoverflow.com/a/16151140.
 uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
 
 java_bundled_libs := $(call uniq,$(java_bundled_libs))
 java_bundled_libs := $(subst $(NULL) ,:,$(strip $(java_bundled_libs)))
 
+ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
 GECKOVIEW_JARS = \
   constants.jar \
   gecko-R.jar \
   gecko-mozglue.jar \
   gecko-util.jar \
   gecko-view.jar \
   sync-thirdparty.jar \
   $(NULL)
@@ -161,32 +164,41 @@ endif
 ifdef MOZ_INSTALL_TRACKING
 GECKOVIEW_JARS += gecko-thirdparty-adjust_sdk.jar
 endif
 
 ifdef MOZ_ANDROID_MMA
 GECKOVIEW_JARS += gecko-thirdparty-leanplum_sdk.jar
 endif
 
-geckoview_jars_classpath := $(subst $(NULL) ,:,$(strip $(GECKOVIEW_JARS)))
-
 FENNEC_JARS = \
   gecko-browser.jar \
   gecko-thirdparty.jar \
   services.jar \
   $(NULL)
 
 ifdef MOZ_ANDROID_SEARCH_ACTIVITY
 FENNEC_JARS += search-activity.jar
 endif
 
 ifdef MOZ_ANDROID_MLS_STUMBLER
 FENNEC_JARS += ../stumbler/stumbler.jar
 endif
 
+else # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+
+GECKOVIEW_JARS := $(gradle_dir)/geckoview/intermediates/bundles/debug/classes.jar
+FENNEC_JARS := $(gradle_dir)/app/intermediates/packaged/officialPhoton/debug/classes.jar
+
+$(GECKOVIEW_JARS): .gradle.deps
+$(FENNEC_JARS): .gradle.deps
+
+endif # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+
+geckoview_jars_classpath := $(subst $(NULL) ,:,$(strip $(GECKOVIEW_JARS)))
 
 # All the jars we're compiling from source. (not to be confused with
 # java_bundled_libs, which holds the jars which we're including as binaries).
 ALL_JARS = \
   $(GECKOVIEW_JARS) \
   $(FENNEC_JARS) \
   $(NULL)
 
@@ -223,32 +235,40 @@ library_jars := \
 # MOZ_ANDROID_MMA requires MOZ_INSTALL_TRACKING, so we don't need a
 # separate clause for MMA (Leanplum) support.
 ifdef MOZ_INSTALL_TRACKING
 library_jars += $(ANDROID_SDK)/optional/org.apache.http.legacy.jar
 endif # MOZ_INSTALL_TRACKING
 
 library_jars := $(subst $(NULL) ,:,$(strip $(library_jars)))
 
-gradle_dir := $(topobjdir)/gradle/build/mobile/android
-
 ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
 .gradle.deps: .aapt.deps FORCE
 	@$(TOUCH) $@
 	$(topsrcdir)/mach gradle \
-		app:assembleOfficialPhotonDebug app:assembleOfficialPhotonDebugAndroidTest -x lint
+		geckoview:generateJNIWrappersForGeneratedRelease \
+		app:generateJNIWrappersForFennecOfficialPhotonDebug \
+		app:assembleOfficialPhotonDebug \
+		app:assembleOfficialPhotonDebugAndroidTest \
+		-x lint
 
 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
 classes.dex: .proguard.deps
 	$(REPORT_BUILD)
 	$(DX) --dex --output=classes.dex --force-jumbo jars-proguarded
-endif
 
 ifdef MOZ_DISABLE_PROGUARD
   PROGUARD_PASSES=0
 else
   ifdef MOZ_DEBUG
     PROGUARD_PASSES=1
   else
     ifndef MOZILLA_OFFICIAL
@@ -323,16 +343,18 @@ GeneratedJNIWrappers.cpp: $(ANNOTATION_P
 
 # This annotation processing step also generates
 # FennecJNIWrappers.h and FennecJNINatives.h
 FennecJNIWrappers.cpp: $(ANNOTATION_PROCESSOR_JAR_FILES) $(FENNEC_JARS)
 	$(JAVA) -classpath $(all_jars_classpath):$(JAVA_BOOTCLASSPATH):$(JAVA_CLASSPATH):$(ANNOTATION_PROCESSOR_JAR_FILES) \
 		org.mozilla.gecko.annotationProcessors.AnnotationProcessor \
 		Fennec $(FENNEC_JARS)
 
+endif # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+
 include $(topsrcdir)/config/rules.mk
 
 not_android_res_files := \
   *.mkdir.done* \
   *.DS_Store* \
   *\#* \
   *.rej \
   *.orig \
@@ -531,17 +553,16 @@ gradle-omnijar:
 endif
 
 .PHONY: gradle-targets gradle-omnijar
 
 # GeneratedJNIWrappers.cpp target also generates
 #   GeneratedJNIWrappers.h and GeneratedJNINatives.h
 # FennecJNIWrappers.cpp target also generates
 #   FennecJNIWrappers.h and FennecJNINatives.h
-ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
 
 # List of build flags used by auto-generated JNI bindings (through the
 # @BuildFlag annotation in Java). For example, add a "MOZ_FOO \" line to this
 # list to support @BuildFlag(MOZ_FOO).
 BINDING_BUILD_FLAGS = \
   $(NULL)
 
 # Preprocess a JNI binding file using the build flags defined above.
@@ -581,21 +602,22 @@ libs:: FennecJNIWrappers.cpp
 	  echo '***     Error: The Fennec JNI code has changed    ***' && \
 	  echo '* To update generated code in the tree, please run  *' && \
 	  echo && \
 	  echo '  make -C $(CURDIR) update-fennec-wrappers' && \
 	  echo && \
 	  echo '* Repeat the build, and check in any changes.       *' && \
 	  echo '*****************************************************' && \
 	  exit 1)
-endif
 
 libs:: classes.dex
 	$(INSTALL) classes.dex $(FINAL_TARGET)
 
+ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+
 # Generate Java binder interfaces from AIDL files.
 GECKOVIEW_AIDLS = \
   org/mozilla/gecko/IGeckoEditableChild.aidl \
   org/mozilla/gecko/IGeckoEditableParent.aidl \
   org/mozilla/gecko/gfx/ISurfaceAllocator.aidl \
   org/mozilla/gecko/media/ICodec.aidl \
   org/mozilla/gecko/media/ICodecCallbacks.aidl \
   org/mozilla/gecko/media/IMediaDrmBridge.aidl \
@@ -618,8 +640,10 @@ FENNEC_AIDLS = \
 
 fennec_aidl_src_path := $(srcdir)/aidl
 fennec_aidl_target_path := generated
 fennec_aidl_targets := $(addprefix $(fennec_aidl_target_path)/,$(patsubst %.aidl,%.java,$(FENNEC_AIDLS:.java=)))
 
 $(fennec_aidl_targets): $(fennec_aidl_target_path)/%.java: $(fennec_aidl_src_path)/%.aidl
 	@echo "Processing AIDL: $< => $@"
 	$(AIDL) -p$(ANDROID_SDK)/framework.aidl -I$(fennec_aidl_src_path) -I$(geckoview_aidl_src_path) -o$(fennec_aidl_target_path) $<
+
+endif # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
--- a/mobile/android/geckoview/build.gradle
+++ b/mobile/android/geckoview/build.gradle
@@ -162,16 +162,20 @@ android.libraryVariants.all { variant ->
     task "sourcesJar${name.capitalize()}"(type: Jar) {
         classifier 'sources'
         description = "Generate Javadoc for build variant $name"
         destinationDir = new File(destinationDir, variant.baseName)
         from files(variant.javaCompile.source)
     }
 }
 
+android.libraryVariants.all { variant ->
+    configureVariantWithJNIWrappers(variant, "Generated")
+}
+
 apply plugin: 'maven'
  
 uploadArchives {
     repositories.mavenDeployer {
         pom.groupId = 'org.mozilla'
         pom.artifactId = 'geckoview'
         pom.version = VERSION_NAME
         pom.project {
--- a/mobile/android/gradle/with_gecko_binaries.gradle
+++ b/mobile/android/gradle/with_gecko_binaries.gradle
@@ -120,8 +120,38 @@ ext.configureVariantWithGeckoBinaries = 
     generateAssetsTask.dependsOn syncLibsFromDistDir
     generateAssetsTask.dependsOn syncAssetsFromDistDir
 
     def sourceSet = productFlavor ? "${productFlavor}${buildType.capitalize()}" : buildType
     android.sourceSets."${sourceSet}".assets.srcDir syncOmnijarFromDistDir.destinationDir
     android.sourceSets."${sourceSet}".assets.srcDir syncAssetsFromDistDir.destinationDir
     android.sourceSets."${sourceSet}".jniLibs.srcDir syncLibsFromDistDir.destinationDir
 }
+
+ext.configureVariantWithJNIWrappers = { variant, module ->
+
+    def jarTask = tasks.findByName("jar${variant.name.capitalize()}Classes")
+    if (jarTask == null) {
+        jarTask = tasks.findByName("package${variant.name.capitalize()}JarArtifact")
+    }
+    if (jarTask == null) {
+        throw new GradleException("Jar task not found: \"jar${variant.name.capitalize()}Classes\"\t\"package${variant.name.capitalize()}JarArtifact\"" )
+    }
+    if (jarTask.outputs.files.size() != 1) {
+        throw new GradleException("Jar task output multiple files other than one single jar")
+    }
+
+    def wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}", type: JavaExec) {
+        classpath = variant.javaCompile.classpath
+        // Include android.jar.
+        classpath variant.javaCompile.options.bootClasspath
+        classpath "${topobjdir}/build/annotationProcessors/annotationProcessors.jar"
+        main = 'org.mozilla.gecko.annotationProcessors.AnnotationProcessor'
+        args module
+        args jarTask.outputs.files.iterator().next()
+
+        workingDir "${topobjdir}/mobile/android/base"
+
+        dependsOn jarTask
+    }
+
+    variant.assemble.dependsOn wrapperTask
+}