Bug 1543982 - Part 1: Avoid re-configuring from within Gradle. r=emilio
authorNick Alexander <nalexander@mozilla.com>
Thu, 09 May 2019 20:38:48 +0000
changeset 535209 55b7de7850bebd08d85caeb719de711a32f71369
parent 535208 d62e8172a66f2b3956997848b127f31b458e9e9d
child 535210 17c76d081a9a78e20e52dbfe7b89f072e110c471
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1543982
milestone68.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 1543982 - Part 1: Avoid re-configuring from within Gradle. r=emilio The inline comment explains what is happening here. The issue is that client.mk is setting MOZ_OBJDIR (and autoconf.mk is setting CC/CXX and others) as part of `mach build`, which means that recursively invoking `mach build` sees a different environment, and that triggers reconfigure. In some situations we can avoid this by recognizing that the environment has changed and setting it back to what it was at the time of `mach build` before client.mk adjusts it. Differential Revision: https://phabricator.services.mozilla.com/D30425
build.gradle
settings.gradle
--- a/build.gradle
+++ b/build.gradle
@@ -133,17 +133,29 @@ ext.geckoBinariesOnlyIf = { task ->
         rootProject.logger.lifecycle("Skipping task ${task.path} because: IS_LANGUAGE_REPACK")
         return false
     }
 
     rootProject.logger.lifecycle("Executing task ${task.path}")
     return true
 }
 
-task machBuildGeneratedAndroidCodeAndResources(type: Exec) {
+class MachExec extends Exec {
+    def MachExec() {
+        // Bug 1543982: When invoking `mach build` recursively, the outer `mach
+        // build` itself modifies the environment, causing configure to run
+        // again.  This tries to restore the environment that the outer `mach
+        // build` was invoked in.  See the comment in
+        // $topsrcdir/settings.gradle.
+        project.ext.mozconfig.mozconfig.env.unmodified.each { k, v -> environment.remove(k) }
+        environment project.ext.mozconfig.orig_mozconfig.env.unmodified
+    }
+}
+
+task machBuildGeneratedAndroidCodeAndResources(type: MachExec) {
     onlyIf rootProject.ext.geckoBinariesOnlyIf
 
     workingDir "${topsrcdir}"
 
     commandLine mozconfig.substs.PYTHON
     args "${topsrcdir}/mach"
     args 'build'
     args 'mobile/android/base/generated_android_code_and_resources'
@@ -159,17 +171,17 @@ task machBuildGeneratedAndroidCodeAndRes
 }
 
 // Why |mach build mobile/android/base/...| and |mach build faster|?  |mach
 // build faster| generates dependentlibs.list, which in turn depends on compiled
 // code.  That causes a circular dependency between Java compilation/JNI wrapper
 // generation/native code compilation.  So we have the special target for
 // Android-specific generated code, and the |mach build faster| target for all
 // the stuff that goes into the omnijar.
-task machBuildFaster(type: Exec) {
+task machBuildFaster(type: MachExec) {
     onlyIf rootProject.ext.geckoBinariesOnlyIf
 
     workingDir "${topsrcdir}"
 
     commandLine mozconfig.substs.PYTHON
     args "${topsrcdir}/mach"
     args 'build'
     args 'faster'
@@ -180,17 +192,17 @@ task machBuildFaster(type: Exec) {
     }
 
     // `path` is like `:machBuildFaster`.
     standardOutput = new TaggedLogOutputStream("${path}>", logger)
     errorOutput = standardOutput
 }
 
 def createMachStagePackageTask(name) {
-    return task(name, type: Exec) {
+    return task(name, type: MachExec) {
         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"
--- a/settings.gradle
+++ b/settings.gradle
@@ -56,8 +56,17 @@ project(':thirdparty').projectDir = new 
 // 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
 // saves invoking |mach environment| multiple times.
 gradle.ext.mozconfig = json
+
+// Produced by `mach build`.  Bug 1543982: the mozconfig determined by `mach
+// environment` above can be different because `mach build` itself sets certain
+// critical environment variables including MOZ_OBJDIR, CC, and CXX.  We use
+// this record to patch up the environment when we recursively invoke `mach
+// build ...` commands from within Gradle.  This avoids invalidating configure
+// based on the changed environment variables.
+def orig = slurper.parse(new File(json.topobjdir, '.mozconfig.json'))
+gradle.ext.mozconfig.orig_mozconfig = orig.mozconfig