Merge back from checkpoint.
[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         'HOST_ARCH': None,
293         'HOST_OS': None,
294         'IDLSUFFIXES': ['.idl', '.IDL'],
295         'INSTALL': &lt;function copyFunc at 0x700000&gt;,
296         'LIBPREFIX': 'lib',
297         'LIBPREFIXES': ['$LIBPREFIX'],
298         'LIBSUFFIX': '.a',
299         'LIBSUFFIXES': ['$LIBSUFFIX', '$SHLIBSUFFIX'],
300         'MAXLINELENGTH': 128072,
301         'OBJPREFIX': '',
302         'OBJSUFFIX': '.o',
303         'PLATFORM': 'posix',
304         'PROGPREFIX': '',
305         'PROGSUFFIX': '',
306         'PSPAWN': &lt;function piped_env_spawn at 0x700000&gt;,
307         'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
308         'SCANNERS': [],
309         'SHELL': 'sh',
310         'SHLIBPREFIX': '$LIBPREFIX',
311         'SHLIBSUFFIX': '.so',
312         'SHOBJPREFIX': '$OBJPREFIX',
313         'SHOBJSUFFIX': '$OBJSUFFIX',
314         'SPAWN': &lt;function spawnvpe_spawn at 0x700000&gt;,
315         'TARGET_ARCH': None,
316         'TARGET_OS': None,
317         'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
318         'TEMPFILEPREFIX': '@',
319         'TOOLS': ['install', 'install'],
320         '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
321         '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
322         '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
323         '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
324         '__RPATH': '$_RPATH',
325         '_concat': &lt;function _concat at 0x700000&gt;,
326         '_defines': &lt;function _defines at 0x700000&gt;,
327         '_stripixes': &lt;function _stripixes at 0x700000&gt;}
328       scons: done reading SConscript files.
329       scons: Building targets ...
330       scons: `.' is up to date.
331       scons: done building targets.
332     </screen>
333
334     <para>
335
336     On a Windows system with Visual C++
337     the output might look like:
338
339     </para>
340
341     <screen>
342       C:\><userinput>scons</userinput>
343       scons: Reading SConscript files ...
344       
345       scons: warning: No installed VCs
346       File "&lt;stdin&gt;", line 67, in __call__
347       
348       scons: warning: No version of Visual Studio compiler found - C/C++ compilers most likely not set correctly
349       File "&lt;stdin&gt;", line 67, in __call__
350       
351       scons: warning: No installed VCs
352       File "&lt;stdin&gt;", line 67, in __call__
353       
354       scons: warning: No version of Visual Studio compiler found - C/C++ compilers most likely not set correctly
355       File "&lt;stdin&gt;", line 67, in __call__
356       { '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;},
357         'CC': 'cl',
358         'CCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
359         'CCFLAGS': ['/nologo'],
360         'CCPCHFLAGS': ['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'],
361         'CCPDBFLAGS': ['${(PDB and "/Z7") or ""}'],
362         'CFILESUFFIX': '.c',
363         'CFLAGS': [],
364         'CONFIGUREDIR': '#/.sconf_temp',
365         'CONFIGURELOG': '#/config.log',
366         'CPPDEFPREFIX': '/D',
367         'CPPDEFSUFFIX': '',
368         'CPPSUFFIXES': [ '.c',
369                          '.C',
370                          '.cxx',
371                          '.cpp',
372                          '.c++',
373                          '.cc',
374                          '.h',
375                          '.H',
376                          '.hxx',
377                          '.hpp',
378                          '.hh',
379                          '.F',
380                          '.fpp',
381                          '.FPP',
382                          '.m',
383                          '.mm',
384                          '.S',
385                          '.spp',
386                          '.SPP'],
387         'CXX': '$CC',
388         'CXXCOM': '$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM',
389         'CXXFILESUFFIX': '.cc',
390         'CXXFLAGS': ['$(', '/TP', '$)'],
391         'DSUFFIXES': ['.d'],
392         'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
393         'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
394         'ENV': { 'PATH': 'C:/WINDOWS\\System32',
395                  'PATHEXT': '.COM;.EXE;.BAT;.CMD',
396                  'SystemRoot': 'C:\\WINDOWS'},
397         'ESCAPE': &lt;function escape at 0x700000&gt;,
398         'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
399         'HOST_ARCH': '',
400         'HOST_OS': 'win32',
401         'IDLSUFFIXES': ['.idl', '.IDL'],
402         'INCPREFIX': '/I',
403         'INCSUFFIX': '',
404         'INSTALL': &lt;function copyFunc at 0x700000&gt;,
405         'LIBPREFIX': '',
406         'LIBPREFIXES': ['$LIBPREFIX'],
407         'LIBSUFFIX': '.lib',
408         'LIBSUFFIXES': ['$LIBSUFFIX'],
409         'MAXLINELENGTH': 2048,
410         'MSVC_SETUP_RUN': True,
411         'OBJPREFIX': '',
412         'OBJSUFFIX': '.obj',
413         'PCHCOM': '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS',
414         'PCHPDBFLAGS': ['${(PDB and "/Yd") or ""}'],
415         'PLATFORM': 'win32',
416         'PROGPREFIX': '',
417         'PROGSUFFIX': '.exe',
418         'PSPAWN': &lt;function piped_spawn at 0x700000&gt;,
419         'RC': 'rc',
420         'RCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
421         'RCFLAGS': [],
422         'RCSUFFIXES': ['.rc', '.rc2'],
423         'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
424         'SCANNERS': [],
425         'SHCC': '$CC',
426         'SHCCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
427         'SHCCFLAGS': ['$CCFLAGS'],
428         'SHCFLAGS': ['$CFLAGS'],
429         'SHCXX': '$CXX',
430         'SHCXXCOM': '$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM',
431         'SHCXXFLAGS': ['$CXXFLAGS'],
432         'SHELL': None,
433         'SHLIBPREFIX': '',
434         'SHLIBSUFFIX': '.dll',
435         'SHOBJPREFIX': '$OBJPREFIX',
436         'SHOBJSUFFIX': '$OBJSUFFIX',
437         'SPAWN': &lt;function spawn at 0x700000&gt;,
438         'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1,
439         'TARGET_ARCH': '',
440         'TARGET_OS': 'win32',
441         'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
442         'TEMPFILEPREFIX': '@',
443         'TOOLS': ['msvc', 'install', 'install'],
444         '_CCCOMCOM': '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS',
445         '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
446         '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
447         '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
448         '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
449         '_MSVC_OUTPUT_FLAG': &lt;function msvc_output_flag at 0x700000&gt;,
450         '_concat': &lt;function _concat at 0x700000&gt;,
451         '_defines': &lt;function _defines at 0x700000&gt;,
452         '_stripixes': &lt;function _stripixes at 0x700000&gt;}
453       scons: done reading SConscript files.
454       scons: Building targets ...
455       scons: `.' is up to date.
456       scons: done building targets.
457     </screen>
458
459     <para>
460
461     The construction environments in these examples have
462     actually been restricted to just gcc and Visual C++,
463     respectively.
464     In a real-life situation,
465     the construction environments will
466     likely contain a great many more variables.
467     Also note that we've massaged the example output above
468     to make the memory address of all objects a constant 0x700000.
469     In reality, you would see a different hexadecimal
470     number for each object.
471
472     </para>
473
474     <para>
475
476     To make it easier to see just what you're
477     interested in,
478     the &Dump; method allows you to
479     specify a specific constrcution variable
480     that you want to disply.
481     For example,
482     it's not unusual to want to verify
483     the external environment used to execute build commands,
484     to make sure that the PATH and other
485     environment variables are set up the way they should be.
486     You can do this as follows:
487
488     </para>
489
490     <programlisting>
491          env = Environment()
492          print env.Dump('ENV')
493     </programlisting>
494
495     <para>
496
497     Which might display the following when executed on a POSIX system:
498
499     </para>
500
501     <screen>
502       % <userinput>scons</userinput>
503       scons: Reading SConscript files ...
504       {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}
505       scons: done reading SConscript files.
506       scons: Building targets ...
507       scons: `.' is up to date.
508       scons: done building targets.
509     </screen>
510
511     <para>
512
513     And the following when executed on a Windows system:
514
515     </para>
516
517     <screen>
518       C:\><userinput>scons</userinput>
519       scons: Reading SConscript files ...
520       scons: warning: No installed VCs
521       File "&lt;stdin&gt;", line 67, in __call__
522       
523       scons: warning: No version of Visual Studio compiler found - C/C++ compilers most likely not set correctly
524       File "&lt;stdin&gt;", line 67, in __call__
525       
526       scons: warning: No installed VCs
527       File "&lt;stdin&gt;", line 67, in __call__
528       
529       scons: warning: No version of Visual Studio compiler found - C/C++ compilers most likely not set correctly
530       File "&lt;stdin&gt;", line 67, in __call__
531       { 'PATH': 'C:/WINDOWS\\System32',
532         'PATHEXT': '.COM;.EXE;.BAT;.CMD',
533         'SystemRoot': 'C:\\WINDOWS'}
534       scons: done reading SConscript files.
535       scons: Building targets ...
536       scons: `.' is up to date.
537       scons: done building targets.
538     </screen>
539
540   </section>
541
542   <section>
543
544   <title>What Dependencies Does &SCons; Know About?  the &tree; Option</title>
545
546     <para>
547
548     Sometimes the best way to try to figure out what
549     &SCons; is doing is simply to take a look at the
550     dependency graph that it constructs
551     based on your &SConscript; files.
552     The <literal>--tree</literal> option
553     will display all or part of the
554     &SCons; dependency graph in an
555     "ASCII art" graphical format
556     that shows the dependency hierarchy.
557
558     </para>
559
560     <para>
561
562     For example, given the following input &SConstruct; file:
563
564     </para>
565
566     <programlisting>
567          env = Environment(CPPPATH = ['.'])
568          env.Program('prog', ['f1.c', 'f2.c', 'f3.c'])
569     </programlisting>
570
571     <para>
572
573     Running &SCons; with the <literal>--tree=all</literal>
574     option yields:
575
576     </para>
577
578     <screen>
579       % <userinput>scons -Q --tree=all</userinput>
580       cc -o f1.o -c -I. f1.c
581       cc -o f2.o -c -I. f2.c
582       cc -o f3.o -c -I. f3.c
583       cc -o prog f1.o f2.o f3.o
584       +-.
585         +-SConstruct
586         +-f1.c
587         +-f1.o
588         | +-f1.c
589         | +-inc.h
590         +-f2.c
591         +-f2.o
592         | +-f2.c
593         | +-inc.h
594         +-f3.c
595         +-f3.o
596         | +-f3.c
597         | +-inc.h
598         +-inc.h
599         +-prog
600           +-f1.o
601           | +-f1.c
602           | +-inc.h
603           +-f2.o
604           | +-f2.c
605           | +-inc.h
606           +-f3.o
607             +-f3.c
608             +-inc.h
609     </screen>
610
611     <para>
612
613     The tree will also be printed when the
614     <literal>-n</literal> (no execute) option is used,
615     which allows you to examine the dependency graph
616     for a configuration without actually
617     rebuilding anything in the tree.
618
619     </para>
620
621     <para>
622
623     The <literal>--tree</literal> option only prints
624     the dependency graph for the specified targets
625     (or the default target(s) if none are specified on the command line).
626     So if you specify a target like <filename>f2.o</filename>
627     on the command line,
628     the <literal>--tree</literal> option will only
629     print the dependency graph for that file:
630
631     </para>
632
633     <screen>
634       % <userinput>scons -Q --tree=all f2.o</userinput>
635       cc -o f2.o -c -I. f2.c
636       +-f2.o
637         +-f2.c
638         +-inc.h
639     </screen>
640
641     <para>
642
643     This is, of course, useful for
644     restricting the output from a very large
645     build configuration to just a
646     portion in which you're interested.
647     Multiple targets are fine,
648     in which case a tree will be printed
649     for each specified target:
650
651     </para>
652
653     <screen>
654       % <userinput>scons -Q --tree=all f1.o f3.o</userinput>
655       cc -o f1.o -c -I. f1.c
656       +-f1.o
657         +-f1.c
658         +-inc.h
659       cc -o f3.o -c -I. f3.c
660       +-f3.o
661         +-f3.c
662         +-inc.h
663     </screen>
664
665     <para>
666
667     The <literal>status</literal> argument may be used
668     to tell &SCons; to print status information about
669     each file in the dependency graph:
670
671     </para>
672
673     <screen>
674       % <userinput>scons -Q --tree=status</userinput>
675       cc -o f1.o -c -I. f1.c
676       cc -o f2.o -c -I. f2.c
677       cc -o f3.o -c -I. f3.c
678       cc -o prog f1.o f2.o f3.o
679        E         = exists
680         R        = exists in repository only
681          b       = implicit builder
682          B       = explicit builder
683           S      = side effect
684            P     = precious
685             A    = always build
686              C   = current
687               N  = no clean
688                H = no cache
689       
690       [E b      ]+-.
691       [E     C  ]  +-SConstruct
692       [E     C  ]  +-f1.c
693       [E B   C  ]  +-f1.o
694       [E     C  ]  | +-f1.c
695       [E     C  ]  | +-inc.h
696       [E     C  ]  +-f2.c
697       [E B   C  ]  +-f2.o
698       [E     C  ]  | +-f2.c
699       [E     C  ]  | +-inc.h
700       [E     C  ]  +-f3.c
701       [E B   C  ]  +-f3.o
702       [E     C  ]  | +-f3.c
703       [E     C  ]  | +-inc.h
704       [E     C  ]  +-inc.h
705       [E B   C  ]  +-prog
706       [E B   C  ]    +-f1.o
707       [E     C  ]    | +-f1.c
708       [E     C  ]    | +-inc.h
709       [E B   C  ]    +-f2.o
710       [E     C  ]    | +-f2.c
711       [E     C  ]    | +-inc.h
712       [E B   C  ]    +-f3.o
713       [E     C  ]      +-f3.c
714       [E     C  ]      +-inc.h
715     </screen>
716
717     <para>
718
719     Note that <literal>--tree=all,status</literal> is equivalent;
720     the <literal>all</literal>
721     is assumed if only <literal>status</literal> is present.
722     As an alternative to <literal>all</literal>,
723     you can specify <literal>--tree=derived</literal>
724     to have &SCons; only print derived targets
725     in the tree output,
726     skipping source files
727     (like <filename>.c</filename> and <filename>.h</filename> files):
728
729     </para>
730
731     <screen>
732       % <userinput>scons -Q --tree=derived</userinput>
733       cc -o f1.o -c -I. f1.c
734       cc -o f2.o -c -I. f2.c
735       cc -o f3.o -c -I. f3.c
736       cc -o prog f1.o f2.o f3.o
737       +-.
738         +-f1.o
739         +-f2.o
740         +-f3.o
741         +-prog
742           +-f1.o
743           +-f2.o
744           +-f3.o
745     </screen>
746
747     <para>
748
749     You can use the <literal>status</literal>
750     modifier with <literal>derived</literal> as well:
751
752     </para>
753
754     <screen>
755       % <userinput>scons -Q --tree=derived,status</userinput>
756       cc -o f1.o -c -I. f1.c
757       cc -o f2.o -c -I. f2.c
758       cc -o f3.o -c -I. f3.c
759       cc -o prog f1.o f2.o f3.o
760        E         = exists
761         R        = exists in repository only
762          b       = implicit builder
763          B       = explicit builder
764           S      = side effect
765            P     = precious
766             A    = always build
767              C   = current
768               N  = no clean
769                H = no cache
770       
771       [E b      ]+-.
772       [E B   C  ]  +-f1.o
773       [E B   C  ]  +-f2.o
774       [E B   C  ]  +-f3.o
775       [E B   C  ]  +-prog
776       [E B   C  ]    +-f1.o
777       [E B   C  ]    +-f2.o
778       [E B   C  ]    +-f3.o
779     </screen>
780
781     <para>
782
783     Note that the order of the <literal>--tree=</literal>
784     arguments doesn't matter;
785     <literal>--tree=status,derived</literal> is
786     completely equivalent.
787
788     </para>
789
790     <para>
791
792     The default behavior of the <literal>--tree</literal> option
793     is to repeat all of the dependencies each time the library dependency
794     (or any other dependency file) is encountered in the tree.
795     If certain target files share other target files,
796     such as two programs that use the same library:
797
798     </para>
799
800     <programlisting>
801          env = Environment(CPPPATH = ['.'],
802                            LIBS = ['foo'],
803                            LIBPATH = ['.'])
804          env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
805          env.Program('prog1.c')
806          env.Program('prog2.c')
807     </programlisting>
808
809     <para>
810
811     Then there can be a <emphasis>lot</emphasis> of repetition in the
812     <literal>--tree=</literal> output:
813
814     </para>
815
816     <screen>
817       % <userinput>scons -Q --tree=all</userinput>
818       cc -o f1.o -c -I. f1.c
819       cc -o f2.o -c -I. f2.c
820       cc -o f3.o -c -I. f3.c
821       ar rc libfoo.a f1.o f2.o f3.o
822       ranlib libfoo.a
823       cc -o prog1.o -c -I. prog1.c
824       cc -o prog1 prog1.o -L. -lfoo
825       cc -o prog2.o -c -I. prog2.c
826       cc -o prog2 prog2.o -L. -lfoo
827       +-.
828         +-SConstruct
829         +-f1.c
830         +-f1.o
831         | +-f1.c
832         | +-inc.h
833         +-f2.c
834         +-f2.o
835         | +-f2.c
836         | +-inc.h
837         +-f3.c
838         +-f3.o
839         | +-f3.c
840         | +-inc.h
841         +-inc.h
842         +-libfoo.a
843         | +-f1.o
844         | | +-f1.c
845         | | +-inc.h
846         | +-f2.o
847         | | +-f2.c
848         | | +-inc.h
849         | +-f3.o
850         |   +-f3.c
851         |   +-inc.h
852         +-prog1
853         | +-prog1.o
854         | | +-prog1.c
855         | | +-inc.h
856         | +-libfoo.a
857         |   +-f1.o
858         |   | +-f1.c
859         |   | +-inc.h
860         |   +-f2.o
861         |   | +-f2.c
862         |   | +-inc.h
863         |   +-f3.o
864         |     +-f3.c
865         |     +-inc.h
866         +-prog1.c
867         +-prog1.o
868         | +-prog1.c
869         | +-inc.h
870         +-prog2
871         | +-prog2.o
872         | | +-prog2.c
873         | | +-inc.h
874         | +-libfoo.a
875         |   +-f1.o
876         |   | +-f1.c
877         |   | +-inc.h
878         |   +-f2.o
879         |   | +-f2.c
880         |   | +-inc.h
881         |   +-f3.o
882         |     +-f3.c
883         |     +-inc.h
884         +-prog2.c
885         +-prog2.o
886           +-prog2.c
887           +-inc.h
888     </screen>
889
890     <para>
891
892     In a large configuration with many internal libraries
893     and include files,
894     this can very quickly lead to huge output trees.
895     To help make this more manageable,
896     a <literal>prune</literal> modifier may
897     be added to the option list,
898     in which case &SCons;
899     will print the name of a target that has
900     already been visited during the tree-printing
901     in <literal>[square brackets]</literal>
902     as an indication that the dependencies
903     of the target file may be found
904     by looking farther up the tree:
905
906     </para>
907
908     <screen>
909       % <userinput>scons -Q --tree=prune</userinput>
910       cc -o f1.o -c -I. f1.c
911       cc -o f2.o -c -I. f2.c
912       cc -o f3.o -c -I. f3.c
913       ar rc libfoo.a f1.o f2.o f3.o
914       ranlib libfoo.a
915       cc -o prog1.o -c -I. prog1.c
916       cc -o prog1 prog1.o -L. -lfoo
917       cc -o prog2.o -c -I. prog2.c
918       cc -o prog2 prog2.o -L. -lfoo
919       +-.
920         +-SConstruct
921         +-f1.c
922         +-f1.o
923         | +-f1.c
924         | +-inc.h
925         +-f2.c
926         +-f2.o
927         | +-f2.c
928         | +-inc.h
929         +-f3.c
930         +-f3.o
931         | +-f3.c
932         | +-inc.h
933         +-inc.h
934         +-libfoo.a
935         | +-[f1.o]
936         | +-[f2.o]
937         | +-[f3.o]
938         +-prog1
939         | +-prog1.o
940         | | +-prog1.c
941         | | +-inc.h
942         | +-[libfoo.a]
943         +-prog1.c
944         +-[prog1.o]
945         +-prog2
946         | +-prog2.o
947         | | +-prog2.c
948         | | +-inc.h
949         | +-[libfoo.a]
950         +-prog2.c
951         +-[prog2.o]
952     </screen>
953
954     <para>
955
956     Like the <literal>status</literal> keyword,
957     the <literal>prune</literal> argument by itself
958     is equivalent to <literal>--tree=all,prune</literal>.
959
960     </para>
961
962   </section>
963
964   <section>
965
966   <title>How is &SCons; Constructing the Command Lines It Executes?  the &debug-presub; Option</title>
967
968     <para>
969
970     Sometimes it's useful to look at the
971     pre-substitution string
972     that &SCons; uses to generate
973     the command lines it executes.
974     This can be done with the &debug-presub; option:
975
976     </para>
977
978     
979
980     <!--
981
982     Have to capture output here, otherwise the - -debug=presub output
983     shows the Python functions from the sconsdoc.py execution wrapper
984     used to generate this manual, not the underlying command-line strings.
985
986     <scons_output example="presub">
987       <scons_output_command>scons -Q - -debug=presub</scons_output_command>
988     </scons_output>
989
990     -->
991
992     <screen>
993       % <userinput>scons -Q --debug=presub</userinput>
994       Building prog.o with action:
995         $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCOMCOM $SOURCES
996       cc -o prog.o -c -I. prog.c
997       Building prog with action:
998         $SMART_LINKCOM
999       cc -o prog prog.o
1000     </screen>
1001
1002   </section>
1003
1004   <section>
1005
1006   <title>Where is &SCons; Searching for Libraries?  the &debug-findlibs; Option</title>
1007
1008     <para>
1009
1010     To get some insight into what library names
1011     &SCons; is searching for,
1012     and in which directories it is searching,
1013     Use the <literal>--debug=findlibs</literal> option.
1014     Given the following input &SConstruct; file:
1015
1016     </para>
1017
1018     <programlisting>
1019         env = Environment(LIBPATH = ['libs1', 'libs2'])
1020         env.Program('prog.c', LIBS=['foo', 'bar'])
1021     </programlisting>
1022
1023     <para>
1024
1025     And the libraries <filename>libfoo.a</filename>
1026     and <filename>libbar.a</filename>
1027     in <filename>libs1</filename> and <filename>libs2</filename>,
1028     respectively,
1029     use of the <literal>--debug=findlibs</literal> option yields:
1030
1031     </para>
1032
1033     <screen>
1034       % <userinput>scons -Q --debug=findlibs</userinput>
1035         findlibs: looking for 'libfoo.a' in 'libs1' ...
1036         findlibs: ... FOUND 'libfoo.a' in 'libs1'
1037         findlibs: looking for 'libfoo.so' in 'libs1' ...
1038         findlibs: looking for 'libfoo.so' in 'libs2' ...
1039         findlibs: looking for 'libbar.a' in 'libs1' ...
1040         findlibs: looking for 'libbar.a' in 'libs2' ...
1041         findlibs: ... FOUND 'libbar.a' in 'libs2'
1042         findlibs: looking for 'libbar.so' in 'libs1' ...
1043         findlibs: looking for 'libbar.so' in 'libs2' ...
1044       cc -o prog.o -c prog.c
1045       cc -o prog prog.o -Llibs1 -Llibs2 -lfoo -lbar
1046     </screen>
1047
1048   </section>
1049
1050   <!--
1051
1052   <section>
1053
1054   <title>What Implicit Dependencies Did the &SCons; Scanner find?  the &debug-includes; Option</title>
1055
1056     <para>
1057
1058     XXX explain the - - debug=includes option
1059
1060     </para>
1061
1062     <scons_example name="includes">
1063       <file name="SConstruct" printme="1">
1064         env = Environment(CPPPATH = ['inc1', 'inc2'])
1065         env.Program('prog.c')
1066       </file>
1067       <file name="prog.c">
1068       #include "file1.h"
1069       #include "file2.h"
1070       prog.c
1071       </file>
1072       <file name="inc1/file1.h">
1073       inc1/file1.h
1074       </file>
1075       <file name="inc2/file2.h">
1076       inc2/file2.h
1077       </file>
1078     </scons_example>
1079
1080     <scons_output example="includes">
1081       <scons_output_command>scons -Q - - debug=includes prog</scons_output_command>
1082     </scons_output>
1083
1084   </section>
1085
1086   -->
1087
1088   <section>
1089
1090   <title>Where is &SCons; Blowing Up?  the &debug-stacktrace; Option</title>
1091
1092     <para>
1093
1094     In general, &SCons; tries to keep its error
1095     messages short and informative.
1096     That means we usually try to avoid showing
1097     the stack traces that are familiar
1098     to experienced Python programmers,
1099     since they usually contain much more
1100     information than is useful to most people.
1101
1102     </para>
1103
1104     <para>
1105
1106     For example, the following &SConstruct; file:
1107
1108     </para>
1109
1110     <programlisting>
1111          Program('prog.c')
1112     </programlisting>
1113
1114     <para>
1115
1116     Generates the following error if the
1117     <filename>prog.c</filename> file
1118     does not exist:
1119
1120     </para>
1121
1122     <screen>
1123       % <userinput>scons -Q</userinput>
1124       scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'.
1125     </screen>
1126
1127     <para>
1128
1129     In this case,
1130     the error is pretty obvious.
1131     But if it weren't,
1132     and you wanted to try to get more information
1133     about the error,
1134     the &debug-stacktrace; option
1135     would show you exactly where in the &SCons; source code
1136     the problem occurs:
1137
1138     </para>
1139
1140     <screen>
1141       % <userinput>scons -Q --debug=stacktrace</userinput>
1142       scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'.
1143       scons: internal stack trace:
1144         File "bootstrap/src/engine/SCons/Job.py", line 197, in start
1145           task.prepare()
1146         File "bootstrap/src/engine/SCons/Script/Main.py", line 167, in prepare
1147         File "bootstrap/src/engine/SCons/Taskmaster.py", line 190, in prepare
1148         File "bootstrap/src/engine/SCons/Executor.py", line 397, in prepare
1149     </screen>
1150
1151     <para>
1152
1153     Of course, if you do need to dive into the &SCons; source code,
1154     we'd like to know if, or how,
1155     the error messages or troubleshooting options
1156     could have been improved to avoid that.
1157     Not everyone has the necessary time or
1158     Python skill to dive into the source code,
1159     and we'd like to improve &SCons;
1160     for those people as well...
1161
1162     </para>
1163
1164   </section>
1165
1166   <section>
1167
1168   <title>How is &SCons; Making Its Decisions?  the &taskmastertrace; Option</title>
1169
1170     <para>
1171
1172     The internal &SCons; subsystem that handles walking
1173     the dependency graph
1174     and controls the decision-making about what to rebuild
1175     is the <literal>Taskmaster</literal>.
1176     &SCons; supports a <literal>--taskmastertrace</literal>
1177     option that tells the Taskmaster to print
1178     information about the children (dependencies)
1179     of the various Nodes on its walk down the graph,
1180     which specific dependent Nodes are being evaluated,
1181     and in what order.
1182
1183     </para>
1184
1185     <para>
1186
1187     The <literal>--taskmastertrace</literal> option
1188     takes as an argument the name of a file in
1189     which to put the trace output,
1190     with <filename>-</filename> (a single hyphen)
1191     indicating that the trace messages
1192     should be printed to the standard output:
1193
1194     </para>
1195
1196     <programlisting>
1197       env = Environment(CPPPATH = ['.'])
1198       env.Program('prog.c')
1199     </programlisting>
1200
1201     <screen>
1202       % <userinput>scons -Q --taskmastertrace=- prog</userinput>
1203       
1204       Taskmaster: Looking for a node to evaluate
1205       Taskmaster:     Considering node &lt;no_state   0   'prog'&gt; and its children:
1206       Taskmaster:        &lt;no_state   0   'prog.o'&gt;
1207       Taskmaster:      adjusted ref count: &lt;pending    1   'prog'&gt;, child 'prog.o'
1208       Taskmaster:     Considering node &lt;no_state   0   'prog.o'&gt; and its children:
1209       Taskmaster:        &lt;no_state   0   'prog.c'&gt;
1210       Taskmaster:        &lt;no_state   0   'inc.h'&gt;
1211       Taskmaster:      adjusted ref count: &lt;pending    1   'prog.o'&gt;, child 'prog.c'
1212       Taskmaster:      adjusted ref count: &lt;pending    2   'prog.o'&gt;, child 'inc.h'
1213       Taskmaster:     Considering node &lt;no_state   0   'prog.c'&gt; and its children:
1214       Taskmaster: Evaluating &lt;pending    0   'prog.c'&gt;
1215       
1216       Task.make_ready_current(): node &lt;pending    0   'prog.c'&gt;
1217       Task.prepare():      node &lt;up_to_date 0   'prog.c'&gt;
1218       Task.executed_with_callbacks(): node &lt;up_to_date 0   'prog.c'&gt;
1219       Task.postprocess():  node &lt;up_to_date 0   'prog.c'&gt;
1220       Task.postprocess():  removing &lt;up_to_date 0   'prog.c'&gt;
1221       Task.postprocess():  adjusted parent ref count &lt;pending    1   'prog.o'&gt;
1222       
1223       Taskmaster: Looking for a node to evaluate
1224       Taskmaster:     Considering node &lt;no_state   0   'inc.h'&gt; and its children:
1225       Taskmaster: Evaluating &lt;pending    0   'inc.h'&gt;
1226       
1227       Task.make_ready_current(): node &lt;pending    0   'inc.h'&gt;
1228       Task.prepare():      node &lt;up_to_date 0   'inc.h'&gt;
1229       Task.executed_with_callbacks(): node &lt;up_to_date 0   'inc.h'&gt;
1230       Task.postprocess():  node &lt;up_to_date 0   'inc.h'&gt;
1231       Task.postprocess():  removing &lt;up_to_date 0   'inc.h'&gt;
1232       Task.postprocess():  adjusted parent ref count &lt;pending    0   'prog.o'&gt;
1233       
1234       Taskmaster: Looking for a node to evaluate
1235       Taskmaster:     Considering node &lt;pending    0   'prog.o'&gt; and its children:
1236       Taskmaster:        &lt;up_to_date 0   'prog.c'&gt;
1237       Taskmaster:        &lt;up_to_date 0   'inc.h'&gt;
1238       Taskmaster: Evaluating &lt;pending    0   'prog.o'&gt;
1239       
1240       Task.make_ready_current(): node &lt;pending    0   'prog.o'&gt;
1241       Task.prepare():      node &lt;executing  0   'prog.o'&gt;
1242       Task.execute():      node &lt;executing  0   'prog.o'&gt;
1243       cc -o prog.o -c -I. prog.c
1244       Task.executed_with_callbacks(): node &lt;executing  0   'prog.o'&gt;
1245       Task.postprocess():  node &lt;executed   0   'prog.o'&gt;
1246       Task.postprocess():  removing &lt;executed   0   'prog.o'&gt;
1247       Task.postprocess():  adjusted parent ref count &lt;pending    0   'prog'&gt;
1248       
1249       Taskmaster: Looking for a node to evaluate
1250       Taskmaster:     Considering node &lt;pending    0   'prog'&gt; and its children:
1251       Taskmaster:        &lt;executed   0   'prog.o'&gt;
1252       Taskmaster: Evaluating &lt;pending    0   'prog'&gt;
1253       
1254       Task.make_ready_current(): node &lt;pending    0   'prog'&gt;
1255       Task.prepare():      node &lt;executing  0   'prog'&gt;
1256       Task.execute():      node &lt;executing  0   'prog'&gt;
1257       cc -o prog prog.o
1258       Task.executed_with_callbacks(): node &lt;executing  0   'prog'&gt;
1259       Task.postprocess():  node &lt;executed   0   'prog'&gt;
1260       
1261       Taskmaster: Looking for a node to evaluate
1262       Taskmaster: No candidate anymore.
1263     </screen>
1264
1265     <para>
1266
1267     The <literal>--taskmastertrace</literal> option
1268     doesn't provide information about the actual
1269     calculations involved in deciding if a file is up-to-date,
1270     but it does show all of the dependencies
1271     it knows about for each Node,
1272     and the order in which those dependencies are evaluated.
1273     This can be useful as an alternate way to determine
1274     whether or not your &SCons; configuration,
1275     or the implicit dependency scan,
1276     has actually identified all the correct dependencies
1277     you want it to.
1278
1279     </para>
1280
1281   </section>
1282
1283   <!--
1284
1285   <section>
1286
1287   <title>Where Are My Build Bottlenecks?  the &profile; Option</title>
1288
1289     <para>
1290
1291     XXX explain the - - profile= option
1292
1293     </para>
1294
1295   </section>
1296
1297   -->
1298
1299   <!--
1300
1301   <section>
1302   <title>Troubleshooting Shared Caching:  the &cache-debug; Option</title>
1303
1304     <para>
1305
1306     XXX describe the - - cache-debug option
1307     XXX maybe point to the caching.in chapter?
1308
1309     </para>
1310
1311   </section>
1312
1313   -->