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