Fix XML in documentation, and in the bin/scons-doc.py script that generates
[scons.git] / doc / user / troubleshoot.in
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     <scons_example name="explain1">
73       <file name="SConstruct" printme="1">
74       # Intentionally misspell the output file name in the
75       # command used to create the file:
76       Command('file.out', 'file.in', 'cp $SOURCE file.oout')
77       </file>
78       <file name="file.in">
79       file.in
80       </file>
81     </scons_example>
82
83     <para>
84
85     (Note to Windows users:  The POSIX &cp; command
86     copies the first file named on the command line
87     to the second file.
88     In our example, it copies the &file_in; file
89     to the &file_out; file.)
90
91     </para>
92
93     <para>
94
95     Now if we run &SCons; multiple times on this example,
96     we see that it re-runs the &cp;
97     command every time:
98
99     </para>
100
101     <scons_output example="explain1" os="posix">
102       <scons_output_command>scons -Q</scons_output_command>
103       <scons_output_command>scons -Q</scons_output_command>
104       <scons_output_command>scons -Q</scons_output_command>
105     </scons_output>
106
107     <para>
108
109     In this example,
110     the underlying cause is obvious:
111     we've intentionally misspelled the output file name
112     in the &cp; command,
113     so the command doesn't actually
114     build the &file_out; file that we've told &SCons; to expect.
115     But if the problem weren't obvious,
116     it would be helpful
117     to specify the &debug-explain; option
118     on the command line
119     to have &SCons; tell us very specifically
120     why it's decided to rebuild the target:
121
122     </para>
123
124     <scons_output example="explain1" os="posix">
125       <scons_output_command>scons -Q --debug=explain</scons_output_command>
126     </scons_output>
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     <scons_example name="explain2">
155       <file name="SConstruct">
156       Program('prog', ['file1.c', 'file2.c', 'file3.c'])
157       </file>
158       <file name="file1.c">
159       file1.c
160       </file>
161       <file name="file2.c">
162       file2.c
163       </file>
164       <file name="file3.c">
165       file3.c
166       </file>
167     </scons_example>
168
169     <scons_output example="explain2" os="posix">
170       <scons_output_command>scons -Q</scons_output_command>
171       <scons_output_command output="    [CHANGE THE CONTENTS OF file2.c]">edit file2.c</scons_output_command>
172       <scons_output_command>scons -Q --debug=explain</scons_output_command>
173     </scons_output>
174
175     <para>
176
177     This becomes even more helpful
178     in identifying when a file is rebuilt
179     due to a change in an implicit dependency,
180     such as an incuded <filename>.h</filename> file.
181     If the <filename>file1.c</filename>
182     and <filename>file3.c</filename> files
183     in our example
184     both included a &hello_h; file,
185     then changing that included file
186     and re-running &SCons; with the &debug-explain; option
187     will pinpoint that it's the change to the included file
188     that starts the chain of rebuilds:
189
190     </para>
191
192     <scons_example name="explain3">
193       <file name="SConstruct">
194       Program('prog', ['file1.c', 'file2.c', 'file3.c'], CPPPATH='.')
195       </file>
196       <file name="file1.c">
197       #include &lt;hello.h&gt;
198       file1.c
199       </file>
200       <file name="file2.c">
201       file2.c
202       </file>
203       <file name="file3.c">
204       #include &lt;hello.h&gt;
205       file3.c
206       </file>
207       <file name="hello.h">
208       #define string    "world"
209       </file>
210     </scons_example>
211
212     <scons_output example="explain3" os="posix">
213       <scons_output_command>scons -Q</scons_output_command>
214       <scons_output_command output="    [CHANGE THE CONTENTS OF hello.h]">edit hello.h</scons_output_command>
215       <scons_output_command>scons -Q --debug=explain</scons_output_command>
216     </scons_output>
217
218     <para>
219
220     (Note that the &debug-explain; option will only tell you
221     why &SCons; decided to rebuild necessary targets.
222     It does not tell you what files it examined
223     when deciding <emphasis>not</emphasis>
224     to rebuild a target file,
225     which is often a more valuable question to answer.)
226
227     </para>
228
229   </section>
230
231   <section>
232   <title>What's in That Construction Environment?  the &Dump; Method</title>
233
234     <para>
235
236     When you create a construction environment,
237     &SCons; populates it
238     with construction variables that are set up
239     for various compilers, linkers and utilities
240     that it finds on your system.
241     Although this is usually helpful and what you want,
242     it might be frustrating if &SCons;
243     doesn't set certain variables that you
244     expect to be set.
245     In situations like this,
246     it's sometimes helpful to use the
247     construction environment &Dump; method
248     to print all or some of
249     the construction variables.
250     Note that the &Dump; method
251     <emphasis>returns</emphasis>
252     the representation of the variables
253     in the environment
254     for you to print (or otherwise manipulate):
255
256     </para>
257
258     <scons_example name="Dump">
259       <file name="SConstruct" printme="1">
260          env = Environment()
261          print env.Dump()
262       </file>
263     </scons_example>
264
265     <para>
266
267     On a POSIX system with gcc installed,
268     this might generate:
269
270     </para>
271
272     <scons_output example="Dump" os="posix" tools="gcc">
273       <scons_output_command>scons</scons_output_command>
274     </scons_output>
275
276     <para>
277
278     On a Windows system with Visual C++
279     the output might look like:
280
281     </para>
282
283     <scons_output example="Dump" os="win32" tools="msvc">
284       <scons_output_command>scons</scons_output_command>
285     </scons_output>
286
287     <para>
288
289     The construction environments in these examples have
290     actually been restricted to just gcc and Visual C++,
291     respectively.
292     In a real-life situation,
293     the construction environments will
294     likely contain a great many more variables.
295     Also note that we've massaged the example output above
296     to make the memory address of all objects a constant 0x700000.
297     In reality, you would see a different hexadecimal
298     number for each object.
299
300     </para>
301
302     <para>
303
304     To make it easier to see just what you're
305     interested in,
306     the &Dump; method allows you to
307     specify a specific constrcution variable
308     that you want to disply.
309     For example,
310     it's not unusual to want to verify
311     the external environment used to execute build commands,
312     to make sure that the PATH and other
313     environment variables are set up the way they should be.
314     You can do this as follows:
315
316     </para>
317
318     <scons_example name="Dump_ENV">
319       <file name="SConstruct" printme="1">
320          env = Environment()
321          print env.Dump('ENV')
322       </file>
323     </scons_example>
324
325     <para>
326
327     Which might display the following when executed on a POSIX system:
328
329     </para>
330
331     <scons_output example="Dump_ENV" os="posix">
332       <scons_output_command>scons</scons_output_command>
333     </scons_output>
334
335     <para>
336
337     And the following when executed on a Windows system:
338
339     </para>
340
341     <scons_output example="Dump_ENV" os="win32">
342       <scons_output_command>scons</scons_output_command>
343     </scons_output>
344
345   </section>
346
347   <section>
348
349   <title>What Dependencies Does &SCons; Know About?  the &tree; Option</title>
350
351     <para>
352
353     Sometimes the best way to try to figure out what
354     &SCons; is doing is simply to take a look at the
355     dependency graph that it constructs
356     based on your &SConscript; files.
357     The <literal>--tree</literal> option
358     will display all or part of the
359     &SCons; dependency graph in an
360     "ASCII art" graphical format
361     that shows the dependency hierarchy.
362
363     </para>
364
365     <para>
366
367     For example, given the following input &SConstruct; file:
368
369     </para>
370
371     <scons_example name="tree1">
372       <file name="SConstruct" printme="1">
373          env = Environment(CPPPATH = ['.'])
374          env.Program('prog', ['f1.c', 'f2.c', 'f3.c'])
375       </file>
376       <file name="f1.c">
377       #include "inc.h"
378       </file>
379       <file name="f2.c">
380       #include "inc.h"
381       </file>
382       <file name="f3.c">
383       #include "inc.h"
384       </file>
385       <file name="inc.h">
386       inc.h
387       </file>
388     </scons_example>
389
390     <para>
391
392     Running &SCons; with the <literal>--tree=all</literal>
393     option yields:
394
395     </para>
396
397     <scons_output example="tree1">
398       <scons_output_command>scons -Q --tree=all</scons_output_command>
399     </scons_output>
400
401     <para>
402
403     The tree will also be printed when the
404     <literal>-n</literal> (no execute) option is used,
405     which allows you to examine the dependency graph
406     for a configuration without actually
407     rebuilding anything in the tree.
408
409     </para>
410
411     <para>
412
413     The <literaL>--tree</literal> option only prints
414     the dependency graph for the specified targets
415     (or the default target(s) if none are specified on the command line).
416     So if you specify a target like <filename>f2.o</filename>
417     on the command line,
418     the <literaL>--tree</literal> option will only
419     print the dependency graph for that file:
420
421     </para>
422
423     <scons_output example="tree1">
424       <scons_output_command>scons -Q --tree=all f2.o</scons_output_command>
425     </scons_output>
426
427     <para>
428
429     This is, of course, useful for
430     restricting the output from a very large
431     build configuration to just a
432     portion in which you're interested.
433     Multiple targets are fine,
434     in which case a tree will be printed
435     for each specified target:
436
437     </para>
438
439     <scons_output example="tree1">
440       <scons_output_command>scons -Q --tree=all f1.o f3.o</scons_output_command>
441     </scons_output>
442
443     <para>
444
445     The <literal>status</literal> argument may be used
446     to tell &SCons; to print status information about
447     each file in the dependency graph:
448
449     </para>
450
451     <scons_output example="tree1">
452       <scons_output_command>scons -Q --tree=status</scons_output_command>
453     </scons_output>
454
455     <para>
456
457     Note that <literal>--tree=all,status</literal> is equivalent;
458     the <literal>all</literal>
459     is assumed if only <literal>status</literal> is present.
460     As an alternative to <literal>all</literal>,
461     you can specify <literal>--tree=derived</literal>
462     to have &SCons; only print derived targets
463     in the tree output,
464     skipping source files
465     (like <filename>.c</filename> and <filename>.h</filename> files):
466
467     </para>
468
469     <scons_output example="tree1">
470       <scons_output_command>scons -Q --tree=derived</scons_output_command>
471     </scons_output>
472
473     <para>
474
475     You can use the <literal>status</literal>
476     modifier with <literal>derived</literal> as well:
477
478     </para>
479
480     <scons_output example="tree1">
481       <scons_output_command>scons -Q --tree=derived,status</scons_output_command>
482     </scons_output>
483
484     <para>
485
486     Note that the order of the <literal>--tree=</literal>
487     arguments doesn't matter;
488     <literal>--tree=status,derived</literal> is
489     completely equivalent.
490
491     </para>
492
493     <para>
494
495     The default behavior of the <literal>--tree</literal> option
496     is to repeat all of the dependencies each time the library dependency
497     (or any other dependency file) is encountered in the tree.
498     If certain target files share other target files,
499     such as two programs that use the same library:
500
501     </para>
502
503     <scons_example name="tree2">
504       <file name="SConstruct" printme="1">
505          env = Environment(CPPPATH = ['.'],
506                            LIBS = ['foo'],
507                            LIBPATH = ['.'])
508          env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
509          env.Program('prog1.c')
510          env.Program('prog2.c')
511       </file>
512       <file name="prog1.c">
513       #include "inc.h"
514       </file>
515       <file name="prog2.c">
516       #include "inc.h"
517       </file>
518       <file name="f1.c">
519       #include "inc.h"
520       </file>
521       <file name="f2.c">
522       #include "inc.h"
523       </file>
524       <file name="f3.c">
525       #include "inc.h"
526       </file>
527       <file name="inc.h">
528       inc.h
529       </file>
530     </scons_example>
531
532     <para>
533
534     Then there can be a <emphasis>lot</emphasis> of repetition in the
535     <literal>--tree=</literal> output:
536
537     </para>
538
539     <scons_output example="tree2">
540       <scons_output_command>scons -Q --tree=all</scons_output_command>
541     </scons_output>
542
543     <para>
544
545     In a large configuration with many internal libraries
546     and include files,
547     this can very quickly lead to huge output trees.
548     To help make this more manageable,
549     a <literal>prune</literal> modifier may
550     be added to the option list,
551     in which case &SCons;
552     will print the name of a target that has
553     already been visited during the tree-printing
554     in <literal>[square brackets]</literal>
555     as an indication that the dependencies
556     of the target file may be found
557     by looking farther up the tree:
558
559     </para>
560
561     <scons_output example="tree2">
562       <scons_output_command>scons -Q --tree=prune</scons_output_command>
563     </scons_output>
564
565     <para>
566
567     Like the <literal>status</literal> keyword,
568     the <literal>prune</literal> argument by itself
569     is equivalent to <literal>--tree=all,prune</literal>.
570
571     </para>
572
573   </section>
574
575   <section>
576
577   <title>How is &SCons; Constructing the Command Lines It Executes?  the &debug-presub; Option</title>
578
579     <para>
580
581     Sometimes it's useful to look at the
582     pre-substitution string
583     that &SCons; uses to generate
584     the command lines it executes.
585     This can be done with the &debug-presub; option:
586
587     </para>
588
589     <scons_example name="presub">
590       <file name="SConstruct">
591          env = Environment(CPPPATH = ['.'])
592          env.Program('prog', 'prog.c')
593       </file>
594       <file name="prog.c">
595       prog.c
596       </file>
597     </scons_example>
598
599     <!--
600
601     Have to capture output here, otherwise the - -debug=presub output
602     shows the Python functions from the sconsdoc.py execution wrapper
603     used to generate this manual, not the underlying command-line strings.
604
605     <scons_output example="presub">
606       <scons_output_command>scons -Q - -debug=presub</scons_output_command>
607     </scons_output>
608
609     -->
610
611     <screen>
612       % <userinput>scons -Q --debug=presub</userinput>
613       Building prog.o with action:
614         $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCOMCOM $SOURCES
615       cc -o prog.o -c -I. prog.c
616       Building prog with action:
617         $SMART_LINKCOM
618       cc -o prog prog.o
619     </screen>
620
621   </section>
622
623   <section>
624
625   <title>Where is &SCons; Searching for Libraries?  the &debug-findlibs; Option</title>
626
627     <para>
628
629     To get some insight into what library names
630     &SCons; is searching for,
631     and in which directories it is searching,
632     Use the <literal>--debug=findlibs</literal> option.
633     Given the following input &SConstruct; file:
634
635     </para>
636
637     <scons_example name="findlibs">
638       <file name="SConstruct" printme="1">
639         env = Environment(LIBPATH = ['libs1', 'libs2'])
640         env.Program('prog.c', LIBS=['foo', 'bar'])
641       </file>
642       <file name="prog.c">
643       prog.c
644       </file>
645       <file name="libs1/libfoo.a">
646       libs1/libfoo.a
647       </file>
648       <file name="libs2/libbar.a">
649       libs2/libbar.a
650       </file>
651     </scons_example>
652
653     <para>
654
655     And the libraries <filename>libfoo.a</filename>
656     and <filename>libbar.a</filename>
657     in <filename>libs1</filename> and <filename>libs2</filename>,
658     respectively,
659     use of the <literal>--debug=findlibs</literal> option yields:
660
661     </para>
662
663     <scons_output example="findlibs">
664       <scons_output_command>scons -Q --debug=findlibs</scons_output_command>
665     </scons_output>
666
667   </section>
668
669   <!--
670
671   <section>
672
673   <title>What Implicit Dependencies Did the &SCons; Scanner find?  the &debug-includes; Option</title>
674
675     <para>
676
677     XXX explain the - - debug=includes option
678
679     </para>
680
681     <scons_example name="includes">
682       <file name="SConstruct" printme="1">
683         env = Environment(CPPPATH = ['inc1', 'inc2'])
684         env.Program('prog.c')
685       </file>
686       <file name="prog.c">
687       #include "file1.h"
688       #include "file2.h"
689       prog.c
690       </file>
691       <file name="inc1/file1.h">
692       inc1/file1.h
693       </file>
694       <file name="inc2/file2.h">
695       inc2/file2.h
696       </file>
697     </scons_example>
698
699     <scons_output example="includes">
700       <scons_output_command>scons -Q - - debug=includes prog</scons_output_command>
701     </scons_output>
702
703   </section>
704
705   -->
706
707   <section>
708
709   <title>Where is &SCons; Blowing Up?  the &debug-stacktrace; Option</title>
710
711     <para>
712
713     In general, &SCons; tries to keep its error
714     messages short and informative.
715     That means we usually try to avoid showing
716     the stack traces that are familiar
717     to experienced Python programmers,
718     since they usually contain much more
719     information than is useful to most people.
720
721     </para>
722
723     <para>
724
725     For example, the following &SConstruct file:
726
727     </para>
728
729     <scons_example name="stacktrace">
730       <file name="SConstruct" printme="1">
731          Program('prog.c')
732       </file>
733     </scons_example>
734
735     <para>
736
737     Generates the following error if the
738     <filename>prog.c</filename> file
739     does not exist:
740
741     </para>
742
743     <scons_output example="stacktrace">
744       <scons_output_command>scons -Q</scons_output_command>
745     </scons_output>
746
747     <para>
748
749     In this case,
750     the error is pretty obvious.
751     But if it weren't,
752     and you wanted to try to get more information
753     about the error,
754     the &debug-stacktrace; option
755     would show you exactly where in the &SCons; source code
756     the problem occurs:
757
758     </para>
759
760     <scons_output example="stacktrace">
761       <scons_output_command>scons -Q --debug=stacktrace</scons_output_command>
762     </scons_output>
763
764     <para>
765
766     Of course, if you do need to dive into the &SCons; source code,
767     we'd like to know if, or how,
768     the error messages or troubleshooting options
769     could have been improved to avoid that.
770     Not everyone has the necessary time or
771     Python skill to dive into the source code,
772     and we'd like to improve &SCons;
773     for those people as well...
774
775     </para>
776
777   </section>
778
779   <section>
780
781   <title>How is &SCons; Making Its Decisions?  the &taskmastertrace; Option</title>
782
783     <para>
784
785     The internal &SCons; subsystem that handles walking
786     the dependency graph
787     and controls the decision-making about what to rebuild
788     is the <literal>Taskmaster</literal>.
789     &SCons; supports a <literal>--taskmastertrace</literal>
790     option that tells the Taskmaster to print
791     information about the children (dependencies)
792     of the various Nodes on its walk down the graph,
793     which specific dependent Nodes are being evaluated,
794     and in what order.
795
796     </para>
797
798     <para>
799
800     The <literal>--taskmastertrace</literal> option
801     takes as an argument the name of a file in
802     which to put the trace output,
803     with <filename>-</filename> (a single hyphen)
804     indicating that the trace messages
805     should be printed to the standard output:
806
807     </para>
808
809     <scons_example name="taskmastertrace">
810       <file name="SConstruct" printme="1">
811       env = Environment(CPPPATH = ['.'])
812       env.Program('prog.c')
813       </file>
814       <file name="prog.c">
815       #include "inc.h"
816       prog.c
817       </file>
818       <file name="inc.h">
819       #define   STRING  "one"
820       </file>
821     </scons_example>
822
823     <scons_output example="taskmastertrace" os="posix">
824       <scons_output_command>scons -Q --taskmastertrace=- prog</scons_output_command>
825     </scons_output>
826
827     <para>
828
829     The <literal>--taskmastertrace</literal> option
830     doesn't provide information about the actual
831     calculations involved in deciding if a file is up-to-date,
832     but it does show all of the dependencies
833     it knows about for each Node,
834     and the order in which those dependencies are evaluated.
835     This can be useful as an alternate way to determine
836     whether or not your &SCons; configuration,
837     or the implicit dependency scan,
838     has actually identified all the correct dependencies
839     you want it to.
840
841     </para>
842
843   </section>
844
845   <!--
846
847   <section>
848
849   <title>Where Are My Build Bottlenecks?  the &profile; Option</title>
850
851     <para>
852
853     XXX explain the - - profile= option
854
855     </para>
856
857   </section>
858
859   -->
860
861   <!--
862
863   <section>
864   <title>Troubleshooting Shared Caching:  the &cache-debug; Option</title>
865
866     <para>
867
868     XXX describe the - - cache-debug option
869     XXX maybe point to the caching.in chapter?
870
871     </para>
872
873   </section>
874
875   -->