mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
169 lines
5.3 KiB
Python
169 lines
5.3 KiB
Python
# 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/.
|
|
|
|
# This script is used to capture the content of config.status-generated
|
|
# files and subsequently restore their timestamp if they haven't changed.
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import pickle
|
|
|
|
class File(object):
|
|
def __init__(self, path):
|
|
self._path = path
|
|
self._content = open(path, 'rb').read()
|
|
stat = os.stat(path)
|
|
self._times = (stat.st_atime, stat.st_mtime)
|
|
|
|
@property
|
|
def path(self):
|
|
return self._path
|
|
|
|
@property
|
|
def mtime(self):
|
|
return self._times[1]
|
|
|
|
def update_time(self):
|
|
'''If the file hasn't changed since the instance was created,
|
|
restore its old modification time.'''
|
|
if not os.path.exists(self._path):
|
|
return
|
|
if open(self._path, 'rb').read() == self._content:
|
|
os.utime(self._path, self._times)
|
|
|
|
|
|
# As defined in the various sub-configures in the tree
|
|
PRECIOUS_VARS = set([
|
|
'build_alias',
|
|
'host_alias',
|
|
'target_alias',
|
|
'CC',
|
|
'CFLAGS',
|
|
'LDFLAGS',
|
|
'LIBS',
|
|
'CPPFLAGS',
|
|
'CPP',
|
|
'CCC',
|
|
'CXXFLAGS',
|
|
'CXX',
|
|
'CCASFLAGS',
|
|
'CCAS',
|
|
])
|
|
|
|
|
|
# Autoconf, in some of the sub-configures used in the tree, likes to error
|
|
# out when "precious" variables change in value. The solution it gives to
|
|
# straighten things is to either run make distclean or remove config.cache.
|
|
# There's no reason not to do the latter automatically instead of failing,
|
|
# doing the cleanup (which, on buildbots means a full clobber), and
|
|
# restarting from scratch.
|
|
def maybe_clear_cache(args):
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--target', type=str)
|
|
parser.add_argument('--host', type=str)
|
|
parser.add_argument('--build', type=str)
|
|
args, others = parser.parse_known_args(args)
|
|
env = dict(os.environ)
|
|
for kind in ('target', 'host', 'build'):
|
|
arg = getattr(args, kind)
|
|
if arg is not None:
|
|
env['%s_alias' % kind] = arg
|
|
# configure can take variables assignments in its arguments, and that
|
|
# overrides whatever is in the environment.
|
|
for arg in others:
|
|
if arg[:1] != '-' and '=' in arg:
|
|
key, value = arg.split('=', 1)
|
|
env[key] = value
|
|
|
|
comment = re.compile(r'^\s+#')
|
|
cache = {}
|
|
with open('config.cache') as f:
|
|
for line in f:
|
|
if not comment.match(line) and '=' in line:
|
|
key, value = line.rstrip(os.linesep).split('=', 1)
|
|
# If the value is quoted, unquote it
|
|
if value[:1] == "'":
|
|
value = value[1:-1].replace("'\\''", "'")
|
|
cache[key] = value
|
|
for precious in PRECIOUS_VARS:
|
|
# If there is no entry at all for that precious variable, then
|
|
# its value is not precious for that particular configure.
|
|
if 'ac_cv_env_%s_set' % precious not in cache:
|
|
continue
|
|
is_set = cache.get('ac_cv_env_%s_set' % precious) == 'set'
|
|
value = cache.get('ac_cv_env_%s_value' % precious) if is_set else None
|
|
if value != env.get(precious):
|
|
print 'Removing config.cache because of %s value change from:' \
|
|
% precious
|
|
print ' %s' % (value if value is not None else 'undefined')
|
|
print 'to:'
|
|
print ' %s' % env.get(precious, 'undefined')
|
|
os.remove('config.cache')
|
|
return
|
|
|
|
|
|
def dump(dump_file, shell, args):
|
|
if os.path.exists('config.cache'):
|
|
maybe_clear_cache(args)
|
|
if not os.path.exists('config.status'):
|
|
if os.path.exists(dump_file):
|
|
os.remove(dump_file)
|
|
return
|
|
|
|
config_files = [File('config.status')]
|
|
|
|
# Scan the config.status output for information about configuration files
|
|
# it generates.
|
|
config_status_output = subprocess.check_output(
|
|
[shell, '-c', './config.status --help'],
|
|
stderr=subprocess.STDOUT).splitlines()
|
|
state = None
|
|
for line in config_status_output:
|
|
if line.startswith('Configuration') and line.endswith(':'):
|
|
state = 'config'
|
|
elif not line.startswith(' '):
|
|
state = None
|
|
elif state == 'config':
|
|
for f in (couple.split(':')[0] for couple in line.split()):
|
|
if os.path.isfile(f):
|
|
config_files.append(File(f))
|
|
|
|
with open(dump_file, 'wb') as f:
|
|
pickle.dump(config_files, f)
|
|
|
|
|
|
def adjust(dump_file, configure):
|
|
if not os.path.exists(dump_file):
|
|
return
|
|
|
|
config_files = []
|
|
|
|
try:
|
|
with open(dump_file, 'rb') as f:
|
|
config_files = pickle.load(f)
|
|
except Exception:
|
|
pass
|
|
|
|
for f in config_files:
|
|
# Still touch config.status if configure is newer than its original
|
|
# mtime.
|
|
if configure and os.path.basename(f.path) == 'config.status' and \
|
|
os.path.getmtime(configure) > f.mtime:
|
|
continue
|
|
f.update_time()
|
|
|
|
os.remove(dump_file)
|
|
|
|
|
|
CONFIG_DUMP = 'config_files.pkl'
|
|
|
|
if __name__ == '__main__':
|
|
if sys.argv[1] == 'dump':
|
|
dump(CONFIG_DUMP, sys.argv[2], sys.argv[3:])
|
|
elif sys.argv[1] == 'adjust':
|
|
adjust(CONFIG_DUMP, sys.argv[2] if len(sys.argv) > 2 else None)
|