summaryrefslogtreecommitdiffstats
path: root/doc/user/troubleshoot.in
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user/troubleshoot.in')
-rw-r--r--doc/user/troubleshoot.in571
1 files changed, 567 insertions, 4 deletions
diff --git a/doc/user/troubleshoot.in b/doc/user/troubleshoot.in
index 206e50e..11f44dd 100644
--- a/doc/user/troubleshoot.in
+++ b/doc/user/troubleshoot.in
@@ -32,6 +32,28 @@
the tool is behaving a certain way,
and how to get it to behave the way you want.
&SCons; is no different.
+ This appendix contains a number of
+ different ways in which you can
+ get some additional insight into &SCons' behavior.
+
+ </para>
+
+ <para>
+
+ Note that we're always interested in trying to
+ improve how you can troubleshoot configuration problems.
+ If you run into a problem that has
+ you scratching your head,
+ and which there just doesn't seem to be a good way to debug,
+ odds are pretty good that someone else will run into
+ the same problem, too.
+ If so, please let the SCons development team know
+ (preferably by filing a bug report
+ or feature request at our project pages at tigris.org)
+ so that we can use your feedback
+ to try to come up with a better way to help you,
+ and others, get the necessary insight into &SCons; behavior
+ to help identify and fix configuration issues.
</para>
@@ -40,7 +62,7 @@
<para>
- Let's take a simple example of
+ Let's look at a simple example of
a misconfigured build
that causes a target to be rebuilt
every time &SCons; is run:
@@ -70,7 +92,7 @@
<para>
- Now if we run &SCons; multiple on this example,
+ Now if we run &SCons; multiple times on this example,
we see that it re-runs the &cp;
command every time:
@@ -193,6 +215,17 @@
<scons_output_command>scons -Q --debug=explain</scons_output_command>
</scons_output>
+ <para>
+
+ (Note that the &debug-explain; option will only tell you
+ why &SCons; decided to rebuild necessary targets.
+ It does not tell you what files it examined
+ when deciding <emphasis>not</emphasis>
+ to rebuild a target file,
+ which is often a more valuable question to answer.)
+
+ </para>
+
</section>
<section>
@@ -223,7 +256,7 @@
</para>
<scons_example name="Dump">
- <file name="SConstruct" print="1">
+ <file name="SConstruct" printme="1">
env = Environment()
print env.Dump()
</file>
@@ -279,7 +312,7 @@
</para>
<scons_example name="Dump_ENV">
- <file name="SConstruct" print="1">
+ <file name="SConstruct" printme="1">
env = Environment()
print env.Dump('ENV')
</file>
@@ -306,3 +339,533 @@
</scons_output>
</section>
+
+ <section>
+
+ <title>What Dependencies Does &SCons; Know About? the &tree; Option</title>
+
+ <para>
+
+ Sometimes the best way to try to figure out what
+ &SCons; is doing is simply to take a look at the
+ dependency graph that it constructs
+ based on your &SConscript; files.
+ The <literal>--tree</literal> option
+ will display all or part of the
+ &SCons; dependency graph in an
+ "ASCII art" graphical format
+ that shows the dependency hierarchy.
+
+ </para>
+
+ <para>
+
+ For example, given the following input &SConstruct; file:
+
+ </para>
+
+ <scons_example name="tree1">
+ <file name="SConstruct" printme="1">
+ env = Environment(CPPPATH = ['.'])
+ env.Program('prog', ['f1.c', 'f2.c', 'f3.c'])
+ </file>
+ <file name="f1.c">
+ #include "inc.h"
+ </file>
+ <file name="f2.c">
+ #include "inc.h"
+ </file>
+ <file name="f3.c">
+ #include "inc.h"
+ </file>
+ <file name="inc.h">
+ inc.h
+ </file>
+ </scons_example>
+
+ <para>
+
+ Running &SCons; with the <literal>--tree=all</literal>
+ option yields:
+
+ </para>
+
+ <scons_output example="tree1">
+ <scons_output_command>scons -Q --tree=all</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ The tree will also be printed when the
+ <literal>-n</literal> (no execute) option is used,
+ which allows you to examine the dependency graph
+ for a configuration without actually
+ rebuilding anything in the tree.
+
+ </para>
+
+ <para>
+
+ The <literaL>--tree</literal> option only prints
+ the dependency graph for the specified targets
+ (or the default target(s) if none are specified on the command line).
+ So if you specify a target like <filename>f2.o</filename>
+ on the command line,
+ the <literaL>--tree</literal> option will only
+ print the dependency graph for that file:
+
+ </para>
+
+ <scons_output example="tree1">
+ <scons_output_command>scons -Q --tree=all f2.o</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ This is, of course, useful for
+ restricting the output from a very large
+ build configuration to just a
+ portion in which you're interested.
+ Multiple targets are fine,
+ in which case a tree will be printed
+ for each specified target:
+
+ </para>
+
+ <scons_output example="tree1">
+ <scons_output_command>scons -Q --tree=all f1.o f3.o</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ The <literal>status</literal> argument may be used
+ to tell &SCons; to print status information about
+ each file in the dependency graph:
+
+ </para>
+
+ <scons_output example="tree1">
+ <scons_output_command>scons -Q --tree=status</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ Note that <literal>--tree=all,status</literal> is equivalent;
+ the <literal>all</literal>
+ is assumed if only <literal>status</literal> is present.
+ As an alternative to <literal>all</literal>,
+ you can specify <literal>--tree=derived</literal>
+ to have &SCons; only print derived targets
+ in the tree output,
+ skipping source files
+ (like <filename>.c</filename> and <filename>.h</filename> files):
+
+ </para>
+
+ <scons_output example="tree1">
+ <scons_output_command>scons -Q --tree=derived</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ You can use the <literal>status</literal>
+ modifier with <literal>derived</literal> as well:
+
+ </para>
+
+ <scons_output example="tree1">
+ <scons_output_command>scons -Q --tree=derived,status</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ Note that the order of the <literal>--tree=</literal>
+ arguments doesn't matter;
+ <literal>--tree=status,derived</literal> is
+ completely equivalent.
+
+ </para>
+
+ <para>
+
+ The default behavior of the <literal>--tree</literal> option
+ is to repeat all of the dependencies each time the library dependency
+ (or any other dependency file) is encountered in the tree.
+ If certain target files share other target files,
+ such as two programs that use the same library:
+
+ </para>
+
+ <scons_example name="tree2">
+ <file name="SConstruct" printme="1">
+ env = Environment(CPPPATH = ['.'],
+ LIBS = ['foo'],
+ LIBPATH = ['.'])
+ env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
+ env.Program('prog1.c')
+ env.Program('prog2.c')
+ </file>
+ <file name="prog1.c">
+ #include "inc.h"
+ </file>
+ <file name="prog2.c">
+ #include "inc.h"
+ </file>
+ <file name="f1.c">
+ #include "inc.h"
+ </file>
+ <file name="f2.c">
+ #include "inc.h"
+ </file>
+ <file name="f3.c">
+ #include "inc.h"
+ </file>
+ <file name="inc.h">
+ inc.h
+ </file>
+ </scons_example>
+
+ <para>
+
+ Then there can be a <emphasis>lot</emphasis> of repetition in the
+ <literal>--tree=</literal> output:
+
+ </para>
+
+ <scons_output example="tree2">
+ <scons_output_command>scons -Q --tree=all</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ In a large configuration with many internal libraries
+ and include files,
+ this can very quickly lead to huge output trees.
+ To help make this more manageable,
+ a <literal>prune</literal> modifier may
+ be added to the option list,
+ in which case &SCons;
+ will print the name of a target that has
+ already been visited during the tree-printing
+ in <literal>[square brackets]</literal>
+ as an indication that the dependencies
+ of the target file may be found
+ by looking farther up the tree:
+
+ </para>
+
+ <scons_output example="tree2">
+ <scons_output_command>scons -Q --tree=prune</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ Like the <literal>status</literal> keyword,
+ the <literal>prune</literal> argument by itself
+ is equivalent to <literal>--tree=all,prune</literal>.
+
+ </para>
+
+ </section>
+
+ <section>
+
+ <title>How is &SCons; Constructing the Command Lines It Executes? the &debug-presub; Option</title>
+
+ <para>
+
+ Sometimes it's useful to look at the
+ pre-substitution string
+ that &SCons; uses to generate
+ the command lines it executes.
+ This can be done with the &debug-presub; option:
+
+ </para>
+
+ <scons_example name="presub">
+ <file name="SConstruct">
+ env = Environment(CPPPATH = ['.'])
+ env.Program('prog', 'prog.c')
+ </file>
+ <file name="prog.c">
+ prog.c
+ </file>
+ </scons_example>
+
+ <!--
+
+ Have to capture output here, otherwise the - -debug=presub output
+ shows the Python functions from the sconsdoc.py execution wrapper
+ used to generate this manual, not the underlying command-line strings.
+
+ <scons_output example="presub">
+ <scons_output_command>scons -Q - -debug=presub</scons_output_command>
+ </scons_output>
+
+ -->
+
+ <screen>
+ % <userinput>scons -Q --debug=presub</userinput>
+ Building prog.o with action:
+ $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCOMCOM $SOURCES
+ cc -o prog.o -c -I. prog.c
+ Building prog with action:
+ $SMART_LINKCOM
+ cc -o prog prog.o
+ </screen>
+
+ </section>
+
+ <section>
+
+ <title>Where is &SCons; Searching for Libraries? the &debug-findlibs; Option</title>
+
+ <para>
+
+ To get some insight into what library names
+ &SCons; is searching for,
+ and in which directories it is searching,
+ Use the <literal>--debug=findlibs</literal> option.
+ Given the following input &SConstruct; file:
+
+ </para>
+
+ <scons_example name="findlibs">
+ <file name="SConstruct" printme="1">
+ env = Environment(LIBPATH = ['libs1', 'libs2'])
+ env.Program('prog.c', LIBS=['foo', 'bar'])
+ </file>
+ <file name="prog.c">
+ prog.c
+ </file>
+ <file name="libs1/libfoo.a">
+ libs1/libfoo.a
+ </file>
+ <file name="libs2/libbar.a">
+ libs2/libbar.a
+ </file>
+ </scons_example>
+
+ <para>
+
+ And the libraries <filename>libfoo.a</filename>
+ and <filename>libbar.a</filename>
+ in <filename>libs1</filename> and <filename>libs2</filename>,
+ respectively,
+ use of the <literal>--debug=findlibs</literal> option yields:
+
+ </para>
+
+ <scons_output example="findlibs">
+ <scons_output_command>scons -Q --debug=findlibs</scons_output_command>
+ </scons_output>
+
+ </section>
+
+ <!--
+
+ <section>
+
+ <title>What Implicit Dependencies Did the &SCons; Scanner find? the &debug-includes; Option</title>
+
+ <para>
+
+ XXX explain the - - debug=includes option
+
+ </para>
+
+ <scons_example name="includes">
+ <file name="SConstruct" printme="1">
+ env = Environment(CPPPATH = ['inc1', 'inc2'])
+ env.Program('prog.c')
+ </file>
+ <file name="prog.c">
+ #include "file1.h"
+ #include "file2.h"
+ prog.c
+ </file>
+ <file name="inc1/file1.h">
+ inc1/file1.h
+ </file>
+ <file name="inc2/file2.h">
+ inc2/file2.h
+ </file>
+ </scons_example>
+
+ <scons_output example="includes">
+ <scons_output_command>scons -Q - - debug=includes prog</scons_output_command>
+ </scons_output>
+
+ </section>
+
+ -->
+
+ <section>
+
+ <title>Where is &SCons; Blowing Up? the &debug-stacktrace; Option</title>
+
+ <para>
+
+ In general, &SCons; tries to keep its error
+ messages short and informative.
+ That means we usually try to avoid showing
+ the stack traces that are familiar
+ to experienced Python programmers,
+ since they usually contain much more
+ information than is useful to most people.
+
+ </para>
+
+ <para>
+
+ For example, the following &SConstruct file:
+
+ </para>
+
+ <scons_example name="stacktrace">
+ <file name="SConstruct" printme="1">
+ Program('prog.c')
+ </file>
+ </scons_example>
+
+ <para>
+
+ Generates the following error if the
+ <filename>prog.c</filename> file
+ does not exist:
+
+ </para>
+
+ <scons_output example="stacktrace">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ In this case,
+ the error is pretty obvious.
+ But if it weren't,
+ and you wanted to try to get more information
+ about the error,
+ the &debug-stacktrace; option
+ would show you exactly where in the &SCons; source code
+ the problem occurs:
+
+ </para>
+
+ <scons_output example="stacktrace">
+ <scons_output_command>scons -Q --debug=stacktrace</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ Of course, if you do need to dive into the &SCons; source code,
+ we'd like to know if, or how,
+ the error messages or troubleshooting options
+ could have been improved to avoid that.
+ Not everyone has the necessary time or
+ Python skill to dive into the source code,
+ and we'd like to improve &SCons;
+ for those people as well...
+
+ </para>
+
+ </section>
+
+ <section>
+
+ <title>How is &SCons; Making Its Decisions? the &taskmastertrace; Option</title>
+
+ <para>
+
+ The internal &SCons; subsystem that handles walking
+ the dependency graph
+ and controls the decision-making about what to rebuild
+ is the <literal>Taskmaster</literal>.
+ &SCons; supports a <literal>--taskmastertrace</literal>
+ option that tells the Taskmaster to print
+ information about the children (dependencies)
+ of the various Nodes on its walk down the graph,
+ which specific dependent Nodes are being evaluated,
+ and in what order.
+
+ </para>
+
+ <para>
+
+ The <literal>--taskmastertrace</literal> option
+ takes as an argument the name of a file in
+ which to put the trace output,
+ with <filename>-</filename> (a single hyphen)
+ indicating that the trace messages
+ should be printed to the standard output:
+
+ </para>
+
+ <scons_example name="taskmastertrace">
+ <file name="SConstruct" printme="1">
+ env = Environment(CPPPATH = ['.'])
+ env.Program('prog.c')
+ </file>
+ <file name="prog.c">
+ #include "inc.h"
+ prog.c
+ </file>
+ <file name="inc.h">
+ #define STRING "one"
+ </file>
+ </scons_example>
+
+ <scons_output example="taskmastertrace" os="posix">
+ <scons_output_command>scons -Q --taskmastertrace=- prog</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ The <literal>--taskmastertrace</literal> option
+ doesn't provide information about the actual
+ calculations involved in deciding if a file is up-to-date,
+ but it does show all of the dependencies
+ it knows about for each Node,
+ and the order in which those dependencies are evaluated.
+ This can be useful as an alternate way to determine
+ whether or not your &SCons; configuration,
+ or the implicit dependency scan,
+ has actually identified all the correct dependencies
+ you want it to.
+
+ </para>
+
+ </section>
+
+ <!--
+
+ <section>
+
+ <title>Where Are My Build Bottlenecks? the &profile; Option</title>
+
+ <para>
+
+ XXX explain the - - profile= option
+
+ </para>
+
+ </section>
+
+ -->
+
+ <!--
+
+ <section>
+ <title>Troubleshooting Shared Caching: the &cache-debug; Option</title>
+
+ <para>
+
+ XXX describe the - - cache-debug option
+ XXX maybe point to the caching.in chapter?
+
+ </para>
+
+ </section>
+
+ -->