summaryrefslogtreecommitdiffstats
path: root/doc/user
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user')
-rw-r--r--doc/user/ENV.in2
-rw-r--r--doc/user/ENV.xml2
-rw-r--r--doc/user/builders-writing.in2
-rw-r--r--doc/user/builders-writing.xml2
-rw-r--r--doc/user/command-line.in12
-rw-r--r--doc/user/command-line.xml12
-rw-r--r--doc/user/depends.in760
-rw-r--r--doc/user/depends.xml737
-rw-r--r--doc/user/environments.in6
-rw-r--r--doc/user/environments.xml6
-rw-r--r--doc/user/factories.in4
-rw-r--r--doc/user/factories.xml4
-rw-r--r--doc/user/file-removal.in2
-rw-r--r--doc/user/file-removal.xml2
-rw-r--r--doc/user/help.in2
-rw-r--r--doc/user/help.xml2
-rw-r--r--doc/user/hierarchy.in6
-rw-r--r--doc/user/hierarchy.xml6
-rw-r--r--doc/user/install.in2
-rw-r--r--doc/user/install.xml2
-rw-r--r--doc/user/libraries.in6
-rw-r--r--doc/user/libraries.xml6
-rw-r--r--doc/user/main.in15
-rw-r--r--doc/user/main.xml15
-rw-r--r--doc/user/parseconfig.in2
-rw-r--r--doc/user/parseconfig.xml3
-rw-r--r--doc/user/repositories.in6
-rw-r--r--doc/user/repositories.xml6
-rw-r--r--doc/user/sconf.in2
-rw-r--r--doc/user/sconf.xml2
-rw-r--r--doc/user/simple.in2
-rw-r--r--doc/user/simple.xml2
-rw-r--r--doc/user/sourcecode.xml4
-rw-r--r--doc/user/troubleshoot.in6
-rw-r--r--doc/user/troubleshoot.xml121
35 files changed, 1356 insertions, 415 deletions
diff --git a/doc/user/ENV.in b/doc/user/ENV.in
index 3c8cfd5..3d8bc4b 100644
--- a/doc/user/ENV.in
+++ b/doc/user/ENV.in
@@ -196,7 +196,7 @@
The drawback is that the build can behave
differently if it's run by people with
different &PATH; values in their environment--for example,
- both the <literal>/bin</literal> and
+ if both the <literal>/bin</literal> and
<literal>/usr/local/bin</literal> directories
have different &cc; commands,
then which one will be used to compile programs
diff --git a/doc/user/ENV.xml b/doc/user/ENV.xml
index d843276..9fa2ec1 100644
--- a/doc/user/ENV.xml
+++ b/doc/user/ENV.xml
@@ -196,7 +196,7 @@
The drawback is that the build can behave
differently if it's run by people with
different &PATH; values in their environment--for example,
- both the <literal>/bin</literal> and
+ if both the <literal>/bin</literal> and
<literal>/usr/local/bin</literal> directories
have different &cc; commands,
then which one will be used to compile programs
diff --git a/doc/user/builders-writing.in b/doc/user/builders-writing.in
index 7497277..2285ac8 100644
--- a/doc/user/builders-writing.in
+++ b/doc/user/builders-writing.in
@@ -263,7 +263,7 @@ This functionality could be invoked as in the following example:
<para>
- To be able use both our own defined &Builder; objects
+ To be able to use both our own defined &Builder; objects
and the default &Builder; objects in the same &consenv;,
you can either add to the &cv-BUILDERS; variable
using the &Append; function:
diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml
index 50f6556..8ab4fca 100644
--- a/doc/user/builders-writing.xml
+++ b/doc/user/builders-writing.xml
@@ -239,7 +239,7 @@ This functionality could be invoked as in the following example:
<para>
- To be able use both our own defined &Builder; objects
+ To be able to use both our own defined &Builder; objects
and the default &Builder; objects in the same &consenv;,
you can either add to the &cv-BUILDERS; variable
using the &Append; function:
diff --git a/doc/user/command-line.in b/doc/user/command-line.in
index b2cb888..dbbddaf 100644
--- a/doc/user/command-line.in
+++ b/doc/user/command-line.in
@@ -53,7 +53,7 @@
<para>
If, for example,
- and you're using a POSIX shell that's
+ you're using a POSIX shell that's
compatible with the Bourne shell,
and you always want &SCons; to use the
<literal>-Q</literal> option,
@@ -96,7 +96,7 @@
<para>
- Windows users may typically want to set this
+ Windows users may typically want to set the
&SCONSFLAGS; in the appropriate tab of the
<literal>System Properties</literal> window.
@@ -1285,7 +1285,7 @@
to control an expected path name.
If, for example, you need to
define a variable in the preprocessor
- that control the location of a
+ that controls the location of a
configuration file:
</para>
@@ -1557,3 +1557,9 @@
</para>
</section>
+
+ <!--
+
+ AddOption() function for things like - -prefix=, - -force
+
+ -->
diff --git a/doc/user/command-line.xml b/doc/user/command-line.xml
index d7f3d7b..8675c19 100644
--- a/doc/user/command-line.xml
+++ b/doc/user/command-line.xml
@@ -53,7 +53,7 @@
<para>
If, for example,
- and you're using a POSIX shell that's
+ you're using a POSIX shell that's
compatible with the Bourne shell,
and you always want &SCons; to use the
<literal>-Q</literal> option,
@@ -89,7 +89,7 @@
<para>
- Windows users may typically want to set this
+ Windows users may typically want to set the
&SCONSFLAGS; in the appropriate tab of the
<literal>System Properties</literal> window.
@@ -1256,7 +1256,7 @@
to control an expected path name.
If, for example, you need to
define a variable in the preprocessor
- that control the location of a
+ that controls the location of a
configuration file:
</para>
@@ -1484,3 +1484,9 @@
</para>
</section>
+
+ <!--
+
+ AddOption() function for things like - -prefix=, - -force
+
+ -->
diff --git a/doc/user/depends.in b/doc/user/depends.in
index e0d5e92..7c15c52 100644
--- a/doc/user/depends.in
+++ b/doc/user/depends.in
@@ -26,12 +26,12 @@
<para>
So far we've seen how &SCons; handles one-time builds.
- But the real point of a build tool like &SCons;
+ But one of the main functions of a build tool like &SCons;
is to rebuild only the necessary things
when source files change--or, put another way,
&SCons; should <emphasis>not</emphasis>
waste time rebuilding things that have already been built.
- You can see this at work simply be re-invoking &SCons;
+ You can see this at work simply by re-invoking &SCons;
after building our simple &hello; example:
</para>
@@ -75,33 +75,36 @@
</para>
<section>
- <title>Deciding When a Source File Has Changed: the &SourceSignatures; Function</title>
+ <title>Deciding When an Input File Has Changed: the &Decider; Function</title>
<para>
- The other side of avoiding unnecessary rebuilds
+ Another aspect of avoiding unnecessary rebuilds
is the fundamental build tool behavior
of <emphasis>rebuilding</emphasis>
- things when a source file changes,
+ things when an input file changes,
so that the built software is up to date.
- &SCons; keeps track of this through a
- &signature; for each source file,
- and allows you to configure
- whether you want to use the source
- file contents or the modification time (timestamp)
- as the signature.
+ By default,
+ &SCons; keeps track of this through an
+ MD5 &signature;, or checksum, of the contents of each file,
+ although you can easily configure
+ &SCons; to use the
+ modification times (or time stamps)
+ instead.
+ You can even specify your own Python function
+ for deciding if an input file has changed.
</para>
<section>
- <title>MD5 Source File Signatures</title>
+ <title>Using MD5 Signatures to Decide if a File Has Changed</title>
<para>
By default,
- &SCons; keeps track of whether a source file has changed
- based on the file's contents,
- not the modification time.
+ &SCons; keeps track of whether a file has changed
+ based on an MD5 checksum of the file's contents,
+ not the file's modification time.
This means that you may be surprised by the
default &SCons; behavior if you are used to the
&Make; convention of forcing
@@ -143,36 +146,110 @@
Note that you can, if you wish,
specify this default behavior
(MD5 signatures) explicitly
- using the &SourceSignatures; function as follows:
+ using the &Decider; function as follows:
</para>
<sconstruct>
Program('hello.c')
- SourceSignatures('MD5')
+ Decider('MD5')
</sconstruct>
+ <para>
+
+ You can also use the string <literal>'content'</literal>
+ as a synonym for <literal>'MD5'</literal>
+ when calling the &Decider; function.
+
+ </para>
+
+ <section>
+ <title>Ramifications of Using MD5 Signatures</title>
+
+ <para>
+
+ Using MD5 Signatures to decide if an input file has changed
+ has one surprising benefit:
+ if a source file has been changed
+ in such a way that the contents of the
+ rebuilt target file(s)
+ will be exactly the same as the last time
+ the file was built,
+ then any "downstream" target files
+ that depend on the rebuilt-but-not-changed target
+ file actually need not be rebuilt.
+
+ </para>
+
+ <para>
+
+ So if, for example,
+ a user were to only change a comment in a &hello_c; file,
+ then the rebuilt &hello_o; file
+ would be exactly the same as the one previously built
+ (assuming the compiler doesn't put any build-specific
+ information in the object file).
+ &SCons; would then realize that it would not
+ need to rebuild the &hello; program as follows:
+
+ </para>
+
+ <scons_output example="ex1" os="posix">
+ <scons_output_command>scons -Q hello</scons_output_command>
+ <scons_output_command output=" [CHANGE A COMMENT IN hello.c]" edit="STRIP CCCOM line">edit hello.c</scons_output_command>
+ <scons_output_command>scons -Q hello</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ In essence, &SCons;
+ "short-circuits" any dependent builds
+ when it realizes that a target file
+ has been rebuilt to exactly the same file as the last build.
+ This does take some extra processing time
+ to read the contents of the target (&hello_o;) file,
+ but often saves time when the rebuild that was avoided
+ would have been time-consuming and expensive.
+
+ </para>
+
+ </section>
+
</section>
<section>
- <title>Source File Time Stamps</title>
+ <title>Using Time Stamps to Decide If a File Has Changed</title>
<para>
If you prefer, you can
configure &SCons; to use the modification time
- of source files,
- not the file contents,
- when deciding if something needs to be rebuilt.
- To do this, call the &SourceSignatures;
+ of a file, not the file contents,
+ when deciding if a target needs to be rebuilt.
+ &SCons; gives you two ways to use time stamps
+ to decide if an input file has changed
+ since the last time a target has been built.
+
+ </para>
+
+ <para>
+
+ The most familiar way to use time stamps
+ is the way &Make; does:
+ that is, have &SCons; decide
+ and target must be rebuilt if
+ if a source file's modification time is
+ <emphasis>newer</emphasis>
+ than the target file.
+ To do this, call the &Decider;
function as follows:
</para>
- <scons_example name="ex2">
+ <scons_example name="newer">
<file name="SConstruct" printme="1">
Program('hello.c')
- SourceSignatures('timestamp')
+ Decider('timestamp-newer')
</file>
<file name="hello.c">
int main() { printf("Hello, world!\n"); }
@@ -187,117 +264,222 @@
</para>
- <scons_output example="ex2" os="posix">
+ <scons_output example="newer" os="posix">
<scons_output_command>scons -Q hello</scons_output_command>
<scons_output_command>touch hello.c</scons_output_command>
<scons_output_command>scons -Q hello</scons_output_command>
</scons_output>
- </section>
+ <para>
- </section>
+ And, in fact, because this behavior is the same
+ as the behavior of &Make;,
+ you can also use the string <literal>'make'</literal>
+ as a synonym for <literal>'timestamp-newer'</literal>
+ when calling the &Decider; function:
- <section>
- <title>Deciding When a Target File Has Changed: the &TargetSignatures; Function</title>
+ </para>
- <para>
+ <sconstruct>
+ Program('hello.c')
+ Decider('make')
+ </sconstruct>
- As you've just seen,
- &SCons; uses signatures to decide whether a
- target file is up to date or must be rebuilt.
- When a target file depends on another target file,
- &SCons; allows you to configure separately
- how the signatures of "intermediate" target files
- are used when deciding if a dependent target file
- must be rebuilt.
+ <para>
- </para>
+ One drawback to using times stamps exactly like &Make;
+ is that if an input file's modification time suddenly
+ becomes <emphasis>older</emphasis> than a target file,
+ the target file will not be rebuilt.
+ This can happen if an old copy of a source file is restored
+ from a backup archive, for example.
+ The contents of the restored file will likely be different
+ than they were the last time a dependent target was built,
+ but the target won't be rebuilt
+ because the modification time of the source file
+ is not newer than the target.
- <section>
- <title>Build Signatures</title>
+ </para>
<para>
- Modifying a source file
- will cause not only its direct target file to be rebuilt,
- but also the target file(s)
- that depend on that direct target file.
- In our example,
- changing the contents of the &hello_c; file causes
- the &hello_o; file to be rebuilt,
- which in turn causes the
- &hello; program to be rebuilt:
+ Because &SCons; actually stores information
+ about the source files' time stamps whenever a target is built,
+ it can handle this situation by checking for
+ an exact match of the source file time stamp,
+ instead of just whether or not the source file
+ is newer than the target file.
+ To do this, specify the argument
+ <literal>'timestamp-match'</literal>
+ when calling the &Decider; function:
</para>
- <scons_output example="ex1" os="posix">
+ <scons_example name="match">
+ <file name="SConstruct" printme="1">
+ Program('hello.c')
+ Decider('timestamp-match')
+ </file>
+ <file name="hello.c">
+ int main() { printf("Hello, world!\n"); }
+ </file>
+ </scons_example>
+
+ <para>
+
+ When configured this way,
+ &SCons; will rebuild a target whenever
+ a source file's modification time has changed.
+ So if we use the <literal>touch -t</literal>
+ option to change the modification time of
+ &hello_c; to an old date (January 1, 1989),
+ &SCons; will still rebuild the target file:
+
+ </para>
+
+ <scons_output example="match" os="posix">
<scons_output_command>scons -Q hello</scons_output_command>
- <scons_output_command output=" [CHANGE THE CONTENTS OF hello.c]">edit hello.c</scons_output_command>
+ <scons_output_command>touch -t 198901010000 hello.c</scons_output_command>
<scons_output_command>scons -Q hello</scons_output_command>
</scons_output>
<para>
- What's not obvious, though,
- is that &SCons; internally handles the signature of
- the target file(s)
- (&hello_o; in the above example)
- differently from the signature of the source file
- (&hello_c;).
- By default,
- &SCons; tracks whether a target file must be rebuilt
- by using a &buildsignature;
- that consists of the combined
- signatures of all the files
- that go into making the target file.
- This is efficient because
- the accumulated signatures
- actually give &SCons; all of the
- information it needs
- to decide if the target file is out of date.
+ In general, the only reason to prefer
+ <literal>timestamp-newer</literal>
+ instead of
+ <literal>timestamp-match</literal>,
+ would be if you have some specific reason
+ to require this &Make;-like behavior of
+ not rebuilding a target when an otherwise-modified
+ source file is older.
</para>
+ </section>
+
+ <section>
+ <title>Deciding If a File Has Changed Using Both MD Signatures and Time Stamps</title>
+
<para>
- If you wish, you can
- specify this default behavior
- (build signatures) explicitly
- using the &TargetSignatures; function:
+ As a performance enhancement,
+ &SCons; provides a way to use
+ MD5 checksums of file contents
+ but to only read the contents
+ whenever the file's timestamp has changed.
+ To do this, call the &Decider;
+ function with <literal>'MD5-timestamp'</literal>
+ argument as follows:
</para>
- <sconstruct>
+ <scons_example name="MD5-timestamp">
+ <file name="SConstruct" printme="1">
Program('hello.c')
- TargetSignatures('build')
- </sconstruct>
+ Decider('MD5-timestamp')
+ </file>
+ <file name="hello.c">
+ int main() { printf("Hello, world!\n"); }
+ </file>
+ </scons_example>
+
+ <para>
+
+ So configured, &SCons will still behave like
+ it does when using <literal>Decider('MD5')</literal>:
+
+ </para>
+
+ <scons_output example="MD5-timestamp" os="posix">
+ <scons_output_command>scons -Q hello</scons_output_command>
+ <scons_output_command>touch hello.c</scons_output_command>
+ <scons_output_command>scons -Q hello</scons_output_command>
+ <scons_output_command output=" [CHANGE THE CONTENTS OF hello.c]">edit hello.c</scons_output_command>
+ <scons_output_command>scons -Q hello</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ However, the second call to &SCons; in the above output,
+ when the build is up-to-date,
+ will have been performed by simply looking at the
+ modification time of the &hello_c; file,
+ not by opening it and performing
+ an MD5 checksum calcuation on its contents.
+ This can significantly speed up many up-to-date builds.
+
+ </para>
+
+ <para>
+
+ The only drawback to using
+ <literal>Decider('MD5-timestamp')</literal>
+ is that &SCons; will <emphasis>not</emphasis>
+ rebuild a target file if a source file was modified
+ within one second of the last time &SCons; built the file.
+ While most developers are programming,
+ this isn't a problem in practice,
+ since it's unlikely that someone will have built
+ and then thought quickly enought to make a substantive
+ change to a source file within one second.
+ Certain build scripts or
+ continuous integration tools may, however,
+ rely on the ability to applying changes to files
+ automatically and then rebuild as quickly as possible,
+ in which case use of
+ <literal>Decider('MD5-timestamp')</literal>
+ may not be appropriate.
+
+ </para>
</section>
<section>
- <title>File Contents</title>
+ <title>Writing Your Own Custom &Decider; Function</title>
<para>
- Sometimes a source file can be changed
- in such a way that the contents of the
- rebuilt target file(s)
- will be exactly the same as the last time
- the file was built.
- If so, then any other target files
- that depend on such a built-but-not-changed target
- file actually need not be rebuilt.
- You can make &SCons;
- realize that it does not need to rebuild
- a dependent target file in this situation
- using the &TargetSignatures; function as follows:
+ The different string values that we've passed to
+ the &Decider; function are essentially used by &SCons;
+ to pick one of several specific internal functions
+ that implement various ways of deciding if a dependency
+ (usually a source file)
+ has changed since a target file has been built.
+ As it turns out,
+ you can also supply your own function
+ to decide if a dependency has changed.
</para>
- <scons_example name="ex3">
+ <para>
+
+ For example, suppose we have an input file
+ that contains a lot of data,
+ in some specific regular format,
+ that is used to rebuild a lot of different target files,
+ but each target file really only depends on
+ one particular section of the input file.
+ We'd like to have each target file depend on
+ only its section of the input file.
+ However, since the input file may contain a lot of data,
+ we only want to open the input file if its timestamp has changed.
+ This could done with a custom
+ &Decider; function that might look something like this:
+
+ </para>
+
+ <scons_example name="function">
<file name="SConstruct" printme="1">
Program('hello.c')
- TargetSignatures('content')
+ def decide_if_changed(dependency, target, prev_ni):
+ if self.get_timestamp() != prev_ni.timestamp:
+ dep = str(dependency)
+ tgt = str(target)
+ if specific_part_of_file_has_changed(dep, tgt):
+ return True
+ return False
+ Decider(decide_if_changed)
</file>
<file name="hello.c">
int main() { printf("Hello, world!\n"); }
@@ -306,35 +488,294 @@
<para>
- So if, for example,
- a user were to only change a comment in a C file,
- then the rebuilt &hello_o; file
- would be exactly the same as the one previously built
- (assuming the compiler doesn't put any build-specific
- information in the object file).
- &SCons; would then realize that it would not
- need to rebuild the &hello; program as follows:
+ Note that in the function definition,
+ the <literal>dependency</literal>
+ (input file) is the first argument,
+ and then the <literal>target</literal>.
+ Both of these are passed to the functions as
+ SCons &Node; objects,
+ which we convert to strings using the Python
+ <function>str()</function>.
+ The third argument, <literal>prev_ni</literal>,
+ is an object that holds the
+ signature or timestamp information
+ that was recorded about the dependency
+ the last time the target was built.
</para>
- <scons_output example="ex3" os="posix">
- <scons_output_command>scons -Q hello</scons_output_command>
- <scons_output_command output=" [CHANGE A COMMENT IN hello.c]" edit="STRIP CCCOM line">edit hello.c</scons_output_command>
- <scons_output_command>scons -Q hello</scons_output_command>
+ <para>
+
+ Note that ignoring some of the arguments
+ in your custom &Decider; function
+ is a perfectly normal thing to do,
+ if they don't impact the way you want to
+ decide if the dependency file has changed.
+
+ </para>
+
+ </section>
+
+ <section>
+ <title>Mixing Different Ways of Deciding If a File Has Changed</title>
+
+ <para>
+
+ The previous examples have all demonstrated calling
+ the global &Decider; function
+ to configure all dependency decisions that &SCons; makes.
+ Sometimes, however, you want to be able to configure
+ different decision-making for different targets.
+ When that's necessary, you can use the
+ <function>env.Decider</function>
+ method to affect only the configuration
+ decisions for targets built with a
+ specific construction environment.
+
+ </para>
+
+ <para>
+
+ For example, if we arbitrarily want to build
+ one program using MD5 checkums
+ and another use file modification times
+ from the same source
+ we might configure it this way:
+
+ </para>
+
+ <scons_example name="mixing">
+ <file name="SConstruct" printme="1">
+ env1 = Environment(CPPPATH = ['.'])
+ env2 = env1.Clone()
+ env2.Decider('timestamp-match')
+ env1.Program('prog-MD5', 'program1.c')
+ env2.Program('prog-timestamp', 'program2.c')
+ </file>
+ <file name="program1.c">
+ #include "inc.h"
+ int main() { printf("Hello, world!\n"); }
+ </file>
+ <file name="program2.c">
+ #include "inc.h"
+ int main() { printf("Hello, world!\n"); }
+ </file>
+ <file name="inc.h">
+ #define INC 1
+ </file>
+ </scons_example>
+
+ <para>
+
+ If both of the programs include the same
+ <filename>inc.h</filename> file,
+ then updating the modification time of
+ <filename>inc.h</filename>
+ (using the &touch; command)
+ will cause only <filename>prog-timestamp</filename>
+ to be rebuilt:
+
+ </para>
+
+ <scons_output example="mixing" os="posix">
+ <scons_output_command>scons -Q</scons_output_command>
+ <scons_output_command>touch inc.h</scons_output_command>
+ <scons_output_command>scons -Q</scons_output_command>
</scons_output>
+ </section>
+
+ </section>
+
+ <section>
+ <title>Older Functions for Deciding When an Input File Has Changed</title>
+
+ <para>
+
+ &SCons; still supports two functions that used to be the
+ primary methods for configuring the
+ decision about whether or not an input file has changed.
+ Although they're not officially deprecated yet,
+ their use is discouraged,
+ mainly because they rely on a somewhat
+ confusing distinction between how
+ source files and target files are handled.
+ These functions are documented here mainly in case you
+ encounter them in existing &SConscript; files.
+
+ </para>
+
+ <section>
+ <title>The &SourceSignatures; Function</title>
+
<para>
- In essence, &SCons; has
- "short-circuited" any dependent builds
- when it realizes that a target file
- has been rebuilt to exactly the same file as the last build.
- So configured,
- &SCons; does take some extra processing time
- to scan the contents of the target (&hello_o;) file,
- but this may save time
- if the rebuild that was avoided
- would have been very time-consuming and expensive.
+ The &SourceSignatures; function is fairly straightforward,
+ and supports two different argument values
+ to configure whether source file changes should be decided
+ using MD5 signatures:
+
+ </para>
+
+ <sconstruct>
+ Program('hello.c')
+ SourceSignatures('MD5')
+ </sconstruct>
+
+ <para>
+
+ Or using time stamps:
+
+ </para>
+
+ <sconstruct>
+ Program('hello.c')
+ SourceSignatures('timestamp')
+ </sconstruct>
+
+ <para>
+
+ These are roughly equivalent to specifying
+ <function>Decider('MD5')</function>
+ or
+ <function>Decider('timestamp-match')</function>,
+ respectively,
+ although it only affects how SCons makes
+ decisions about dependencies on
+ <emphasis>source</emphasis> files--that is,
+ files that are not built from any other files.
+
+ </para>
+
+ </section>
+
+ <section>
+ <title>The &TargetSignatures; Function</title>
+
+ <para>
+
+ The &TargetSignatures; function
+ specifies how &SCons; decides
+ when a target file has changed
+ <emphasis>when it is used as a
+ dependency of (input to) another target</emphasis>--that is,
+ the &TargetSignatures; function configures
+ how the signatures of "intermediate" target files
+ are used when deciding if a "downstream" target file
+ must be rebuilt.
+ <footnote><para>
+ This easily-overlooked distinction between
+ how &SCons; decides if the target itself must be rebuilt
+ and how the target is then used to decide if a different
+ target must be rebuilt is one of the confusing
+ things that has led to the &TargetSignatures;
+ and &SourceSignatures; functions being
+ replaced by the simpler &Decider; function.
+ </para></footnote>
+
+ </para>
+
+ <para>
+
+ The &TargetSignatures; function supports the same
+ <literal>'MD5'</literal> and <literal>'timestamp'</literal>
+ argument values that are supported by the &SourceSignatures;,
+ with the same meanings, but applied to target files.
+ That is, in the example:
+
+ </para>
+
+ <sconstruct>
+ Program('hello.c')
+ TargetSignatures('MD5')
+ </sconstruct>
+
+ <para>
+
+ The MD5 checksum of the &hello_o; target file
+ will be used to decide if it has changed since the last
+ time the "downstream" &hello; target file was built.
+ And in the example:
+
+ </para>
+
+ <sconstruct>
+ Program('hello.c')
+ TargetSignatures('timestamp')
+ </sconstruct>
+
+ <para>
+
+ The modification time of the &hello_o; target file
+ will be used to decide if it has changed since the last
+ time the "downstream" &hello; target file was built.
+
+ </para>
+
+ <para>
+
+ The &TargetSignatures; function supports
+ two additional argument values:
+ <literal>'source'</literal> and <literal>'build'</literal>.
+ The <literal>'source'</literal> argument
+ specifies that decisions involving
+ whether target files have changed
+ since a previous build
+ should use the same behavior
+ for the decisions configured for source files
+ (using the &SourceSignatures; function).
+ So in the example:
+
+ </para>
+
+ <sconstruct>
+ Program('hello.c')
+ TargetSignatures('source')
+ SourceSignatures('timestamp')
+ </sconstruct>
+
+ <para>
+
+ All files, both targets and sources,
+ will use modification times
+ when deciding if an input file
+ has changed since the last
+ time a target was built.
+
+ </para>
+
+ <para>
+
+ Lastly, the <literal>'build'</literal> argument
+ specifies that &SCons; should examine
+ the build status of a target file
+ and always rebuild a "downstream" target
+ if the target file was itself rebuilt,
+ without re-examining the contents or timestamp
+ of the newly-built target file.
+ If the target file was not rebuilt during
+ this &scons; invocation,
+ then the target file will be examined
+ the same way as configured by
+ the &SourceSignature; call
+ to decide if it has changed.
+
+ </para>
+
+ <para>
+
+ This mimics the behavior of
+ <literal>build signatures</literal>
+ in earlier versions of &SCons;.
+ A &buildsignature; re-combined
+ signatures of all the input files
+ that went into making the target file,
+ so that the target file itself
+ did not need to have its contents read
+ to compute an MD5 signature.
+ This can improve performance for some configurations,
+ but is generally not as effective as using
+ <literal>Decider('MD5-timestamp')</literal>.
</para>
@@ -348,12 +789,12 @@
<para>
Now suppose that our "Hello, World!" program
- actually has a <literal>#include</literal> line
+ actually has an <literal>#include</literal> line
to include the &hello_h; file in the compilation:
</para>
- <scons_example name="ex4">
+ <scons_example name="include">
<file name="SConstruct">
Program('hello.c', CPPPATH = '.')
</file>
@@ -376,7 +817,7 @@
</para>
- <scons_example_file example="ex4" name="hello.h">
+ <scons_example_file example="include" name="hello.h">
</scons_example_file>
<para>
@@ -389,7 +830,7 @@
</para>
- <scons_example_file example="ex4" name="SConstruct">
+ <scons_example_file example="include" name="SConstruct">
</scons_example_file>
<para>
@@ -403,7 +844,7 @@
</para>
- <scons_output example="ex4" os="posix">
+ <scons_output example="include" os="posix">
<scons_output_command>scons -Q hello</scons_output_command>
<scons_output_command>scons -Q hello</scons_output_command>
<scons_output_command output=" [CHANGE THE CONTENTS OF hello.h]">edit hello.h</scons_output_command>
@@ -445,7 +886,7 @@
the &cv-CPPPATH; variable
may be a list of directories,
or a string separated by
- the system-specific path separate character
+ the system-specific path separation character
(':' on POSIX/Linux, ';' on Windows).
Either way, &SCons; creates the
right command-line options
@@ -682,7 +1123,44 @@
</section>
<section>
- <title>Ignoring Dependencies: the &Ignore; Method</title>
+ <title>Explicit Dependencies: the &Depends; Function</title>
+
+ <para>
+
+ Sometimes a file depends on another file
+ that is not detected by an &SCons; scanner.
+ For this situation,
+ &SCons; allows you to specific explicitly that one file
+ depends on another file,
+ and must be rebuilt whenever that file changes.
+ This is specified using the &Depends; method:
+
+ </para>
+
+ <programlisting>
+ hello = Program('hello.c')
+ Depends(hello, 'other_file')
+ </programlisting>
+
+ <!-- XXX mention that you can use arrays for target and source? -->
+
+ <screen>
+ % <userinput>scons -Q hello</userinput>
+ cc -c hello.c -o hello.o
+ cc -o hello hello.o
+ % <userinput>scons -Q hello</userinput>
+ scons: `hello' is up to date.
+ % <userinput>edit other_file</userinput>
+ [CHANGE THE CONTENTS OF other_file]
+ % <userinput>scons -Q hello</userinput>
+ cc -c hello.c -o hello.o
+ cc -o hello hello.o
+ </screen>
+
+ </section>
+
+ <section>
+ <title>Ignoring Dependencies: the &Ignore; Function</title>
<para>
@@ -737,7 +1215,7 @@
Now, the above example is a little contrived,
because it's hard to imagine a real-world situation
- where you wouldn't to rebuild &hello;
+ where you wouldn't want to rebuild &hello;
if the &hello_h; file changed.
A more realistic example
might be if the &hello;
@@ -762,45 +1240,7 @@
</section>
<section>
- <title>Explicit Dependencies: the &Depends; Method</title>
-
- <para>
-
- On the other hand,
- sometimes a file depends on another file
- that is not detected by an &SCons; scanner.
- For this situation,
- &SCons; allows you to specific explicitly that one file
- depends on another file,
- and must be rebuilt whenever that file changes.
- This is specified using the &Depends; method:
-
- </para>
-
- <programlisting>
- hello = Program('hello.c')
- Depends(hello, 'other_file')
- </programlisting>
-
- <!-- XXX mention that you can use arrays for target and source? -->
-
- <screen>
- % <userinput>scons -Q hello</userinput>
- cc -c hello.c -o hello.o
- cc -o hello hello.o
- % <userinput>scons -Q hello</userinput>
- scons: `hello' is up to date.
- % <userinput>edit other_file</userinput>
- [CHANGE THE CONTENTS OF other_file]
- % <userinput>scons -Q hello</userinput>
- cc -c hello.c -o hello.o
- cc -o hello hello.o
- </screen>
-
- </section>
-
- <section>
- <title>The &AlwaysBuild; Method</title>
+ <title>The &AlwaysBuild; Function</title>
<para>
diff --git a/doc/user/depends.xml b/doc/user/depends.xml
index 9e055ee..936e4b2 100644
--- a/doc/user/depends.xml
+++ b/doc/user/depends.xml
@@ -26,12 +26,12 @@
<para>
So far we've seen how &SCons; handles one-time builds.
- But the real point of a build tool like &SCons;
+ But one of the main functions of a build tool like &SCons;
is to rebuild only the necessary things
when source files change--or, put another way,
&SCons; should <emphasis>not</emphasis>
waste time rebuilding things that have already been built.
- You can see this at work simply be re-invoking &SCons;
+ You can see this at work simply by re-invoking &SCons;
after building our simple &hello; example:
</para>
@@ -74,33 +74,36 @@
</para>
<section>
- <title>Deciding When a Source File Has Changed: the &SourceSignatures; Function</title>
+ <title>Deciding When an Input File Has Changed: the &Decider; Function</title>
<para>
- The other side of avoiding unnecessary rebuilds
+ Another aspect of avoiding unnecessary rebuilds
is the fundamental build tool behavior
of <emphasis>rebuilding</emphasis>
- things when a source file changes,
+ things when an input file changes,
so that the built software is up to date.
- &SCons; keeps track of this through a
- &signature; for each source file,
- and allows you to configure
- whether you want to use the source
- file contents or the modification time (timestamp)
- as the signature.
+ By default,
+ &SCons; keeps track of this through an
+ MD5 &signature;, or checksum, of the contents of each file,
+ although you can easily configure
+ &SCons; to use the
+ modification times (or time stamps)
+ instead.
+ You can even specify your own Python function
+ for deciding if an input file has changed.
</para>
<section>
- <title>MD5 Source File Signatures</title>
+ <title>Using MD5 Signatures to Decide if a File Has Changed</title>
<para>
By default,
- &SCons; keeps track of whether a source file has changed
- based on the file's contents,
- not the modification time.
+ &SCons; keeps track of whether a file has changed
+ based on an MD5 checksum of the file's contents,
+ not the file's modification time.
This means that you may be surprised by the
default &SCons; behavior if you are used to the
&Make; convention of forcing
@@ -150,35 +153,114 @@
Note that you can, if you wish,
specify this default behavior
(MD5 signatures) explicitly
- using the &SourceSignatures; function as follows:
+ using the &Decider; function as follows:
</para>
<programlisting>
Program('hello.c')
- SourceSignatures('MD5')
+ Decider('MD5')
</programlisting>
+ <para>
+
+ You can also use the string <literal>'content'</literal>
+ as a synonym for <literal>'MD5'</literal>
+ when calling the &Decider; function.
+
+ </para>
+
+ <section>
+ <title>Ramifications of Using MD5 Signatures</title>
+
+ <para>
+
+ Using MD5 Signatures to decide if an input file has changed
+ has one surprising benefit:
+ if a source file has been changed
+ in such a way that the contents of the
+ rebuilt target file(s)
+ will be exactly the same as the last time
+ the file was built,
+ then any "downstream" target files
+ that depend on the rebuilt-but-not-changed target
+ file actually need not be rebuilt.
+
+ </para>
+
+ <para>
+
+ So if, for example,
+ a user were to only change a comment in a &hello_c; file,
+ then the rebuilt &hello_o; file
+ would be exactly the same as the one previously built
+ (assuming the compiler doesn't put any build-specific
+ information in the object file).
+ &SCons; would then realize that it would not
+ need to rebuild the &hello; program as follows:
+
+ </para>
+
+ <screen>
+ % <userinput>scons -Q hello</userinput>
+ cc -o hello.o -c hello.c
+ cc -o hello hello.o
+ % <userinput>edit hello.c</userinput>
+ [CHANGE A COMMENT IN hello.c]
+ % <userinput>scons -Q hello</userinput>
+ cc -o hello.o -c hello.c
+ scons: `hello' is up to date.
+ </screen>
+
+ <para>
+
+ In essence, &SCons;
+ "short-circuits" any dependent builds
+ when it realizes that a target file
+ has been rebuilt to exactly the same file as the last build.
+ This does take some extra processing time
+ to read the contents of the target (&hello_o;) file,
+ but often saves time when the rebuild that was avoided
+ would have been time-consuming and expensive.
+
+ </para>
+
+ </section>
+
</section>
<section>
- <title>Source File Time Stamps</title>
+ <title>Using Time Stamps to Decide If a File Has Changed</title>
<para>
If you prefer, you can
configure &SCons; to use the modification time
- of source files,
- not the file contents,
- when deciding if something needs to be rebuilt.
- To do this, call the &SourceSignatures;
+ of a file, not the file contents,
+ when deciding if a target needs to be rebuilt.
+ &SCons; gives you two ways to use time stamps
+ to decide if an input file has changed
+ since the last time a target has been built.
+
+ </para>
+
+ <para>
+
+ The most familiar way to use time stamps
+ is the way &Make; does:
+ that is, have &SCons; decide
+ and target must be rebuilt if
+ if a source file's modification time is
+ <emphasis>newer</emphasis>
+ than the target file.
+ To do this, call the &Decider;
function as follows:
</para>
<programlisting>
Program('hello.c')
- SourceSignatures('timestamp')
+ Decider('timestamp-newer')
</programlisting>
<para>
@@ -199,40 +281,118 @@
cc -o hello hello.o
</screen>
- </section>
+ <para>
- </section>
+ And, in fact, because this behavior is the same
+ as the behavior of &Make;,
+ you can also use the string <literal>'make'</literal>
+ as a synonym for <literal>'timestamp-newer'</literal>
+ when calling the &Decider; function:
- <section>
- <title>Deciding When a Target File Has Changed: the &TargetSignatures; Function</title>
+ </para>
- <para>
+ <programlisting>
+ Program('hello.c')
+ Decider('make')
+ </programlisting>
- As you've just seen,
- &SCons; uses signatures to decide whether a
- target file is up to date or must be rebuilt.
- When a target file depends on another target file,
- &SCons; allows you to configure separately
- how the signatures of "intermediate" target files
- are used when deciding if a dependent target file
- must be rebuilt.
+ <para>
- </para>
+ One drawback to using times stamps exactly like &Make;
+ is that if an input file's modification time suddenly
+ becomes <emphasis>older</emphasis> than a target file,
+ the target file will not be rebuilt.
+ This can happen if an old copy of a source file is restored
+ from a backup archive, for example.
+ The contents of the restored file will likely be different
+ than they were the last time a dependent target was built,
+ but the target won't be rebuilt
+ because the modification time of the source file
+ is not newer than the target.
+
+ </para>
+
+ <para>
+
+ Because &SCons; actually stores information
+ about the source files' time stamps whenever a target is built,
+ it can handle this situation by checking for
+ an exact match of the source file time stamp,
+ instead of just whether or not the source file
+ is newer than the target file.
+ To do this, specify the argument
+ <literal>'timestamp-match'</literal>
+ when calling the &Decider; function:
+
+ </para>
+
+ <programlisting>
+ Program('hello.c')
+ Decider('timestamp-match')
+ </programlisting>
+
+ <para>
+
+ When configured this way,
+ &SCons; will rebuild a target whenever
+ a source file's modification time has changed.
+ So if we use the <literal>touch -t</literal>
+ option to change the modification time of
+ &hello_c; to an old date (January 1, 1989),
+ &SCons; will still rebuild the target file:
+
+ </para>
+
+ <screen>
+ % <userinput>scons -Q hello</userinput>
+ cc -o hello.o -c hello.c
+ cc -o hello hello.o
+ % <userinput>touch -t 198901010000 hello.c</userinput>
+ % <userinput>scons -Q hello</userinput>
+ cc -o hello.o -c hello.c
+ scons: `hello' is up to date.
+ </screen>
+
+ <para>
+
+ In general, the only reason to prefer
+ <literal>timestamp-newer</literal>
+ instead of
+ <literal>timestamp-match</literal>,
+ would be if you have some specific reason
+ to require this &Make;-like behavior of
+ not rebuilding a target when an otherwise-modified
+ source file is older.
+
+ </para>
+
+ </section>
<section>
- <title>Build Signatures</title>
+ <title>Deciding If a File Has Changed Using Both MD Signatures and Time Stamps</title>
+
+ <para>
+
+ As a performance enhancement,
+ &SCons; provides a way to use
+ MD5 checksums of file contents
+ but to only read the contents
+ whenever the file's timestamp has changed.
+ To do this, call the &Decider;
+ function with <literal>'MD5-timestamp'</literal>
+ argument as follows:
+
+ </para>
+
+ <programlisting>
+ Program('hello.c')
+ Decider('MD5-timestamp')
+ </programlisting>
<para>
- Modifying a source file
- will cause not only its direct target file to be rebuilt,
- but also the target file(s)
- that depend on that direct target file.
- In our example,
- changing the contents of the &hello_c; file causes
- the &hello_o; file to be rebuilt,
- which in turn causes the
- &hello; program to be rebuilt:
+ So configured, &SCons; will still behave like
+ it does when using <literal>Decider('MD5')</literal>:
</para>
@@ -240,112 +400,380 @@
% <userinput>scons -Q hello</userinput>
cc -o hello.o -c hello.c
cc -o hello hello.o
+ % <userinput>touch hello.c</userinput>
+ % <userinput>scons -Q hello</userinput>
+ scons: `hello' is up to date.
% <userinput>edit hello.c</userinput>
[CHANGE THE CONTENTS OF hello.c]
% <userinput>scons -Q hello</userinput>
- cc -o hello.o -c hello.c
- cc -o hello hello.o
+ scons: `hello' is up to date.
</screen>
<para>
- What's not obvious, though,
- is that &SCons; internally handles the signature of
- the target file(s)
- (&hello_o; in the above example)
- differently from the signature of the source file
- (&hello_c;).
- By default,
- &SCons; tracks whether a target file must be rebuilt
- by using a &buildsignature;
- that consists of the combined
- signatures of all the files
- that go into making the target file.
- This is efficient because
- the accumulated signatures
- actually give &SCons; all of the
- information it needs
- to decide if the target file is out of date.
+ However, the second call to &SCons; in the above output,
+ when the build is up-to-date,
+ will have been performed by simply looking at the
+ modification time of the &hello_c; file,
+ not by opening it and performing
+ an MD5 checksum calcuation on its contents.
+ This can significantly speed up many up-to-date builds.
</para>
<para>
- If you wish, you can
- specify this default behavior
- (build signatures) explicitly
- using the &TargetSignatures; function:
+ The only drawback to using
+ <literal>Decider('MD5-timestamp')</literal>
+ is that &SCons; will <emphasis>not</emphasis>
+ rebuild a target file if a source file was modified
+ within one second of the last time &SCons; built the file.
+ While most developers are programming,
+ this isn't a problem in practice,
+ since it's unlikely that someone will have built
+ and then thought quickly enought to make a substantive
+ change to a source file within one second.
+ Certain build scripts or
+ continuous integration tools may, however,
+ rely on the ability to applying changes to files
+ automatically and then rebuild as quickly as possible,
+ in which case use of
+ <literal>Decider('MD5-timestamp')</literal>
+ may not be appropriate.
+
+ </para>
+
+ </section>
+
+ <section>
+ <title>Writing Your Own Custom &Decider; Function</title>
+
+ <para>
+
+ The different string values that we've passed to
+ the &Decider; function are essentially used by &SCons;
+ to pick one of several specific internal functions
+ that implement various ways of deciding if a dependency
+ (usually a source file)
+ has changed since a target file has been built.
+ As it turns out,
+ you can also supply your own function
+ to decide if a dependency has changed.
+
+ </para>
+
+ <para>
+
+ For example, suppose we have an input file
+ that contains a lot of data,
+ in some specific regular format,
+ that is used to rebuild a lot of different target files,
+ but each target file really only depends on
+ one particular section of the input file.
+ We'd like to have each target file depend on
+ only its section of the input file.
+ However, since the input file may contain a lot of data,
+ we only want to open the input file if its timestamp has changed.
+ This could done with a custom
+ &Decider; function that might look something like this:
</para>
<programlisting>
Program('hello.c')
- TargetSignatures('build')
+ def decide_if_changed(dependency, target, prev_ni):
+ if self.get_timestamp() != prev_ni.timestamp:
+ dep = str(dependency)
+ tgt = str(target)
+ if specific_part_of_file_has_changed(dep, tgt):
+ return True
+ return False
+ Decider(decide_if_changed)
</programlisting>
+ <para>
+
+ Note that in the function definition,
+ the <literal>dependency</literal>
+ (input file) is the first argument,
+ and then the <literal>target</literal>.
+ Both of these are passed to the functions as
+ SCons &Node; objects,
+ which we convert to strings using the Python
+ <function>str()</function>.
+ The third argument, <literal>prev_ni</literal>,
+ is an object that holds the
+ signature or timestamp information
+ that was recorded about the dependency
+ the last time the target was built.
+
+ </para>
+
+ <para>
+
+ Note that ignoring some of the arguments
+ in your custom &Decider; function
+ is a perfectly normal thing to do,
+ if they don't impact the way you want to
+ decide if the dependency file has changed.
+
+ </para>
+
</section>
<section>
- <title>File Contents</title>
+ <title>Mixing Different Ways of Deciding If a File Has Changed</title>
+
+ <para>
+
+ The previous examples have all demonstrated calling
+ the global &Decider; function
+ to configure all dependency decisions that &SCons; makes.
+ Sometimes, however, you want to be able to configure
+ different decision-making for different targets.
+ When that's necessary, you can use the
+ <function>env.Decider</function>
+ method to affect only the configuration
+ decisions for targets built with a
+ specific construction environment.
+
+ </para>
<para>
- Sometimes a source file can be changed
- in such a way that the contents of the
- rebuilt target file(s)
- will be exactly the same as the last time
- the file was built.
- If so, then any other target files
- that depend on such a built-but-not-changed target
- file actually need not be rebuilt.
- You can make &SCons;
- realize that it does not need to rebuild
- a dependent target file in this situation
- using the &TargetSignatures; function as follows:
+ For example, if we arbitrarily want to build
+ one program using MD5 checkums
+ and another use file modification times
+ from the same source
+ we might configure it this way:
</para>
<programlisting>
- Program('hello.c')
- TargetSignatures('content')
+ env1 = Environment(CPPPATH = ['.'])
+ env2 = env1.Clone()
+ env2.Decider('timestamp-match')
+ env1.Program('prog-MD5', 'program1.c')
+ env2.Program('prog-timestamp', 'program2.c')
</programlisting>
<para>
- So if, for example,
- a user were to only change a comment in a C file,
- then the rebuilt &hello_o; file
- would be exactly the same as the one previously built
- (assuming the compiler doesn't put any build-specific
- information in the object file).
- &SCons; would then realize that it would not
- need to rebuild the &hello; program as follows:
+ If both of the programs include the same
+ <filename>inc.h</filename> file,
+ then updating the modification time of
+ <filename>inc.h</filename>
+ (using the &touch; command)
+ will cause only <filename>prog-timestamp</filename>
+ to be rebuilt:
</para>
<screen>
- % <userinput>scons -Q hello</userinput>
- cc -o hello.o -c hello.c
- cc -o hello hello.o
- % <userinput>edit hello.c</userinput>
- [CHANGE A COMMENT IN hello.c]
- % <userinput>scons -Q hello</userinput>
- cc -o hello.o -c hello.c
- scons: `hello' is up to date.
+ % <userinput>scons -Q</userinput>
+ cc -o program1.o -c -I. program1.c
+ cc -o prog-MD5 program1.o
+ cc -o program2.o -c -I. program2.c
+ cc -o prog-timestamp program2.o
+ % <userinput>touch inc.h</userinput>
+ % <userinput>scons -Q</userinput>
+ cc -o program2.o -c -I. program2.c
+ cc -o prog-timestamp program2.o
</screen>
+ </section>
+
+ </section>
+
+ <section>
+ <title>Older Functions for Deciding When an Input File Has Changed</title>
+
+ <para>
+
+ &SCons; still supports two functions that used to be the
+ primary methods for configuring the
+ decision about whether or not an input file has changed.
+ Although they're not officially deprecated yet,
+ their use is discouraged,
+ mainly because they rely on a somewhat
+ confusing distinction between how
+ source files and target files are handled.
+ These functions are documented here mainly in case you
+ encounter them in existing &SConscript; files.
+
+ </para>
+
+ <section>
+ <title>The &SourceSignatures; Function</title>
+
+ <para>
+
+ The &SourceSignatures; function is fairly straightforward,
+ and supports two different argument values
+ to configure whether source file changes should be decided
+ using MD5 signatures:
+
+ </para>
+
+ <programlisting>
+ Program('hello.c')
+ SourceSignatures('MD5')
+ </programlisting>
+
+ <para>
+
+ Or using time stamps:
+
+ </para>
+
+ <programlisting>
+ Program('hello.c')
+ SourceSignatures('timestamp')
+ </programlisting>
+
<para>
- In essence, &SCons; has
- "short-circuited" any dependent builds
- when it realizes that a target file
- has been rebuilt to exactly the same file as the last build.
- So configured,
- &SCons; does take some extra processing time
- to scan the contents of the target (&hello_o;) file,
- but this may save time
- if the rebuild that was avoided
- would have been very time-consuming and expensive.
+ These are roughly equivalent to specifying
+ <function>Decider('MD5')</function>
+ or
+ <function>Decider('timestamp-match')</function>,
+ respectively,
+ although it only affects how SCons makes
+ decisions about dependencies on
+ <emphasis>source</emphasis> files--that is,
+ files that are not built from any other files.
+
+ </para>
+
+ </section>
+
+ <section>
+ <title>The &TargetSignatures; Function</title>
+
+ <para>
+
+ The &TargetSignatures; function
+ specifies how &SCons; decides
+ when a target file has changed
+ <emphasis>when it is used as a
+ dependency of (input to) another target</emphasis>--that is,
+ the &TargetSignatures; function configures
+ how the signatures of "intermediate" target files
+ are used when deciding if a "downstream" target file
+ must be rebuilt.
+ <footnote><para>
+ This easily-overlooked distinction between
+ how &SCons; decides if the target itself must be rebuilt
+ and how the target is then used to decide if a different
+ target must be rebuilt is one of the confusing
+ things that has led to the &TargetSignatures;
+ and &SourceSignatures; functions being
+ replaced by the simpler &Decider; function.
+ </para></footnote>
+
+ </para>
+
+ <para>
+
+ The &TargetSignatures; function supports the same
+ <literal>'MD5'</literal> and <literal>'timestamp'</literal>
+ argument values that are supported by the &SourceSignatures;,
+ with the same meanings, but applied to target files.
+ That is, in the example:
+
+ </para>
+
+ <programlisting>
+ Program('hello.c')
+ TargetSignatures('MD5')
+ </programlisting>
+
+ <para>
+
+ The MD5 checksum of the &hello_o; target file
+ will be used to decide if it has changed since the last
+ time the "downstream" &hello; target file was built.
+ And in the example:
+
+ </para>
+
+ <programlisting>
+ Program('hello.c')
+ TargetSignatures('timestamp')
+ </programlisting>
+
+ <para>
+
+ The modification time of the &hello_o; target file
+ will be used to decide if it has changed since the last
+ time the "downstream" &hello; target file was built.
+
+ </para>
+
+ <para>
+
+ The &TargetSignatures; function supports
+ two additional argument values:
+ <literal>'source'</literal> and <literal>'build'</literal>.
+ The <literal>'source'</literal> argument
+ specifies that decisions involving
+ whether target files have changed
+ since a previous build
+ should use the same behavior
+ for the decisions configured for source files
+ (using the &SourceSignatures; function).
+ So in the example:
+
+ </para>
+
+ <programlisting>
+ Program('hello.c')
+ TargetSignatures('source')
+ SourceSignatures('timestamp')
+ </programlisting>
+
+ <para>
+
+ All files, both targets and sources,
+ will use modification times
+ when deciding if an input file
+ has changed since the last
+ time a target was built.
+
+ </para>
+
+ <para>
+
+ Lastly, the <literal>'build'</literal> argument
+ specifies that &SCons; should examine
+ the build status of a target file
+ and always rebuild a "downstream" target
+ if the target file was itself rebuilt,
+ without re-examining the contents or timestamp
+ of the newly-built target file.
+ If the target file was not rebuilt during
+ this &scons; invocation,
+ then the target file will be examined
+ the same way as configured by
+ the &SourceSignature; call
+ to decide if it has changed.
+
+ </para>
+
+ <para>
+
+ This mimics the behavior of
+ <literal>build signatures</literal>
+ in earlier versions of &SCons;.
+ A &buildsignature; re-combined
+ signatures of all the input files
+ that went into making the target file,
+ so that the target file itself
+ did not need to have its contents read
+ to compute an MD5 signature.
+ This can improve performance for some configurations,
+ but is generally not as effective as using
+ <literal>Decider('MD5-timestamp')</literal>.
</para>
@@ -359,7 +787,7 @@
<para>
Now suppose that our "Hello, World!" program
- actually has a <literal>#include</literal> line
+ actually has an <literal>#include</literal> line
to include the &hello_h; file in the compilation:
</para>
@@ -458,7 +886,7 @@
the &cv-CPPPATH; variable
may be a list of directories,
or a string separated by
- the system-specific path separate character
+ the system-specific path separation character
(':' on POSIX/Linux, ';' on Windows).
Either way, &SCons; creates the
right command-line options
@@ -703,7 +1131,44 @@
</section>
<section>
- <title>Ignoring Dependencies: the &Ignore; Method</title>
+ <title>Explicit Dependencies: the &Depends; Function</title>
+
+ <para>
+
+ Sometimes a file depends on another file
+ that is not detected by an &SCons; scanner.
+ For this situation,
+ &SCons; allows you to specific explicitly that one file
+ depends on another file,
+ and must be rebuilt whenever that file changes.
+ This is specified using the &Depends; method:
+
+ </para>
+
+ <programlisting>
+ hello = Program('hello.c')
+ Depends(hello, 'other_file')
+ </programlisting>
+
+ <!-- XXX mention that you can use arrays for target and source? -->
+
+ <screen>
+ % <userinput>scons -Q hello</userinput>
+ cc -c hello.c -o hello.o
+ cc -o hello hello.o
+ % <userinput>scons -Q hello</userinput>
+ scons: `hello' is up to date.
+ % <userinput>edit other_file</userinput>
+ [CHANGE THE CONTENTS OF other_file]
+ % <userinput>scons -Q hello</userinput>
+ cc -c hello.c -o hello.o
+ cc -o hello hello.o
+ </screen>
+
+ </section>
+
+ <section>
+ <title>Ignoring Dependencies: the &Ignore; Function</title>
<para>
@@ -749,7 +1214,7 @@
Now, the above example is a little contrived,
because it's hard to imagine a real-world situation
- where you wouldn't to rebuild &hello;
+ where you wouldn't want to rebuild &hello;
if the &hello_h; file changed.
A more realistic example
might be if the &hello;
@@ -774,45 +1239,7 @@
</section>
<section>
- <title>Explicit Dependencies: the &Depends; Method</title>
-
- <para>
-
- On the other hand,
- sometimes a file depends on another file
- that is not detected by an &SCons; scanner.
- For this situation,
- &SCons; allows you to specific explicitly that one file
- depends on another file,
- and must be rebuilt whenever that file changes.
- This is specified using the &Depends; method:
-
- </para>
-
- <programlisting>
- hello = Program('hello.c')
- Depends(hello, 'other_file')
- </programlisting>
-
- <!-- XXX mention that you can use arrays for target and source? -->
-
- <screen>
- % <userinput>scons -Q hello</userinput>
- cc -c hello.c -o hello.o
- cc -o hello hello.o
- % <userinput>scons -Q hello</userinput>
- scons: `hello' is up to date.
- % <userinput>edit other_file</userinput>
- [CHANGE THE CONTENTS OF other_file]
- % <userinput>scons -Q hello</userinput>
- cc -c hello.c -o hello.o
- cc -o hello hello.o
- </screen>
-
- </section>
-
- <section>
- <title>The &AlwaysBuild; Method</title>
+ <title>The &AlwaysBuild; Function</title>
<para>
diff --git a/doc/user/environments.in b/doc/user/environments.in
index 504ef67..3fcec02 100644
--- a/doc/user/environments.in
+++ b/doc/user/environments.in
@@ -391,7 +391,7 @@ environment undisturbed.
enabled on the command line,
or different executable programs need to be linked
with different libraries.
- &SCons; accomodates these different build
+ &SCons; accommodates these different build
requirements by allowing you to create and
configure multiple &consenvs;
that control how the software is built.
@@ -416,7 +416,7 @@ environment undisturbed.
<para>
- By default, &SCons; intializes every
+ By default, &SCons; initializes every
new construction environment
with a set of &consvars;
based on the tools that it finds on your system,
@@ -845,7 +845,7 @@ environment undisturbed.
(Note that because we're not expanding this
in the context of building something
there are no target or source files
- for &cv-link-TARGET; and &cv-link-SOURCES; to expand.
+ for &cv-link-TARGET; and &cv-link-SOURCES; to expand.)
</para>
diff --git a/doc/user/environments.xml b/doc/user/environments.xml
index fbcef99..01ae2ed 100644
--- a/doc/user/environments.xml
+++ b/doc/user/environments.xml
@@ -391,7 +391,7 @@ environment undisturbed.
enabled on the command line,
or different executable programs need to be linked
with different libraries.
- &SCons; accomodates these different build
+ &SCons; accommodates these different build
requirements by allowing you to create and
configure multiple &consenvs;
that control how the software is built.
@@ -416,7 +416,7 @@ environment undisturbed.
<para>
- By default, &SCons; intializes every
+ By default, &SCons; initializes every
new construction environment
with a set of &consvars;
based on the tools that it finds on your system,
@@ -842,7 +842,7 @@ environment undisturbed.
(Note that because we're not expanding this
in the context of building something
there are no target or source files
- for &cv-link-TARGET; and &cv-link-SOURCES; to expand.
+ for &cv-link-TARGET; and &cv-link-SOURCES; to expand.)
</para>
diff --git a/doc/user/factories.in b/doc/user/factories.in
index d0c5313..222f02a 100644
--- a/doc/user/factories.in
+++ b/doc/user/factories.in
@@ -246,7 +246,7 @@
The &Move; factory
allows you to rename a file or directory.
For example, if we don't want to copy the temporary file,
- we could:
+ we could use:
</para>
@@ -334,7 +334,7 @@
a file in a temporary directory
in which the processing tool
will create other files that we don't care about,
- you could:
+ you could use:
</para>
diff --git a/doc/user/factories.xml b/doc/user/factories.xml
index 7c09e4b..6d0de02 100644
--- a/doc/user/factories.xml
+++ b/doc/user/factories.xml
@@ -224,7 +224,7 @@
The &Move; factory
allows you to rename a file or directory.
For example, if we don't want to copy the temporary file,
- we could:
+ we could use:
</para>
@@ -296,7 +296,7 @@
a file in a temporary directory
in which the processing tool
will create other files that we don't care about,
- you could:
+ you could use:
</para>
diff --git a/doc/user/file-removal.in b/doc/user/file-removal.in
index adc5b5f..1d1b604 100644
--- a/doc/user/file-removal.in
+++ b/doc/user/file-removal.in
@@ -101,7 +101,7 @@
By default, &SCons; removes all built targets when invoked
with the <literal>-c</literal> option to clean a source tree
- of built tragets.
+ of built targets.
Sometimes, however, this is not what you want.
For example, you may want to remove only intermediate generated files
(such as object files),
diff --git a/doc/user/file-removal.xml b/doc/user/file-removal.xml
index f64d394..bfec7ac 100644
--- a/doc/user/file-removal.xml
+++ b/doc/user/file-removal.xml
@@ -94,7 +94,7 @@
By default, &SCons; removes all built targets when invoked
with the <literal>-c</literal> option to clean a source tree
- of built tragets.
+ of built targets.
Sometimes, however, this is not what you want.
For example, you may want to remove only intermediate generated files
(such as object files),
diff --git a/doc/user/help.in b/doc/user/help.in
index 4356d18..5ab7e83 100644
--- a/doc/user/help.in
+++ b/doc/user/help.in
@@ -105,7 +105,7 @@
<para>
- Will display the completely help text on Windows:
+ Will display the complete help text on Windows:
</para>
diff --git a/doc/user/help.xml b/doc/user/help.xml
index ca44a40..ed2b5de 100644
--- a/doc/user/help.xml
+++ b/doc/user/help.xml
@@ -108,7 +108,7 @@
<para>
- Will display the completely help text on Windows:
+ Will display the complete help text on Windows:
</para>
diff --git a/doc/user/hierarchy.in b/doc/user/hierarchy.in
index e0d6b00..4286556 100644
--- a/doc/user/hierarchy.in
+++ b/doc/user/hierarchy.in
@@ -518,7 +518,7 @@ make no difference to the build.
so that it may be used by other &SConscript; files.
First, you can call the &Export;
function with a list of variables,
- or a string white-space separated variable names.
+ or a string of white-space separated variable names.
Each call to &Export; adds one
or more variables to a global list
of variables that are available for import
@@ -770,6 +770,10 @@ make no difference to the build.
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
+ <!--
+ XXX Return(stop=False)
+ -->
+
</section>
</section>
diff --git a/doc/user/hierarchy.xml b/doc/user/hierarchy.xml
index 4c84d5b..2e2941c 100644
--- a/doc/user/hierarchy.xml
+++ b/doc/user/hierarchy.xml
@@ -482,7 +482,7 @@ make no difference to the build.
so that it may be used by other &SConscript; files.
First, you can call the &Export;
function with a list of variables,
- or a string white-space separated variable names.
+ or a string of white-space separated variable names.
Each call to &Export; adds one
or more variables to a global list
of variables that are available for import
@@ -722,6 +722,10 @@ make no difference to the build.
ranlib libprog.a
</screen>
+ <!--
+ XXX Return(stop=False)
+ -->
+
</section>
</section>
diff --git a/doc/user/install.in b/doc/user/install.in
index ac9510f..ba179e7 100644
--- a/doc/user/install.in
+++ b/doc/user/install.in
@@ -209,7 +209,7 @@
you can either call the &InstallAs; function
multiple times, or as a shorthand,
you can supply same-length lists
- for the both the target and source arguments:
+ for both the target and source arguments:
</para>
diff --git a/doc/user/install.xml b/doc/user/install.xml
index 2a6d1b8..dd79153 100644
--- a/doc/user/install.xml
+++ b/doc/user/install.xml
@@ -201,7 +201,7 @@
you can either call the &InstallAs; function
multiple times, or as a shorthand,
you can supply same-length lists
- for the both the target and source arguments:
+ for both the target and source arguments:
</para>
diff --git a/doc/user/libraries.in b/doc/user/libraries.in
index 1ccb1c3..73ba6c9 100644
--- a/doc/user/libraries.in
+++ b/doc/user/libraries.in
@@ -251,6 +251,10 @@
the library will be found in the
&cv-link-LIBPATH; construction variable:
+ <!-- In the preceding paragraph, the "$" notation for
+ LIBS, LIBPATH etc. is used for the first time.
+ Maybe some words of explanation would be nice. -->
+
</para>
<scons_example name="ex2">
@@ -427,6 +431,8 @@
<scons_output example="ex3" os="win32">
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
+ <!-- The link command is too wide in the PDF version.
+ There are some other examples of this throughout the document. -->
<para>
diff --git a/doc/user/libraries.xml b/doc/user/libraries.xml
index 035ebd3..da7d835 100644
--- a/doc/user/libraries.xml
+++ b/doc/user/libraries.xml
@@ -235,6 +235,10 @@
the library will be found in the
&cv-link-LIBPATH; construction variable:
+ <!-- In the preceding paragraph, the "$" notation for
+ LIBS, LIBPATH etc. is used for the first time.
+ Maybe some words of explanation would be nice. -->
+
</para>
<programlisting>
@@ -409,6 +413,8 @@
cl /nologo /c prog.c /Foprog.obj
link /nologo /OUT:prog.exe /LIBPATH:\usr\lib /LIBPATH:\usr\local\lib m.lib prog.obj
</screen>
+ <!-- The link command is too wide in the PDF version.
+ There are some other examples of this throughout the document. -->
<para>
diff --git a/doc/user/main.in b/doc/user/main.in
index c3cf2c2..4095e6b 100644
--- a/doc/user/main.in
+++ b/doc/user/main.in
@@ -103,6 +103,7 @@
XXX GetBuildPath()
XXX GetLaunchDir()
+ XXX ParseConfig()
XXX MergeFlags()
XXX ParseFlags()
@@ -125,6 +126,20 @@
XXX GetOption('num_jobs')
XXX SetOption('num_jobs')
+ XXX Options.UnknownOption()
+
+ XXX GetBuildFailures()
+
+ XXX Requires()
+
+ XXX CheckTypeSize()
+
+ XXX Glob()
+
+ XXX Progress()
+
+ XXX AddMethod()
+
XXX - - diskcheck=
XXX site_scons
diff --git a/doc/user/main.xml b/doc/user/main.xml
index c3cf2c2..4095e6b 100644
--- a/doc/user/main.xml
+++ b/doc/user/main.xml
@@ -103,6 +103,7 @@
XXX GetBuildPath()
XXX GetLaunchDir()
+ XXX ParseConfig()
XXX MergeFlags()
XXX ParseFlags()
@@ -125,6 +126,20 @@
XXX GetOption('num_jobs')
XXX SetOption('num_jobs')
+ XXX Options.UnknownOption()
+
+ XXX GetBuildFailures()
+
+ XXX Requires()
+
+ XXX CheckTypeSize()
+
+ XXX Glob()
+
+ XXX Progress()
+
+ XXX AddMethod()
+
XXX - - diskcheck=
XXX site_scons
diff --git a/doc/user/parseconfig.in b/doc/user/parseconfig.in
index d3f563c..45b58cc 100644
--- a/doc/user/parseconfig.in
+++ b/doc/user/parseconfig.in
@@ -50,7 +50,7 @@
<scons_example name="ParseConfig1">
<file name="SConstruct" printme="1">
env = Environment()
- env.ParseConfig("pkg-config")
+ env.ParseConfig("pkg-config x11")
</file>
<file name="f1.c">
int f1() { }
diff --git a/doc/user/parseconfig.xml b/doc/user/parseconfig.xml
index 067ef37..25ea12c 100644
--- a/doc/user/parseconfig.xml
+++ b/doc/user/parseconfig.xml
@@ -49,7 +49,7 @@
<programlisting>
env = Environment()
- env.ParseConfig("pkg-config")
+ env.ParseConfig("pkg-config x11")
</programlisting>
<para>
@@ -62,7 +62,6 @@
<screen>
% <userinput>scons -Q</userinput>
scons: `.' is up to date.
- Must specify package names on the command line
</screen>
<para>
diff --git a/doc/user/repositories.in b/doc/user/repositories.in
index 9065593..d4ed418 100644
--- a/doc/user/repositories.in
+++ b/doc/user/repositories.in
@@ -487,8 +487,8 @@ coming into existence.)
Usually, this would be done by a build integrator
who would run &SCons; in the repository
to create all of its derived files and &sconsign; files,
- or who would &SCons; in a separate build directory
- and copying the resulting tree to the desired repository:
+ or who would run &SCons; in a separate build directory
+ and copy the resulting tree to the desired repository:
</para>
@@ -552,7 +552,7 @@ coming into existence.)
<para>
Notice that &SCons; realizes that it does not need to
- rebuild local copies file1.o and file2.o files,
+ rebuild local copies <filename>file1.o</filename> and <filename>file2.o</filename> files,
but instead uses the already-compiled files
from the repository.
diff --git a/doc/user/repositories.xml b/doc/user/repositories.xml
index f22611b..766d8bc 100644
--- a/doc/user/repositories.xml
+++ b/doc/user/repositories.xml
@@ -457,8 +457,8 @@ coming into existence.)
Usually, this would be done by a build integrator
who would run &SCons; in the repository
to create all of its derived files and &sconsign; files,
- or who would &SCons; in a separate build directory
- and copying the resulting tree to the desired repository:
+ or who would run &SCons; in a separate build directory
+ and copy the resulting tree to the desired repository:
</para>
@@ -511,7 +511,7 @@ coming into existence.)
<para>
Notice that &SCons; realizes that it does not need to
- rebuild local copies file1.o and file2.o files,
+ rebuild local copies <filename>file1.o</filename> and <filename>file2.o</filename> files,
but instead uses the already-compiled files
from the repository.
diff --git a/doc/user/sconf.in b/doc/user/sconf.in
index 0165ddd..265b720 100644
--- a/doc/user/sconf.in
+++ b/doc/user/sconf.in
@@ -124,7 +124,7 @@
Note that you can choose to terminate
the build if a given header file doesn't exist,
- or you can modify the contstruction environment
+ or you can modify the construction environment
based on the existence of a header file.
</para>
diff --git a/doc/user/sconf.xml b/doc/user/sconf.xml
index df530fe..163db3b 100644
--- a/doc/user/sconf.xml
+++ b/doc/user/sconf.xml
@@ -124,7 +124,7 @@
Note that you can choose to terminate
the build if a given header file doesn't exist,
- or you can modify the contstruction environment
+ or you can modify the construction environment
based on the existence of a header file.
</para>
diff --git a/doc/user/simple.in b/doc/user/simple.in
index b468f9a..3382f86 100644
--- a/doc/user/simple.in
+++ b/doc/user/simple.in
@@ -508,7 +508,7 @@
Because we want this User's Guide to focus
on what &SCons; is actually doing,
- we're going use the &Q; option
+ we're going to use the &Q; option
to remove these messages from the
output of all the remaining examples in this Guide.
diff --git a/doc/user/simple.xml b/doc/user/simple.xml
index c5ef430..4e4ff0e 100644
--- a/doc/user/simple.xml
+++ b/doc/user/simple.xml
@@ -542,7 +542,7 @@
Because we want this User's Guide to focus
on what &SCons; is actually doing,
- we're going use the &Q; option
+ we're going to use the &Q; option
to remove these messages from the
output of all the remaining examples in this Guide.
diff --git a/doc/user/sourcecode.xml b/doc/user/sourcecode.xml
index 6cb4162..1818d8e 100644
--- a/doc/user/sourcecode.xml
+++ b/doc/user/sourcecode.xml
@@ -50,7 +50,6 @@
<screen>
% <userinput>scons -Q</userinput>
- bk get -
bk get hello.c
cc -o hello.o -c hello.c
cc -o hello hello.o
@@ -75,7 +74,6 @@
<screen>
% <userinput>scons -Q</userinput>
- cvs -d /usr/local/CVS co -
cvs -d /usr/local/CVS co hello.c
cc -o hello.o -c hello.c
cc -o hello hello.o
@@ -100,7 +98,6 @@
<screen>
% <userinput>scons -Q</userinput>
- co -
co hello.c
cc -o hello.o -c hello.c
cc -o hello hello.o
@@ -125,7 +122,6 @@
<screen>
% <userinput>scons -Q</userinput>
- sccs get -
sccs get hello.c
cc -o hello.o -c hello.c
cc -o hello hello.o
diff --git a/doc/user/troubleshoot.in b/doc/user/troubleshoot.in
index 11f44dd..3e0bfdb 100644
--- a/doc/user/troubleshoot.in
+++ b/doc/user/troubleshoot.in
@@ -241,7 +241,7 @@
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 sit.
+ expect to be set.
In situations like this,
it's sometimes helpful to use the
construction environment &Dump; method
@@ -292,6 +292,10 @@
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.
</para>
diff --git a/doc/user/troubleshoot.xml b/doc/user/troubleshoot.xml
index 6ec6185..ca5ace8 100644
--- a/doc/user/troubleshoot.xml
+++ b/doc/user/troubleshoot.xml
@@ -232,7 +232,7 @@
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 sit.
+ expect to be set.
In situations like this,
it's sometimes helpful to use the
construction environment &Dump; method
@@ -261,7 +261,7 @@
<screen>
% <userinput>scons</userinput>
scons: Reading SConscript files ...
- { 'BUILDERS': {'InstallAs': &lt;function InstallAsBuilderWrapper at 0xb23a28&gt;, 'Install': &lt;function InstallBuilderWrapper at 0xb1b7d0&gt;},
+ { 'BUILDERS': {'InstallAs': &lt;function InstallAsBuilderWrapper at 0x700000&gt;, 'Install': &lt;function InstallBuilderWrapper at 0x700000&gt;},
'CONFIGUREDIR': '#/.sconf_temp',
'CONFIGURELOG': '#/config.log',
'CPPSUFFIXES': [ '.c',
@@ -284,13 +284,13 @@
'.spp',
'.SPP'],
'DSUFFIXES': ['.d'],
- 'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1eb48&gt;,
- 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1eb90&gt;,
+ 'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
+ 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
'ENV': {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'},
- 'ESCAPE': &lt;function escape at 0xb1fa28&gt;,
- 'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1ebd8&gt;,
+ 'ESCAPE': &lt;function escape at 0x700000&gt;,
+ 'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
'IDLSUFFIXES': ['.idl', '.IDL'],
- 'INSTALL': &lt;function copyFunc at 0xb23aa0&gt;,
+ 'INSTALL': &lt;function copyFunc at 0x700000&gt;,
'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'],
'LIBPREFIX': 'lib',
'LIBPREFIXES': '$LIBPREFIX',
@@ -302,16 +302,16 @@
'PLATFORM': 'posix',
'PROGPREFIX': '',
'PROGSUFFIX': '',
- 'PSPAWN': &lt;function piped_env_spawn at 0xb23230&gt;,
- 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1ec20&gt;,
+ 'PSPAWN': &lt;function piped_env_spawn at 0x700000&gt;,
+ 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
'SCANNERS': [],
'SHELL': 'sh',
'SHLIBPREFIX': '$LIBPREFIX',
'SHLIBSUFFIX': '.so',
'SHOBJPREFIX': '$OBJPREFIX',
'SHOBJSUFFIX': '$OBJSUFFIX',
- 'SPAWN': &lt;function spawnvpe_spawn at 0xb1f7d0&gt;,
- 'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0xa4e170&gt;,
+ 'SPAWN': &lt;function spawnvpe_spawn at 0x700000&gt;,
+ 'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
'TEMPFILEPREFIX': '@',
'TOOLS': ['install', 'install'],
'_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
@@ -319,9 +319,9 @@
'_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
'_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
'__RPATH': '$_RPATH',
- '_concat': &lt;function _concat at 0xa3d398&gt;,
- '_defines': &lt;function _defines at 0xa3d500&gt;,
- '_stripixes': &lt;function _stripixes at 0xa3d488&gt;}
+ '_concat': &lt;function _concat at 0x700000&gt;,
+ '_defines': &lt;function _defines at 0x700000&gt;,
+ '_stripixes': &lt;function _stripixes at 0x700000&gt;}
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
@@ -338,9 +338,9 @@
<screen>
C:\><userinput>scons</userinput>
scons: Reading SConscript files ...
- { 'BUILDERS': {'RES': &lt;SCons.Builder.BuilderBase instance at 0xb39518&gt;, 'Object': &lt;SCons.Builder.CompositeBuilder instance at 0xb4a710&gt;, 'InstallAs': &lt;function InstallAsBuilderWrapper at 0xb45c08&gt;, 'PCH': &lt;SCons.Builder.BuilderBase instance at 0xb1cef0&gt;, 'Install': &lt;function InstallBuilderWrapper at 0xb1b7d0&gt;, 'SharedObject': &lt;SCons.Builder.CompositeBuilder instance at 0xb4aa28&gt;, 'StaticObject': &lt;SCons.Builder.CompositeBuilder instance at 0xb4a710&gt;},
+ { 'BUILDERS': {'RES': &lt;SCons.Builder.BuilderBase instance at 0x700000&gt;, 'Object': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, 'InstallAs': &lt;function InstallAsBuilderWrapper at 0x700000&gt;, 'PCH': &lt;SCons.Builder.BuilderBase instance at 0x700000&gt;, 'Install': &lt;function InstallBuilderWrapper at 0x700000&gt;, 'SharedObject': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, 'StaticObject': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;},
'CC': 'cl',
- 'CCCOM': &lt;SCons.Action.FunctionAction instance at 0xb4c290&gt;,
+ 'CCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
'CCCOMFLAGS': '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS',
'CCFLAGS': ['/nologo'],
'CCPCHFLAGS': ['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'],
@@ -375,19 +375,19 @@
'CXXFILESUFFIX': '.cc',
'CXXFLAGS': ['$CCFLAGS', '$(', '/TP', '$)'],
'DSUFFIXES': ['.d'],
- 'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1eb48&gt;,
- 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1eb90&gt;,
+ 'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
+ 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
'ENV': { 'INCLUDE': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\include',
'LIB': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\lib',
'PATH': 'C:\\Program Files\\Microsoft Visual Studio\\Common\\tools\\WIN95;C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\bin;C:\\Program Files\\Microsoft Visual Studio\\Common\\tools;C:\\Program Files\\Microsoft Visual Studio/VC98\\bin',
'PATHEXT': '.COM;.EXE;.BAT;.CMD',
'SystemRoot': 'C:/WINDOWS'},
- 'ESCAPE': &lt;function escape at 0xb24848&gt;,
- 'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1ebd8&gt;,
+ 'ESCAPE': &lt;function escape at 0x700000&gt;,
+ 'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
'IDLSUFFIXES': ['.idl', '.IDL'],
'INCPREFIX': '/I',
'INCSUFFIX': '',
- 'INSTALL': &lt;function copyFunc at 0xb45c80&gt;,
+ 'INSTALL': &lt;function copyFunc at 0x700000&gt;,
'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'],
'LIBPREFIX': '',
'LIBPREFIXES': ['$LIBPREFIX'],
@@ -403,14 +403,14 @@
'PLATFORM': 'win32',
'PROGPREFIX': '',
'PROGSUFFIX': '.exe',
- 'PSPAWN': &lt;function piped_spawn at 0xb20488&gt;,
+ 'PSPAWN': &lt;function piped_spawn at 0x700000&gt;,
'RC': 'rc',
'RCCOM': '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES',
'RCFLAGS': [],
- 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0xa1ec20&gt;,
+ 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
'SCANNERS': [],
'SHCC': '$CC',
- 'SHCCCOM': &lt;SCons.Action.FunctionAction instance at 0xb4c320&gt;,
+ 'SHCCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
'SHCCFLAGS': ['$CCFLAGS'],
'SHCFLAGS': ['$CFLAGS'],
'SHCXX': '$CXX',
@@ -421,18 +421,18 @@
'SHLIBSUFFIX': '.dll',
'SHOBJPREFIX': '$OBJPREFIX',
'SHOBJSUFFIX': '$OBJSUFFIX',
- 'SPAWN': &lt;function spawn at 0xb247d0&gt;,
+ 'SPAWN': &lt;function spawn at 0x700000&gt;,
'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1,
- 'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0xa4e170&gt;,
+ 'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
'TEMPFILEPREFIX': '@',
'TOOLS': ['msvc', 'install', 'install'],
'_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
'_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
'_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
'_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
- '_concat': &lt;function _concat at 0xa3d398&gt;,
- '_defines': &lt;function _defines at 0xa3d500&gt;,
- '_stripixes': &lt;function _stripixes at 0xa3d488&gt;}
+ '_concat': &lt;function _concat at 0x700000&gt;,
+ '_defines': &lt;function _defines at 0x700000&gt;,
+ '_stripixes': &lt;function _stripixes at 0x700000&gt;}
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
@@ -447,6 +447,10 @@
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.
</para>
@@ -552,7 +556,6 @@
cc -o f3.o -c -I. f3.c
cc -o prog f1.o f2.o f3.o
+-.
- +--
+-SConstruct
+-f1.c
+-f1.o
@@ -659,31 +662,30 @@
H = no cache
[E b ]+-.
- [ ] +--
- [E ] +-SConstruct
- [E ] +-f1.c
+ [E C ] +-SConstruct
+ [E C ] +-f1.c
[E B C ] +-f1.o
- [E ] | +-f1.c
- [E ] | +-inc.h
- [E ] +-f2.c
+ [E C ] | +-f1.c
+ [E C ] | +-inc.h
+ [E C ] +-f2.c
[E B C ] +-f2.o
- [E ] | +-f2.c
- [E ] | +-inc.h
- [E ] +-f3.c
+ [E C ] | +-f2.c
+ [E C ] | +-inc.h
+ [E C ] +-f3.c
[E B C ] +-f3.o
- [E ] | +-f3.c
- [E ] | +-inc.h
- [E ] +-inc.h
+ [E C ] | +-f3.c
+ [E C ] | +-inc.h
+ [E C ] +-inc.h
[E B C ] +-prog
[E B C ] +-f1.o
- [E ] | +-f1.c
- [E ] | +-inc.h
+ [E C ] | +-f1.c
+ [E C ] | +-inc.h
[E B C ] +-f2.o
- [E ] | +-f2.c
- [E ] | +-inc.h
+ [E C ] | +-f2.c
+ [E C ] | +-inc.h
[E B C ] +-f3.o
- [E ] +-f3.c
- [E ] +-inc.h
+ [E C ] +-f3.c
+ [E C ] +-inc.h
</screen>
<para>
@@ -707,6 +709,13 @@
cc -o f3.o -c -I. f3.c
cc -o prog f1.o f2.o f3.o
+-.
+ +-f1.o
+ +-f2.o
+ +-f3.o
+ +-prog
+ +-f1.o
+ +-f2.o
+ +-f3.o
</screen>
<para>
@@ -790,7 +799,6 @@
cc -o prog2.o -c -I. prog2.c
cc -o prog2 prog2.o -L. -lfoo
+-.
- +--
+-SConstruct
+-f1.c
+-f1.o
@@ -883,7 +891,6 @@
cc -o prog2.o -c -I. prog2.c
cc -o prog2 prog2.o -L. -lfoo
+-.
- +--
+-SConstruct
+-f1.c
+-f1.o
@@ -1109,9 +1116,10 @@
scons: *** Source `prog.c' not found, needed by target `prog.o'. Stop.
scons: internal stack trace:
File "bootstrap/src/engine/SCons/Job.py", line 114, in start
+ File "bootstrap/src/engine/SCons/Script/Main.py", line 157, in prepare
File "bootstrap/src/engine/SCons/Taskmaster.py", line 169, in prepare
- File "bootstrap/src/engine/SCons/Node/FS.py", line 2220, in prepare
- File "bootstrap/src/engine/SCons/Node/__init__.py", line 819, in prepare
+ File "bootstrap/src/engine/SCons/Node/FS.py", line 2568, in prepare
+ File "bootstrap/src/engine/SCons/Node/__init__.py", line 349, in prepare
</screen>
<para>
@@ -1168,17 +1176,22 @@
% <userinput>scons -Q --taskmastertrace=- prog</userinput>
Taskmaster: 'prog': children:
['prog.o']
- waiting on unstarted children:
+ waiting on unfinished children:
['prog.o']
Taskmaster: 'prog.o': children:
['inc.h', 'prog.c']
+ waiting on unfinished children:
+ ['inc.h', 'prog.c']
+ Taskmaster: 'prog.c': evaluating prog.c
+ Taskmaster: 'inc.h': evaluating inc.h
+ Taskmaster: 'prog.o': children:
+ ['inc.h', 'prog.c']
evaluating prog.o
cc -o prog.o -c -I. prog.c
Taskmaster: 'prog': children:
['prog.o']
evaluating prog
cc -o prog prog.o
- Taskmaster: 'prog': already handled (executed)
</screen>
<para>