summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2018-07-13 15:20:36 (GMT)
committerTobias Markmann <tm@ayena.de>2018-09-26 14:05:36 (GMT)
commit1536284a15743f6ec41d3230177a24d245158a9d (patch)
tree21216d18d93ddfc620e6b36dc28428c5d5b71775 /3rdParty/SCons/scons-2.4.0/script/scons-time
parent091f6e520694360a0407ab0cf3bb036fb461e6e3 (diff)
downloadswift-1536284a15743f6ec41d3230177a24d245158a9d.zip
swift-1536284a15743f6ec41d3230177a24d245158a9d.tar.bz2
Update SCons in 3rdParty from 2.4.0 to 3.0.1
This also has our scons patch in 3rdParty/SCons applied. Test-Information: Builds with unit tests on macOS 10.13.6. Change-Id: I25d3662eeec27a76dab10d501ba46dc16f0bef4b
Diffstat (limited to '3rdParty/SCons/scons-2.4.0/script/scons-time')
-rw-r--r--3rdParty/SCons/scons-2.4.0/script/scons-time1544
1 files changed, 0 insertions, 1544 deletions
diff --git a/3rdParty/SCons/scons-2.4.0/script/scons-time b/3rdParty/SCons/scons-2.4.0/script/scons-time
deleted file mode 100644
index f37d906..0000000
--- a/3rdParty/SCons/scons-2.4.0/script/scons-time
+++ /dev/null
@@ -1,1544 +0,0 @@
-#!/usr/bin/env python
-#
-# scons-time - run SCons timings and collect statistics
-#
-# A script for running a configuration through SCons with a standard
-# set of invocations to collect timing and memory statistics and to
-# capture the results in a consistent set of output files for display
-# and analysis.
-#
-
-#
-# Copyright (c) 2001 - 2015 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-from __future__ import division
-from __future__ import nested_scopes
-
-__revision__ = "src/script/scons-time.py rel_2.4.0:3365:9259ea1c13d7 2015/09/21 14:03:43 bdbaddog"
-
-import getopt
-import glob
-import os
-import re
-import shutil
-import sys
-import tempfile
-import time
-
-try:
- sorted
-except NameError:
- # Pre-2.4 Python has no sorted() function.
- #
- # The pre-2.4 Python list.sort() method does not support
- # list.sort(key=) nor list.sort(reverse=) keyword arguments, so
- # we must implement the functionality of those keyword arguments
- # by hand instead of passing them to list.sort().
- def sorted(iterable, cmp=None, key=None, reverse=False):
- if key is not None:
- result = [(key(x), x) for x in iterable]
- else:
- result = iterable[:]
- if cmp is None:
- # Pre-2.3 Python does not support list.sort(None).
- result.sort()
- else:
- result.sort(cmp)
- if key is not None:
- result = [t1 for t0,t1 in result]
- if reverse:
- result.reverse()
- return result
-
-if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is not None:
- # We can't apply the 'callable' fixer until the floor is 2.6, but the
- # '-3' option to Python 2.6 and 2.7 generates almost ten thousand
- # warnings. This hack allows us to run regression tests with the '-3'
- # option by replacing the callable() built-in function with a hack
- # that performs the same function but doesn't generate the warning.
- # Note that this hack is ONLY intended to be used for regression
- # testing, and should NEVER be used for real runs.
- from types import ClassType
- def callable(obj):
- if hasattr(obj, '__call__'): return True
- if isinstance(obj, (ClassType, type)): return True
- return False
-
-def make_temp_file(**kw):
- try:
- result = tempfile.mktemp(**kw)
- try:
- result = os.path.realpath(result)
- except AttributeError:
- # Python 2.1 has no os.path.realpath() method.
- pass
- except TypeError:
- try:
- save_template = tempfile.template
- prefix = kw['prefix']
- del kw['prefix']
- tempfile.template = prefix
- result = tempfile.mktemp(**kw)
- finally:
- tempfile.template = save_template
- return result
-
-def HACK_for_exec(cmd, *args):
- '''
- For some reason, Python won't allow an exec() within a function
- that also declares an internal function (including lambda functions).
- This function is a hack that calls exec() in a function with no
- internal functions.
- '''
- if not args: exec(cmd)
- elif len(args) == 1: exec cmd in args[0]
- else: exec cmd in args[0], args[1]
-
-class Plotter(object):
- def increment_size(self, largest):
- """
- Return the size of each horizontal increment line for a specified
- maximum value. This returns a value that will provide somewhere
- between 5 and 9 horizontal lines on the graph, on some set of
- boundaries that are multiples of 10/100/1000/etc.
- """
- i = largest // 5
- if not i:
- return largest
- multiplier = 1
- while i >= 10:
- i = i // 10
- multiplier = multiplier * 10
- return i * multiplier
-
- def max_graph_value(self, largest):
- # Round up to next integer.
- largest = int(largest) + 1
- increment = self.increment_size(largest)
- return ((largest + increment - 1) // increment) * increment
-
-class Line(object):
- def __init__(self, points, type, title, label, comment, fmt="%s %s"):
- self.points = points
- self.type = type
- self.title = title
- self.label = label
- self.comment = comment
- self.fmt = fmt
-
- def print_label(self, inx, x, y):
- if self.label:
- print 'set label %s "%s" at %s,%s right' % (inx, self.label, x, y)
-
- def plot_string(self):
- if self.title:
- title_string = 'title "%s"' % self.title
- else:
- title_string = 'notitle'
- return "'-' %s with lines lt %s" % (title_string, self.type)
-
- def print_points(self, fmt=None):
- if fmt is None:
- fmt = self.fmt
- if self.comment:
- print '# %s' % self.comment
- for x, y in self.points:
- # If y is None, it usually represents some kind of break
- # in the line's index number. We might want to represent
- # this some way rather than just drawing the line straight
- # between the two points on either side.
- if not y is None:
- print fmt % (x, y)
- print 'e'
-
- def get_x_values(self):
- return [ p[0] for p in self.points ]
-
- def get_y_values(self):
- return [ p[1] for p in self.points ]
-
-class Gnuplotter(Plotter):
-
- def __init__(self, title, key_location):
- self.lines = []
- self.title = title
- self.key_location = key_location
-
- def line(self, points, type, title=None, label=None, comment=None, fmt='%s %s'):
- if points:
- line = Line(points, type, title, label, comment, fmt)
- self.lines.append(line)
-
- def plot_string(self, line):
- return line.plot_string()
-
- def vertical_bar(self, x, type, label, comment):
- if self.get_min_x() <= x and x <= self.get_max_x():
- points = [(x, 0), (x, self.max_graph_value(self.get_max_y()))]
- self.line(points, type, label, comment)
-
- def get_all_x_values(self):
- result = []
- for line in self.lines:
- result.extend(line.get_x_values())
- return [r for r in result if not r is None]
-
- def get_all_y_values(self):
- result = []
- for line in self.lines:
- result.extend(line.get_y_values())
- return [r for r in result if not r is None]
-
- def get_min_x(self):
- try:
- return self.min_x
- except AttributeError:
- try:
- self.min_x = min(self.get_all_x_values())
- except ValueError:
- self.min_x = 0
- return self.min_x
-
- def get_max_x(self):
- try:
- return self.max_x
- except AttributeError:
- try:
- self.max_x = max(self.get_all_x_values())
- except ValueError:
- self.max_x = 0
- return self.max_x
-
- def get_min_y(self):
- try:
- return self.min_y
- except AttributeError:
- try:
- self.min_y = min(self.get_all_y_values())
- except ValueError:
- self.min_y = 0
- return self.min_y
-
- def get_max_y(self):
- try:
- return self.max_y
- except AttributeError:
- try:
- self.max_y = max(self.get_all_y_values())
- except ValueError:
- self.max_y = 0
- return self.max_y
-
- def draw(self):
-
- if not self.lines:
- return
-
- if self.title:
- print 'set title "%s"' % self.title
- print 'set key %s' % self.key_location
-
- min_y = self.get_min_y()
- max_y = self.max_graph_value(self.get_max_y())
- incr = (max_y - min_y) / 10.0
- start = min_y + (max_y / 2.0) + (2.0 * incr)
- position = [ start - (i * incr) for i in range(5) ]
-
- inx = 1
- for line in self.lines:
- line.print_label(inx, line.points[0][0]-1,
- position[(inx-1) % len(position)])
- inx += 1
-
- plot_strings = [ self.plot_string(l) for l in self.lines ]
- print 'plot ' + ', \\\n '.join(plot_strings)
-
- for line in self.lines:
- line.print_points()
-
-
-
-def untar(fname):
- import tarfile
- tar = tarfile.open(name=fname, mode='r')
- for tarinfo in tar:
- tar.extract(tarinfo)
- tar.close()
-
-def unzip(fname):
- import zipfile
- zf = zipfile.ZipFile(fname, 'r')
- for name in zf.namelist():
- dir = os.path.dirname(name)
- try:
- os.makedirs(dir)
- except:
- pass
- open(name, 'w').write(zf.read(name))
-
-def read_tree(dir):
- for dirpath, dirnames, filenames in os.walk(dir):
- for fn in filenames:
- fn = os.path.join(dirpath, fn)
- if os.path.isfile(fn):
- open(fn, 'rb').read()
-
-def redirect_to_file(command, log):
- return '%s > %s 2>&1' % (command, log)
-
-def tee_to_file(command, log):
- return '%s 2>&1 | tee %s' % (command, log)
-
-
-
-class SConsTimer(object):
- """
- Usage: scons-time SUBCOMMAND [ARGUMENTS]
- Type "scons-time help SUBCOMMAND" for help on a specific subcommand.
-
- Available subcommands:
- func Extract test-run data for a function
- help Provides help
- mem Extract --debug=memory data from test runs
- obj Extract --debug=count data from test runs
- time Extract --debug=time data from test runs
- run Runs a test configuration
- """
-
- name = 'scons-time'
- name_spaces = ' '*len(name)
-
- def makedict(**kw):
- return kw
-
- default_settings = makedict(
- aegis = 'aegis',
- aegis_project = None,
- chdir = None,
- config_file = None,
- initial_commands = [],
- key_location = 'bottom left',
- orig_cwd = os.getcwd(),
- outdir = None,
- prefix = '',
- python = '"%s"' % sys.executable,
- redirect = redirect_to_file,
- scons = None,
- scons_flags = '--debug=count --debug=memory --debug=time --debug=memoizer',
- scons_lib_dir = None,
- scons_wrapper = None,
- startup_targets = '--help',
- subdir = None,
- subversion_url = None,
- svn = 'svn',
- svn_co_flag = '-q',
- tar = 'tar',
- targets = '',
- targets0 = None,
- targets1 = None,
- targets2 = None,
- title = None,
- unzip = 'unzip',
- verbose = False,
- vertical_bars = [],
-
- unpack_map = {
- '.tar.gz' : (untar, '%(tar)s xzf %%s'),
- '.tgz' : (untar, '%(tar)s xzf %%s'),
- '.tar' : (untar, '%(tar)s xf %%s'),
- '.zip' : (unzip, '%(unzip)s %%s'),
- },
- )
-
- run_titles = [
- 'Startup',
- 'Full build',
- 'Up-to-date build',
- ]
-
- run_commands = [
- '%(python)s %(scons_wrapper)s %(scons_flags)s --profile=%(prof0)s %(targets0)s',
- '%(python)s %(scons_wrapper)s %(scons_flags)s --profile=%(prof1)s %(targets1)s',
- '%(python)s %(scons_wrapper)s %(scons_flags)s --profile=%(prof2)s %(targets2)s',
- ]
-
- stages = [
- 'pre-read',
- 'post-read',
- 'pre-build',
- 'post-build',
- ]
-
- stage_strings = {
- 'pre-read' : 'Memory before reading SConscript files:',
- 'post-read' : 'Memory after reading SConscript files:',
- 'pre-build' : 'Memory before building targets:',
- 'post-build' : 'Memory after building targets:',
- }
-
- memory_string_all = 'Memory '
-
- default_stage = stages[-1]
-
- time_strings = {
- 'total' : 'Total build time',
- 'SConscripts' : 'Total SConscript file execution time',
- 'SCons' : 'Total SCons execution time',
- 'commands' : 'Total command execution time',
- }
-
- time_string_all = 'Total .* time'
-
- #
-
- def __init__(self):
- self.__dict__.update(self.default_settings)
-
- # Functions for displaying and executing commands.
-
- def subst(self, x, dictionary):
- try:
- return x % dictionary
- except TypeError:
- # x isn't a string (it's probably a Python function),
- # so just return it.
- return x
-
- def subst_variables(self, command, dictionary):
- """
- Substitutes (via the format operator) the values in the specified
- dictionary into the specified command.
-
- The command can be an (action, string) tuple. In all cases, we
- perform substitution on strings and don't worry if something isn't
- a string. (It's probably a Python function to be executed.)
- """
- try:
- command + ''
- except TypeError:
- action = command[0]
- string = command[1]
- args = command[2:]
- else:
- action = command
- string = action
- args = (())
- action = self.subst(action, dictionary)
- string = self.subst(string, dictionary)
- return (action, string, args)
-
- def _do_not_display(self, msg, *args):
- pass
-
- def display(self, msg, *args):
- """
- Displays the specified message.
-
- Each message is prepended with a standard prefix of our name
- plus the time.
- """
- if callable(msg):
- msg = msg(*args)
- else:
- msg = msg % args
- if msg is None:
- return
- fmt = '%s[%s]: %s\n'
- sys.stdout.write(fmt % (self.name, time.strftime('%H:%M:%S'), msg))
-
- def _do_not_execute(self, action, *args):
- pass
-
- def execute(self, action, *args):
- """
- Executes the specified action.
-
- The action is called if it's a callable Python function, and
- otherwise passed to os.system().
- """
- if callable(action):
- action(*args)
- else:
- os.system(action % args)
-
- def run_command_list(self, commands, dict):
- """
- Executes a list of commands, substituting values from the
- specified dictionary.
- """
- commands = [ self.subst_variables(c, dict) for c in commands ]
- for action, string, args in commands:
- self.display(string, *args)
- sys.stdout.flush()
- status = self.execute(action, *args)
- if status:
- sys.exit(status)
-
- def log_display(self, command, log):
- command = self.subst(command, self.__dict__)
- if log:
- command = self.redirect(command, log)
- return command
-
- def log_execute(self, command, log):
- command = self.subst(command, self.__dict__)
- output = os.popen(command).read()
- if self.verbose:
- sys.stdout.write(output)
- open(log, 'wb').write(output)
-
- #
-
- def archive_splitext(self, path):
- """
- Splits an archive name into a filename base and extension.
-
- This is like os.path.splitext() (which it calls) except that it
- also looks for '.tar.gz' and treats it as an atomic extensions.
- """
- if path.endswith('.tar.gz'):
- return path[:-7], path[-7:]
- else:
- return os.path.splitext(path)
-
- def args_to_files(self, args, tail=None):
- """
- Takes a list of arguments, expands any glob patterns, and
- returns the last "tail" files from the list.
- """
- files = []
- for a in args:
- files.extend(sorted(glob.glob(a)))
-
- if tail:
- files = files[-tail:]
-
- return files
-
- def ascii_table(self, files, columns,
- line_function, file_function=lambda x: x,
- *args, **kw):
-
- header_fmt = ' '.join(['%12s'] * len(columns))
- line_fmt = header_fmt + ' %s'
-
- print header_fmt % columns
-
- for file in files:
- t = line_function(file, *args, **kw)
- if t is None:
- t = []
- diff = len(columns) - len(t)
- if diff > 0:
- t += [''] * diff
- t.append(file_function(file))
- print line_fmt % tuple(t)
-
- def collect_results(self, files, function, *args, **kw):
- results = {}
-
- for file in files:
- base = os.path.splitext(file)[0]
- run, index = base.split('-')[-2:]
-
- run = int(run)
- index = int(index)
-
- value = function(file, *args, **kw)
-
- try:
- r = results[index]
- except KeyError:
- r = []
- results[index] = r
- r.append((run, value))
-
- return results
-
- def doc_to_help(self, obj):
- """
- Translates an object's __doc__ string into help text.
-
- This strips a consistent number of spaces from each line in the
- help text, essentially "outdenting" the text to the left-most
- column.
- """
- doc = obj.__doc__
- if doc is None:
- return ''
- return self.outdent(doc)
-
- def find_next_run_number(self, dir, prefix):
- """
- Returns the next run number in a directory for the specified prefix.
-
- Examines the contents the specified directory for files with the
- specified prefix, extracts the run numbers from each file name,
- and returns the next run number after the largest it finds.
- """
- x = re.compile(re.escape(prefix) + '-([0-9]+).*')
- matches = [x.match(e) for e in os.listdir(dir)]
- matches = [_f for _f in matches if _f]
- if not matches:
- return 0
- run_numbers = [int(m.group(1)) for m in matches]
- return int(max(run_numbers)) + 1
-
- def gnuplot_results(self, results, fmt='%s %.3f'):
- """
- Prints out a set of results in Gnuplot format.
- """
- gp = Gnuplotter(self.title, self.key_location)
-
- for i in sorted(results.keys()):
- try:
- t = self.run_titles[i]
- except IndexError:
- t = '??? %s ???' % i
- results[i].sort()
- gp.line(results[i], i+1, t, None, t, fmt=fmt)
-
- for bar_tuple in self.vertical_bars:
- try:
- x, type, label, comment = bar_tuple
- except ValueError:
- x, type, label = bar_tuple
- comment = label
- gp.vertical_bar(x, type, label, comment)
-
- gp.draw()
-
- def logfile_name(self, invocation):
- """
- Returns the absolute path of a log file for the specificed
- invocation number.
- """
- name = self.prefix_run + '-%d.log' % invocation
- return os.path.join(self.outdir, name)
-
- def outdent(self, s):
- """
- Strip as many spaces from each line as are found at the beginning
- of the first line in the list.
- """
- lines = s.split('\n')
- if lines[0] == '':
- lines = lines[1:]
- spaces = re.match(' *', lines[0]).group(0)
- def strip_initial_spaces(l, s=spaces):
- if l.startswith(spaces):
- l = l[len(spaces):]
- return l
- return '\n'.join([ strip_initial_spaces(l) for l in lines ]) + '\n'
-
- def profile_name(self, invocation):
- """
- Returns the absolute path of a profile file for the specified
- invocation number.
- """
- name = self.prefix_run + '-%d.prof' % invocation
- return os.path.join(self.outdir, name)
-
- def set_env(self, key, value):
- os.environ[key] = value
-
- #
-
- def get_debug_times(self, file, time_string=None):
- """
- Fetch times from the --debug=time strings in the specified file.
- """
- if time_string is None:
- search_string = self.time_string_all
- else:
- search_string = time_string
- contents = open(file).read()
- if not contents:
- sys.stderr.write('file %s has no contents!\n' % repr(file))
- return None
- result = re.findall(r'%s: ([\d\.]*)' % search_string, contents)[-4:]
- result = [ float(r) for r in result ]
- if not time_string is None:
- try:
- result = result[0]
- except IndexError:
- sys.stderr.write('file %s has no results!\n' % repr(file))
- return None
- return result
-
- def get_function_profile(self, file, function):
- """
- Returns the file, line number, function name, and cumulative time.
- """
- try:
- import pstats
- except ImportError, e:
- sys.stderr.write('%s: func: %s\n' % (self.name, e))
- sys.stderr.write('%s This version of Python is missing the profiler.\n' % self.name_spaces)
- sys.stderr.write('%s Cannot use the "func" subcommand.\n' % self.name_spaces)
- sys.exit(1)
- statistics = pstats.Stats(file).stats
- matches = [ e for e in statistics.items() if e[0][2] == function ]
- r = matches[0]
- return r[0][0], r[0][1], r[0][2], r[1][3]
-
- def get_function_time(self, file, function):
- """
- Returns just the cumulative time for the specified function.
- """
- return self.get_function_profile(file, function)[3]
-
- def get_memory(self, file, memory_string=None):
- """
- Returns a list of integers of the amount of memory used. The
- default behavior is to return all the stages.
- """
- if memory_string is None:
- search_string = self.memory_string_all
- else:
- search_string = memory_string
- lines = open(file).readlines()
- lines = [ l for l in lines if l.startswith(search_string) ][-4:]
- result = [ int(l.split()[-1]) for l in lines[-4:] ]
- if len(result) == 1:
- result = result[0]
- return result
-
- def get_object_counts(self, file, object_name, index=None):
- """
- Returns the counts of the specified object_name.
- """
- object_string = ' ' + object_name + '\n'
- lines = open(file).readlines()
- line = [ l for l in lines if l.endswith(object_string) ][0]
- result = [ int(field) for field in line.split()[:4] ]
- if index is not None:
- result = result[index]
- return result
-
- #
-
- command_alias = {}
-
- def execute_subcommand(self, argv):
- """
- Executes the do_*() function for the specified subcommand (argv[0]).
- """
- if not argv:
- return
- cmdName = self.command_alias.get(argv[0], argv[0])
- try:
- func = getattr(self, 'do_' + cmdName)
- except AttributeError:
- return self.default(argv)
- try:
- return func(argv)
- except TypeError, e:
- sys.stderr.write("%s %s: %s\n" % (self.name, cmdName, e))
- import traceback
- traceback.print_exc(file=sys.stderr)
- sys.stderr.write("Try '%s help %s'\n" % (self.name, cmdName))
-
- def default(self, argv):
- """
- The default behavior for an unknown subcommand. Prints an
- error message and exits.
- """
- sys.stderr.write('%s: Unknown subcommand "%s".\n' % (self.name, argv[0]))
- sys.stderr.write('Type "%s help" for usage.\n' % self.name)
- sys.exit(1)
-
- #
-
- def do_help(self, argv):
- """
- """
- if argv[1:]:
- for arg in argv[1:]:
- try:
- func = getattr(self, 'do_' + arg)
- except AttributeError:
- sys.stderr.write('%s: No help for "%s"\n' % (self.name, arg))
- else:
- try:
- help = getattr(self, 'help_' + arg)
- except AttributeError:
- sys.stdout.write(self.doc_to_help(func))
- sys.stdout.flush()
- else:
- help()
- else:
- doc = self.doc_to_help(self.__class__)
- if doc:
- sys.stdout.write(doc)
- sys.stdout.flush()
- return None
-
- #
-
- def help_func(self):
- help = """\
- Usage: scons-time func [OPTIONS] FILE [...]
-
- -C DIR, --chdir=DIR Change to DIR before looking for files
- -f FILE, --file=FILE Read configuration from specified FILE
- --fmt=FORMAT, --format=FORMAT Print data in specified FORMAT
- --func=NAME, --function=NAME Report time for function NAME
- -h, --help Print this help and exit
- -p STRING, --prefix=STRING Use STRING as log file/profile prefix
- -t NUMBER, --tail=NUMBER Only report the last NUMBER files
- --title=TITLE Specify the output plot TITLE
- """
- sys.stdout.write(self.outdent(help))
- sys.stdout.flush()
-
- def do_func(self, argv):
- """
- """
- format = 'ascii'
- function_name = '_main'
- tail = None
-
- short_opts = '?C:f:hp:t:'
-
- long_opts = [
- 'chdir=',
- 'file=',
- 'fmt=',
- 'format=',
- 'func=',
- 'function=',
- 'help',
- 'prefix=',
- 'tail=',
- 'title=',
- ]
-
- opts, args = getopt.getopt(argv[1:], short_opts, long_opts)
-
- for o, a in opts:
- if o in ('-C', '--chdir'):
- self.chdir = a
- elif o in ('-f', '--file'):
- self.config_file = a
- elif o in ('--fmt', '--format'):
- format = a
- elif o in ('--func', '--function'):
- function_name = a
- elif o in ('-?', '-h', '--help'):
- self.do_help(['help', 'func'])
- sys.exit(0)
- elif o in ('--max',):
- max_time = int(a)
- elif o in ('-p', '--prefix'):
- self.prefix = a
- elif o in ('-t', '--tail'):
- tail = int(a)
- elif o in ('--title',):
- self.title = a
-
- if self.config_file:
- exec open(self.config_file, 'rU').read() in self.__dict__
-
- if self.chdir:
- os.chdir(self.chdir)
-
- if not args:
-
- pattern = '%s*.prof' % self.prefix
- args = self.args_to_files([pattern], tail)
-
- if not args:
- if self.chdir:
- directory = self.chdir
- else:
- directory = os.getcwd()
-
- sys.stderr.write('%s: func: No arguments specified.\n' % self.name)
- sys.stderr.write('%s No %s*.prof files found in "%s".\n' % (self.name_spaces, self.prefix, directory))
- sys.stderr.write('%s Type "%s help func" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
-
- else:
-
- args = self.args_to_files(args, tail)
-
- cwd_ = os.getcwd() + os.sep
-
- if format == 'ascii':
-
- for file in args:
- try:
- f, line, func, time = \
- self.get_function_profile(file, function_name)
- except ValueError, e:
- sys.stderr.write("%s: func: %s: %s\n" %
- (self.name, file, e))
- else:
- if f.startswith(cwd_):
- f = f[len(cwd_):]
- print "%.3f %s:%d(%s)" % (time, f, line, func)
-
- elif format == 'gnuplot':
-
- results = self.collect_results(args, self.get_function_time,
- function_name)
-
- self.gnuplot_results(results)
-
- else:
-
- sys.stderr.write('%s: func: Unknown format "%s".\n' % (self.name, format))
- sys.exit(1)
-
- #
-
- def help_mem(self):
- help = """\
- Usage: scons-time mem [OPTIONS] FILE [...]
-
- -C DIR, --chdir=DIR Change to DIR before looking for files
- -f FILE, --file=FILE Read configuration from specified FILE
- --fmt=FORMAT, --format=FORMAT Print data in specified FORMAT
- -h, --help Print this help and exit
- -p STRING, --prefix=STRING Use STRING as log file/profile prefix
- --stage=STAGE Plot memory at the specified stage:
- pre-read, post-read, pre-build,
- post-build (default: post-build)
- -t NUMBER, --tail=NUMBER Only report the last NUMBER files
- --title=TITLE Specify the output plot TITLE
- """
- sys.stdout.write(self.outdent(help))
- sys.stdout.flush()
-
- def do_mem(self, argv):
-
- format = 'ascii'
- logfile_path = lambda x: x
- stage = self.default_stage
- tail = None
-
- short_opts = '?C:f:hp:t:'
-
- long_opts = [
- 'chdir=',
- 'file=',
- 'fmt=',
- 'format=',
- 'help',
- 'prefix=',
- 'stage=',
- 'tail=',
- 'title=',
- ]
-
- opts, args = getopt.getopt(argv[1:], short_opts, long_opts)
-
- for o, a in opts:
- if o in ('-C', '--chdir'):
- self.chdir = a
- elif o in ('-f', '--file'):
- self.config_file = a
- elif o in ('--fmt', '--format'):
- format = a
- elif o in ('-?', '-h', '--help'):
- self.do_help(['help', 'mem'])
- sys.exit(0)
- elif o in ('-p', '--prefix'):
- self.prefix = a
- elif o in ('--stage',):
- if not a in self.stages:
- sys.stderr.write('%s: mem: Unrecognized stage "%s".\n' % (self.name, a))
- sys.exit(1)
- stage = a
- elif o in ('-t', '--tail'):
- tail = int(a)
- elif o in ('--title',):
- self.title = a
-
- if self.config_file:
- HACK_for_exec(open(self.config_file, 'rU').read(), self.__dict__)
-
- if self.chdir:
- os.chdir(self.chdir)
- logfile_path = lambda x: os.path.join(self.chdir, x)
-
- if not args:
-
- pattern = '%s*.log' % self.prefix
- args = self.args_to_files([pattern], tail)
-
- if not args:
- if self.chdir:
- directory = self.chdir
- else:
- directory = os.getcwd()
-
- sys.stderr.write('%s: mem: No arguments specified.\n' % self.name)
- sys.stderr.write('%s No %s*.log files found in "%s".\n' % (self.name_spaces, self.prefix, directory))
- sys.stderr.write('%s Type "%s help mem" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
-
- else:
-
- args = self.args_to_files(args, tail)
-
- cwd_ = os.getcwd() + os.sep
-
- if format == 'ascii':
-
- self.ascii_table(args, tuple(self.stages), self.get_memory, logfile_path)
-
- elif format == 'gnuplot':
-
- results = self.collect_results(args, self.get_memory,
- self.stage_strings[stage])
-
- self.gnuplot_results(results)
-
- else:
-
- sys.stderr.write('%s: mem: Unknown format "%s".\n' % (self.name, format))
- sys.exit(1)
-
- return 0
-
- #
-
- def help_obj(self):
- help = """\
- Usage: scons-time obj [OPTIONS] OBJECT FILE [...]
-
- -C DIR, --chdir=DIR Change to DIR before looking for files
- -f FILE, --file=FILE Read configuration from specified FILE
- --fmt=FORMAT, --format=FORMAT Print data in specified FORMAT
- -h, --help Print this help and exit
- -p STRING, --prefix=STRING Use STRING as log file/profile prefix
- --stage=STAGE Plot memory at the specified stage:
- pre-read, post-read, pre-build,
- post-build (default: post-build)
- -t NUMBER, --tail=NUMBER Only report the last NUMBER files
- --title=TITLE Specify the output plot TITLE
- """
- sys.stdout.write(self.outdent(help))
- sys.stdout.flush()
-
- def do_obj(self, argv):
-
- format = 'ascii'
- logfile_path = lambda x: x
- stage = self.default_stage
- tail = None
-
- short_opts = '?C:f:hp:t:'
-
- long_opts = [
- 'chdir=',
- 'file=',
- 'fmt=',
- 'format=',
- 'help',
- 'prefix=',
- 'stage=',
- 'tail=',
- 'title=',
- ]
-
- opts, args = getopt.getopt(argv[1:], short_opts, long_opts)
-
- for o, a in opts:
- if o in ('-C', '--chdir'):
- self.chdir = a
- elif o in ('-f', '--file'):
- self.config_file = a
- elif o in ('--fmt', '--format'):
- format = a
- elif o in ('-?', '-h', '--help'):
- self.do_help(['help', 'obj'])
- sys.exit(0)
- elif o in ('-p', '--prefix'):
- self.prefix = a
- elif o in ('--stage',):
- if not a in self.stages:
- sys.stderr.write('%s: obj: Unrecognized stage "%s".\n' % (self.name, a))
- sys.stderr.write('%s Type "%s help obj" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
- stage = a
- elif o in ('-t', '--tail'):
- tail = int(a)
- elif o in ('--title',):
- self.title = a
-
- if not args:
- sys.stderr.write('%s: obj: Must specify an object name.\n' % self.name)
- sys.stderr.write('%s Type "%s help obj" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
-
- object_name = args.pop(0)
-
- if self.config_file:
- HACK_for_exec(open(self.config_file, 'rU').read(), self.__dict__)
-
- if self.chdir:
- os.chdir(self.chdir)
- logfile_path = lambda x: os.path.join(self.chdir, x)
-
- if not args:
-
- pattern = '%s*.log' % self.prefix
- args = self.args_to_files([pattern], tail)
-
- if not args:
- if self.chdir:
- directory = self.chdir
- else:
- directory = os.getcwd()
-
- sys.stderr.write('%s: obj: No arguments specified.\n' % self.name)
- sys.stderr.write('%s No %s*.log files found in "%s".\n' % (self.name_spaces, self.prefix, directory))
- sys.stderr.write('%s Type "%s help obj" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
-
- else:
-
- args = self.args_to_files(args, tail)
-
- cwd_ = os.getcwd() + os.sep
-
- if format == 'ascii':
-
- self.ascii_table(args, tuple(self.stages), self.get_object_counts, logfile_path, object_name)
-
- elif format == 'gnuplot':
-
- stage_index = 0
- for s in self.stages:
- if stage == s:
- break
- stage_index = stage_index + 1
-
- results = self.collect_results(args, self.get_object_counts,
- object_name, stage_index)
-
- self.gnuplot_results(results)
-
- else:
-
- sys.stderr.write('%s: obj: Unknown format "%s".\n' % (self.name, format))
- sys.exit(1)
-
- return 0
-
- #
-
- def help_run(self):
- help = """\
- Usage: scons-time run [OPTIONS] [FILE ...]
-
- --aegis=PROJECT Use SCons from the Aegis PROJECT
- --chdir=DIR Name of unpacked directory for chdir
- -f FILE, --file=FILE Read configuration from specified FILE
- -h, --help Print this help and exit
- -n, --no-exec No execute, just print command lines
- --number=NUMBER Put output in files for run NUMBER
- --outdir=OUTDIR Put output files in OUTDIR
- -p STRING, --prefix=STRING Use STRING as log file/profile prefix
- --python=PYTHON Time using the specified PYTHON
- -q, --quiet Don't print command lines
- --scons=SCONS Time using the specified SCONS
- --svn=URL, --subversion=URL Use SCons from Subversion URL
- -v, --verbose Display output of commands
- """
- sys.stdout.write(self.outdent(help))
- sys.stdout.flush()
-
- def do_run(self, argv):
- """
- """
- run_number_list = [None]
-
- short_opts = '?f:hnp:qs:v'
-
- long_opts = [
- 'aegis=',
- 'file=',
- 'help',
- 'no-exec',
- 'number=',
- 'outdir=',
- 'prefix=',
- 'python=',
- 'quiet',
- 'scons=',
- 'svn=',
- 'subdir=',
- 'subversion=',
- 'verbose',
- ]
-
- opts, args = getopt.getopt(argv[1:], short_opts, long_opts)
-
- for o, a in opts:
- if o in ('--aegis',):
- self.aegis_project = a
- elif o in ('-f', '--file'):
- self.config_file = a
- elif o in ('-?', '-h', '--help'):
- self.do_help(['help', 'run'])
- sys.exit(0)
- elif o in ('-n', '--no-exec'):
- self.execute = self._do_not_execute
- elif o in ('--number',):
- run_number_list = self.split_run_numbers(a)
- elif o in ('--outdir',):
- self.outdir = a
- elif o in ('-p', '--prefix'):
- self.prefix = a
- elif o in ('--python',):
- self.python = a
- elif o in ('-q', '--quiet'):
- self.display = self._do_not_display
- elif o in ('-s', '--subdir'):
- self.subdir = a
- elif o in ('--scons',):
- self.scons = a
- elif o in ('--svn', '--subversion'):
- self.subversion_url = a
- elif o in ('-v', '--verbose'):
- self.redirect = tee_to_file
- self.verbose = True
- self.svn_co_flag = ''
-
- if not args and not self.config_file:
- sys.stderr.write('%s: run: No arguments or -f config file specified.\n' % self.name)
- sys.stderr.write('%s Type "%s help run" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
-
- if self.config_file:
- exec open(self.config_file, 'rU').read() in self.__dict__
-
- if args:
- self.archive_list = args
-
- archive_file_name = os.path.split(self.archive_list[0])[1]
-
- if not self.subdir:
- self.subdir = self.archive_splitext(archive_file_name)[0]
-
- if not self.prefix:
- self.prefix = self.archive_splitext(archive_file_name)[0]
-
- prepare = None
- if self.subversion_url:
- prepare = self.prep_subversion_run
- elif self.aegis_project:
- prepare = self.prep_aegis_run
-
- for run_number in run_number_list:
- self.individual_run(run_number, self.archive_list, prepare)
-
- def split_run_numbers(self, s):
- result = []
- for n in s.split(','):
- try:
- x, y = n.split('-')
- except ValueError:
- result.append(int(n))
- else:
- result.extend(list(range(int(x), int(y)+1)))
- return result
-
- def scons_path(self, dir):
- return os.path.join(dir, 'src', 'script', 'scons.py')
-
- def scons_lib_dir_path(self, dir):
- return os.path.join(dir, 'src', 'engine')
-
- def prep_aegis_run(self, commands, removals):
- self.aegis_tmpdir = make_temp_file(prefix = self.name + '-aegis-')
- removals.append((shutil.rmtree, 'rm -rf %%s', self.aegis_tmpdir))
-
- self.aegis_parent_project = os.path.splitext(self.aegis_project)[0]
- self.scons = self.scons_path(self.aegis_tmpdir)
- self.scons_lib_dir = self.scons_lib_dir_path(self.aegis_tmpdir)
-
- commands.extend([
- 'mkdir %(aegis_tmpdir)s',
- (lambda: os.chdir(self.aegis_tmpdir), 'cd %(aegis_tmpdir)s'),
- '%(aegis)s -cp -ind -p %(aegis_parent_project)s .',
- '%(aegis)s -cp -ind -p %(aegis_project)s -delta %(run_number)s .',
- ])
-
- def prep_subversion_run(self, commands, removals):
- self.svn_tmpdir = make_temp_file(prefix = self.name + '-svn-')
- removals.append((shutil.rmtree, 'rm -rf %%s', self.svn_tmpdir))
-
- self.scons = self.scons_path(self.svn_tmpdir)
- self.scons_lib_dir = self.scons_lib_dir_path(self.svn_tmpdir)
-
- commands.extend([
- 'mkdir %(svn_tmpdir)s',
- '%(svn)s co %(svn_co_flag)s -r %(run_number)s %(subversion_url)s %(svn_tmpdir)s',
- ])
-
- def individual_run(self, run_number, archive_list, prepare=None):
- """
- Performs an individual run of the default SCons invocations.
- """
-
- commands = []
- removals = []
-
- if prepare:
- prepare(commands, removals)
-
- save_scons = self.scons
- save_scons_wrapper = self.scons_wrapper
- save_scons_lib_dir = self.scons_lib_dir
-
- if self.outdir is None:
- self.outdir = self.orig_cwd
- elif not os.path.isabs(self.outdir):
- self.outdir = os.path.join(self.orig_cwd, self.outdir)
-
- if self.scons is None:
- self.scons = self.scons_path(self.orig_cwd)
-
- if self.scons_lib_dir is None:
- self.scons_lib_dir = self.scons_lib_dir_path(self.orig_cwd)
-
- if self.scons_wrapper is None:
- self.scons_wrapper = self.scons
-
- if not run_number:
- run_number = self.find_next_run_number(self.outdir, self.prefix)
-
- self.run_number = str(run_number)
-
- self.prefix_run = self.prefix + '-%03d' % run_number
-
- if self.targets0 is None:
- self.targets0 = self.startup_targets
- if self.targets1 is None:
- self.targets1 = self.targets
- if self.targets2 is None:
- self.targets2 = self.targets
-
- self.tmpdir = make_temp_file(prefix = self.name + '-')
-
- commands.extend([
- 'mkdir %(tmpdir)s',
-
- (os.chdir, 'cd %%s', self.tmpdir),
- ])
-
- for archive in archive_list:
- if not os.path.isabs(archive):
- archive = os.path.join(self.orig_cwd, archive)
- if os.path.isdir(archive):
- dest = os.path.split(archive)[1]
- commands.append((shutil.copytree, 'cp -r %%s %%s', archive, dest))
- else:
- suffix = self.archive_splitext(archive)[1]
- unpack_command = self.unpack_map.get(suffix)
- if not unpack_command:
- dest = os.path.split(archive)[1]
- commands.append((shutil.copyfile, 'cp %%s %%s', archive, dest))
- else:
- commands.append(unpack_command + (archive,))
-
- commands.extend([
- (os.chdir, 'cd %%s', self.subdir),
- ])
-
- commands.extend(self.initial_commands)
-
- commands.extend([
- (lambda: read_tree('.'),
- 'find * -type f | xargs cat > /dev/null'),
-
- (self.set_env, 'export %%s=%%s',
- 'SCONS_LIB_DIR', self.scons_lib_dir),
-
- '%(python)s %(scons_wrapper)s --version',
- ])
-
- index = 0
- for run_command in self.run_commands:
- setattr(self, 'prof%d' % index, self.profile_name(index))
- c = (
- self.log_execute,
- self.log_display,
- run_command,
- self.logfile_name(index),
- )
- commands.append(c)
- index = index + 1
-
- commands.extend([
- (os.chdir, 'cd %%s', self.orig_cwd),
- ])
-
- if not os.environ.get('PRESERVE'):
- commands.extend(removals)
-
- commands.append((shutil.rmtree, 'rm -rf %%s', self.tmpdir))
-
- self.run_command_list(commands, self.__dict__)
-
- self.scons = save_scons
- self.scons_lib_dir = save_scons_lib_dir
- self.scons_wrapper = save_scons_wrapper
-
- #
-
- def help_time(self):
- help = """\
- Usage: scons-time time [OPTIONS] FILE [...]
-
- -C DIR, --chdir=DIR Change to DIR before looking for files
- -f FILE, --file=FILE Read configuration from specified FILE
- --fmt=FORMAT, --format=FORMAT Print data in specified FORMAT
- -h, --help Print this help and exit
- -p STRING, --prefix=STRING Use STRING as log file/profile prefix
- -t NUMBER, --tail=NUMBER Only report the last NUMBER files
- --which=TIMER Plot timings for TIMER: total,
- SConscripts, SCons, commands.
- """
- sys.stdout.write(self.outdent(help))
- sys.stdout.flush()
-
- def do_time(self, argv):
-
- format = 'ascii'
- logfile_path = lambda x: x
- tail = None
- which = 'total'
-
- short_opts = '?C:f:hp:t:'
-
- long_opts = [
- 'chdir=',
- 'file=',
- 'fmt=',
- 'format=',
- 'help',
- 'prefix=',
- 'tail=',
- 'title=',
- 'which=',
- ]
-
- opts, args = getopt.getopt(argv[1:], short_opts, long_opts)
-
- for o, a in opts:
- if o in ('-C', '--chdir'):
- self.chdir = a
- elif o in ('-f', '--file'):
- self.config_file = a
- elif o in ('--fmt', '--format'):
- format = a
- elif o in ('-?', '-h', '--help'):
- self.do_help(['help', 'time'])
- sys.exit(0)
- elif o in ('-p', '--prefix'):
- self.prefix = a
- elif o in ('-t', '--tail'):
- tail = int(a)
- elif o in ('--title',):
- self.title = a
- elif o in ('--which',):
- if not a in self.time_strings.keys():
- sys.stderr.write('%s: time: Unrecognized timer "%s".\n' % (self.name, a))
- sys.stderr.write('%s Type "%s help time" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
- which = a
-
- if self.config_file:
- HACK_for_exec(open(self.config_file, 'rU').read(), self.__dict__)
-
- if self.chdir:
- os.chdir(self.chdir)
- logfile_path = lambda x: os.path.join(self.chdir, x)
-
- if not args:
-
- pattern = '%s*.log' % self.prefix
- args = self.args_to_files([pattern], tail)
-
- if not args:
- if self.chdir:
- directory = self.chdir
- else:
- directory = os.getcwd()
-
- sys.stderr.write('%s: time: No arguments specified.\n' % self.name)
- sys.stderr.write('%s No %s*.log files found in "%s".\n' % (self.name_spaces, self.prefix, directory))
- sys.stderr.write('%s Type "%s help time" for help.\n' % (self.name_spaces, self.name))
- sys.exit(1)
-
- else:
-
- args = self.args_to_files(args, tail)
-
- cwd_ = os.getcwd() + os.sep
-
- if format == 'ascii':
-
- columns = ("Total", "SConscripts", "SCons", "commands")
- self.ascii_table(args, columns, self.get_debug_times, logfile_path)
-
- elif format == 'gnuplot':
-
- results = self.collect_results(args, self.get_debug_times,
- self.time_strings[which])
-
- self.gnuplot_results(results, fmt='%s %.6f')
-
- else:
-
- sys.stderr.write('%s: time: Unknown format "%s".\n' % (self.name, format))
- sys.exit(1)
-
-if __name__ == '__main__':
- opts, args = getopt.getopt(sys.argv[1:], 'h?V', ['help', 'version'])
-
- ST = SConsTimer()
-
- for o, a in opts:
- if o in ('-?', '-h', '--help'):
- ST.do_help(['help'])
- sys.exit(0)
- elif o in ('-V', '--version'):
- sys.stdout.write('scons-time version\n')
- sys.exit(0)
-
- if not args:
- sys.stderr.write('Type "%s help" for usage.\n' % ST.name)
- sys.exit(1)
-
- ST.execute_subcommand(args)
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4: