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 using the contact information at https://scons.org/contact.html 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.
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')
(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
cp file.in file.oout %scons -Q
cp file.in file.oout %scons -Q
cp file.in file.oout
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
scons: building `file.out' because it doesn't exist
cp file.in file.oout
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.
Note that you can also use
--warn=target-not-built
which checks
whether or not expected targets exist after a build rule is
executed.
% scons -Q --warn=target-not-built
cp file.in file.oout
scons: warning: Cannot find target file.out after building
File "/Users/bdbaddog/devel/scons/git/mwichmann/scripts/scons.py", line 97, in <module>
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:
%scons -Q
cc -o file1.o -c file1.c cc -o file2.o -c file2.c cc -o file3.o -c file3.c cc -o prog file1.o file2.o file3.o % [CHANGE THE CONTENTS OF file2.c] %scons -Q --debug=explain
scons: rebuilding `file2.o' because `file2.c' changed cc -o file2.o -c file2.c scons: rebuilding `prog' because `file2.o' changed cc -o prog file1.o file2.o file3.o
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:
%scons -Q
cc -o file1.o -c -I. file1.c cc -o file2.o -c -I. file2.c cc -o file3.o -c -I. file3.c cc -o prog file1.o file2.o file3.o % [CHANGE THE CONTENTS OF hello.h] %scons -Q --debug=explain
scons: rebuilding `file1.o' because `hello.h' changed cc -o file1.o -c -I. file1.c scons: rebuilding `file3.o' because `hello.h' changed cc -o file3.o -c -I. file3.c scons: rebuilding `prog' because: `file1.o' changed `file3.o' changed cc -o prog file1.o file2.o file3.o
(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.)