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 3266 2008/08/12 07:31:01 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
209
229
231
232
233
234 status = 2
235 exc_info = self.exc_info()
236 try:
237 t, e, tb = exc_info
238 except ValueError:
239 t, e = exc_info
240 tb = None
241 if t is None:
242
243
244 t, e = sys.exc_info()[:2]
245
246 def nodestring(n):
247 if not SCons.Util.is_List(n):
248 n = [ n ]
249 return string.join(map(str, n), ', ')
250
251 errfmt = "scons: *** [%s] %s\n"
252
253 if t == SCons.Errors.BuildError:
254 tname = nodestring(e.node)
255 errstr = e.errstr
256 if e.filename:
257 errstr = e.filename + ': ' + errstr
258 sys.stderr.write(errfmt % (tname, errstr))
259 elif t == SCons.Errors.TaskmasterException:
260 tname = nodestring(e.node)
261 sys.stderr.write(errfmt % (tname, e.errstr))
262 type, value, trace = e.exc_info
263 traceback.print_exception(type, value, trace)
264 elif t == SCons.Errors.ExplicitExit:
265 status = e.status
266 tname = nodestring(e.node)
267 errstr = 'Explicit exit, status %s' % status
268 sys.stderr.write(errfmt % (tname, errstr))
269 else:
270 if e is None:
271 e = t
272 s = str(e)
273 if t == SCons.Errors.StopError and not self.options.keep_going:
274 s = s + ' Stop.'
275 sys.stderr.write("scons: *** %s\n" % s)
276
277 if tb and print_stacktrace:
278 sys.stderr.write("scons: internal stack trace:\n")
279 traceback.print_tb(tb, file=sys.stderr)
280
281 self.do_failed(status)
282
283 self.exc_clear()
284
285 - def postprocess(self):
286 if self.top:
287 t = self.targets[0]
288 for tp in self.options.tree_printers:
289 tp.display(t)
290 if self.options.debug_includes:
291 tree = t.render_include_tree()
292 if tree:
293 print
294 print tree
295 SCons.Taskmaster.Task.postprocess(self)
296
298 """Make a task ready for execution"""
299 SCons.Taskmaster.Task.make_ready(self)
300 if self.out_of_date and self.options.debug_explain:
301 explanation = self.out_of_date[0].explain()
302 if explanation:
303 sys.stdout.write("scons: " + explanation)
304
380
382 """An SCons task for the -q (question) option."""
385
394
397
398
401 self.derived = derived
402 self.prune = prune
403 self.status = status
416
417
420
422 return version < (1, 5, 2)
423
425 return version < (2, 2, 0)
426
427
428
429
430 print_objects = 0
431 print_memoizer = 0
432 print_stacktrace = 0
433 print_time = 0
434 sconscript_time = 0
435 cumulative_command_time = 0
436 exit_status = 0
437 this_build_status = 0
438 num_jobs = None
439 delayed_warnings = []
440
442 """
443 A do-nothing option parser, used for the initial OptionsParser variable.
444
445 During normal SCons operation, the OptionsParser is created right
446 away by the main() function. Certain tests scripts however, can
447 introspect on different Tool modules, the initialization of which
448 can try to add a new, local option to an otherwise uninitialized
449 OptionsParser object. This allows that introspection to happen
450 without blowing up.
451
452 """
456 values = FakeOptionValues()
459
460 OptionsParser = FakeOptionParser()
461
467
470
473
474
487
493 stats_table = {}
494 for s in self.stats:
495 for n in map(lambda t: t[0], s):
496 stats_table[n] = [0, 0, 0, 0]
497 i = 0
498 for s in self.stats:
499 for n, c in s:
500 stats_table[n][i] = c
501 i = i + 1
502 keys = stats_table.keys()
503 keys.sort()
504 self.outfp.write("Object counts:\n")
505 pre = [" "]
506 post = [" %s\n"]
507 l = len(self.stats)
508 fmt1 = string.join(pre + [' %7s']*l + post, '')
509 fmt2 = string.join(pre + [' %7d']*l + post, '')
510 labels = self.labels[:l]
511 labels.append(("", "Class"))
512 self.outfp.write(fmt1 % tuple(map(lambda x: x[0], labels)))
513 self.outfp.write(fmt1 % tuple(map(lambda x: x[1], labels)))
514 for k in keys:
515 r = stats_table[k][:l] + [k]
516 self.outfp.write(fmt2 % tuple(r))
517
518 count_stats = CountStats()
519
525 fmt = 'Memory %-32s %12d\n'
526 for label, stats in map(None, self.labels, self.stats):
527 self.outfp.write(fmt % (label, stats))
528
529 memory_stats = MemStats()
530
531
532
534 """Handle syntax errors. Print out a message and show where the error
535 occurred.
536 """
537 etype, value, tb = sys.exc_info()
538 lines = traceback.format_exception_only(etype, value)
539 for line in lines:
540 sys.stderr.write(line+'\n')
541 sys.exit(2)
542
544 """
545 Find the deepest stack frame that is not part of SCons.
546
547 Input is a "pre-processed" stack trace in the form
548 returned by traceback.extract_tb() or traceback.extract_stack()
549 """
550
551 tb.reverse()
552
553
554
555 for frame in tb:
556 filename = frame[0]
557 if string.find(filename, os.sep+'SCons'+os.sep) == -1:
558 return frame
559 return tb[0]
560
562 """Handle user errors. Print out a message and a description of the
563 error, along with the line number and routine where it occured.
564 The file and line number will be the deepest stack frame that is
565 not part of SCons itself.
566 """
567 global print_stacktrace
568 etype, value, tb = sys.exc_info()
569 if print_stacktrace:
570 traceback.print_exception(etype, value, tb)
571 filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb))
572 sys.stderr.write("\nscons: *** %s\n" % value)
573 sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine))
574 sys.exit(2)
575
577 """Handle user warnings. Print out a message and a description of
578 the warning, along with the line number and routine where it occured.
579 The file and line number will be the deepest stack frame that is
580 not part of SCons itself.
581 """
582 etype, value, tb = sys.exc_info()
583 filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb))
584 sys.stderr.write("\nscons: warning: %s\n" % e)
585 sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine))
586
588 """Slightly different from _scons_user_warning in that we use the
589 *current call stack* rather than sys.exc_info() to get our stack trace.
590 This is used by the warnings framework to print warnings."""
591 filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_stack())
592 sys.stderr.write("\nscons: warning: %s\n" % e[0])
593 sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine))
594
596 """Handle all errors but user errors. Print out a message telling
597 the user what to do in this case and print a normal trace.
598 """
599 print 'internal error'
600 traceback.print_exc()
601 sys.exit(2)
602
604 """This function checks that an SConstruct file exists in a directory.
605 If so, it returns the path of the file. By default, it checks the
606 current directory.
607 """
608 for file in ['SConstruct', 'Sconstruct', 'sconstruct']:
609 sfile = os.path.join(dirname, file)
610 if os.path.isfile(sfile):
611 return sfile
612 if not os.path.isabs(sfile):
613 for rep in repositories:
614 if os.path.isfile(os.path.join(rep, sfile)):
615 return sfile
616 return None
617
656
665
667 """Load the site_scons dir under topdir.
668 Adds site_scons to sys.path, imports site_scons/site_init.py,
669 and adds site_scons/site_tools to default toolpath."""
670 if site_dir_name:
671 err_if_not_found = True
672 else:
673 site_dir_name = "site_scons"
674 err_if_not_found = False
675
676 site_dir = os.path.join(topdir.path, site_dir_name)
677 if not os.path.exists(site_dir):
678 if err_if_not_found:
679 raise SCons.Errors.UserError, "site dir %s not found."%site_dir
680 return
681
682 site_init_filename = "site_init.py"
683 site_init_modname = "site_init"
684 site_tools_dirname = "site_tools"
685 sys.path = [os.path.abspath(site_dir)] + sys.path
686 site_init_file = os.path.join(site_dir, site_init_filename)
687 site_tools_dir = os.path.join(site_dir, site_tools_dirname)
688 if os.path.exists(site_init_file):
689 import imp
690 try:
691 fp, pathname, description = imp.find_module(site_init_modname,
692 [site_dir])
693 try:
694 imp.load_module(site_init_modname, fp, pathname, description)
695 finally:
696 if fp:
697 fp.close()
698 except ImportError, e:
699 sys.stderr.write("Can't import site init file '%s': %s\n"%(site_init_file, e))
700 raise
701 except Exception, e:
702 sys.stderr.write("Site init file '%s' raised exception: %s\n"%(site_init_file, e))
703 raise
704 if os.path.exists(site_tools_dir):
705 SCons.Tool.DefaultToolpath.append(os.path.abspath(site_tools_dir))
706
720
722 global exit_status
723 global this_build_status
724
725 options = parser.values
726
727
728
729
730
731
732
733
734 default_warnings = [ SCons.Warnings.CorruptSConsignWarning,
735 SCons.Warnings.DeprecatedWarning,
736 SCons.Warnings.DuplicateEnvironmentWarning,
737 SCons.Warnings.LinkWarning,
738 SCons.Warnings.MissingSConscriptWarning,
739 SCons.Warnings.NoMD5ModuleWarning,
740 SCons.Warnings.NoMetaclassSupportWarning,
741 SCons.Warnings.NoObjectCountWarning,
742 SCons.Warnings.NoParallelSupportWarning,
743 SCons.Warnings.MisleadingKeywordsWarning,
744 SCons.Warnings.StackSizeWarning, ]
745
746 for warning in default_warnings:
747 SCons.Warnings.enableWarningClass(warning)
748 SCons.Warnings._warningOut = _scons_internal_warning
749 SCons.Warnings.process_warn_strings(options.warn)
750
751
752
753
754 try:
755 dw = options.delayed_warnings
756 except AttributeError:
757 pass
758 else:
759 delayed_warnings.extend(dw)
760 for warning_type, message in delayed_warnings:
761 SCons.Warnings.warn(warning_type, message)
762
763 if options.diskcheck:
764 SCons.Node.FS.set_diskcheck(options.diskcheck)
765
766
767
768
769
770
771 if options.directory:
772 cdir = _create_path(options.directory)
773 try:
774 os.chdir(cdir)
775 except OSError:
776 sys.stderr.write("Could not change directory to %s\n" % cdir)
777
778 target_top = None
779 if options.climb_up:
780 target_top = '.'
781 script_dir = os.getcwd()
782 while script_dir and not _SConstruct_exists(script_dir, options.repository):
783 script_dir, last_part = os.path.split(script_dir)
784 if last_part:
785 target_top = os.path.join(last_part, target_top)
786 else:
787 script_dir = ''
788 if script_dir:
789 display("scons: Entering directory `%s'" % script_dir)
790 os.chdir(script_dir)
791
792
793
794
795 fs = SCons.Node.FS.get_default_fs()
796
797 for rep in options.repository:
798 fs.Repository(rep)
799
800
801
802
803 scripts = []
804 if options.file:
805 scripts.extend(options.file)
806 if not scripts:
807 sfile = _SConstruct_exists(repositories=options.repository)
808 if sfile:
809 scripts.append(sfile)
810
811 if not scripts:
812 if options.help:
813
814
815
816 raise SConsPrintHelpException
817 raise SCons.Errors.UserError, "No SConstruct file found."
818
819 if scripts[0] == "-":
820 d = fs.getcwd()
821 else:
822 d = fs.File(scripts[0]).dir
823 fs.set_SConstruct_dir(d)
824
825 _set_debug_values(options)
826 SCons.Node.implicit_cache = options.implicit_cache
827 SCons.Node.implicit_deps_changed = options.implicit_deps_changed
828 SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
829
830 if options.no_exec:
831 SCons.SConf.dryrun = 1
832 SCons.Action.execute_actions = None
833 if options.question:
834 SCons.SConf.dryrun = 1
835 if options.clean:
836 SCons.SConf.SetBuildType('clean')
837 if options.help:
838 SCons.SConf.SetBuildType('help')
839 SCons.SConf.SetCacheMode(options.config)
840 SCons.SConf.SetProgressDisplay(progress_display)
841
842 if options.no_progress or options.silent:
843 progress_display.set_mode(0)
844
845 if options.site_dir:
846 _load_site_scons_dir(d, options.site_dir)
847 elif not options.no_site_dir:
848 _load_site_scons_dir(d)
849
850 if options.include_dir:
851 sys.path = options.include_dir + sys.path
852
853
854
855
856 targets = []
857 xmit_args = []
858 for a in parser.largs:
859 if a[0] == '-':
860 continue
861 if '=' in a:
862 xmit_args.append(a)
863 else:
864 targets.append(a)
865 SCons.Script._Add_Targets(targets + parser.rargs)
866 SCons.Script._Add_Arguments(xmit_args)
867
868
869
870
871
872
873
874
875
876 if not sys.stdout.isatty():
877 sys.stdout = SCons.Util.Unbuffered(sys.stdout)
878 if not sys.stderr.isatty():
879 sys.stderr = SCons.Util.Unbuffered(sys.stderr)
880
881 memory_stats.append('before reading SConscript files:')
882 count_stats.append(('pre-', 'read'))
883
884
885
886 progress_display("scons: Reading SConscript files ...")
887
888 start_time = time.time()
889 try:
890 for script in scripts:
891 SCons.Script._SConscript._SConscript(fs, script)
892 except SCons.Errors.StopError, e:
893
894
895
896
897
898 sys.stderr.write("scons: *** %s Stop.\n" % e)
899 exit_status = 2
900 sys.exit(exit_status)
901 global sconscript_time
902 sconscript_time = time.time() - start_time
903
904 progress_display("scons: done reading SConscript files.")
905
906 memory_stats.append('after reading SConscript files:')
907 count_stats.append(('post-', 'read'))
908
909
910
911
912
913
914
915
916
917 SCons.Warnings.enableWarningClass(SCons.Warnings.PythonVersionWarning)
918 SCons.Warnings.process_warn_strings(options.warn)
919
920
921
922
923 if python_version_deprecated():
924 msg = "Support for pre-2.2 Python (%s) is deprecated.\n" + \
925 " If this will cause hardship, contact dev@scons.tigris.org."
926 SCons.Warnings.warn(SCons.Warnings.PythonVersionWarning,
927 msg % python_version_string())
928
929 if not options.help:
930 SCons.SConf.CreateConfigHBuilder(SCons.Defaults.DefaultEnvironment())
931
932
933
934
935
936
937
938 parser.preserve_unknown_options = False
939 parser.parse_args(parser.largs, options)
940
941 if options.help:
942 help_text = SCons.Script.help_text
943 if help_text is None:
944
945
946 raise SConsPrintHelpException
947 else:
948 print help_text
949 print "Use scons -H for help about command-line options."
950 exit_status = 0
951 return
952
953
954
955
956
957
958
959 fs.chdir(fs.Top)
960
961 SCons.Node.FS.save_strings(1)
962
963
964
965 SCons.Node.implicit_cache = options.implicit_cache
966 SCons.Node.FS.set_duplicate(options.duplicate)
967 fs.set_max_drift(options.max_drift)
968 if not options.stack_size is None:
969 SCons.Job.stack_size = options.stack_size
970
971 platform = SCons.Platform.platform_module()
972
973 if options.interactive:
974 SCons.Script.Interactive.interact(fs, OptionsParser, options,
975 targets, target_top)
976
977 else:
978
979
980 nodes = _build_targets(fs, options, targets, target_top)
981 if not nodes:
982 exit_status = 2
983
1045 d = filter(check_dir, SCons.Script.DEFAULT_TARGETS)
1046 SCons.Script.DEFAULT_TARGETS[:] = d
1047 target_top = None
1048 lookup_top = None
1049
1050 targets = SCons.Script._Get_Default_Targets(d, fs)
1051
1052 if not targets:
1053 sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n")
1054 return None
1055
1056 def Entry(x, ltop=lookup_top, ttop=target_top, fs=fs):
1057 if isinstance(x, SCons.Node.Node):
1058 node = x
1059 else:
1060 node = None
1061
1062 if ltop == None: ltop = ''
1063
1064
1065
1066 curdir = os.path.join(os.getcwd(), str(ltop))
1067 for lookup in SCons.Node.arg2nodes_lookups:
1068 node = lookup(x, curdir=curdir)
1069 if node != None:
1070 break
1071 if node is None:
1072 node = fs.Entry(x, directory=ltop, create=1)
1073 if ttop and not node.is_under(ttop):
1074 if isinstance(node, SCons.Node.FS.Dir) and ttop.is_under(node):
1075 node = ttop
1076 else:
1077 node = None
1078 return node
1079
1080 nodes = filter(None, map(Entry, targets))
1081
1082 task_class = BuildTask
1083 opening_message = "Building targets ..."
1084 closing_message = "done building targets."
1085 if options.keep_going:
1086 failure_message = "done building targets (errors occurred during build)."
1087 else:
1088 failure_message = "building terminated because of errors."
1089 if options.question:
1090 task_class = QuestionTask
1091 try:
1092 if options.clean:
1093 task_class = CleanTask
1094 opening_message = "Cleaning targets ..."
1095 closing_message = "done cleaning targets."
1096 if options.keep_going:
1097 failure_message = "done cleaning targets (errors occurred during clean)."
1098 else:
1099 failure_message = "cleaning terminated because of errors."
1100 except AttributeError:
1101 pass
1102
1103 task_class.progress = ProgressObject
1104
1105 if options.random:
1106 def order(dependencies):
1107 """Randomize the dependencies."""
1108 import random
1109
1110
1111 d = dependencies
1112 for i in xrange(len(d)-1, 0, -1):
1113 j = int(random.random() * (i+1))
1114 d[i], d[j] = d[j], d[i]
1115 return d
1116 else:
1117 def order(dependencies):
1118 """Leave the order of dependencies alone."""
1119 return dependencies
1120
1121 if options.taskmastertrace_file == '-':
1122 tmtrace = sys.stdout
1123 elif options.taskmastertrace_file:
1124 tmtrace = open(options.taskmastertrace_file, 'wb')
1125 else:
1126 tmtrace = None
1127 taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, order, tmtrace)
1128
1129
1130
1131 BuildTask.options = options
1132
1133 global num_jobs
1134 num_jobs = options.num_jobs
1135 jobs = SCons.Job.Jobs(num_jobs, taskmaster)
1136 if num_jobs > 1:
1137 msg = None
1138 if jobs.num_jobs == 1:
1139 msg = "parallel builds are unsupported by this version of Python;\n" + \
1140 "\tignoring -j or num_jobs option.\n"
1141 elif sys.platform == 'win32':
1142 msg = fetch_win32_parallel_msg()
1143 if msg:
1144 SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
1145
1146 memory_stats.append('before building targets:')
1147 count_stats.append(('pre-', 'build'))
1148
1149 def jobs_postfunc(
1150 jobs=jobs,
1151 options=options,
1152 closing_message=closing_message,
1153 failure_message=failure_message
1154 ):
1155 if jobs.were_interrupted():
1156 progress_display("scons: Build interrupted.")
1157 global exit_status
1158 global this_build_status
1159 exit_status = 2
1160 this_build_status = 2
1161
1162 if this_build_status:
1163 progress_display("scons: " + failure_message)
1164 else:
1165 progress_display("scons: " + closing_message)
1166 if not options.no_exec:
1167 if jobs.were_interrupted():
1168 progress_display("scons: writing .sconsign file.")
1169 SCons.SConsign.write()
1170
1171 progress_display("scons: " + opening_message)
1172 jobs.run(postfunc = jobs_postfunc)
1173
1174 memory_stats.append('after building targets:')
1175 count_stats.append(('post-', 'build'))
1176
1177 return nodes
1178
1179 -def _exec_main(parser, values):
1180 sconsflags = os.environ.get('SCONSFLAGS', '')
1181 all_args = string.split(sconsflags) + sys.argv[1:]
1182
1183 options, args = parser.parse_args(all_args, values)
1184
1185 if type(options.debug) == type([]) and "pdb" in options.debug:
1186 import pdb
1187 pdb.Pdb().runcall(_main, parser)
1188 elif options.profile_file:
1189 from profile import Profile
1190
1191
1192
1193
1194
1195
1196 try:
1197 dispatch = Profile.dispatch
1198 except AttributeError:
1199 pass
1200 else:
1201 dispatch['c_exception'] = Profile.trace_dispatch_return
1202
1203 prof = Profile()
1204 try:
1205 prof.runcall(_main, parser)
1206 except SConsPrintHelpException, e:
1207 prof.dump_stats(options.profile_file)
1208 raise e
1209 except SystemExit:
1210 pass
1211 prof.dump_stats(options.profile_file)
1212 else:
1213 _main(parser)
1214
1216 global OptionsParser
1217 global exit_status
1218 global first_command_start
1219
1220
1221
1222
1223
1224 if python_version_unsupported():
1225 msg = "scons: *** SCons version %s does not run under Python version %s.\n"
1226 sys.stderr.write(msg % (SCons.__version__, python_version_string()))
1227 sys.exit(1)
1228
1229 parts = ["SCons by Steven Knight et al.:\n"]
1230 try:
1231 import __main__
1232 parts.append(version_string("script", __main__))
1233 except (ImportError, AttributeError):
1234
1235
1236 pass
1237 parts.append(version_string("engine", SCons))
1238 parts.append("Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation")
1239 version = string.join(parts, '')
1240
1241 import SConsOptions
1242 parser = SConsOptions.Parser(version)
1243 values = SConsOptions.SConsValues(parser.get_default_values())
1244
1245 OptionsParser = parser
1246
1247 try:
1248 _exec_main(parser, values)
1249 except SystemExit, s:
1250 if s:
1251 exit_status = s
1252 except KeyboardInterrupt:
1253 print("scons: Build interrupted.")
1254 sys.exit(2)
1255 except SyntaxError, e:
1256 _scons_syntax_error(e)
1257 except SCons.Errors.InternalError:
1258 _scons_internal_error()
1259 except SCons.Errors.UserError, e:
1260 _scons_user_error(e)
1261 except SConsPrintHelpException:
1262 parser.print_help()
1263 exit_status = 0
1264 except:
1265
1266
1267
1268 SCons.Script._SConscript.SConscript_exception()
1269 sys.exit(2)
1270
1271 memory_stats.print_stats()
1272 count_stats.print_stats()
1273
1274 if print_objects:
1275 SCons.Debug.listLoggedInstances('*')
1276
1277
1278 if print_memoizer:
1279 SCons.Memoize.Dump("Memoizer (memory cache) hits and misses:")
1280
1281
1282
1283
1284
1285 SCons.Debug.dump_caller_counts()
1286 SCons.Taskmaster.dump_stats()
1287
1288 if print_time:
1289 total_time = time.time() - SCons.Script.start_time
1290 if num_jobs == 1:
1291 ct = cumulative_command_time
1292 else:
1293 if last_command_end is None or first_command_start is None:
1294 ct = 0.0
1295 else:
1296 ct = last_command_end - first_command_start
1297 scons_time = total_time - sconscript_time - ct
1298 print "Total build time: %f seconds"%total_time
1299 print "Total SConscript file execution time: %f seconds"%sconscript_time
1300 print "Total SCons execution time: %f seconds"%scons_time
1301 print "Total command execution time: %f seconds"%ct
1302
1303 sys.exit(exit_status)
1304