Bug 1509573 - Part 4: Use |make -C ... stage-package| rather than special Make target. r=snorp
authorNick Alexander <nalexander@mozilla.com>
Wed, 28 Nov 2018 19:47:48 +0000
changeset 505081 ace2d2ada8eff0cc3505f1d6cc1f81da2bcf9179
parent 505080 059741f95cf4d4f680bea3eeadb714e567cd5413
child 505082 4939e4a1cc202d78ab4506c0ef37e06c587537cb
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1509573
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1509573 - Part 4: Use |make -C ... stage-package| rather than special Make target. r=snorp This splits the two stage-package invocations (which are rather slow) between Fennec and GeckoView, hopefully speeding local GV development up a little (in the IDE). In addition, we feed the packaged libs (and asset libs) through. Differential Revision: https://phabricator.services.mozilla.com/D12799
build.gradle
mobile/android/app/omnijar/build.gradle
mobile/android/base/Makefile.in
mobile/android/gradle/with_gecko_binaries.gradle
--- a/build.gradle
+++ b/build.gradle
@@ -124,16 +124,61 @@ task machBuildFaster(type: Exec) {
         args '-v'
     }
 
     // `path` is like `:machBuildFaster`.
     standardOutput = new TaggedLogOutputStream("${path}>", logger)
     errorOutput = standardOutput
 }
 
+def createMachStagePackageTask(name) {
+    return task(name, type: Exec) {
+        onlyIf rootProject.ext.geckoBinariesOnlyIf
+
+        dependsOn rootProject.machBuildFaster
+
+        // We'd prefer to take these from the :omnijar project directly, but
+        // it's awkward to reach across projects at evaluation time, so we
+        // duplicate the list here.
+        inputs.dir "${topsrcdir}/mobile/android/chrome"
+        inputs.dir "${topsrcdir}/mobile/android/components"
+        inputs.dir "${topsrcdir}/mobile/android/locales"
+        inputs.dir "${topsrcdir}/mobile/android/modules"
+        inputs.dir "${topsrcdir}/mobile/android/themes"
+        inputs.dir "${topsrcdir}/toolkit"
+
+        workingDir "${topobjdir}"
+
+        // We'd prefer this to be a `mach` invocation, but `mach build
+        // mobile/android/installer/stage-package` doesn't work as expected.
+        commandLine mozconfig.substs.GMAKE
+        args '-C'
+        args "${topobjdir}/mobile/android/installer"
+        args 'stage-package'
+
+        outputs.file "${topobjdir}/dist/fennec/assets/${mozconfig.substs.ANDROID_CPU_ARCH}/libxul.so"
+        outputs.file "${topobjdir}/dist/fennec/lib/${mozconfig.substs.ANDROID_CPU_ARCH}/libmozglue.so"
+
+        // `path` is like `:machStagePackage`.
+        standardOutput = new TaggedLogOutputStream("${path}>", logger)
+        errorOutput = standardOutput
+    }
+}
+
+createMachStagePackageTask("machStagePackageForFennec").with {
+    outputs.file "${topobjdir}/dist/fennec/assets/omni.ja"
+}
+
+createMachStagePackageTask("machStagePackageForGeckoview").with {
+    args 'MOZ_GECKOVIEW_JAR=1'
+    outputs.file "${topobjdir}/dist/geckoview/assets/omni.ja"
+    // Avoid races between stage-package invocations.
+    mustRunAfter tasks["machStagePackageForFennec"]
+}
+
 afterEvaluate {
     subprojects { project ->
         if (project.name != 'thirdparty') {
             tasks.withType(JavaCompile) {
                 // Add compiler args for all code except third-party code.
                 options.compilerArgs += [
                     // Turn on all warnings, except...
                     "-Xlint:all",
--- a/mobile/android/app/omnijar/build.gradle
+++ b/mobile/android/app/omnijar/build.gradle
@@ -1,24 +1,25 @@
 buildDir "${topobjdir}/gradle/build/mobile/android/omnijar"
 
 apply plugin: 'java'
 
-// This project is a dummy project; the JAR produced is not used.  The :app
+// This project is a dummy project; the JAR produced is not used.  The root
 // project uses the set of inputs here to check if the omnijar needs to be
 // rebuilt.  By listing them here as resource directories, IntelliJ labels each
 // checked directly nicely.  Why list the directories here?  There's a mismatch
 // between SourceDirectorySet and TaskInputs: the former is directory oriented,
 // while the latter is more general.  That means its easy to convert this list
-// into inputs for :app, but not vice-versa.  Sadly this implies that :app
-// evaluation depends on :omnijar, but the evaluation overhead is low enough
-// that we accept it.
+// into inputs for the root project, but not vice-versa.  Sadly this would mean
+// that the root project evaluation depends on :omnijar, so we duplicate in the
+// root project.
 sourceSets {
     main {
-        // Depend on the Gecko resources in mobile/android.
+        // These are supposed to be files that go into the omnijar.  But yes,
+        // toolkit/ has lots of native code.
         resources {
             srcDir "${topsrcdir}/mobile/android/chrome"
             srcDir "${topsrcdir}/mobile/android/components"
             srcDir "${topsrcdir}/mobile/android/locales"
             srcDir "${topsrcdir}/mobile/android/modules"
             srcDir "${topsrcdir}/mobile/android/themes"
             srcDir "${topsrcdir}/toolkit"
         }
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -12,33 +12,9 @@ chrome-%:: AB_CD=$*
 chrome-%::
 	$(MAKE) \
 	  res/values$(AB_rCD)/strings.xml \
 	  res/raw$(AB_rCD)/suggestedsites.json \
 	  AB_CD=$*
 
 include $(topsrcdir)/config/rules.mk
 
-# This target is only used by IDE integrations. It rebuilds resources
-# that end up in omni.ja using the equivalent of |mach build faster|,
-# does most of the packaging step, and then updates omni.ja in
-# place. If you're not using an IDE, you should be using |mach build
-# mobile/android && mach package|.
-$(ABS_DIST)/fennec/$(OMNIJAR_NAME): FORCE
-	$(REPORT_BUILD)
-	$(MAKE) -C ../../../faster
-	$(MAKE) -C ../installer stage-package
-	$(MKDIR) -p $(@D)
-	rsync --update $(DIST)/fennec/$(notdir $(OMNIJAR_NAME)) $@
-	$(RM) $(DIST)/fennec/$(notdir $(OMNIJAR_NAME))
-
-ifndef MOZILLA_OFFICIAL
-# Local developers update omni.ja during their builds.  There's a
-# chicken-and-egg problem here.
-gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
-else
-# In automation, omni.ja is built only during packaging.
-gradle-omnijar:
-endif
-
-.PHONY: gradle-omnijar
-
 export:: android_apks
--- a/mobile/android/gradle/with_gecko_binaries.gradle
+++ b/mobile/android/gradle/with_gecko_binaries.gradle
@@ -1,49 +1,16 @@
 /* -*- Mode: Groovy; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-// The omnijar inputs are listed as resource directory inputs to a dummy JAR.
-// That arrangement labels them nicely in IntelliJ.  See the comment in the
-// :omnijar project for more context.
-evaluationDependsOn(':omnijar')
-
 // The JNI wrapper generation tasks depend on the JAR creation task of the :annotations project.
 evaluationDependsOn(':annotations')
 
-task buildOmnijars(type:Exec) {
-    dependsOn rootProject.machBuildFaster
-
-    // See comment in :omnijar project regarding interface mismatches here.
-    inputs.file(project(':omnijar').sourceSets.main.resources.srcDirs).skipWhenEmpty() 
-
-    // Produce both the Fennec and the GeckoView omnijars.
-    outputs.file "${topobjdir}/dist/fennec/assets/omni.ja"
-    outputs.file "${topobjdir}/dist/geckoview/assets/omni.ja"
-
-    workingDir "${topobjdir}"
-
-    commandLine mozconfig.substs.GMAKE
-    args '-C'
-    args "${topobjdir}/mobile/android/base"
-    args 'gradle-omnijar'
-
-    // Only show the output if something went wrong.
-    ignoreExitValue = true
-    standardOutput = new ByteArrayOutputStream()
-    errorOutput = standardOutput
-    doLast {
-        if (execResult.exitValue != 0) {
-            throw new GradleException("Process '${commandLine}' finished with non-zero exit value ${execResult.exitValue}:\n\n${standardOutput.toString()}")
-        }
-    }
-}
-
 ext.configureVariantWithGeckoBinaries = { variant ->
     // :app needs the full Fennec omni.ja, whereas other projects need the
     // GeckoView-specific omni.ja.
     def omnijarDir = { "${topobjdir}/dist/${it}" }("app".equals(project.name) ? "fennec" : "geckoview")
     // All projects take the same Gecko libraries, which (for historical
     // reasons) are in "fennec".
     def distDir = "${topobjdir}/dist/fennec"
 
@@ -78,21 +45,30 @@ ext.configureVariantWithGeckoBinaries = 
     def syncAssetsFromDistDir = task("syncAssetsFromDistDirFor${variant.name.capitalize()}", type: Sync) {
         into("${project.buildDir}/moz.build/src/${variant.name}/assets")
         from("${distDir}/assets") {
             exclude 'omni.ja'
         }
     }
 
     // Local (read, not 'official') builds want to reflect developer changes to
-    // the Omnijar sources.  To do this, the Gradle build calls out to the
+    // the omnijar sources, and (when compiling) to reflect developer changes to
+    // the native binaries.  To do this, the Gradle build calls out to the
     // moz.build system, which can be re-entrant.  Official builds are driven by
     // the moz.build system and should never be re-entrant in this way.
     if (!mozconfig.substs.MOZILLA_OFFICIAL) {
-        syncOmnijarFromDistDir.dependsOn buildOmnijars
+        if ("app".equals(project.name)) {
+            syncOmnijarFromDistDir.dependsOn rootProject.machStagePackageForFennec
+            syncLibsFromDistDir.dependsOn rootProject.machStagePackageForFennec
+            syncAssetsFromDistDir.dependsOn rootProject.machStagePackageForFennec
+        } else {
+            syncOmnijarFromDistDir.dependsOn rootProject.machStagePackageForGeckoview
+            syncLibsFromDistDir.dependsOn rootProject.machStagePackageForGeckoview
+            syncAssetsFromDistDir.dependsOn rootProject.machStagePackageForGeckoview
+        }
     }
 
     def assetGenTask = tasks.findByName("generate${variant.name.capitalize()}Assets")
     if ((variant.productFlavors*.name).contains('withGeckoBinaries')) {
         assetGenTask.dependsOn syncOmnijarFromDistDir
         assetGenTask.dependsOn syncLibsFromDistDir
         assetGenTask.dependsOn syncAssetsFromDistDir