diff options
Diffstat (limited to 'src/engine/SCons/Script')
| -rw-r--r-- | src/engine/SCons/Script/Interactive.py | 10 | ||||
| -rw-r--r-- | src/engine/SCons/Script/Main.py | 87 | ||||
| -rw-r--r-- | src/engine/SCons/Script/SConsOptions.py | 69 | ||||
| -rw-r--r-- | src/engine/SCons/Script/SConscript.py | 4 | ||||
| -rw-r--r-- | src/engine/SCons/Script/__init__.py | 23 |
5 files changed, 115 insertions, 78 deletions
diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py index d18eec1..b1774eb 100644 --- a/src/engine/SCons/Script/Interactive.py +++ b/src/engine/SCons/Script/Interactive.py @@ -185,6 +185,16 @@ class SConsInteractiveCmd(cmd.Cmd): if not nodes: return + # Call each of the Node's alter_targets() methods, which may + # provide additional targets that ended up as part of the build + # (the canonical example being a VariantDir() when we're building + # from a source directory) and which we therefore need their + # state cleared, too. + x = [] + for n in nodes: + x.extend(n.alter_targets()[0]) + nodes.extend(x) + # Clean up so that we can perform the next build correctly. # # We do this by walking over all the children of the targets, diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 80b9032..75d0117 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -168,28 +168,29 @@ class BuildTask(SCons.Taskmaster.Task): self.progress(self.targets[0]) return SCons.Taskmaster.Task.prepare(self) - def execute(self): - for target in self.targets: - if target.get_state() == SCons.Node.up_to_date: - continue - if target.has_builder() and not hasattr(target.builder, 'status'): - if print_time: - start_time = time.time() - global first_command_start - if first_command_start is None: - first_command_start = start_time - SCons.Taskmaster.Task.execute(self) - if print_time: - global cumulative_command_time - global last_command_end - finish_time = time.time() - last_command_end = finish_time - cumulative_command_time = cumulative_command_time+finish_time-start_time - sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time)) - break + def needs_execute(self): + target = self.targets[0] + if target.get_state() == SCons.Node.executing: + return True else: if self.top and target.has_builder(): display("scons: `%s' is up to date." % str(self.node)) + return False + + def execute(self): + if print_time: + start_time = time.time() + global first_command_start + if first_command_start is None: + first_command_start = start_time + SCons.Taskmaster.Task.execute(self) + if print_time: + global cumulative_command_time + global last_command_end + finish_time = time.time() + last_command_end = finish_time + cumulative_command_time = cumulative_command_time+finish_time-start_time + sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time)) def do_failed(self, status=2): _BuildFailures.append(self.exception[1]) @@ -207,10 +208,15 @@ class BuildTask(SCons.Taskmaster.Task): t = self.targets[0] if self.top and not t.has_builder() and not t.side_effect: if not t.exists(): - sys.stderr.write("scons: *** Do not know how to make target `%s'." % t) + errstr="Do not know how to make target `%s'." % t + sys.stderr.write("scons: *** " + errstr) if not self.options.keep_going: sys.stderr.write(" Stop.") sys.stderr.write("\n") + try: + raise SCons.Errors.BuildError(t, errstr) + except: + self.exception_set() self.do_failed() else: print "scons: Nothing to be done for `%s'." % t @@ -977,11 +983,6 @@ def _build_targets(fs, options, targets, target_top): if options.diskcheck: SCons.Node.FS.set_diskcheck(options.diskcheck) - _set_debug_values(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 - SCons.CacheDir.cache_enabled = not options.cache_disable SCons.CacheDir.cache_debug = options.cache_debug SCons.CacheDir.cache_force = options.cache_force @@ -1133,26 +1134,29 @@ def _build_targets(fs, options, targets, target_top): memory_stats.append('before building targets:') count_stats.append(('pre-', 'build')) - try: - progress_display("scons: " + opening_message) - try: - jobs.run() - except KeyboardInterrupt: - # If we are in interactive mode, a KeyboardInterrupt - # interrupts only this current run. Return 'nodes' normally - # so that the outer loop can clean up the nodes and continue. - if options.interactive: - print "Build interrupted." - # Continue and return normally - finally: - jobs.cleanup() + def jobs_postfunc( + jobs=jobs, + options=options, + closing_message=closing_message, + failure_message=failure_message + ): + if jobs.were_interrupted(): + progress_display("scons: Build interrupted.") + global exit_status + exit_status = 2 + if exit_status: progress_display("scons: " + failure_message) else: progress_display("scons: " + closing_message) if not options.no_exec: + if jobs.were_interrupted(): + progress_display("scons: writing .sconsign file.") SCons.SConsign.write() + progress_display("scons: " + opening_message) + jobs.run(postfunc = jobs_postfunc) + memory_stats.append('after building targets:') count_stats.append(('post-', 'build')) @@ -1210,10 +1214,9 @@ def main(): parts = ["SCons by Steven Knight et al.:\n"] try: + import __main__ parts.append(version_string("script", __main__)) - except KeyboardInterrupt: - raise - except: + except (ImportError, AttributeError): # On Windows there is no scons.py, so there is no # __main__.__version__, hence there is no script version. pass @@ -1233,7 +1236,7 @@ def main(): if s: exit_status = s except KeyboardInterrupt: - print "Build interrupted." + print("scons: Build interrupted.") sys.exit(2) except SyntaxError, e: _scons_syntax_error(e) diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index ee34a85..2148068 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -26,11 +26,19 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.compat import optparse +import re import string import sys import textwrap try: + no_hyphen_re = re.compile(r'(\s+|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') +except re.error: + # Pre-2.0 Python versions don't have the (?<= negative + # look-behind assertion. + no_hyphen_re = re.compile(r'(\s+|-*\w{2,}-(?=\w{2,}))') + +try: from gettext import gettext except ImportError: def gettext(message): @@ -382,8 +390,16 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): def format_option(self, option): """ A copy of the normal optparse.IndentedHelpFormatter.format_option() - method, snarfed so we can set the subsequent_indent on the - textwrap.wrap() call below... + method. This has been snarfed so we can modify text wrapping to + out liking: + + -- add our own regular expression that doesn't break on hyphens + (so things like --no-print-directory don't get broken); + + -- wrap the list of options themselves when it's too long + (the wrapper.fill(opts) call below); + + -- set the subsequent_indent when wrapping the help_text. """ # The help for each option consists of two parts: # * the opt strings and metavars @@ -410,7 +426,11 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): opt_width = self.help_position - self.current_indent - 2 if len(opts) > opt_width: - opts = "%*s%s\n" % (self.current_indent, "", opts) + wrapper = textwrap.TextWrapper(width=self.width, + initial_indent = ' ', + subsequent_indent = ' ') + wrapper.wordsep_re = no_hyphen_re + opts = wrapper.fill(opts) + '\n' indent_first = self.help_position else: # start help on same line as opts opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) @@ -428,8 +448,10 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): help_text = expand_default(option) # SCons: indent every line of the help text but the first. - help_lines = textwrap.wrap(help_text, self.help_width, - subsequent_indent = ' ') + wrapper = textwrap.TextWrapper(width=self.help_width, + subsequent_indent = ' ') + wrapper.wordsep_re = no_hyphen_re + help_lines = wrapper.wrap(help_text) result.append("%*s%s\n" % (indent_first, "", help_lines[0])) for line in help_lines[1:]: result.append("%*s%s\n" % (self.help_position, "", line)) @@ -503,8 +525,13 @@ def Parser(version): # options ignored for compatibility def opt_ignore(option, opt, value, parser): sys.stderr.write("Warning: ignoring %s option\n" % opt) - op.add_option("-b", "-m", "-S", "-t", - "--no-keep-going", "--stop", "--touch", + op.add_option("-b", "-d", "-e", "-m", "-S", "-t", "-w", + "--environment-overrides", + "--no-keep-going", + "--no-print-directory", + "--print-directory", + "--stop", + "--touch", action="callback", callback=opt_ignore, help="Ignored for compatibility.") @@ -557,13 +584,6 @@ def Parser(version): help = opt_config_help, metavar="MODE") - def opt_not_yet(option, opt, value, parser): - sys.stderr.write("Warning: the %s option is not yet implemented\n" % opt) - sys.exit(0) - op.add_option('-d', - action="callback", callback=opt_not_yet, - help = "Print file dependency information.") - op.add_option('-D', dest="climb_up", default=None, action="store_const", const=2, @@ -836,11 +856,12 @@ def Parser(version): # we don't want to change. These all get a "the -X option is not # yet implemented" message and don't show up in the help output. - op.add_option('-e', '--environment-overrides', - dest="environment_overrides", - action="callback", callback=opt_not_yet, - # help="Environment variables override makefiles." - help=SUPPRESS_HELP) + def opt_not_yet(option, opt, value, parser): + msg = "Warning: the %s option is not yet implemented\n" % opt + sys.stderr.write(msg) + sys.exit(0) + + op.add_option('-l', '--load-average', '--max-load', nargs=1, type="int", dest="load_average", default=0, @@ -887,16 +908,6 @@ def Parser(version): dest="no_builtin_rules", # help="Clear default environments and variables." help=SUPPRESS_HELP) - op.add_option('-w', '--print-directory', - action="callback", callback=opt_not_yet, - dest="print_directory", - # help="Print the current directory." - help=SUPPRESS_HELP) - op.add_option('--no-print-directory', - action="callback", callback=opt_not_yet, - dest="no_print_directory", - # help="Turn off -w, even if it was turned on implicitly." - help=SUPPRESS_HELP) op.add_option('--write-filenames', nargs=1, type="string", dest="write_filenames", diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 36a147d..7e38ffd 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -39,7 +39,6 @@ import SCons.Errors import SCons.Node import SCons.Node.Alias import SCons.Node.FS -import SCons.Options import SCons.Platform import SCons.SConf import SCons.Script.Main @@ -141,7 +140,8 @@ call_stack = [] def Return(*vars, **kw): retval = [] try: - for var in vars: + fvars = SCons.Util.flatten(vars) + for var in fvars: for v in string.split(var): retval.append(call_stack[-1].globals[v]) except KeyError, x: diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index ddeaf9e..72e31d1 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -84,6 +84,7 @@ import SCons.SConf import SCons.Subst import SCons.Tool import SCons.Util +import SCons.Variables import SCons.Defaults import Main @@ -138,22 +139,31 @@ call_stack = _SConscript.call_stack Action = SCons.Action.Action AddMethod = SCons.Util.AddMethod AllowSubstExceptions = SCons.Subst.SetAllowableExceptions -BoolOption = SCons.Options.BoolOption Builder = SCons.Builder.Builder Configure = _SConscript.Configure -EnumOption = SCons.Options.EnumOption Environment = SCons.Environment.Environment #OptParser = SCons.SConsOptions.OptParser FindPathDirs = SCons.Scanner.FindPathDirs -ListOption = SCons.Options.ListOption -PackageOption = SCons.Options.PackageOption -PathOption = SCons.Options.PathOption Platform = SCons.Platform.Platform Return = _SConscript.Return Scanner = SCons.Scanner.Base Tool = SCons.Tool.Tool WhereIs = SCons.Util.WhereIs +# +BoolVariable = SCons.Variables.BoolVariable +EnumVariable = SCons.Variables.EnumVariable +ListVariable = SCons.Variables.ListVariable +PackageVariable = SCons.Variables.PackageVariable +PathVariable = SCons.Variables.PathVariable + +# Deprecated names that will go away some day. +BoolOption = SCons.Options.BoolOption +EnumOption = SCons.Options.EnumOption +ListOption = SCons.Options.ListOption +PackageOption = SCons.Options.PackageOption +PathOption = SCons.Options.PathOption + # Action factories. Chmod = SCons.Defaults.Chmod Copy = SCons.Defaults.Copy @@ -262,6 +272,9 @@ def HelpFunction(text): sconscript_reading = 0 # +def Variables(files=[], args=ARGUMENTS): + return SCons.Variables.Variables(files, args) + def Options(files=[], args=ARGUMENTS): return SCons.Options.Options(files, args) |
