| Home | Trees | Indices | Help |
|
|---|
|
|
1 """SCons.Script 2 3 This file implements the main() function used by the scons script. 4 5 Architecturally, this *is* the scons script, and will likely only be 6 called from the external "scons" wrapper. Consequently, anything here 7 should not be, or be considered, part of the build engine. If it's 8 something that we expect other software to want to use, it should go in 9 some other module. If it's specific to the "scons" script invocation, 10 it goes here. 11 12 """ 13 14 # 15 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation 16 # 17 # Permission is hereby granted, free of charge, to any person obtaining 18 # a copy of this software and associated documentation files (the 19 # "Software"), to deal in the Software without restriction, including 20 # without limitation the rights to use, copy, modify, merge, publish, 21 # distribute, sublicense, and/or sell copies of the Software, and to 22 # permit persons to whom the Software is furnished to do so, subject to 23 # the following conditions: 24 # 25 # The above copyright notice and this permission notice shall be included 26 # in all copies or substantial portions of the Software. 27 # 28 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 29 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 30 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 31 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 32 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 33 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 34 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 # 36 37 __revision__ = "src/engine/SCons/Script/Main.py 3795 2008/11/25 22:04:43 scons" 38 39 import os 40 import os.path 41 import string 42 import sys 43 import time 44 import traceback 45 46 # Strip the script directory from sys.path() so on case-insensitive 47 # (Windows) systems Python doesn't think that the "scons" script is the 48 # "SCons" package. Replace it with our own version directory so, if 49 # if they're there, we pick up the right version of the build engine 50 # modules. 51 #sys.path = [os.path.join(sys.prefix, 52 # 'lib', 53 # 'scons-%d' % SCons.__version__)] + sys.path[1:] 54 55 import SCons.CacheDir 56 import SCons.Debug 57 import SCons.Defaults 58 import SCons.Environment 59 import SCons.Errors 60 import SCons.Job 61 import SCons.Node 62 import SCons.Node.FS 63 import SCons.SConf 64 import SCons.Script 65 import SCons.Taskmaster 66 import SCons.Util 67 import SCons.Warnings 68 69 import SCons.Script.Interactive 7072 # A subsidiary function that exists solely to isolate this import 73 # so we don't have to pull it in on all platforms, and so that an 74 # in-line "import" statement in the _main() function below doesn't 75 # cause warnings about local names shadowing use of the 'SCons' 76 # globl in nest scopes and UnboundLocalErrors and the like in some 77 # versions (2.1) of Python. 78 import SCons.Platform.win32 79 return SCons.Platform.win32.parallel_msg80 81 # 82 85 86 display = SCons.Util.display 87 progress_display = SCons.Util.DisplayEngine() 88 89 first_command_start = None 90 last_command_end = None 9193 prev = '' 94 count = 0 95 target_string = '$TARGET' 96143 144 ProgressObject = SCons.Util.Null() 145 149 150 # Task control. 151 # 152 153 _BuildFailures = [] 15498 if file is None: 99 file = sys.stdout 100 101 self.obj = obj 102 self.file = file 103 self.interval = interval 104 self.overwrite = overwrite 105 106 if callable(obj): 107 self.func = obj 108 elif SCons.Util.is_List(obj): 109 self.func = self.spinner 110 elif string.find(obj, self.target_string) != -1: 111 self.func = self.replace_string 112 else: 113 self.func = self.string114 119121 if self.prev: 122 length = len(self.prev) 123 if self.prev[-1] in ('\n', '\r'): 124 length = length - 1 125 self.write(' ' * length + '\r') 126 self.prev = ''127 130132 self.write(self.obj)133 136138 self.count = self.count + 1 139 if (self.count % self.interval) == 0: 140 if self.overwrite: 141 self.erase_previous() 142 self.func(node)156 return _BuildFailures157159 """An SCons build task.""" 160 progress = ProgressObject 161305163 display('scons: ' + message)164 168170 target = self.targets[0] 171 if target.get_state() == SCons.Node.executing: 172 return True 173 else: 174 if self.top and target.has_builder(): 175 display("scons: `%s' is up to date." % str(self.node)) 176 return False177179 if print_time: 180 start_time = time.time() 181 global first_command_start 182 if first_command_start is None: 183 first_command_start = start_time 184 SCons.Taskmaster.Task.execute(self) 185 if print_time: 186 global cumulative_command_time 187 global last_command_end 188 finish_time = time.time() 189 last_command_end = finish_time 190 cumulative_command_time = cumulative_command_time+finish_time-start_time 191 sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time))192194 _BuildFailures.append(self.exception[1]) 195 global exit_status 196 global this_build_status 197 if self.options.ignore_errors: 198 SCons.Taskmaster.Task.executed(self) 199 elif self.options.keep_going: 200 SCons.Taskmaster.Task.fail_continue(self) 201 exit_status = status 202 this_build_status = status 203 else: 204 SCons.Taskmaster.Task.fail_stop(self) 205 exit_status = status 206 this_build_status = status207209 t = self.targets[0] 210 if self.top and not t.has_builder() and not t.side_effect: 211 if not t.exists(): 212 errstr="Do not know how to make target `%s'." % t 213 sys.stderr.write("scons: *** " + errstr) 214 if not self.options.keep_going: 215 sys.stderr.write(" Stop.") 216 sys.stderr.write("\n") 217 try: 218 raise SCons.Errors.BuildError(t, errstr) 219 except KeyboardInterrupt: 220 raise 221 except: 222 self.exception_set() 223 self.do_failed() 224 else: 225 print "scons: Nothing to be done for `%s'." % t 226 SCons.Taskmaster.Task.executed(self) 227 else: 228 SCons.Taskmaster.Task.executed(self)229231 # Handle the failure of a build task. The primary purpose here 232 # is to display the various types of Errors and Exceptions 233 # appropriately. 234 exc_info = self.exc_info() 235 try: 236 t, e, tb = exc_info 237 except ValueError: 238 t, e = exc_info 239 tb = None 240 241 if t is None: 242 # The Taskmaster didn't record an exception for this Task; 243 # see if the sys module has one. 244 try: 245 t, e, tb = sys.exc_info()[:] 246 except ValueError: 247 t, e = exc_info 248 tb = None 249 250 # Deprecated string exceptions will have their string stored 251 # in the first entry of the tuple. 252 if e is None: 253 e = t 254 255 buildError = SCons.Errors.convert_to_BuildError(e) 256 if not buildError.node: 257 buildError.node = self.node 258 259 node = buildError.node 260 if not SCons.Util.is_List(node): 261 node = [ node ] 262 nodename = string.join(map(str, node), ', ') 263 264 errfmt = "scons: *** [%s] %s\n" 265 sys.stderr.write(errfmt % (nodename, buildError)) 266 267 if (buildError.exc_info[2] and buildError.exc_info[1] and 268 # TODO(1.5) 269 #not isinstance( 270 # buildError.exc_info[1], 271 # (EnvironmentError, SCons.Errors.StopError, SCons.Errors.UserError))): 272 not isinstance(buildError.exc_info[1], EnvironmentError) and 273 not isinstance(buildError.exc_info[1], SCons.Errors.StopError) and 274 not isinstance(buildError.exc_info[1], SCons.Errors.UserError)): 275 type, value, trace = buildError.exc_info 276 traceback.print_exception(type, value, trace) 277 elif tb and print_stacktrace: 278 sys.stderr.write("scons: internal stack trace:\n") 279 traceback.print_tb(tb, file=sys.stderr) 280 281 self.exception = (e, buildError, tb) # type, value, traceback 282 self.do_failed(buildError.exitstatus) 283 284 self.exc_clear()285287 if self.top: 288 t = self.targets[0] 289 for tp in self.options.tree_printers: 290 tp.display(t) 291 if self.options.debug_includes: 292 tree = t.render_include_tree() 293 if tree: 294 print 295 print tree 296 SCons.Taskmaster.Task.postprocess(self)297299 """Make a task ready for execution""" 300 SCons.Taskmaster.Task.make_ready(self) 301 if self.out_of_date and self.options.debug_explain: 302 explanation = self.out_of_date[0].explain() 303 if explanation: 304 sys.stdout.write("scons: " + explanation)