diff options
Diffstat (limited to 'doc/user')
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': <function InstallAsBuilderWrapper at 0xb23a28>, 'Install': <function InstallBuilderWrapper at 0xb1b7d0>}, + { 'BUILDERS': {'InstallAs': <function InstallAsBuilderWrapper at 0x700000>, 'Install': <function InstallBuilderWrapper at 0x700000>}, 'CONFIGUREDIR': '#/.sconf_temp', 'CONFIGURELOG': '#/config.log', 'CPPSUFFIXES': [ '.c', @@ -284,13 +284,13 @@ '.spp', '.SPP'], 'DSUFFIXES': ['.d'], - 'Dir': <SCons.Defaults.Variable_Method_Caller instance at 0xa1eb48>, - 'Dirs': <SCons.Defaults.Variable_Method_Caller instance at 0xa1eb90>, + 'Dir': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, 'ENV': {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}, - 'ESCAPE': <function escape at 0xb1fa28>, - 'File': <SCons.Defaults.Variable_Method_Caller instance at 0xa1ebd8>, + 'ESCAPE': <function escape at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, 'IDLSUFFIXES': ['.idl', '.IDL'], - 'INSTALL': <function copyFunc at 0xb23aa0>, + 'INSTALL': <function copyFunc at 0x700000>, 'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'], 'LIBPREFIX': 'lib', 'LIBPREFIXES': '$LIBPREFIX', @@ -302,16 +302,16 @@ 'PLATFORM': 'posix', 'PROGPREFIX': '', 'PROGSUFFIX': '', - 'PSPAWN': <function piped_env_spawn at 0xb23230>, - 'RDirs': <SCons.Defaults.Variable_Method_Caller instance at 0xa1ec20>, + 'PSPAWN': <function piped_env_spawn at 0x700000>, + 'RDirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, 'SCANNERS': [], 'SHELL': 'sh', 'SHLIBPREFIX': '$LIBPREFIX', 'SHLIBSUFFIX': '.so', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function spawnvpe_spawn at 0xb1f7d0>, - 'TEMPFILE': <class SCons.Platform.TempFileMunge at 0xa4e170>, + 'SPAWN': <function spawnvpe_spawn at 0x700000>, + 'TEMPFILE': <class SCons.Platform.TempFileMunge at 0x700000>, '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': <function _concat at 0xa3d398>, - '_defines': <function _defines at 0xa3d500>, - '_stripixes': <function _stripixes at 0xa3d488>} + '_concat': <function _concat at 0x700000>, + '_defines': <function _defines at 0x700000>, + '_stripixes': <function _stripixes at 0x700000>} 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': <SCons.Builder.BuilderBase instance at 0xb39518>, 'Object': <SCons.Builder.CompositeBuilder instance at 0xb4a710>, 'InstallAs': <function InstallAsBuilderWrapper at 0xb45c08>, 'PCH': <SCons.Builder.BuilderBase instance at 0xb1cef0>, 'Install': <function InstallBuilderWrapper at 0xb1b7d0>, 'SharedObject': <SCons.Builder.CompositeBuilder instance at 0xb4aa28>, 'StaticObject': <SCons.Builder.CompositeBuilder instance at 0xb4a710>}, + { 'BUILDERS': {'RES': <SCons.Builder.BuilderBase instance at 0x700000>, 'Object': <SCons.Builder.CompositeBuilder instance at 0x700000>, 'InstallAs': <function InstallAsBuilderWrapper at 0x700000>, 'PCH': <SCons.Builder.BuilderBase instance at 0x700000>, 'Install': <function InstallBuilderWrapper at 0x700000>, 'SharedObject': <SCons.Builder.CompositeBuilder instance at 0x700000>, 'StaticObject': <SCons.Builder.CompositeBuilder instance at 0x700000>}, 'CC': 'cl', - 'CCCOM': <SCons.Action.FunctionAction instance at 0xb4c290>, + 'CCCOM': <SCons.Action.FunctionAction instance at 0x700000>, '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': <SCons.Defaults.Variable_Method_Caller instance at 0xa1eb48>, - 'Dirs': <SCons.Defaults.Variable_Method_Caller instance at 0xa1eb90>, + 'Dir': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, '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': <function escape at 0xb24848>, - 'File': <SCons.Defaults.Variable_Method_Caller instance at 0xa1ebd8>, + 'ESCAPE': <function escape at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, 'IDLSUFFIXES': ['.idl', '.IDL'], 'INCPREFIX': '/I', 'INCSUFFIX': '', - 'INSTALL': <function copyFunc at 0xb45c80>, + 'INSTALL': <function copyFunc at 0x700000>, 'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'], 'LIBPREFIX': '', 'LIBPREFIXES': ['$LIBPREFIX'], @@ -403,14 +403,14 @@ 'PLATFORM': 'win32', 'PROGPREFIX': '', 'PROGSUFFIX': '.exe', - 'PSPAWN': <function piped_spawn at 0xb20488>, + 'PSPAWN': <function piped_spawn at 0x700000>, 'RC': 'rc', 'RCCOM': '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES', 'RCFLAGS': [], - 'RDirs': <SCons.Defaults.Variable_Method_Caller instance at 0xa1ec20>, + 'RDirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, 'SCANNERS': [], 'SHCC': '$CC', - 'SHCCCOM': <SCons.Action.FunctionAction instance at 0xb4c320>, + 'SHCCCOM': <SCons.Action.FunctionAction instance at 0x700000>, 'SHCCFLAGS': ['$CCFLAGS'], 'SHCFLAGS': ['$CFLAGS'], 'SHCXX': '$CXX', @@ -421,18 +421,18 @@ 'SHLIBSUFFIX': '.dll', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function spawn at 0xb247d0>, + 'SPAWN': <function spawn at 0x700000>, 'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1, - 'TEMPFILE': <class SCons.Platform.TempFileMunge at 0xa4e170>, + 'TEMPFILE': <class SCons.Platform.TempFileMunge at 0x700000>, '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': <function _concat at 0xa3d398>, - '_defines': <function _defines at 0xa3d500>, - '_stripixes': <function _stripixes at 0xa3d488>} + '_concat': <function _concat at 0x700000>, + '_defines': <function _defines at 0x700000>, + '_stripixes': <function _stripixes at 0x700000>} 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> |