Cache scons subprocess calls

This commit is contained in:
Kp 2015-04-22 02:44:30 +00:00
parent d4080c2505
commit bb3f414128

View file

@ -32,6 +32,44 @@ def get_Werror_string(l):
return '-W'
return '-Werror='
class StaticSubprocess:
class CachedCall:
def __init__(self,out,err,returncode):
self.out = out
self.err = err
self.returncode = returncode
__call_cache = {}
@classmethod
def pcall(cls,args,stdout,stderr=None):
a = repr(args)
try:
return cls.__call_cache[a]
except KeyError:
pass
p = subprocess.Popen(args, executable=args[0], stdout=stdout, stderr=stderr, close_fds=True)
(o, e) = p.communicate()
cls.__call_cache[a] = c = cls.CachedCall(o, e, p.wait())
return c
class Git(StaticSubprocess):
__missing_git = StaticSubprocess.CachedCall(None, None, 1)
__path_git = None
@classmethod
def pcall(cls,args,stdout,stderr=None):
git = cls.__path_git
if git is None:
cls.__path_git = git = (os.environ.get('GIT', 'git').split(),)
git = git[0]
if not git:
return cls.__missing_git
return StaticSubprocess.pcall(git + args, stdout=stdout, stderr=stderr)
@classmethod
def spcall(cls,args,stdout,stderr=None):
g = cls.pcall(args, stdout, stderr)
if g.returncode:
return None
return g.out
class ConfigureTests:
class Collector:
def __init__(self):
@ -1369,8 +1407,7 @@ class DXXCommon(LazyObjectConstructor):
check_header_includes = os.path.join(builddir, 'check_header_includes.cpp')
if not self.__shared_header_file_list:
open(check_header_includes, 'wt')
git = subprocess.Popen(['git', 'ls-files', '-z', '--', '*.h'], executable='/usr/bin/git', stdout=subprocess.PIPE, close_fds=True)
headers = git.communicate(None)[0]
headers = Git.pcall(['ls-files', '-z', '--', '*.h'], stdout=subprocess.PIPE).out
excluded_directories = (
'common/arch/cocoa/',
'common/arch/carbon/',
@ -1985,38 +2022,27 @@ class DXXProgram(DXXCommon):
def compute_extra_version(cls):
c = cls._computed_extra_version
if c is None:
git = (os.environ.get('GIT', 'git')).split()
v = s = ds = None
if git:
v = cls._compute_extra_version(git)
if v:
g = subprocess.Popen(git + ['status', '--short', '--branch'], executable=git[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(go, ge) = g.communicate(None)
if not g.wait():
s = go
g = subprocess.Popen(git + ['diff', '--stat', 'HEAD'], executable=git[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(go, ge) = g.communicate(None)
if not g.wait():
ds = go
s = ds = None
v = cls._compute_extra_version()
if v:
s = Git.spcall(['status', '--short', '--branch'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
ds = Git.spcall(['diff', '--stat', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
cls._computed_extra_version = c = (v or '', s, ds)
return c
@classmethod
def _compute_extra_version(cls, git):
def _compute_extra_version(cls):
try:
g = subprocess.Popen(git + ['describe', '--tags', '--abbrev=8'], executable=git[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
g = Git.pcall(['describe', '--tags', '--abbrev=8'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError as e:
if e.errno == errno.ENOENT:
return None
raise
(go, ge) = g.communicate(None)
if g.wait():
if g.returncode:
return None
g = subprocess.Popen(git + ['diff', '--quiet', '--cached'], executable=git[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
c = g.wait()
g = subprocess.Popen(git + ['diff', '--quiet'], executable=git[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
d = g.wait()
return go.split('\n')[0] + ('+' if c else '') + ('*' if d else '')
c = Git.pcall(['diff', '--quiet', '--cached'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode
d = Git.pcall(['diff', '--quiet'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode
return g.out.split('\n')[0] + ('+' if c else '') + ('*' if d else '')
def _register_program(self,dxxstr,program_specific_objects=[]):
env = self.env
@ -2045,10 +2071,9 @@ class DXXProgram(DXXCommon):
versid_build_environ = ['CXX', 'CPPFLAGS', 'CXXFLAGS', 'LINKFLAGS']
versid_cppdefines = env['CPPDEFINES'][:]
versid_cppdefines.extend([('DESCENT_%s' % k, self._quote_cppdefine(env.get(k, ''))) for k in versid_build_environ])
v = subprocess.Popen(env['CXX'].split(' ') + ['--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(so,se) = v.communicate(None)
if not v.returncode and (so or se):
v = (so or se).split('\n')[0]
v = StaticSubprocess.pcall(env['CXX'].split(' ') + ['--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if not v.returncode and (v.out or v.err):
v = (v.out or v.err).split('\n')[0]
versid_cppdefines.append(('DESCENT_%s' % 'CXX_version', self._quote_cppdefine(v)))
versid_build_environ.append('CXX_version')
extra_version = self.user_settings.extra_version