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