From d43cf05e8462bbb89b6bb6a7298db6e051de1193 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 20 Aug 2013 15:23:28 +0900 Subject: [PATCH] Bug 903369 - Wrap subconfigure invocation and restore config.status produced file timestamps if they haven't changed. r=gps --- build/autoconf/hooks.m4 | 25 ++++++++++- build/subconfigure.py | 80 ++++++++++++++++++++++++++++++++++ js/src/build/autoconf/hooks.m4 | 25 ++++++++++- js/src/build/subconfigure.py | 80 ++++++++++++++++++++++++++++++++++ js/src/configure.in | 4 +- 5 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 build/subconfigure.py create mode 100644 js/src/build/subconfigure.py diff --git a/build/autoconf/hooks.m4 b/build/autoconf/hooks.m4 index 37d563189d4..539fbb23991 100644 --- a/build/autoconf/hooks.m4 +++ b/build/autoconf/hooks.m4 @@ -19,9 +19,32 @@ MOZ_CONFIG_LOG_TRAP dnl Disable the trap when running sub-configures. define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS])) +define([MOZ_SUBCONFIGURE_WRAP], +[ _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +case "$host" in +*-mingw*) + _CONFIG_SHELL=$(cd $(dirname $_CONFIG_SHELL); pwd -W)/$(basename $_CONFIG_SHELL) + if test ! -e "$_CONFIG_SHELL" -a -e "${_CONFIG_SHELL}.exe"; then + _CONFIG_SHELL="${_CONFIG_SHELL}.exe" + fi + ;; +esac + +if test -d "$1"; then + (cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL") +fi +$2 +(cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py adjust) +]) + define([AC_OUTPUT_SUBDIRS], [trap '' EXIT -_MOZ_AC_OUTPUT_SUBDIRS($1) +for moz_config_dir in $1; do + MOZ_SUBCONFIGURE_WRAP([$moz_config_dir],[ + _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir) + ]) +done + MOZ_CONFIG_LOG_TRAP ]) diff --git a/build/subconfigure.py b/build/subconfigure.py new file mode 100644 index 00000000000..a9b62114dc9 --- /dev/null +++ b/build/subconfigure.py @@ -0,0 +1,80 @@ +# 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 os +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) + + 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) + +def dump(dump_file, shell): + 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): + 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: + 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]) + elif sys.argv[1] == 'adjust': + adjust(CONFIG_DUMP) diff --git a/js/src/build/autoconf/hooks.m4 b/js/src/build/autoconf/hooks.m4 index 37d563189d4..539fbb23991 100644 --- a/js/src/build/autoconf/hooks.m4 +++ b/js/src/build/autoconf/hooks.m4 @@ -19,9 +19,32 @@ MOZ_CONFIG_LOG_TRAP dnl Disable the trap when running sub-configures. define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS])) +define([MOZ_SUBCONFIGURE_WRAP], +[ _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +case "$host" in +*-mingw*) + _CONFIG_SHELL=$(cd $(dirname $_CONFIG_SHELL); pwd -W)/$(basename $_CONFIG_SHELL) + if test ! -e "$_CONFIG_SHELL" -a -e "${_CONFIG_SHELL}.exe"; then + _CONFIG_SHELL="${_CONFIG_SHELL}.exe" + fi + ;; +esac + +if test -d "$1"; then + (cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL") +fi +$2 +(cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py adjust) +]) + define([AC_OUTPUT_SUBDIRS], [trap '' EXIT -_MOZ_AC_OUTPUT_SUBDIRS($1) +for moz_config_dir in $1; do + MOZ_SUBCONFIGURE_WRAP([$moz_config_dir],[ + _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir) + ]) +done + MOZ_CONFIG_LOG_TRAP ]) diff --git a/js/src/build/subconfigure.py b/js/src/build/subconfigure.py new file mode 100644 index 00000000000..a9b62114dc9 --- /dev/null +++ b/js/src/build/subconfigure.py @@ -0,0 +1,80 @@ +# 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 os +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) + + 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) + +def dump(dump_file, shell): + 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): + 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: + 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]) + elif sys.argv[1] == 'adjust': + adjust(CONFIG_DUMP) diff --git a/js/src/configure.in b/js/src/configure.in index 18725935f0d..245e84adbb8 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -4361,7 +4361,8 @@ if test -n "$ENABLE_INTL_API" ; then abs_srcdir=`(cd $srcdir; pwd)` mkdir -p $_objdir/intl/icu - (cd $_objdir/intl/icu; \ + (cd $_objdir/intl/icu + MOZ_SUBCONFIGURE_WRAP([.],[ CC="$CC" CXX="$CXX" \ CFLAGS="$ICU_CFLAGS" CPPFLAGS="$ICU_CPPFLAGS" CXXFLAGS="$ICU_CXXFLAGS" \ $SHELL $abs_srcdir/../../intl/icu/source/runConfigureICU \ @@ -4370,6 +4371,7 @@ if test -n "$ENABLE_INTL_API" ; then $ICU_LINK_OPTS \ --enable-extras=no --enable-icuio=no --enable-layout=no \ --enable-tests=no --enable-samples=no || exit 1 + ]) ) || exit 1 fi