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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 __revision__ = "src/engine/SCons/Script/Main.py 2928 2008/04/29 22:44:09 knight"
38
39 import SCons.compat
40
41 import os
42 import os.path
43 import string
44 import sys
45 import time
46 import traceback
47
48
49
50
51
52
53
54
55
56
57 import SCons.CacheDir
58 import SCons.Debug
59 import SCons.Defaults
60 import SCons.Environment
61 import SCons.Errors
62 import SCons.Job
63 import SCons.Node
64 import SCons.Node.FS
65 import SCons.SConf
66 import SCons.Script
67 import SCons.Taskmaster
68 import SCons.Util
69 import SCons.Warnings
70
71 import SCons.Script.Interactive
72
82
83
84
87
88 display = SCons.Util.display
89 progress_display = SCons.Util.DisplayEngine()
90
91 first_command_start = None
92 last_command_end = None
93
95 prev = ''
96 count = 0
97 target_string = '$TARGET'
98
100 if file is None:
101 file = sys.stdout
102
103 self.obj = obj
104 self.file = file
105 self.interval = interval
106 self.overwrite = overwrite
107
108 if callable(obj):
109 self.func = obj
110 elif SCons.Util.is_List(obj):
111 self.func = self.spinner
112 elif string.find(obj, self.target_string) != -1:
113 self.func = self.replace_string
114 else:
115 self.func = self.string
116
121
123 if self.prev:
124 length = len(self.prev)
125 if self.prev[-1] in ('\n', '\r'):
126 length = length - 1
127 self.write(' ' * length + '\r')
128 self.prev = ''
129
131 self.write(self.obj[self.count % len(self.obj)])
132
135
138
145
146 ProgressObject = SCons.Util.Null()
147
151
152
153
154
155 _BuildFailures = []
156
159
161 """An SCons build task."""
162 progress = ProgressObject
163
166
170
179
194
206
226
228
229
230
231 status = 2
232 exc_info = self.exc_info()
233 try:
234 t, e, tb = exc_info
235 except ValueError:
236 t, e = exc_info
237 tb = None
238 if t is None:
239
240
241 t, e = sys.exc_info()[:2]
242
243 def nodestring(n):
244 if not SCons.Util.is_List(n):
245 n = [ n ]
246 return string.join(map(str, n), ', ')
247
248 errfmt = "scons: *** [%s] %s\n"
249
250 if t == SCons.Errors.BuildError:
251 tname = nodestring(e.node)
252 errstr = e.errstr
253 if e.filename:
254 errstr = e.filename + ': ' + errstr
255 sys.stderr.write(errfmt % (tname, errstr))
256 elif t == SCons.Errors.TaskmasterException:
257 tname = nodestring(e.node)
258 sys.stderr.write(errfmt % (tname, e.errstr))
259 type, value, trace = e.exc_info
260 traceback.print_exception(type, value, trace)
261 elif t == SCons.Errors.ExplicitExit:
262 status = e.status
263 tname = nodestring(e.node)
264 errstr = 'Explicit exit, status %s' % status
265 sys.stderr.write(errfmt % (tname, errstr))
266 else:
267 if e is None:
268 e = t
269 s = str(e)
270 if t == SCons.Errors.StopError and not self.options.keep_going:
271 s = s + ' Stop.'
272 sys.stderr.write("scons: *** %s\n" % s)
273
274 if tb and print_stacktrace:
275 sys.stderr.write("scons: internal stack trace:\n")
276 traceback.print_tb(tb, file=sys.stderr)
277
278 self.do_failed(status)
279
280 self.exc_clear()
281
282 - def postprocess(self):
283 if self.top:
284 t = self.targets[0]
285 for tp in self.options.tree_printers:
286 tp.display(t)
287 if self.options.debug_includes:
288 tree = t.render_include_tree()
289 if tree:
290 print
291 print tree
292 SCons.Taskmaster.Task.postprocess(self)
293
295 """Make a task ready for execution"""
296 SCons.Taskmaster.Task.make_ready(self)
297 if self.out_of_date and self.options.debug_explain:
298 explanation = self.out_of_date[0].explain()
299 if explanation:
300 sys.stdout.write("scons: " + explanation)
301
303 """An SCons clean task."""