From 72c578fd4b0b4a5a43e18594339ac4ff26c376dc Mon Sep 17 00:00:00 2001 From: Luca Falavigna Date: Sat, 2 Jan 2010 20:56:27 +0100 Subject: Imported Upstream version 1.2.0.d20091224 --- doc/user/troubleshoot.in | 875 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 875 insertions(+) create mode 100644 doc/user/troubleshoot.in (limited to 'doc/user/troubleshoot.in') diff --git a/doc/user/troubleshoot.in b/doc/user/troubleshoot.in new file mode 100644 index 0000000..c729149 --- /dev/null +++ b/doc/user/troubleshoot.in @@ -0,0 +1,875 @@ + + + + + The experience of configuring any + software build tool to build a large code base + usually, at some point, + involves trying to figure out why + 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. + + + + + + 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. + + + +
+ Why is That Target Being Rebuilt? the &debug-explain; Option + + + + Let's look at a simple example of + a misconfigured build + that causes a target to be rebuilt + every time &SCons; is run: + + + + + + # Intentionally misspell the output file name in the + # command used to create the file: + Command('file.out', 'file.in', 'cp $SOURCE file.oout') + + + file.in + + + + + + (Note to Windows users: The POSIX &cp; command + copies the first file named on the command line + to the second file. + In our example, it copies the &file_in; file + to the &file_out; file.) + + + + + + Now if we run &SCons; multiple times on this example, + we see that it re-runs the &cp; + command every time: + + + + + scons -Q + scons -Q + scons -Q + + + + + In this example, + the underlying cause is obvious: + we've intentionally misspelled the output file name + in the &cp; command, + so the command doesn't actually + build the &file_out; file that we've told &SCons; to expect. + But if the problem weren't obvious, + it would be helpful + to specify the &debug-explain; option + on the command line + to have &SCons; tell us very specifically + why it's decided to rebuild the target: + + + + + scons -Q --debug=explain + + + + + If this had been a more complicated example + involving a lot of build output, + having &SCons; tell us that + it's trying to rebuild the target file + because it doesn't exist + would be an important clue + that something was wrong with + the command that we invoked to build it. + + + + + + The &debug-explain; option also comes in handy + to help figure out what input file changed. + Given a simple configuration that builds + a program from three source files, + changing one of the source files + and rebuilding with the &debug-explain; + option shows very specifically + why &SCons; rebuilds the files that it does: + + + + + + Program('prog', ['file1.c', 'file2.c', 'file3.c']) + + + file1.c + + + file2.c + + + file3.c + + + + + scons -Q + edit file2.c + scons -Q --debug=explain + + + + + This becomes even more helpful + in identifying when a file is rebuilt + due to a change in an implicit dependency, + such as an incuded .h file. + If the file1.c + and file3.c files + in our example + both included a &hello_h; file, + then changing that included file + and re-running &SCons; with the &debug-explain; option + will pinpoint that it's the change to the included file + that starts the chain of rebuilds: + + + + + + Program('prog', ['file1.c', 'file2.c', 'file3.c'], CPPPATH='.') + + + #include <hello.h> + file1.c + + + file2.c + + + #include <hello.h> + file3.c + + + #define string "world" + + + + + scons -Q + edit hello.h + scons -Q --debug=explain + + + + + (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 not + to rebuild a target file, + which is often a more valuable question to answer.) + + + +
+ +
+ What's in That Construction Environment? the &Dump; Method + + + + When you create a construction environment, + &SCons; populates it + with construction variables that are set up + for various compilers, linkers and utilities + that it finds on your system. + Although this is usually helpful and what you want, + it might be frustrating if &SCons; + doesn't set certain variables that you + expect to be set. + In situations like this, + it's sometimes helpful to use the + construction environment &Dump; method + to print all or some of + the construction variables. + Note that the &Dump; method + returns + the representation of the variables + in the environment + for you to print (or otherwise manipulate): + + + + + + env = Environment() + print env.Dump() + + + + + + On a POSIX system with gcc installed, + this might generate: + + + + + scons + + + + + On a Windows system with Visual C++ + the output might look like: + + + + + scons + + + + + The construction environments in these examples have + actually been restricted to just gcc and Visual C++, + respectively. + In a real-life situation, + the construction environments will + likely contain a great many more variables. + Also note that we've massaged the example output above + to make the memory address of all objects a constant 0x700000. + In reality, you would see a different hexadecimal + number for each object. + + + + + + To make it easier to see just what you're + interested in, + the &Dump; method allows you to + specify a specific constrcution variable + that you want to disply. + For example, + it's not unusual to want to verify + the external environment used to execute build commands, + to make sure that the PATH and other + environment variables are set up the way they should be. + You can do this as follows: + + + + + + env = Environment() + print env.Dump('ENV') + + + + + + Which might display the following when executed on a POSIX system: + + + + + scons + + + + + And the following when executed on a Windows system: + + + + + scons + + +
+ +
+ + What Dependencies Does &SCons; Know About? the &tree; Option + + + + 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 --tree option + will display all or part of the + &SCons; dependency graph in an + "ASCII art" graphical format + that shows the dependency hierarchy. + + + + + + For example, given the following input &SConstruct; file: + + + + + + env = Environment(CPPPATH = ['.']) + env.Program('prog', ['f1.c', 'f2.c', 'f3.c']) + + + #include "inc.h" + + + #include "inc.h" + + + #include "inc.h" + + + inc.h + + + + + + Running &SCons; with the --tree=all + option yields: + + + + + scons -Q --tree=all + + + + + The tree will also be printed when the + -n (no execute) option is used, + which allows you to examine the dependency graph + for a configuration without actually + rebuilding anything in the tree. + + + + + + The --tree 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 f2.o + on the command line, + the --tree option will only + print the dependency graph for that file: + + + + + scons -Q --tree=all f2.o + + + + + 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: + + + + + scons -Q --tree=all f1.o f3.o + + + + + The status argument may be used + to tell &SCons; to print status information about + each file in the dependency graph: + + + + + scons -Q --tree=status + + + + + Note that --tree=all,status is equivalent; + the all + is assumed if only status is present. + As an alternative to all, + you can specify --tree=derived + to have &SCons; only print derived targets + in the tree output, + skipping source files + (like .c and .h files): + + + + + scons -Q --tree=derived + + + + + You can use the status + modifier with derived as well: + + + + + scons -Q --tree=derived,status + + + + + Note that the order of the --tree= + arguments doesn't matter; + --tree=status,derived is + completely equivalent. + + + + + + The default behavior of the --tree 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: + + + + + + env = Environment(CPPPATH = ['.'], + LIBS = ['foo'], + LIBPATH = ['.']) + env.Library('foo', ['f1.c', 'f2.c', 'f3.c']) + env.Program('prog1.c') + env.Program('prog2.c') + + + #include "inc.h" + + + #include "inc.h" + + + #include "inc.h" + + + #include "inc.h" + + + #include "inc.h" + + + inc.h + + + + + + Then there can be a lot of repetition in the + --tree= output: + + + + + scons -Q --tree=all + + + + + 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 prune 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 [square brackets] + as an indication that the dependencies + of the target file may be found + by looking farther up the tree: + + + + + scons -Q --tree=prune + + + + + Like the status keyword, + the prune argument by itself + is equivalent to --tree=all,prune. + + + +
+ +
+ + How is &SCons; Constructing the Command Lines It Executes? the &debug-presub; Option + + + + 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: + + + + + + env = Environment(CPPPATH = ['.']) + env.Program('prog', 'prog.c') + + + prog.c + + + + + + + % scons -Q --debug=presub + 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 + + +
+ +
+ + Where is &SCons; Searching for Libraries? the &debug-findlibs; Option + + + + To get some insight into what library names + &SCons; is searching for, + and in which directories it is searching, + Use the --debug=findlibs option. + Given the following input &SConstruct; file: + + + + + + env = Environment(LIBPATH = ['libs1', 'libs2']) + env.Program('prog.c', LIBS=['foo', 'bar']) + + + prog.c + + + libs1/libfoo.a + + + libs2/libbar.a + + + + + + And the libraries libfoo.a + and libbar.a + in libs1 and libs2, + respectively, + use of the --debug=findlibs option yields: + + + + + scons -Q --debug=findlibs + + +
+ + + +
+ + Where is &SCons; Blowing Up? the &debug-stacktrace; Option + + + + 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. + + + + + + For example, the following &SConstruct file: + + + + + + Program('prog.c') + + + + + + Generates the following error if the + prog.c file + does not exist: + + + + + scons -Q + + + + + 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: + + + + + scons -Q --debug=stacktrace + + + + + 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... + + + +
+ +
+ + How is &SCons; Making Its Decisions? the &taskmastertrace; Option + + + + The internal &SCons; subsystem that handles walking + the dependency graph + and controls the decision-making about what to rebuild + is the Taskmaster. + &SCons; supports a --taskmastertrace + 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. + + + + + + The --taskmastertrace option + takes as an argument the name of a file in + which to put the trace output, + with - (a single hyphen) + indicating that the trace messages + should be printed to the standard output: + + + + + + env = Environment(CPPPATH = ['.']) + env.Program('prog.c') + + + #include "inc.h" + prog.c + + + #define STRING "one" + + + + + scons -Q --taskmastertrace=- prog + + + + + The --taskmastertrace 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. + + + +
+ + + + -- cgit v1.2.3