Bug 1317778 - Emit a depfile with python configure dependencies so Make will know when to re-run configure. r=glandium draft
authorChris Manchester <cmanchester@mozilla.com>
Fri, 02 Dec 2016 10:05:57 -0800
changeset 447121 9c7112c53813fe0faa452cf9f155966e37fe4d21
parent 447079 e756ee86e3ea1225d8cdf38ca0eb8b0ded15dd41
child 538970 67054603c82d86413aac6c303a6d01e8ae88ba86
push id37989
push usercmanchester@mozilla.com
push dateFri, 02 Dec 2016 18:06:24 +0000
reviewersglandium
bugs1317778
milestone53.0a1
Bug 1317778 - Emit a depfile with python configure dependencies so Make will know when to re-run configure. r=glandium MozReview-Commit-ID: AuTHadY7KqO
client.mk
configure.py
--- a/client.mk
+++ b/client.mk
@@ -324,16 +324,20 @@ CONFIG_STATUS_DEPS := \
   $(TOPSRCDIR)/browser/config/version.txt \
   $(TOPSRCDIR)/browser/config/version_display.txt \
   $(TOPSRCDIR)/build/virtualenv_packages.txt \
   $(TOPSRCDIR)/python/mozbuild/mozbuild/virtualenv.py \
   $(TOPSRCDIR)/testing/mozbase/packages.txt \
   $(OBJDIR)/.mozconfig.json \
   $(NULL)
 
+# Include a dep file emitted by configure to track Python files that
+# may incluence the result of configure.
+-include $(OBJDIR)/configure.d
+
 CONFIGURE_ENV_ARGS += \
   MAKE='$(MAKE)' \
   $(NULL)
 
 # configure uses the program name to determine @srcdir@. Calling it without
 #   $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
 #   path of $(TOPSRCDIR).
 ifeq ($(TOPSRCDIR),$(OBJDIR))
--- a/configure.py
+++ b/configure.py
@@ -1,42 +1,44 @@
 # 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/.
 
 from __future__ import print_function, unicode_literals
 
 import codecs
+import itertools
 import os
 import subprocess
 import sys
 import textwrap
 
 
 base_dir = os.path.abspath(os.path.dirname(__file__))
 sys.path.insert(0, os.path.join(base_dir, 'python', 'mozbuild'))
 from mozbuild.configure import ConfigureSandbox
+from mozbuild.makeutil import Makefile
+from mozbuild.pythonutil import iter_modules_in_path
 from mozbuild.util import (
     indented_repr,
     encode,
 )
 
 
 def main(argv):
     config = {}
     sandbox = ConfigureSandbox(config, os.environ, argv)
     sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure'))
 
     if sandbox._help:
         return 0
 
-    return config_status(config)
+    return config_status(config, sandbox)
 
-
-def config_status(config):
+def config_status(config, sandbox):
     # Sanitize config data to feed config.status
     # Ideally, all the backend and frontend code would handle the booleans, but
     # there are so many things involved, that it's easier to keep config.status
     # untouched for now.
     def sanitized_bools(v):
         if v is True:
             return '1'
         if v is False:
@@ -79,16 +81,27 @@ def config_status(config):
         if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
             fh.write(textwrap.dedent('''
                 if __name__ == '__main__':
                     from mozbuild.config_status import config_status
                     args = dict([(name, globals()[name]) for name in __all__])
                     config_status(**args)
             '''))
 
+    # Write out a depfile so Make knows to re-run configure when relevant Python
+    # changes.
+    mk = Makefile()
+    rule = mk.create_rule()
+    rule.add_targets(["$(OBJDIR)/config.status"])
+    rule.add_dependencies(itertools.chain(sandbox._all_paths,
+                                          iter_modules_in_path(config['TOPOBJDIR'],
+                                                               config['TOPSRCDIR'])))
+    with open('configure.d', 'w') as fh:
+        mk.dump(fh)
+
     # Other things than us are going to run this file, so we need to give it
     # executable permissions.
     os.chmod('config.status', 0o755)
     if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
         os.environ[b'WRITE_MOZINFO'] = b'1'
         from mozbuild.config_status import config_status
 
         # Some values in sanitized_config also have more complex types, such as