diff options
author | Steven Knight <knight@baldmt.com> | 2005-04-02 19:50:33 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2005-04-02 19:50:33 (GMT) |
commit | 13dcf8c4ebad065d6296e7a3da24b21a1666a974 (patch) | |
tree | 6149e7e01cdfa22db3b3086c4b525526ac84fec2 /src/engine/SCons/Script/Main.py | |
parent | c378212a5904028315760269a52272a3eb025dca (diff) | |
download | SCons-13dcf8c4ebad065d6296e7a3da24b21a1666a974.zip SCons-13dcf8c4ebad065d6296e7a3da24b21a1666a974.tar.gz SCons-13dcf8c4ebad065d6296e7a3da24b21a1666a974.tar.bz2 |
Remove widespread reliance on SCons.Node.FS.default_fs so we can initialize it once (later than we used to) and eliminate all the __setTopLevelDir() calls.
Diffstat (limited to 'src/engine/SCons/Script/Main.py')
-rw-r--r-- | src/engine/SCons/Script/Main.py | 264 |
1 files changed, 156 insertions, 108 deletions
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index d018d15..fd2a914 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -241,7 +241,6 @@ class QuestionTask(SCons.Taskmaster.Task): # Global variables keep_going_on_error = 0 -count_stats = None print_dtree = 0 print_explanations = 0 print_includes = 0 @@ -251,7 +250,6 @@ print_stacktrace = 0 print_stree = 0 print_time = 0 print_tree = 0 -memory_stats = None ignore_errors = 0 sconscript_time = 0 command_time = 0 @@ -260,6 +258,62 @@ profiling = 0 repositories = [] num_jobs = 1 # this is modifed by SConscript.SetJobs() +# +class Stats: + def __init__(self): + self.stats = [] + self.labels = [] + self.append = self.do_nothing + self.print_stats = self.do_nothing + def enable(self, outfp): + self.outfp = outfp + self.append = self.do_append + self.print_stats = self.do_print + def do_nothing(self, *args, **kw): + pass + +class CountStats(Stats): + def do_append(self, label): + self.labels.append(label) + self.stats.append(SCons.Debug.fetchLoggedInstances()) + def do_print(self): + stats_table = {} + for s in self.stats: + for n in map(lambda t: t[0], s): + stats_table[n] = [0, 0, 0, 0] + i = 0 + for s in self.stats: + for n, c in s: + stats_table[n][i] = c + i = i + 1 + keys = stats_table.keys() + keys.sort() + self.outfp.write("Object counts:\n") + pre = [" "] + post = [" %s\n"] + l = len(self.stats) + fmt1 = string.join(pre + [' %7s']*l + post, '') + fmt2 = string.join(pre + [' %7d']*l + post, '') + self.labels.append(("", "Class")) + self.outfp.write(fmt1 % tuple(map(lambda x: x[0], self.labels))) + self.outfp.write(fmt1 % tuple(map(lambda x: x[1], self.labels))) + for k in keys: + r = stats_table[k] + self.outfp.write(fmt2 % (r[0], r[1], r[2], r[3], k)) + +count_stats = CountStats() + +class MemStats(Stats): + def do_append(self, label): + self.labels.append(label) + self.stats.append(SCons.Debug.memory()) + def do_print(self): + fmt = 'Memory %-32s %12d\n' + for label, stats in map(None, self.labels, self.stats): + self.outfp.write(fmt % (label, stats)) + +memory_stats = MemStats() + # utility functions def get_all_children(node): return node.all_children() @@ -406,15 +460,13 @@ def _SConstruct_exists(dirname=''): return None def _set_globals(options): - global repositories, keep_going_on_error, ignore_errors + global keep_going_on_error, ignore_errors global count_stats, print_dtree global print_explanations, print_includes, print_memoizer global print_objects, print_stacktrace, print_stree global print_time, print_tree - global memory_outf, memory_stats + global memory_stats - if options.repository: - repositories.extend(options.repository) keep_going_on_error = options.keep_going try: debug_values = options.debug @@ -424,7 +476,7 @@ def _set_globals(options): pass else: if "count" in debug_values: - count_stats = [] + count_stats.enable(sys.stdout) if "dtree" in debug_values: print_dtree = 1 if "explain" in debug_values: @@ -436,8 +488,7 @@ def _set_globals(options): if "memoizer" in debug_values: print_memoizer = 1 if "memory" in debug_values: - memory_stats = [] - memory_outf = sys.stdout + memory_stats.enable(sys.stdout) if "objects" in debug_values: print_objects = 1 if "presub" in debug_values: @@ -795,50 +846,28 @@ class SConscriptSettableOptions: def _main(args, parser): - targets = [] - fs = SCons.Node.FS.default_fs - - # Enable deprecated warnings by default. + # Here's where everything really happens. + + # First order of business: set up default warnings and and then + # handle the user's warning options, so we can warn about anything + # that happens appropriately. + default_warnings = [ SCons.Warnings.CorruptSConsignWarning, + SCons.Warnings.DeprecatedWarning, + SCons.Warnings.DuplicateEnvironmentWarning, + SCons.Warnings.MissingSConscriptWarning, + SCons.Warnings.NoParallelSupportWarning, + SCons.Warnings.MisleadingKeywordsWarning, ] + for warning in default_warnings: + SCons.Warnings.enableWarningClass(warning) SCons.Warnings._warningOut = _scons_internal_warning - SCons.Warnings.enableWarningClass(SCons.Warnings.CorruptSConsignWarning) - SCons.Warnings.enableWarningClass(SCons.Warnings.DeprecatedWarning) - SCons.Warnings.enableWarningClass(SCons.Warnings.DuplicateEnvironmentWarning) - SCons.Warnings.enableWarningClass(SCons.Warnings.MissingSConscriptWarning) - SCons.Warnings.enableWarningClass(SCons.Warnings.NoParallelSupportWarning) - # This is good for newbies, and hopefully most everyone else too. - SCons.Warnings.enableWarningClass(SCons.Warnings.MisleadingKeywordsWarning) - - global ssoptions - ssoptions = SConscriptSettableOptions(options) - - _set_globals(options) - SCons.Node.implicit_cache = options.implicit_cache - SCons.Node.implicit_deps_changed = options.implicit_deps_changed - SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged if options.warn: _setup_warn(options.warn) - if options.noexec: - SCons.SConf.dryrun = 1 - SCons.Action.execute_actions = None - CleanTask.execute = CleanTask.show - if options.question: - SCons.SConf.dryrun = 1 - SCons.SConf.SetCacheMode(options.config) - SCons.SConf.SetProgressDisplay(progress_display) - if options.no_progress or options.silent: - progress_display.set_mode(0) - if options.silent: - display.set_mode(0) - if options.silent: - SCons.Action.print_actions = None - if options.cache_disable: - def disable(self): pass - fs.CacheDir = disable - if options.cache_force: - fs.cache_force = 1 - if options.cache_show: - fs.cache_show = 1 + # Next, we want to create the FS object that represents the outside + # world's file system, as that's central to a lot of initialization. + # To do this, however, we need to be in the directory from which we + # want to start everything, which means first handling any relevant + # options that might cause us to chdir somewhere (-C, -D, -U, -u). if options.directory: cdir = _create_path(options.directory) try: @@ -846,14 +875,11 @@ def _main(args, parser): except OSError: sys.stderr.write("Could not change directory to %s\n" % cdir) - xmit_args = [] - for a in args: - if '=' in a: - xmit_args.append(a) - else: - targets.append(a) - SCons.Script._Add_Arguments(xmit_args) - SCons.Script._Add_Targets(targets) + # The SConstruct file may be in a repository, so initialize those + # before we start the search up our path for one. + global repositories + if options.repository: + repositories.extend(options.repository) target_top = None if options.climb_up: @@ -869,8 +895,17 @@ def _main(args, parser): display("scons: Entering directory `%s'" % script_dir) os.chdir(script_dir) - fs.set_toplevel_dir(os.getcwd()) + # Now that we're in the top-level SConstruct directory, go ahead + # and initialize the FS object that represents the file system, + # and make it the build engine default. + fs = SCons.Node.FS.default_fs = SCons.Node.FS.FS() + + for rep in repositories: + fs.Repository(rep) + # Now that we have the FS object, the next order of business is to + # check for an SConstruct file (or other specified config file). + # If there isn't one, we can bail before doing any more work. scripts = [] if options.file: scripts.extend(options.file) @@ -879,15 +914,13 @@ def _main(args, parser): if sfile: scripts.append(sfile) - if options.help_msg: - if not scripts: + if not scripts: + if options.help_msg: # There's no SConstruct, but they specified -h. # Give them the options usage now, before we fail # trying to read a non-existent SConstruct file. parser.print_help() sys.exit(0) - - if not scripts: raise SCons.Errors.UserError, "No SConstruct file found." if scripts[0] == "-": @@ -896,6 +929,54 @@ def _main(args, parser): d = fs.File(scripts[0]).dir fs.set_SConstruct_dir(d) + # Now that we have the FS object and it's intialized, set up (most + # of) the rest of the options. + global ssoptions + ssoptions = SConscriptSettableOptions(options) + + _set_globals(options) + SCons.Node.implicit_cache = options.implicit_cache + SCons.Node.implicit_deps_changed = options.implicit_deps_changed + SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged + if options.noexec: + SCons.SConf.dryrun = 1 + SCons.Action.execute_actions = None + CleanTask.execute = CleanTask.show + if options.question: + SCons.SConf.dryrun = 1 + SCons.SConf.SetCacheMode(options.config) + SCons.SConf.SetProgressDisplay(progress_display) + + if options.no_progress or options.silent: + progress_display.set_mode(0) + if options.silent: + display.set_mode(0) + if options.silent: + SCons.Action.print_actions = None + if options.cache_disable: + def disable(self): pass + fs.CacheDir = disable + if options.cache_force: + fs.cache_force = 1 + if options.cache_show: + fs.cache_show = 1 + + if options.include_dir: + sys.path = options.include_dir + sys.path + + # That should cover (most of) the options. Next, set up the variables + # that hold command-line arguments, so the SConscript files that we + # read and execute have access to them. + targets = [] + xmit_args = [] + for a in args: + if '=' in a: + xmit_args.append(a) + else: + targets.append(a) + SCons.Script._Add_Targets(targets) + SCons.Script._Add_Arguments(xmit_args) + class Unbuffered: def __init__(self, file): self.file = file @@ -907,15 +988,8 @@ def _main(args, parser): sys.stdout = Unbuffered(sys.stdout) - if options.include_dir: - sys.path = options.include_dir + sys.path - - global repositories - for rep in repositories: - fs.Repository(rep) - - if not memory_stats is None: memory_stats.append(SCons.Debug.memory()) - if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances()) + memory_stats.append('before reading SConscript files:') + count_stats.append(('pre-', 'read')) progress_display("scons: Reading SConscript files ...") @@ -944,8 +1018,8 @@ def _main(args, parser): # file system nodes. SCons.Node.FS.save_strings(1) - if not memory_stats is None: memory_stats.append(SCons.Debug.memory()) - if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances()) + memory_stats.append('after reading SConscript files:') + count_stats.append(('post-', 'read')) fs.chdir(fs.Top) @@ -1084,8 +1158,8 @@ def _main(args, parser): "\tignoring -j or num_jobs option.\n" SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg) - if not memory_stats is None: memory_stats.append(SCons.Debug.memory()) - if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances()) + memory_stats.append('before building targets:') + count_stats.append(('pre-', 'build')) try: jobs.run() @@ -1097,37 +1171,11 @@ def _main(args, parser): if not options.noexec: SCons.SConsign.write() - if not memory_stats is None: - memory_stats.append(SCons.Debug.memory()) - when = [ - 'before reading SConscript files', - 'after reading SConscript files', - 'before building targets', - 'after building targets', - ] - for i in xrange(len(when)): - memory_outf.write('Memory %-32s %12d\n' % (when[i]+':', memory_stats[i])) - - if not count_stats is None: - count_stats.append(SCons.Debug.fetchLoggedInstances()) - stats_table = {} - for cs in count_stats: - for n in map(lambda t: t[0], cs): - stats_table[n] = [0, 0, 0, 0] - i = 0 - for cs in count_stats: - for n, c in cs: - stats_table[n][i] = c - i = i + 1 - keys = stats_table.keys() - keys.sort() - print "Object counts:" - fmt = " %7s %7s %7s %7s %s" - print fmt % ("pre-", "post-", "pre-", "post-", "") - print fmt % ("read", "read", "build", "build", "Class") - for k in keys: - r = stats_table[k] - print " %7d %7d %7d %7d %s" % (r[0], r[1], r[2], r[3], k) + memory_stats.append('after building targets:') + memory_stats.print_stats() + + count_stats.append(('post-', 'build')) + count_stats.print_stats() if print_objects: SCons.Debug.listLoggedInstances('*') @@ -1139,8 +1187,8 @@ def _main(args, parser): # Dump any development debug info that may have been enabled. # These are purely for internal debugging during development, so - # there's no need to control the with --debug= options, they're - # controlled by changing the source code.) + # there's no need to control them with --debug= options; they're + # controlled by changing the source code. SCons.Debug.dump_caller_counts() SCons.Taskmaster.dump_stats() |