Bug 1219846 - Part 2: Make 'omnijar' project in srcdir. r=me
authorNick Alexander <nalexander@mozilla.com>
Thu, 29 Oct 2015 11:11:36 -0700
changeset 306266 49063069ff59b4602ef3c6e4b05fc6551520eef7
parent 306265 8b66ed0e3cf1210d5898d7647c9c378d5c13f23b
child 306267 dcd113d0102e773bb3ff1806bf4a5c484039c492
push id1040
push userraliiev@mozilla.com
push dateMon, 29 Feb 2016 17:11:22 +0000
treeherdermozilla-release@8c3167321162 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1219846
milestone45.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 1219846 - Part 2: Make 'omnijar' project in srcdir. r=me DONTBUILD NPOTB The :omnijar project is for IntelliJ only; adding it neatly labels folders we consider part of the omnijar in mobile/android. The JAR produced is not used. We add an evaluation-time dependency from :app to :omnijar so that we can declare the set of omnijar folders exactly once. We'd prefer to have the dependency in the other direction (to save evaluation time) but there's an interface mismatch between the two Gradle model types. See comments in the :omnijar project. This is delicate.
mobile/android/app/build.gradle
mobile/android/app/omnijar/build.gradle
settings.gradle
--- a/mobile/android/app/build.gradle
+++ b/mobile/android/app/build.gradle
@@ -50,17 +50,16 @@ android {
                 srcDir "${topsrcdir}/mobile/android/tests/browser/robocop/assets"
             }
         }
     }
 }
 
 dependencies {
     compile project(':base')
-    compile project(':omnijar')
     // Including the Robotium JAR directly can cause issues with dexing.
     androidTestCompile 'com.jayway.android.robotium:robotium-solo:4.3.1'
 }
 
 task syncOmnijarFromDistDir(type: Sync) {
     into("${project.buildDir}/generated/omnijar")
     from("${topobjdir}/dist/fennec/assets") {
         include 'omni.ja'
@@ -86,38 +85,56 @@ task checkAssetsExistInDistDir<< {
 
 task syncAssetsFromDistDir(type: Sync, dependsOn: checkAssetsExistInDistDir) {
     into("${project.buildDir}/generated/assets")
     from("${topobjdir}/dist/fennec/assets") {
         exclude 'omni.ja'
     }
 }
 
-/**
- * We want to expose the JSM files and chrome content to IDEs; the omnijar
- * project does this.  In addition, the :omnijar:buildOmnijar task builds a new
- * omni.ja (directly into the object directory).
- *
- * The task dependency is: :generateDebugAssets -> :omnijar:buildOmnijar.
- *
- * One might expect that we could do this all in the omnijar project, but there
- * appears to be a bug (which I have not fully isolated) where-by debug-only
- * assets in a library (.aar file) are ignored in favor of release assets.  This
- * means we would have to insert the omni.ja into the omnijar project's release
- * assets, which is altogether confusing.
- */
+// 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')
+
+task buildOmnijar(type:Exec) {
+    dependsOn rootProject.generateCodeAndResources
+
+    // See comment in :omnijar project regarding interface mismatches here.
+    inputs.source project(':omnijar').sourceSets.main.resources.srcDirs
+
+    // Produce a single output file.
+    outputs.file "${topobjdir}/dist/fennec/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()}")
+        }
+    }
+}
+
 android.applicationVariants.all { variant ->
     // We only insert omni.ja and the .so libraries into debug builds.
     def name = variant.buildType.name
     if (!name.contains(com.android.builder.core.BuilderConstants.DEBUG)) {
         return
     }
 
-    def buildOmnijarTask = project(':omnijar').tasks.getByName('buildOmnijar')
-    syncOmnijarFromDistDir.dependsOn buildOmnijarTask
+    syncOmnijarFromDistDir.dependsOn buildOmnijar
     def generateAssetsTask = tasks.findByName("generate${name.capitalize()}Assets")
     generateAssetsTask.dependsOn syncOmnijarFromDistDir
     generateAssetsTask.dependsOn syncLibsFromDistDir
     generateAssetsTask.dependsOn syncAssetsFromDistDir
 
     android.sourceSets.debug.assets.srcDir syncOmnijarFromDistDir.destinationDir
     android.sourceSets.debug.assets.srcDir syncAssetsFromDistDir.destinationDir
     android.sourceSets.debug.jniLibs.srcDir syncLibsFromDistDir.destinationDir
new file mode 100644
--- /dev/null
+++ b/mobile/android/app/omnijar/build.gradle
@@ -0,0 +1,32 @@
+buildDir "${topobjdir}/gradle/build/mobile/android/omnijar"
+
+apply plugin: 'java'
+
+// This project is a dummy project; the JAR produced is not used.  The :app
+// 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.
+sourceSets {
+    main {
+        // Depend on the Gecko resources in mobile/android.
+        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"
+        }
+    }
+}
+
+apply plugin: 'idea'
+
+idea {
+    module {
+    }
+}
--- a/settings.gradle
+++ b/settings.gradle
@@ -24,17 +24,17 @@ if (json.substs.MOZ_BUILD_APP != 'mobile
 include ':app'
 include ':base'
 include ':omnijar'
 include ':thirdparty'
 
 def gradleRoot = new File("${json.topobjdir}/mobile/android/gradle")
 project(':app').projectDir = new File("${json.topsrcdir}/mobile/android/app")
 project(':base').projectDir = new File(gradleRoot, 'base')
-project(':omnijar').projectDir = new File(gradleRoot, 'omnijar')
+project(':omnijar').projectDir = new File("${json.topsrcdir}/mobile/android/app/omnijar")
 project(':thirdparty').projectDir = new File("${json.topsrcdir}/mobile/android/thirdparty")
 
 // The Gradle instance is shared between settings.gradle and all the
 // other build.gradle files (see
 // http://forums.gradle.org/gradle/topics/define_extension_properties_from_settings_xml).
 // We use this ext property to pass the per-object-directory mozconfig
 // between scripts.  This lets us execute set-up code before we gradle
 // tries to configure the project even once, and as a side benefit