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