build/subconfigure.py

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

     1 # This Source Code Form is subject to the terms of the Mozilla Public
     2 # License, v. 2.0. If a copy of the MPL was not distributed with this
     3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     5 # This script is used to capture the content of config.status-generated
     6 # files and subsequently restore their timestamp if they haven't changed.
     8 import os
     9 import re
    10 import subprocess
    11 import sys
    12 import pickle
    14 class File(object):
    15     def __init__(self, path):
    16         self._path = path
    17         self._content = open(path, 'rb').read()
    18         stat = os.stat(path)
    19         self._times = (stat.st_atime, stat.st_mtime)
    21     @property
    22     def path(self):
    23         return self._path
    25     @property
    26     def mtime(self):
    27         return self._times[1]
    29     def update_time(self):
    30         '''If the file hasn't changed since the instance was created,
    31            restore its old modification time.'''
    32         if not os.path.exists(self._path):
    33             return
    34         if open(self._path, 'rb').read() == self._content:
    35             os.utime(self._path, self._times)
    38 # As defined in the various sub-configures in the tree
    39 PRECIOUS_VARS = set([
    40     'build_alias',
    41     'host_alias',
    42     'target_alias',
    43     'CC',
    44     'CFLAGS',
    45     'LDFLAGS',
    46     'LIBS',
    47     'CPPFLAGS',
    48     'CPP',
    49     'CCC',
    50     'CXXFLAGS',
    51     'CXX',
    52     'CCASFLAGS',
    53     'CCAS',
    54 ])
    57 # Autoconf, in some of the sub-configures used in the tree, likes to error
    58 # out when "precious" variables change in value. The solution it gives to
    59 # straighten things is to either run make distclean or remove config.cache.
    60 # There's no reason not to do the latter automatically instead of failing,
    61 # doing the cleanup (which, on buildbots means a full clobber), and
    62 # restarting from scratch.
    63 def maybe_clear_cache():
    64     comment = re.compile(r'^\s+#')
    65     cache = {}
    66     with open('config.cache') as f:
    67         for line in f.readlines():
    68             if not comment.match(line) and '=' in line:
    69                 key, value = line.split('=', 1)
    70                 cache[key] = value
    71     for precious in PRECIOUS_VARS:
    72         entry = 'ac_cv_env_%s_value' % precious
    73         if entry in cache and (not precious in os.environ or os.environ[precious] != cache[entry]):
    74             os.remove('config.cache')
    75             return
    78 def dump(dump_file, shell):
    79     if os.path.exists('config.cache'):
    80         maybe_clear_cache()
    81     if not os.path.exists('config.status'):
    82         if os.path.exists(dump_file):
    83             os.remove(dump_file)
    84         return
    86     config_files = [File('config.status')]
    88     # Scan the config.status output for information about configuration files
    89     # it generates.
    90     config_status_output = subprocess.check_output(
    91         [shell, '-c', './config.status --help'],
    92         stderr=subprocess.STDOUT).splitlines()
    93     state = None
    94     for line in config_status_output:
    95         if line.startswith('Configuration') and line.endswith(':'):
    96             state = 'config'
    97         elif not line.startswith(' '):
    98             state = None
    99         elif state == 'config':
   100             for f in (couple.split(':')[0] for couple in line.split()):
   101                 if os.path.isfile(f):
   102                     config_files.append(File(f))
   104     with open(dump_file, 'wb') as f:
   105         pickle.dump(config_files, f)
   108 def adjust(dump_file, configure):
   109     if not os.path.exists(dump_file):
   110         return
   112     config_files = []
   114     try:
   115         with open(dump_file, 'rb') as f:
   116             config_files = pickle.load(f)
   117     except Exception:
   118         pass
   120     for f in config_files:
   121         # Still touch config.status if configure is newer than its original
   122         # mtime.
   123         if configure and os.path.basename(f.path) == 'config.status' and \
   124                 os.path.getmtime(configure) > f.mtime:
   125             continue
   126         f.update_time()
   128     os.remove(dump_file)
   131 CONFIG_DUMP = 'config_files.pkl'
   133 if __name__ == '__main__':
   134     if sys.argv[1] == 'dump':
   135         dump(CONFIG_DUMP, sys.argv[2])
   136     elif sys.argv[1] == 'adjust':
   137         adjust(CONFIG_DUMP, sys.argv[2] if len(sys.argv) > 2 else None)

mercurial