Bug 1257516 - Send the debug output from our logger to config.log. r?ted draft
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 25 Mar 2016 16:44:53 +0900
changeset 344665 5fb421c3cb23fa0486da40cefacb69c15ddc6af6
parent 344664 d2099a95184bf367a69e144e4dcb248c049fb27c
child 344666 36f93966b47c93158c9de3aec527e47994b594a9
push id13899
push userbmo:mh+mozilla@glandium.org
push dateFri, 25 Mar 2016 08:32:05 +0000
reviewersted
bugs1257516
milestone48.0a1
Bug 1257516 - Send the debug output from our logger to config.log. r?ted And since the file is also used for old-configure, close our handle on the file before spawning old-configure, and make old-configure append there instead of truncating the file.
build/moz.configure/old.configure
python/mozbuild/mozbuild/configure/__init__.py
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -116,21 +116,27 @@ def prepare_configure(old_configure, moz
         ):
             if getmtime(input) > mtime:
                 break
         else:
             refresh = False
 
     if refresh:
         log.info('Refreshing %s with %s', old_configure, autoconf)
+        script = subprocess.check_output([
+            shell, autoconf,
+            '--localdir=%s' % os.path.dirname(old_configure),
+            old_configure + '.in'])
+
+        # Make old-configure append to config.log, where we put our own log.
+        # This could be done with a m4 macro, but it's way easier this way
+        script = script.replace('>./config.log', '>>./config.log')
+
         with open(old_configure, 'wb') as fh:
-            subprocess.check_call([
-                shell, autoconf,
-                '--localdir=%s' % os.path.dirname(old_configure),
-                old_configure + '.in'], stdout=fh)
+            fh.write(script)
 
     cmd = [shell, old_configure]
     with encoded_open('old-configure.vars', 'w') as out:
         if mozconfig['path']:
             for key, value in mozconfig['env']['added'].items():
                 print("export %s=%s" % (key, quote(value)), file=out)
             for key, (old, value) in mozconfig['env']['modified'].items():
                 print("export %s=%s" % (key, quote(value)), file=out)
@@ -363,16 +369,17 @@ def old_configure_options(*options):
     '--enable-ldap',
     '--enable-mapi',
     '--enable-calendar',
     '--enable-incomplete-external-linkage',
 )
 @advanced
 def old_configure(prepare_configure, extra_old_configure_args, all_options,
                   *options):
+    import logging
     import os
     import subprocess
     import sys
     from mozbuild.shellutil import quote
 
     cmd = prepare_configure
 
     # old-configure only supports the options listed in @old_configure_options
@@ -388,16 +395,26 @@ def old_configure(prepare_configure, ext
     # them down to js/src/configure. Note this list is empty when running
     # js/src/configure, in which case we don't need to pass those options
     # to old-configure since old-configure doesn't handle them anyways.
     if extra_old_configure_args:
         cmd += extra_old_configure_args
 
     # For debugging purpose, in case it's not what we'd expect.
     log.info('running %s', ' '.join(quote(a) for a in cmd))
+
+    # Our logging goes to config.log, the same file old.configure uses.
+    # We can't share the handle on the file, so close it. We assume nothing
+    # beyond this point is going to be interesting to log to config.log from
+    # our end, so we don't make the effort to recreate a logging.FileHandler.
+    logger = logging.getLogger('moz.configure')
+    for handler in logger.handlers:
+        if isinstance(handler, logging.FileHandler):
+            handler.close()
+
     ret = subprocess.call(cmd)
     if ret:
         sys.exit(ret)
 
     raw_config = {}
     with encoded_open('config.data', 'r') as fh:
         code = compile(fh.read(), 'config.data', 'exec')
         # Every variation of the exec() function I tried led to:
--- a/python/mozbuild/mozbuild/configure/__init__.py
+++ b/python/mozbuild/mozbuild/configure/__init__.py
@@ -124,41 +124,48 @@ class ConfigureSandbox(dict):
         self._prepared_functions = set()
 
         self._helper = CommandLineHelper(environ, argv)
 
         assert isinstance(config, dict)
         self._config = config
 
         if logger is None:
-            logger = logging.getLogger('moz.configure')
+            logger = moz_logger = logging.getLogger('moz.configure')
             logger.setLevel(logging.INFO)
             formatter = logging.Formatter('%(levelname)s: %(message)s')
             handler = ConfigureOutputHandler(stdout, stderr)
             handler.setLevel(logging.INFO)
             handler.setFormatter(formatter)
             logger.addHandler(handler)
 
         else:
             assert isinstance(logger, logging.Logger)
+            moz_logger = None
 
         self.log_impl = ReadOnlyNamespace(**{
                 k: getattr(logger, k)
                 for k in ('debug', 'info', 'warning', 'error')
         })
 
         self._help = None
         self._help_option = self.option_impl('--help',
                                              help='print this message')
         self._seen.add(self._help_option)
         # self._option_impl('--help') will have set this if --help was on the
         # command line.
         if self._option_values[self._help_option]:
             self._help = HelpFormatter(argv[0])
             self._help.add(self._help_option)
+        elif moz_logger:
+            logger.setLevel(logging.DEBUG)
+            handler = logging.FileHandler('config.log', mode='w', delay=True)
+            handler.setLevel(logging.DEBUG)
+            handler.setFormatter(formatter)
+            logger.addHandler(handler)
 
     def exec_file(self, path):
         '''Execute one file within the sandbox. Users of this class probably
         want to use `run` instead.'''
 
         if self._paths:
             path = mozpath.join(mozpath.dirname(self._paths[-1]), path)
             if not mozpath.basedir(path, (mozpath.dirname(self._paths[0]),)):