Update User's Guide for changes to --debug=taskmastertrace output.
[scons.git] / doc / user / troubleshoot.xml
1 <!--
2
3   __COPYRIGHT__
4
5   Permission is hereby granted, free of charge, to any person obtaining
6   a copy of this software and associated documentation files (the
7   "Software"), to deal in the Software without restriction, including
8   without limitation the rights to use, copy, modify, merge, publish,
9   distribute, sublicense, and/or sell copies of the Software, and to
10   permit persons to whom the Software is furnished to do so, subject to
11   the following conditions:
12
13   The above copyright notice and this permission notice shall be included
14   in all copies or substantial portions of the Software.
15
16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17   KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18   WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 -->
25
26   <para>
27
28   The experience of configuring any
29   software build tool to build a large code base
30   usually, at some point,
31   involves trying to figure out why
32   the tool is behaving a certain way,
33   and how to get it to behave the way you want.
34   &SCons; is no different.
35   This appendix contains a number of
36   different ways in which you can
37   get some additional insight into &SCons;' behavior.
38
39   </para>
40
41   <para>
42
43   Note that we're always interested in trying to
44   improve how you can troubleshoot configuration problems.
45   If you run into a problem that has
46   you scratching your head,
47   and which there just doesn't seem to be a good way to debug,
48   odds are pretty good that someone else will run into
49   the same problem, too.
50   If so, please let the SCons development team know
51   (preferably by filing a bug report
52   or feature request at our project pages at tigris.org)
53   so that we can use your feedback
54   to try to come up with a better way to help you,
55   and others, get the necessary insight into &SCons; behavior
56   to help identify and fix configuration issues.
57
58   </para>
59
60   <section>
61   <title>Why is That Target Being Rebuilt?  the &debug-explain; Option</title>
62
63     <para>
64
65     Let's look at a simple example of
66     a misconfigured build
67     that causes a target to be rebuilt
68     every time &SCons; is run:
69
70     </para>
71
72     <programlisting>
73       # Intentionally misspell the output file name in the
74       # command used to create the file:
75       Command('file.out', 'file.in', 'cp $SOURCE file.oout')
76     </programlisting>
77
78     <para>
79
80     (Note to Windows users:  The POSIX &cp; command
81     copies the first file named on the command line
82     to the second file.
83     In our example, it copies the &file_in; file
84     to the &file_out; file.)
85
86     </para>
87
88     <para>
89
90     Now if we run &SCons; multiple times on this example,
91     we see that it re-runs the &cp;
92     command every time:
93
94     </para>
95
96     <screen>
97       % <userinput>scons -Q</userinput>
98       cp file.in file.oout
99       % <userinput>scons -Q</userinput>
100       cp file.in file.oout
101       % <userinput>scons -Q</userinput>
102       cp file.in file.oout
103     </screen>
104
105     <para>
106
107     In this example,
108     the underlying cause is obvious:
109     we've intentionally misspelled the output file name
110     in the &cp; command,
111     so the command doesn't actually
112     build the &file_out; file that we've told &SCons; to expect.
113     But if the problem weren't obvious,
114     it would be helpful
115     to specify the &debug-explain; option
116     on the command line
117     to have &SCons; tell us very specifically
118     why it's decided to rebuild the target:
119
120     </para>
121
122     <screen>
123       % <userinput>scons -Q --debug=explain</userinput>
124       scons: building `file.out' because it doesn't exist
125       cp file.in file.oout
126     </screen>
127
128     <para>
129
130     If this had been a more complicated example
131     involving a lot of build output,
132     having &SCons; tell us that
133     it's trying to rebuild the target file
134     because it doesn't exist
135     would be an important clue
136     that something was wrong with
137     the command that we invoked to build it.
138
139     </para>
140
141     <para>
142
143     The &debug-explain; option also comes in handy
144     to help figure out what input file changed.
145     Given a simple configuration that builds
146     a program from three source files,
147     changing one of the source files
148     and rebuilding with the &debug-explain;
149     option shows very specifically
150     why &SCons; rebuilds the files that it does:
151
152     </para>
153
154     
155
156     <screen>
157       % <userinput>scons -Q</userinput>
158       cc -o file1.o -c file1.c
159       cc -o file2.o -c file2.c
160       cc -o file3.o -c file3.c
161       cc -o prog file1.o file2.o file3.o
162       % <userinput>edit file2.c</userinput>
163           [CHANGE THE CONTENTS OF file2.c]
164       % <userinput>scons -Q --debug=explain</userinput>
165       scons: rebuilding `file2.o' because `file2.c' changed
166       cc -o file2.o -c file2.c
167       scons: rebuilding `prog' because `file2.o' changed
168       cc -o prog file1.o file2.o file3.o
169     </screen>
170
171     <para>
172
173     This becomes even more helpful
174     in identifying when a file is rebuilt
175     due to a change in an implicit dependency,
176     such as an incuded <filename>.h</filename> file.
177     If the <filename>file1.c</filename>
178     and <filename>file3.c</filename> files
179     in our example
180     both included a &hello_h; file,
181     then changing that included file
182     and re-running &SCons; with the &debug-explain; option
183     will pinpoint that it's the change to the included file
184     that starts the chain of rebuilds:
185
186     </para>
187
188     
189
190     <screen>
191       % <userinput>scons -Q</userinput>
192       cc -o file1.o -c -I. file1.c
193       cc -o file2.o -c -I. file2.c
194       cc -o file3.o -c -I. file3.c
195       cc -o prog file1.o file2.o file3.o
196       % <userinput>edit hello.h</userinput>
197           [CHANGE THE CONTENTS OF hello.h]
198       % <userinput>scons -Q --debug=explain</userinput>
199       scons: rebuilding `file1.o' because `hello.h' changed
200       cc -o file1.o -c -I. file1.c
201       scons: rebuilding `file3.o' because `hello.h' changed
202       cc -o file3.o -c -I. file3.c
203       scons: rebuilding `prog' because:
204                  `file1.o' changed
205                  `file3.o' changed
206       cc -o prog file1.o file2.o file3.o
207     </screen>
208
209     <para>
210
211     (Note that the &debug-explain; option will only tell you
212     why &SCons; decided to rebuild necessary targets.
213     It does not tell you what files it examined
214     when deciding <emphasis>not</emphasis>
215     to rebuild a target file,
216     which is often a more valuable question to answer.)
217
218     </para>
219
220   </section>
221
222   <section>
223   <title>What's in That Construction Environment?  the &Dump; Method</title>
224
225     <para>
226
227     When you create a construction environment,
228     &SCons; populates it
229     with construction variables that are set up
230     for various compilers, linkers and utilities
231     that it finds on your system.
232     Although this is usually helpful and what you want,
233     it might be frustrating if &SCons;
234     doesn't set certain variables that you
235     expect to be set.
236     In situations like this,
237     it's sometimes helpful to use the
238     construction environment &Dump; method
239     to print all or some of
240     the construction variables.
241     Note that the &Dump; method
242     <emphasis>returns</emphasis>
243     the representation of the variables
244     in the environment
245     for you to print (or otherwise manipulate):
246
247     </para>
248
249     <programlisting>
250          env = Environment()
251          print env.Dump()
252     </programlisting>
253
254     <para>
255
256     On a POSIX system with gcc installed,
257     this might generate:
258
259     </para>
260
261     <screen>
262       % <userinput>scons</userinput>
263       scons: Reading SConscript files ...
264       { 'BUILDERS': {'_InternalInstall': &lt;function InstallBuilderWrapper at 0x700000&gt;, '_InternalInstallAs': &lt;function InstallAsBuilderWrapper at 0x700000&gt;},
265         'CONFIGUREDIR': '#/.sconf_temp',
266         'CONFIGURELOG': '#/config.log',
267         'CPPSUFFIXES': [ '.c',
268                          '.C',
269                          '.cxx',
270                          '.cpp',
271                          '.c++',
272                          '.cc',
273                          '.h',
274                          '.H',
275                          '.hxx',
276                          '.hpp',
277                          '.hh',
278                          '.F',
279                          '.fpp',
280                          '.FPP',
281                          '.m',
282                          '.mm',
283                          '.S',
284                          '.spp',
285                          '.SPP'],
286         'DSUFFIXES': ['.d'],
287         'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
288         'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
289         'ENV': {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'},
290         'ESCAPE': &lt;function escape at 0x700000&gt;,
291         'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
292         'IDLSUFFIXES': ['.idl', '.IDL'],
293         'INSTALL': &lt;function copyFunc at 0x700000&gt;,
294         'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'],
295         'LIBPREFIX': 'lib',
296         'LIBPREFIXES': ['$LIBPREFIX'],
297         'LIBSUFFIX': '.a',
298         'LIBSUFFIXES': ['$LIBSUFFIX', '$SHLIBSUFFIX'],
299         'MAXLINELENGTH': 128072,
300         'OBJPREFIX': '',
301         'OBJSUFFIX': '.o',
302         'PLATFORM': 'posix',
303         'PROGPREFIX': '',
304         'PROGSUFFIX': '',
305         'PSPAWN': &lt;function piped_env_spawn at 0x700000&gt;,
306         'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
307         'SCANNERS': [],
308         'SHELL': 'sh',
309         'SHLIBPREFIX': '$LIBPREFIX',
310         'SHLIBSUFFIX': '.so',
311         'SHOBJPREFIX': '$OBJPREFIX',
312         'SHOBJSUFFIX': '$OBJSUFFIX',
313         'SPAWN': &lt;function spawnvpe_spawn at 0x700000&gt;,
314         'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
315         'TEMPFILEPREFIX': '@',
316         'TOOLS': ['install', 'install'],
317         '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
318         '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
319         '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
320         '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
321         '__RPATH': '$_RPATH',
322         '_concat': &lt;function _concat at 0x700000&gt;,
323         '_defines': &lt;function _defines at 0x700000&gt;,
324         '_stripixes': &lt;function _stripixes at 0x700000&gt;}
325       scons: done reading SConscript files.
326       scons: Building targets ...
327       scons: `.' is up to date.
328       scons: done building targets.
329     </screen>
330
331     <para>
332
333     On a Windows system with Visual C++
334     the output might look like:
335
336     </para>
337
338     <screen>
339       C:\><userinput>scons</userinput>
340       scons: Reading SConscript files ...
341       { 'BUILDERS': {'_InternalInstall': &lt;function InstallBuilderWrapper at 0x700000&gt;, 'Object': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, 'PCH': &lt;SCons.Builder.BuilderBase instance at 0x700000&gt;, 'RES': &lt;SCons.Builder.BuilderBase instance at 0x700000&gt;, 'SharedObject': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, 'StaticObject': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, '_InternalInstallAs': &lt;function InstallAsBuilderWrapper at 0x700000&gt;},
342         'CC': 'cl',
343         'CCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
344         'CCCOMFLAGS': '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS',
345         'CCFLAGS': ['/nologo'],
346         'CCPCHFLAGS': ['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'],
347         'CCPDBFLAGS': ['${(PDB and "/Z7") or ""}'],
348         'CFILESUFFIX': '.c',
349         'CFLAGS': [],
350         'CONFIGUREDIR': '#/.sconf_temp',
351         'CONFIGURELOG': '#/config.log',
352         'CPPDEFPREFIX': '/D',
353         'CPPDEFSUFFIX': '',
354         'CPPSUFFIXES': [ '.c',
355                          '.C',
356                          '.cxx',
357                          '.cpp',
358                          '.c++',
359                          '.cc',
360                          '.h',
361                          '.H',
362                          '.hxx',
363                          '.hpp',
364                          '.hh',
365                          '.F',
366                          '.fpp',
367                          '.FPP',
368                          '.m',
369                          '.mm',
370                          '.S',
371                          '.spp',
372                          '.SPP'],
373         'CXX': '$CC',
374         'CXXCOM': '$CXX $CXXFLAGS $CCCOMFLAGS',
375         'CXXFILESUFFIX': '.cc',
376         'CXXFLAGS': ['$CCFLAGS', '$(', '/TP', '$)'],
377         'DSUFFIXES': ['.d'],
378         'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
379         'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
380         'ENV': { 'INCLUDE': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\include',
381                  'LIB': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\lib',
382                  'PATH': 'C:\\Program Files\\Microsoft Visual Studio\\Common\\tools\\WIN95;C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\bin;C:\\Program Files\\Microsoft Visual Studio\\Common\\tools;C:\\Program Files\\Microsoft Visual Studio/VC98\\bin',
383                  'PATHEXT': '.COM;.EXE;.BAT;.CMD',
384                  'SystemRoot': 'C:/WINDOWS'},
385         'ESCAPE': &lt;function escape at 0x700000&gt;,
386         'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
387         'IDLSUFFIXES': ['.idl', '.IDL'],
388         'INCPREFIX': '/I',
389         'INCSUFFIX': '',
390         'INSTALL': &lt;function copyFunc at 0x700000&gt;,
391         'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'],
392         'LIBPREFIX': '',
393         'LIBPREFIXES': ['$LIBPREFIX'],
394         'LIBSUFFIX': '.lib',
395         'LIBSUFFIXES': ['$LIBSUFFIX'],
396         'MAXLINELENGTH': 2048,
397         'MSVS': {'VERSION': '6.0', 'VERSIONS': ['6.0']},
398         'MSVS_VERSION': '6.0',
399         'OBJPREFIX': '',
400         'OBJSUFFIX': '.obj',
401         'PCHCOM': '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS',
402         'PCHPDBFLAGS': ['${(PDB and "/Yd") or ""}'],
403         'PLATFORM': 'win32',
404         'PROGPREFIX': '',
405         'PROGSUFFIX': '.exe',
406         'PSPAWN': &lt;function piped_spawn at 0x700000&gt;,
407         'RC': 'rc',
408         'RCCOM': '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES',
409         'RCFLAGS': [],
410         'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
411         'SCANNERS': [],
412         'SHCC': '$CC',
413         'SHCCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
414         'SHCCFLAGS': ['$CCFLAGS'],
415         'SHCFLAGS': ['$CFLAGS'],
416         'SHCXX': '$CXX',
417         'SHCXXCOM': '$SHCXX $SHCXXFLAGS $CCCOMFLAGS',
418         'SHCXXFLAGS': ['$CXXFLAGS'],
419         'SHELL': None,
420         'SHLIBPREFIX': '',
421         'SHLIBSUFFIX': '.dll',
422         'SHOBJPREFIX': '$OBJPREFIX',
423         'SHOBJSUFFIX': '$OBJSUFFIX',
424         'SPAWN': &lt;function spawn at 0x700000&gt;,
425         'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1,
426         'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
427         'TEMPFILEPREFIX': '@',
428         'TOOLS': ['msvc', 'install', 'install'],
429         '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
430         '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
431         '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
432         '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
433         '_concat': &lt;function _concat at 0x700000&gt;,
434         '_defines': &lt;function _defines at 0x700000&gt;,
435         '_stripixes': &lt;function _stripixes at 0x700000&gt;}
436       scons: done reading SConscript files.
437       scons: Building targets ...
438       scons: `.' is up to date.
439       scons: done building targets.
440     </screen>
441
442     <para>
443
444     The construction environments in these examples have
445     actually been restricted to just gcc and Visual C++,
446     respectively.
447     In a real-life situation,
448     the construction environments will
449     likely contain a great many more variables.
450     Also note that we've massaged the example output above
451     to make the memory address of all objects a constant 0x700000.
452     In reality, you would see a different hexadecimal
453     number for each object.
454
455     </para>
456
457     <para>
458
459     To make it easier to see just what you're
460     interested in,
461     the &Dump; method allows you to
462     specify a specific constrcution variable
463     that you want to disply.
464     For example,
465     it's not unusual to want to verify
466     the external environment used to execute build commands,
467     to make sure that the PATH and other
468     environment variables are set up the way they should be.
469     You can do this as follows:
470
471     </para>
472
473     <programlisting>
474          env = Environment()
475          print env.Dump('ENV')
476     </programlisting>
477
478     <para>
479
480     Which might display the following when executed on a POSIX system:
481
482     </para>
483
484     <screen>
485       % <userinput>scons</userinput>
486       scons: Reading SConscript files ...
487       {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}
488       scons: done reading SConscript files.
489       scons: Building targets ...
490       scons: `.' is up to date.
491       scons: done building targets.
492     </screen>
493
494     <para>
495
496     And the following when executed on a Windows system:
497
498     </para>
499
500     <screen>
501       C:\><userinput>scons</userinput>
502       scons: Reading SConscript files ...
503       { 'INCLUDE': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\include',
504         'LIB': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\lib',
505         'PATH': 'C:\\Program Files\\Microsoft Visual Studio\\Common\\tools\\WIN95;C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\bin;C:\\Program Files\\Microsoft Visual Studio\\Common\\tools;C:\\Program Files\\Microsoft Visual Studio/VC98\\bin',
506         'PATHEXT': '.COM;.EXE;.BAT;.CMD',
507         'SystemRoot': 'C:/WINDOWS'}
508       scons: done reading SConscript files.
509       scons: Building targets ...
510       scons: `.' is up to date.
511       scons: done building targets.
512     </screen>
513
514   </section>
515
516   <section>
517
518   <title>What Dependencies Does &SCons; Know About?  the &tree; Option</title>
519
520     <para>
521
522     Sometimes the best way to try to figure out what
523     &SCons; is doing is simply to take a look at the
524     dependency graph that it constructs
525     based on your &SConscript; files.
526     The <literal>--tree</literal> option
527     will display all or part of the
528     &SCons; dependency graph in an
529     "ASCII art" graphical format
530     that shows the dependency hierarchy.
531
532     </para>
533
534     <para>
535
536     For example, given the following input &SConstruct; file:
537
538     </para>
539
540     <programlisting>
541          env = Environment(CPPPATH = ['.'])
542          env.Program('prog', ['f1.c', 'f2.c', 'f3.c'])
543     </programlisting>
544
545     <para>
546
547     Running &SCons; with the <literal>--tree=all</literal>
548     option yields:
549
550     </para>
551
552     <screen>
553       % <userinput>scons -Q --tree=all</userinput>
554       cc -o f1.o -c -I. f1.c
555       cc -o f2.o -c -I. f2.c
556       cc -o f3.o -c -I. f3.c
557       cc -o prog f1.o f2.o f3.o
558       +-.
559         +-SConstruct
560         +-f1.c
561         +-f1.o
562         | +-f1.c
563         | +-inc.h
564         +-f2.c
565         +-f2.o
566         | +-f2.c
567         | +-inc.h
568         +-f3.c
569         +-f3.o
570         | +-f3.c
571         | +-inc.h
572         +-inc.h
573         +-prog
574           +-f1.o
575           | +-f1.c
576           | +-inc.h
577           +-f2.o
578           | +-f2.c
579           | +-inc.h
580           +-f3.o
581             +-f3.c
582             +-inc.h
583     </screen>
584
585     <para>
586
587     The tree will also be printed when the
588     <literal>-n</literal> (no execute) option is used,
589     which allows you to examine the dependency graph
590     for a configuration without actually
591     rebuilding anything in the tree.
592
593     </para>
594
595     <para>
596
597     The <literal>--tree</literal> option only prints
598     the dependency graph for the specified targets
599     (or the default target(s) if none are specified on the command line).
600     So if you specify a target like <filename>f2.o</filename>
601     on the command line,
602     the <literal>--tree</literal> option will only
603     print the dependency graph for that file:
604
605     </para>
606
607     <screen>
608       % <userinput>scons -Q --tree=all f2.o</userinput>
609       cc -o f2.o -c -I. f2.c
610       +-f2.o
611         +-f2.c
612         +-inc.h
613     </screen>
614
615     <para>
616
617     This is, of course, useful for
618     restricting the output from a very large
619     build configuration to just a
620     portion in which you're interested.
621     Multiple targets are fine,
622     in which case a tree will be printed
623     for each specified target:
624
625     </para>
626
627     <screen>
628       % <userinput>scons -Q --tree=all f1.o f3.o</userinput>
629       cc -o f1.o -c -I. f1.c
630       +-f1.o
631         +-f1.c
632         +-inc.h
633       cc -o f3.o -c -I. f3.c
634       +-f3.o
635         +-f3.c
636         +-inc.h
637     </screen>
638
639     <para>
640
641     The <literal>status</literal> argument may be used
642     to tell &SCons; to print status information about
643     each file in the dependency graph:
644
645     </para>
646
647     <screen>
648       % <userinput>scons -Q --tree=status</userinput>
649       cc -o f1.o -c -I. f1.c
650       cc -o f2.o -c -I. f2.c
651       cc -o f3.o -c -I. f3.c
652       cc -o prog f1.o f2.o f3.o
653        E         = exists
654         R        = exists in repository only
655          b       = implicit builder
656          B       = explicit builder
657           S      = side effect
658            P     = precious
659             A    = always build
660              C   = current
661               N  = no clean
662                H = no cache
663       
664       [E b      ]+-.
665       [E     C  ]  +-SConstruct
666       [E     C  ]  +-f1.c
667       [E B   C  ]  +-f1.o
668       [E     C  ]  | +-f1.c
669       [E     C  ]  | +-inc.h
670       [E     C  ]  +-f2.c
671       [E B   C  ]  +-f2.o
672       [E     C  ]  | +-f2.c
673       [E     C  ]  | +-inc.h
674       [E     C  ]  +-f3.c
675       [E B   C  ]  +-f3.o
676       [E     C  ]  | +-f3.c
677       [E     C  ]  | +-inc.h
678       [E     C  ]  +-inc.h
679       [E B   C  ]  +-prog
680       [E B   C  ]    +-f1.o
681       [E     C  ]    | +-f1.c
682       [E     C  ]    | +-inc.h
683       [E B   C  ]    +-f2.o
684       [E     C  ]    | +-f2.c
685       [E     C  ]    | +-inc.h
686       [E B   C  ]    +-f3.o
687       [E     C  ]      +-f3.c
688       [E     C  ]      +-inc.h
689     </screen>
690
691     <para>
692
693     Note that <literal>--tree=all,status</literal> is equivalent;
694     the <literal>all</literal>
695     is assumed if only <literal>status</literal> is present.
696     As an alternative to <literal>all</literal>,
697     you can specify <literal>--tree=derived</literal>
698     to have &SCons; only print derived targets
699     in the tree output,
700     skipping source files
701     (like <filename>.c</filename> and <filename>.h</filename> files):
702
703     </para>
704
705     <screen>
706       % <userinput>scons -Q --tree=derived</userinput>
707       cc -o f1.o -c -I. f1.c
708       cc -o f2.o -c -I. f2.c
709       cc -o f3.o -c -I. f3.c
710       cc -o prog f1.o f2.o f3.o
711       +-.
712         +-f1.o
713         +-f2.o
714         +-f3.o
715         +-prog
716           +-f1.o
717           +-f2.o
718           +-f3.o
719     </screen>
720
721     <para>
722
723     You can use the <literal>status</literal>
724     modifier with <literal>derived</literal> as well:
725
726     </para>
727
728     <screen>
729       % <userinput>scons -Q --tree=derived,status</userinput>
730       cc -o f1.o -c -I. f1.c
731       cc -o f2.o -c -I. f2.c
732       cc -o f3.o -c -I. f3.c
733       cc -o prog f1.o f2.o f3.o
734        E         = exists
735         R        = exists in repository only
736          b       = implicit builder
737          B       = explicit builder
738           S      = side effect
739            P     = precious
740             A    = always build
741              C   = current
742               N  = no clean
743                H = no cache
744       
745       [E b      ]+-.
746       [E B   C  ]  +-f1.o
747       [E B   C  ]  +-f2.o
748       [E B   C  ]  +-f3.o
749       [E B   C  ]  +-prog
750       [E B   C  ]    +-f1.o
751       [E B   C  ]    +-f2.o
752       [E B   C  ]    +-f3.o
753     </screen>
754
755     <para>
756
757     Note that the order of the <literal>--tree=</literal>
758     arguments doesn't matter;
759     <literal>--tree=status,derived</literal> is
760     completely equivalent.
761
762     </para>
763
764     <para>
765
766     The default behavior of the <literal>--tree</literal> option
767     is to repeat all of the dependencies each time the library dependency
768     (or any other dependency file) is encountered in the tree.
769     If certain target files share other target files,
770     such as two programs that use the same library:
771
772     </para>
773
774     <programlisting>
775          env = Environment(CPPPATH = ['.'],
776                            LIBS = ['foo'],
777                            LIBPATH = ['.'])
778          env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
779          env.Program('prog1.c')
780          env.Program('prog2.c')
781     </programlisting>
782
783     <para>
784
785     Then there can be a <emphasis>lot</emphasis> of repetition in the
786     <literal>--tree=</literal> output:
787
788     </para>
789
790     <screen>
791       % <userinput>scons -Q --tree=all</userinput>
792       cc -o f1.o -c -I. f1.c
793       cc -o f2.o -c -I. f2.c
794       cc -o f3.o -c -I. f3.c
795       ar rc libfoo.a f1.o f2.o f3.o
796       ranlib libfoo.a
797       cc -o prog1.o -c -I. prog1.c
798       cc -o prog1 prog1.o -L. -lfoo
799       cc -o prog2.o -c -I. prog2.c
800       cc -o prog2 prog2.o -L. -lfoo
801       +-.
802         +-SConstruct
803         +-f1.c
804         +-f1.o
805         | +-f1.c
806         | +-inc.h
807         +-f2.c
808         +-f2.o
809         | +-f2.c
810         | +-inc.h
811         +-f3.c
812         +-f3.o
813         | +-f3.c
814         | +-inc.h
815         +-inc.h
816         +-libfoo.a
817         | +-f1.o
818         | | +-f1.c
819         | | +-inc.h
820         | +-f2.o
821         | | +-f2.c
822         | | +-inc.h
823         | +-f3.o
824         |   +-f3.c
825         |   +-inc.h
826         +-prog1
827         | +-prog1.o
828         | | +-prog1.c
829         | | +-inc.h
830         | +-libfoo.a
831         |   +-f1.o
832         |   | +-f1.c
833         |   | +-inc.h
834         |   +-f2.o
835         |   | +-f2.c
836         |   | +-inc.h
837         |   +-f3.o
838         |     +-f3.c
839         |     +-inc.h
840         +-prog1.c
841         +-prog1.o
842         | +-prog1.c
843         | +-inc.h
844         +-prog2
845         | +-prog2.o
846         | | +-prog2.c
847         | | +-inc.h
848         | +-libfoo.a
849         |   +-f1.o
850         |   | +-f1.c
851         |   | +-inc.h
852         |   +-f2.o
853         |   | +-f2.c
854         |   | +-inc.h
855         |   +-f3.o
856         |     +-f3.c
857         |     +-inc.h
858         +-prog2.c
859         +-prog2.o
860           +-prog2.c
861           +-inc.h
862     </screen>
863
864     <para>
865
866     In a large configuration with many internal libraries
867     and include files,
868     this can very quickly lead to huge output trees.
869     To help make this more manageable,
870     a <literal>prune</literal> modifier may
871     be added to the option list,
872     in which case &SCons;
873     will print the name of a target that has
874     already been visited during the tree-printing
875     in <literal>[square brackets]</literal>
876     as an indication that the dependencies
877     of the target file may be found
878     by looking farther up the tree:
879
880     </para>
881
882     <screen>
883       % <userinput>scons -Q --tree=prune</userinput>
884       cc -o f1.o -c -I. f1.c
885       cc -o f2.o -c -I. f2.c
886       cc -o f3.o -c -I. f3.c
887       ar rc libfoo.a f1.o f2.o f3.o
888       ranlib libfoo.a
889       cc -o prog1.o -c -I. prog1.c
890       cc -o prog1 prog1.o -L. -lfoo
891       cc -o prog2.o -c -I. prog2.c
892       cc -o prog2 prog2.o -L. -lfoo
893       +-.
894         +-SConstruct
895         +-f1.c
896         +-f1.o
897         | +-f1.c
898         | +-inc.h
899         +-f2.c
900         +-f2.o
901         | +-f2.c
902         | +-inc.h
903         +-f3.c
904         +-f3.o
905         | +-f3.c
906         | +-inc.h
907         +-inc.h
908         +-libfoo.a
909         | +-[f1.o]
910         | +-[f2.o]
911         | +-[f3.o]
912         +-prog1
913         | +-prog1.o
914         | | +-prog1.c
915         | | +-inc.h
916         | +-[libfoo.a]
917         +-prog1.c
918         +-[prog1.o]
919         +-prog2
920         | +-prog2.o
921         | | +-prog2.c
922         | | +-inc.h
923         | +-[libfoo.a]
924         +-prog2.c
925         +-[prog2.o]
926     </screen>
927
928     <para>
929
930     Like the <literal>status</literal> keyword,
931     the <literal>prune</literal> argument by itself
932     is equivalent to <literal>--tree=all,prune</literal>.
933
934     </para>
935
936   </section>
937
938   <section>
939
940   <title>How is &SCons; Constructing the Command Lines It Executes?  the &debug-presub; Option</title>
941
942     <para>
943
944     Sometimes it's useful to look at the
945     pre-substitution string
946     that &SCons; uses to generate
947     the command lines it executes.
948     This can be done with the &debug-presub; option:
949
950     </para>
951
952     
953
954     <!--
955
956     Have to capture output here, otherwise the - -debug=presub output
957     shows the Python functions from the sconsdoc.py execution wrapper
958     used to generate this manual, not the underlying command-line strings.
959
960     <scons_output example="presub">
961       <scons_output_command>scons -Q - -debug=presub</scons_output_command>
962     </scons_output>
963
964     -->
965
966     <screen>
967       % <userinput>scons -Q --debug=presub</userinput>
968       Building prog.o with action:
969         $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCOMCOM $SOURCES
970       cc -o prog.o -c -I. prog.c
971       Building prog with action:
972         $SMART_LINKCOM
973       cc -o prog prog.o
974     </screen>
975
976   </section>
977
978   <section>
979
980   <title>Where is &SCons; Searching for Libraries?  the &debug-findlibs; Option</title>
981
982     <para>
983
984     To get some insight into what library names
985     &SCons; is searching for,
986     and in which directories it is searching,
987     Use the <literal>--debug=findlibs</literal> option.
988     Given the following input &SConstruct; file:
989
990     </para>
991
992     <programlisting>
993         env = Environment(LIBPATH = ['libs1', 'libs2'])
994         env.Program('prog.c', LIBS=['foo', 'bar'])
995     </programlisting>
996
997     <para>
998
999     And the libraries <filename>libfoo.a</filename>
1000     and <filename>libbar.a</filename>
1001     in <filename>libs1</filename> and <filename>libs2</filename>,
1002     respectively,
1003     use of the <literal>--debug=findlibs</literal> option yields:
1004
1005     </para>
1006
1007     <screen>
1008       % <userinput>scons -Q --debug=findlibs</userinput>
1009         findlibs: looking for 'libfoo.a' in 'libs1' ...
1010         findlibs: ... FOUND 'libfoo.a' in 'libs1'
1011         findlibs: looking for 'libfoo.so' in 'libs1' ...
1012         findlibs: looking for 'libfoo.so' in 'libs2' ...
1013         findlibs: looking for 'libbar.a' in 'libs1' ...
1014         findlibs: looking for 'libbar.a' in 'libs2' ...
1015         findlibs: ... FOUND 'libbar.a' in 'libs2'
1016         findlibs: looking for 'libbar.so' in 'libs1' ...
1017         findlibs: looking for 'libbar.so' in 'libs2' ...
1018       cc -o prog.o -c prog.c
1019       cc -o prog prog.o -Llibs1 -Llibs2 -lfoo -lbar
1020     </screen>
1021
1022   </section>
1023
1024   <!--
1025
1026   <section>
1027
1028   <title>What Implicit Dependencies Did the &SCons; Scanner find?  the &debug-includes; Option</title>
1029
1030     <para>
1031
1032     XXX explain the - - debug=includes option
1033
1034     </para>
1035
1036     <scons_example name="includes">
1037       <file name="SConstruct" printme="1">
1038         env = Environment(CPPPATH = ['inc1', 'inc2'])
1039         env.Program('prog.c')
1040       </file>
1041       <file name="prog.c">
1042       #include "file1.h"
1043       #include "file2.h"
1044       prog.c
1045       </file>
1046       <file name="inc1/file1.h">
1047       inc1/file1.h
1048       </file>
1049       <file name="inc2/file2.h">
1050       inc2/file2.h
1051       </file>
1052     </scons_example>
1053
1054     <scons_output example="includes">
1055       <scons_output_command>scons -Q - - debug=includes prog</scons_output_command>
1056     </scons_output>
1057
1058   </section>
1059
1060   -->
1061
1062   <section>
1063
1064   <title>Where is &SCons; Blowing Up?  the &debug-stacktrace; Option</title>
1065
1066     <para>
1067
1068     In general, &SCons; tries to keep its error
1069     messages short and informative.
1070     That means we usually try to avoid showing
1071     the stack traces that are familiar
1072     to experienced Python programmers,
1073     since they usually contain much more
1074     information than is useful to most people.
1075
1076     </para>
1077
1078     <para>
1079
1080     For example, the following &SConstruct; file:
1081
1082     </para>
1083
1084     <programlisting>
1085          Program('prog.c')
1086     </programlisting>
1087
1088     <para>
1089
1090     Generates the following error if the
1091     <filename>prog.c</filename> file
1092     does not exist:
1093
1094     </para>
1095
1096     <screen>
1097       % <userinput>scons -Q</userinput>
1098       scons: *** Source `prog.c' not found, needed by target `prog.o'.  Stop.
1099     </screen>
1100
1101     <para>
1102
1103     In this case,
1104     the error is pretty obvious.
1105     But if it weren't,
1106     and you wanted to try to get more information
1107     about the error,
1108     the &debug-stacktrace; option
1109     would show you exactly where in the &SCons; source code
1110     the problem occurs:
1111
1112     </para>
1113
1114     <screen>
1115       % <userinput>scons -Q --debug=stacktrace</userinput>
1116       scons: *** Source `prog.c' not found, needed by target `prog.o'.  Stop.
1117       scons: internal stack trace:
1118         File "bootstrap/src/engine/SCons/Job.py", line 198, in start
1119         File "bootstrap/src/engine/SCons/Script/Main.py", line 169, in prepare
1120         File "bootstrap/src/engine/SCons/Taskmaster.py", line 184, in prepare
1121         File "bootstrap/src/engine/SCons/Executor.py", line 171, in prepare
1122     </screen>
1123
1124     <para>
1125
1126     Of course, if you do need to dive into the &SCons; source code,
1127     we'd like to know if, or how,
1128     the error messages or troubleshooting options
1129     could have been improved to avoid that.
1130     Not everyone has the necessary time or
1131     Python skill to dive into the source code,
1132     and we'd like to improve &SCons;
1133     for those people as well...
1134
1135     </para>
1136
1137   </section>
1138
1139   <section>
1140
1141   <title>How is &SCons; Making Its Decisions?  the &taskmastertrace; Option</title>
1142
1143     <para>
1144
1145     The internal &SCons; subsystem that handles walking
1146     the dependency graph
1147     and controls the decision-making about what to rebuild
1148     is the <literal>Taskmaster</literal>.
1149     &SCons; supports a <literal>--taskmastertrace</literal>
1150     option that tells the Taskmaster to print
1151     information about the children (dependencies)
1152     of the various Nodes on its walk down the graph,
1153     which specific dependent Nodes are being evaluated,
1154     and in what order.
1155
1156     </para>
1157
1158     <para>
1159
1160     The <literal>--taskmastertrace</literal> option
1161     takes as an argument the name of a file in
1162     which to put the trace output,
1163     with <filename>-</filename> (a single hyphen)
1164     indicating that the trace messages
1165     should be printed to the standard output:
1166
1167     </para>
1168
1169     <programlisting>
1170       env = Environment(CPPPATH = ['.'])
1171       env.Program('prog.c')
1172     </programlisting>
1173
1174     <screen>
1175       % <userinput>scons -Q --taskmastertrace=- prog</userinput>
1176       
1177       Taskmaster: Looking for a node to evaluate
1178       Taskmaster:     Considering node &lt;no_state   0   'prog'&gt; and its children:
1179       Taskmaster:        &lt;no_state   0   'prog.o'&gt;
1180       Taskmaster:      adjusting ref count: &lt;pending    1   'prog'&gt;
1181       Taskmaster:     Considering node &lt;no_state   0   'prog.o'&gt; and its children:
1182       Taskmaster:        &lt;no_state   0   'prog.c'&gt;
1183       Taskmaster:        &lt;no_state   0   'inc.h'&gt;
1184       Taskmaster:      adjusting ref count: &lt;pending    1   'prog.o'&gt;
1185       Taskmaster:      adjusting ref count: &lt;pending    2   'prog.o'&gt;
1186       Taskmaster:     Considering node &lt;no_state   0   'prog.c'&gt; and its children:
1187       Taskmaster: Evaluating &lt;pending    0   'prog.c'&gt;
1188       
1189       Taskmaster: Looking for a node to evaluate
1190       Taskmaster:     Considering node &lt;no_state   0   'inc.h'&gt; and its children:
1191       Taskmaster: Evaluating &lt;pending    0   'inc.h'&gt;
1192       
1193       Taskmaster: Looking for a node to evaluate
1194       Taskmaster:     Considering node &lt;pending    0   'prog.o'&gt; and its children:
1195       Taskmaster:        &lt;up_to_date 0   'prog.c'&gt;
1196       Taskmaster:        &lt;up_to_date 0   'inc.h'&gt;
1197       Taskmaster: Evaluating &lt;pending    0   'prog.o'&gt;
1198       cc -o prog.o -c -I. prog.c
1199       
1200       Taskmaster: Looking for a node to evaluate
1201       Taskmaster:     Considering node &lt;pending    0   'prog'&gt; and its children:
1202       Taskmaster:        &lt;executed   0   'prog.o'&gt;
1203       Taskmaster: Evaluating &lt;pending    0   'prog'&gt;
1204       cc -o prog prog.o
1205       
1206       Taskmaster: Looking for a node to evaluate
1207       Taskmaster: No candidate anymore.
1208     </screen>
1209
1210     <para>
1211
1212     The <literal>--taskmastertrace</literal> option
1213     doesn't provide information about the actual
1214     calculations involved in deciding if a file is up-to-date,
1215     but it does show all of the dependencies
1216     it knows about for each Node,
1217     and the order in which those dependencies are evaluated.
1218     This can be useful as an alternate way to determine
1219     whether or not your &SCons; configuration,
1220     or the implicit dependency scan,
1221     has actually identified all the correct dependencies
1222     you want it to.
1223
1224     </para>
1225
1226   </section>
1227
1228   <!--
1229
1230   <section>
1231
1232   <title>Where Are My Build Bottlenecks?  the &profile; Option</title>
1233
1234     <para>
1235
1236     XXX explain the - - profile= option
1237
1238     </para>
1239
1240   </section>
1241
1242   -->
1243
1244   <!--
1245
1246   <section>
1247   <title>Troubleshooting Shared Caching:  the &cache-debug; Option</title>
1248
1249     <para>
1250
1251     XXX describe the - - cache-debug option
1252     XXX maybe point to the caching.in chapter?
1253
1254     </para>
1255
1256   </section>
1257
1258   -->