5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
13 The above copyright notice and this permission notice shall be included
14 in all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 So far we've seen how &SCons; handles one-time builds.
29 But one of the main functions of a build tool like &SCons;
30 is to rebuild only the necessary things
31 when source files change--or, put another way,
32 &SCons; should <emphasis>not</emphasis>
33 waste time rebuilding things that have already been built.
34 You can see this at work simply by re-invoking &SCons;
35 after building our simple &hello; example:
39 <scons_example name="ex1">
40 <file name="SConstruct">
44 int main() { printf("Hello, world!\n"); }
48 <scons_output example="ex1" os="posix">
49 <scons_output_command>scons -Q</scons_output_command>
50 <scons_output_command>scons -Q</scons_output_command>
55 The second time it is executed,
56 &SCons; realizes that the &hello; program
57 is up-to-date with respect to the current &hello_c; source file,
58 and avoids rebuilding it.
59 You can see this more clearly by naming
60 the &hello; program explicitly on the command line:
64 <scons_output example="ex1" os="posix">
65 <scons_output_command>scons -Q hello</scons_output_command>
66 <scons_output_command>scons -Q hello</scons_output_command>
71 Note that &SCons; reports <literal>"...is up to date"</literal>
72 only for target files named explicitly on the command line,
73 to avoid cluttering the output.
78 <title>Deciding When an Input File Has Changed: the &Decider; Function</title>
82 Another aspect of avoiding unnecessary rebuilds
83 is the fundamental build tool behavior
84 of <emphasis>rebuilding</emphasis>
85 things when an input file changes,
86 so that the built software is up to date.
88 &SCons; keeps track of this through an
89 MD5 &signature;, or checksum, of the contents of each file,
90 although you can easily configure
92 modification times (or time stamps)
94 You can even specify your own Python function
95 for deciding if an input file has changed.
100 <title>Using MD5 Signatures to Decide if a File Has Changed</title>
105 &SCons; keeps track of whether a file has changed
106 based on an MD5 checksum of the file's contents,
107 not the file's modification time.
108 This means that you may be surprised by the
109 default &SCons; behavior if you are used to the
110 &Make; convention of forcing
111 a rebuild by updating the file's modification time
112 (using the &touch; command, for example):
116 <scons_output example="ex1" os="posix">
117 <scons_output_command>scons -Q hello</scons_output_command>
118 <scons_output_command>touch hello.c</scons_output_command>
119 <scons_output_command>scons -Q hello</scons_output_command>
124 Even though the file's modification time has changed,
125 &SCons; realizes that the contents of the
126 &hello_c; file have <emphasis>not</emphasis> changed,
127 and therefore that the &hello; program
129 This avoids unnecessary rebuilds when,
130 for example, someone rewrites the
131 contents of a file without making a change.
132 But if the contents of the file really do change,
133 then &SCons; detects the change
134 and rebuilds the program as required:
138 <scons_output example="ex1" os="posix">
139 <scons_output_command>scons -Q hello</scons_output_command>
140 <scons_output_command output=" [CHANGE THE CONTENTS OF hello.c]">edit hello.c</scons_output_command>
141 <scons_output_command>scons -Q hello</scons_output_command>
146 Note that you can, if you wish,
147 specify this default behavior
148 (MD5 signatures) explicitly
149 using the &Decider; function as follows:
160 You can also use the string <literal>'content'</literal>
161 as a synonym for <literal>'MD5'</literal>
162 when calling the &Decider; function.
167 <title>Ramifications of Using MD5 Signatures</title>
171 Using MD5 Signatures to decide if an input file has changed
172 has one surprising benefit:
173 if a source file has been changed
174 in such a way that the contents of the
175 rebuilt target file(s)
176 will be exactly the same as the last time
178 then any "downstream" target files
179 that depend on the rebuilt-but-not-changed target
180 file actually need not be rebuilt.
187 a user were to only change a comment in a &hello_c; file,
188 then the rebuilt &hello_o; file
189 would be exactly the same as the one previously built
190 (assuming the compiler doesn't put any build-specific
191 information in the object file).
192 &SCons; would then realize that it would not
193 need to rebuild the &hello; program as follows:
197 <scons_output example="ex1" os="posix">
198 <scons_output_command>scons -Q hello</scons_output_command>
199 <scons_output_command output=" [CHANGE A COMMENT IN hello.c]" edit="STRIP CCCOM line">edit hello.c</scons_output_command>
200 <scons_output_command>scons -Q hello</scons_output_command>
206 "short-circuits" any dependent builds
207 when it realizes that a target file
208 has been rebuilt to exactly the same file as the last build.
209 This does take some extra processing time
210 to read the contents of the target (&hello_o;) file,
211 but often saves time when the rebuild that was avoided
212 would have been time-consuming and expensive.
221 <title>Using Time Stamps to Decide If a File Has Changed</title>
225 If you prefer, you can
226 configure &SCons; to use the modification time
227 of a file, not the file contents,
228 when deciding if a target needs to be rebuilt.
229 &SCons; gives you two ways to use time stamps
230 to decide if an input file has changed
231 since the last time a target has been built.
237 The most familiar way to use time stamps
238 is the way &Make; does:
239 that is, have &SCons; decide
240 and target must be rebuilt if
241 if a source file's modification time is
242 <emphasis>newer</emphasis>
243 than the target file.
244 To do this, call the &Decider;
249 <scons_example name="newer">
250 <file name="SConstruct" printme="1">
252 Decider('timestamp-newer')
254 <file name="hello.c">
255 int main() { printf("Hello, world!\n"); }
261 This makes &SCons; act like &Make;
262 when a file's modification time is updated
263 (using the &touch; command, for example):
267 <scons_output example="newer" os="posix">
268 <scons_output_command>scons -Q hello</scons_output_command>
269 <scons_output_command>touch hello.c</scons_output_command>
270 <scons_output_command>scons -Q hello</scons_output_command>
275 And, in fact, because this behavior is the same
276 as the behavior of &Make;,
277 you can also use the string <literal>'make'</literal>
278 as a synonym for <literal>'timestamp-newer'</literal>
279 when calling the &Decider; function:
290 One drawback to using times stamps exactly like &Make;
291 is that if an input file's modification time suddenly
292 becomes <emphasis>older</emphasis> than a target file,
293 the target file will not be rebuilt.
294 This can happen if an old copy of a source file is restored
295 from a backup archive, for example.
296 The contents of the restored file will likely be different
297 than they were the last time a dependent target was built,
298 but the target won't be rebuilt
299 because the modification time of the source file
300 is not newer than the target.
306 Because &SCons; actually stores information
307 about the source files' time stamps whenever a target is built,
308 it can handle this situation by checking for
309 an exact match of the source file time stamp,
310 instead of just whether or not the source file
311 is newer than the target file.
312 To do this, specify the argument
313 <literal>'timestamp-match'</literal>
314 when calling the &Decider; function:
318 <scons_example name="match">
319 <file name="SConstruct" printme="1">
321 Decider('timestamp-match')
323 <file name="hello.c">
324 int main() { printf("Hello, world!\n"); }
330 When configured this way,
331 &SCons; will rebuild a target whenever
332 a source file's modification time has changed.
333 So if we use the <literal>touch -t</literal>
334 option to change the modification time of
335 &hello_c; to an old date (January 1, 1989),
336 &SCons; will still rebuild the target file:
340 <scons_output example="match" os="posix">
341 <scons_output_command>scons -Q hello</scons_output_command>
342 <scons_output_command>touch -t 198901010000 hello.c</scons_output_command>
343 <scons_output_command>scons -Q hello</scons_output_command>
348 In general, the only reason to prefer
349 <literal>timestamp-newer</literal>
351 <literal>timestamp-match</literal>,
352 would be if you have some specific reason
353 to require this &Make;-like behavior of
354 not rebuilding a target when an otherwise-modified
355 source file is older.
362 <title>Deciding If a File Has Changed Using Both MD Signatures and Time Stamps</title>
366 As a performance enhancement,
367 &SCons; provides a way to use
368 MD5 checksums of file contents
369 but to only read the contents
370 whenever the file's timestamp has changed.
371 To do this, call the &Decider;
372 function with <literal>'MD5-timestamp'</literal>
377 <scons_example name="MD5-timestamp">
378 <file name="SConstruct" printme="1">
380 Decider('MD5-timestamp')
382 <file name="hello.c">
383 int main() { printf("Hello, world!\n"); }
389 So configured, &SCons will still behave like
390 it does when using <literal>Decider('MD5')</literal>:
394 <scons_output example="MD5-timestamp" os="posix">
395 <scons_output_command>scons -Q hello</scons_output_command>
396 <scons_output_command>touch hello.c</scons_output_command>
397 <scons_output_command>scons -Q hello</scons_output_command>
398 <scons_output_command output=" [CHANGE THE CONTENTS OF hello.c]">edit hello.c</scons_output_command>
399 <scons_output_command>scons -Q hello</scons_output_command>
404 However, the second call to &SCons; in the above output,
405 when the build is up-to-date,
406 will have been performed by simply looking at the
407 modification time of the &hello_c; file,
408 not by opening it and performing
409 an MD5 checksum calcuation on its contents.
410 This can significantly speed up many up-to-date builds.
416 The only drawback to using
417 <literal>Decider('MD5-timestamp')</literal>
418 is that &SCons; will <emphasis>not</emphasis>
419 rebuild a target file if a source file was modified
420 within one second of the last time &SCons; built the file.
421 While most developers are programming,
422 this isn't a problem in practice,
423 since it's unlikely that someone will have built
424 and then thought quickly enought to make a substantive
425 change to a source file within one second.
426 Certain build scripts or
427 continuous integration tools may, however,
428 rely on the ability to applying changes to files
429 automatically and then rebuild as quickly as possible,
431 <literal>Decider('MD5-timestamp')</literal>
432 may not be appropriate.
439 <title>Writing Your Own Custom &Decider; Function</title>
443 The different string values that we've passed to
444 the &Decider; function are essentially used by &SCons;
445 to pick one of several specific internal functions
446 that implement various ways of deciding if a dependency
447 (usually a source file)
448 has changed since a target file has been built.
450 you can also supply your own function
451 to decide if a dependency has changed.
457 For example, suppose we have an input file
458 that contains a lot of data,
459 in some specific regular format,
460 that is used to rebuild a lot of different target files,
461 but each target file really only depends on
462 one particular section of the input file.
463 We'd like to have each target file depend on
464 only its section of the input file.
465 However, since the input file may contain a lot of data,
466 we only want to open the input file if its timestamp has changed.
467 This could done with a custom
468 &Decider; function that might look something like this:
472 <scons_example name="function">
473 <file name="SConstruct" printme="1">
475 def decide_if_changed(dependency, target, prev_ni):
476 if self.get_timestamp() != prev_ni.timestamp:
477 dep = str(dependency)
479 if specific_part_of_file_has_changed(dep, tgt):
482 Decider(decide_if_changed)
484 <file name="hello.c">
485 int main() { printf("Hello, world!\n"); }
491 Note that in the function definition,
492 the <literal>dependency</literal>
493 (input file) is the first argument,
494 and then the <literal>target</literal>.
495 Both of these are passed to the functions as
496 SCons &Node; objects,
497 which we convert to strings using the Python
498 <function>str()</function>.
499 The third argument, <literal>prev_ni</literal>,
500 is an object that holds the
501 signature or timestamp information
502 that was recorded about the dependency
503 the last time the target was built.
509 Note that ignoring some of the arguments
510 in your custom &Decider; function
511 is a perfectly normal thing to do,
512 if they don't impact the way you want to
513 decide if the dependency file has changed.
520 <title>Mixing Different Ways of Deciding If a File Has Changed</title>
524 The previous examples have all demonstrated calling
525 the global &Decider; function
526 to configure all dependency decisions that &SCons; makes.
527 Sometimes, however, you want to be able to configure
528 different decision-making for different targets.
529 When that's necessary, you can use the
530 <function>env.Decider</function>
531 method to affect only the configuration
532 decisions for targets built with a
533 specific construction environment.
539 For example, if we arbitrarily want to build
540 one program using MD5 checkums
541 and another use file modification times
543 we might configure it this way:
547 <scons_example name="mixing">
548 <file name="SConstruct" printme="1">
549 env1 = Environment(CPPPATH = ['.'])
551 env2.Decider('timestamp-match')
552 env1.Program('prog-MD5', 'program1.c')
553 env2.Program('prog-timestamp', 'program2.c')
555 <file name="program1.c">
557 int main() { printf("Hello, world!\n"); }
559 <file name="program2.c">
561 int main() { printf("Hello, world!\n"); }
570 If both of the programs include the same
571 <filename>inc.h</filename> file,
572 then updating the modification time of
573 <filename>inc.h</filename>
574 (using the &touch; command)
575 will cause only <filename>prog-timestamp</filename>
580 <scons_output example="mixing" os="posix">
581 <scons_output_command>scons -Q</scons_output_command>
582 <scons_output_command>touch inc.h</scons_output_command>
583 <scons_output_command>scons -Q</scons_output_command>
591 <title>Older Functions for Deciding When an Input File Has Changed</title>
595 &SCons; still supports two functions that used to be the
596 primary methods for configuring the
597 decision about whether or not an input file has changed.
598 Although they're not officially deprecated yet,
599 their use is discouraged,
600 mainly because they rely on a somewhat
601 confusing distinction between how
602 source files and target files are handled.
603 These functions are documented here mainly in case you
604 encounter them in existing &SConscript; files.
609 <title>The &SourceSignatures; Function</title>
613 The &SourceSignatures; function is fairly straightforward,
614 and supports two different argument values
615 to configure whether source file changes should be decided
616 using MD5 signatures:
622 SourceSignatures('MD5')
627 Or using time stamps:
633 SourceSignatures('timestamp')
638 These are roughly equivalent to specifying
639 <function>Decider('MD5')</function>
641 <function>Decider('timestamp-match')</function>,
643 although it only affects how SCons makes
644 decisions about dependencies on
645 <emphasis>source</emphasis> files--that is,
646 files that are not built from any other files.
653 <title>The &TargetSignatures; Function</title>
657 The &TargetSignatures; function
658 specifies how &SCons; decides
659 when a target file has changed
660 <emphasis>when it is used as a
661 dependency of (input to) another target</emphasis>--that is,
662 the &TargetSignatures; function configures
663 how the signatures of "intermediate" target files
664 are used when deciding if a "downstream" target file
667 This easily-overlooked distinction between
668 how &SCons; decides if the target itself must be rebuilt
669 and how the target is then used to decide if a different
670 target must be rebuilt is one of the confusing
671 things that has led to the &TargetSignatures;
672 and &SourceSignatures; functions being
673 replaced by the simpler &Decider; function.
680 The &TargetSignatures; function supports the same
681 <literal>'MD5'</literal> and <literal>'timestamp'</literal>
682 argument values that are supported by the &SourceSignatures;,
683 with the same meanings, but applied to target files.
684 That is, in the example:
690 TargetSignatures('MD5')
695 The MD5 checksum of the &hello_o; target file
696 will be used to decide if it has changed since the last
697 time the "downstream" &hello; target file was built.
704 TargetSignatures('timestamp')
709 The modification time of the &hello_o; target file
710 will be used to decide if it has changed since the last
711 time the "downstream" &hello; target file was built.
717 The &TargetSignatures; function supports
718 two additional argument values:
719 <literal>'source'</literal> and <literal>'build'</literal>.
720 The <literal>'source'</literal> argument
721 specifies that decisions involving
722 whether target files have changed
723 since a previous build
724 should use the same behavior
725 for the decisions configured for source files
726 (using the &SourceSignatures; function).
733 TargetSignatures('source')
734 SourceSignatures('timestamp')
739 All files, both targets and sources,
740 will use modification times
741 when deciding if an input file
742 has changed since the last
743 time a target was built.
749 Lastly, the <literal>'build'</literal> argument
750 specifies that &SCons; should examine
751 the build status of a target file
752 and always rebuild a "downstream" target
753 if the target file was itself rebuilt,
754 without re-examining the contents or timestamp
755 of the newly-built target file.
756 If the target file was not rebuilt during
757 this &scons; invocation,
758 then the target file will be examined
759 the same way as configured by
760 the &SourceSignature; call
761 to decide if it has changed.
767 This mimics the behavior of
768 <literal>build signatures</literal>
769 in earlier versions of &SCons;.
770 A &buildsignature; re-combined
771 signatures of all the input files
772 that went into making the target file,
773 so that the target file itself
774 did not need to have its contents read
775 to compute an MD5 signature.
776 This can improve performance for some configurations,
777 but is generally not as effective as using
778 <literal>Decider('MD5-timestamp')</literal>.
787 <title>Implicit Dependencies: The &cv-CPPPATH; Construction Variable</title>
791 Now suppose that our "Hello, World!" program
792 actually has an <literal>#include</literal> line
793 to include the &hello_h; file in the compilation:
797 <scons_example name="include">
798 <file name="SConstruct">
799 Program('hello.c', CPPPATH = '.')
801 <file name="hello.c" printme="1">
802 #include <hello.h>
806 printf("Hello, %s!\n", string);
809 <file name="hello.h">
810 #define string "world"
816 And, for completeness, the &hello_h; file looks like this:
820 <scons_example_file example="include" name="hello.h">
821 </scons_example_file>
825 In this case, we want &SCons; to recognize that,
826 if the contents of the &hello_h; file change,
827 the &hello; program must be recompiled.
828 To do this, we need to modify the
829 &SConstruct; file like so:
833 <scons_example_file example="include" name="SConstruct">
834 </scons_example_file>
838 The &cv-link-CPPPATH; value
839 tells &SCons; to look in the current directory
840 (<literal>'.'</literal>)
841 for any files included by C source files
842 (<filename>.c</filename> or <filename>.h</filename> files).
843 With this assignment in the &SConstruct; file:
847 <scons_output example="include" os="posix">
848 <scons_output_command>scons -Q hello</scons_output_command>
849 <scons_output_command>scons -Q hello</scons_output_command>
850 <scons_output_command output=" [CHANGE THE CONTENTS OF hello.h]">edit hello.h</scons_output_command>
851 <scons_output_command>scons -Q hello</scons_output_command>
856 First, notice that &SCons;
857 added the <literal>-I.</literal> argument
858 from the &cv-CPPPATH; variable
859 so that the compilation would find the
860 &hello_h; file in the local directory.
866 Second, realize that &SCons; knows that the &hello;
867 program must be rebuilt
868 because it scans the contents of
870 for the <literal>#include</literal> lines that indicate
871 another file is being included in the compilation.
872 &SCons; records these as
873 <emphasis>implicit dependencies</emphasis>
876 when the &hello_h; file changes,
877 &SCons; realizes that the &hello_c; file includes it,
878 and rebuilds the resulting &hello; program
879 that depends on both the &hello_c; and &hello_h; files.
885 Like the &cv-link-LIBPATH; variable,
886 the &cv-CPPPATH; variable
887 may be a list of directories,
888 or a string separated by
889 the system-specific path separation character
890 (':' on POSIX/Linux, ';' on Windows).
891 Either way, &SCons; creates the
892 right command-line options
893 so that the following example:
897 <scons_example name="ex5">
898 <file name="SConstruct" printme="1">
899 Program('hello.c', CPPPATH = ['include', '/home/project/inc'])
901 <file name="hello.c">
902 int main() { printf("Hello, world!\n"); }
908 Will look like this on POSIX or Linux:
912 <scons_output example="ex5" os="posix">
913 <scons_output_command>scons -Q hello</scons_output_command>
918 And like this on Windows:
922 <scons_output example="ex5" os="win32">
923 <scons_output_command>scons -Q hello.exe</scons_output_command>
929 <title>Caching Implicit Dependencies</title>
933 Scanning each file for <literal>#include</literal> lines
934 does take some extra processing time.
935 When you're doing a full build of a large system,
936 the scanning time is usually a very small percentage
937 of the overall time spent on the build.
938 You're most likely to notice the scanning time,
939 however, when you <emphasis>rebuild</emphasis>
940 all or part of a large system:
941 &SCons; will likely take some extra time to "think about"
942 what must be built before it issues the
944 (or decides that everything is up to date
945 and nothing must be rebuilt).
948 Isn't this expensive? The answer is, it depends. If you do a full build of a
949 large system, the scanning time is insignificant. If you do a rebuild of a
950 large system, then Cons will spend a fair amount of time thinking about it
951 before it decides that nothing has to be done (although not necessarily more
952 time than make!). The good news is that Cons makes it very easy to
953 intelligently subset your build, when you are working on localized changes.
960 In practice, having &SCons; scan files saves time
961 relative to the amount of potential time
962 lost to tracking down subtle problems
963 introduced by incorrect dependencies.
964 Nevertheless, the "waiting time"
965 while &SCons; scans files can annoy
966 individual developers waiting for their builds to finish.
967 Consequently, &SCons; lets you cache
968 the implicit dependencies
969 that its scanners find,
970 for use by later builds.
971 You can do this by specifying the
972 &implicit-cache; option on the command line:
976 <scons_output example="ex1">
977 <scons_output_command>scons -Q --implicit-cache hello</scons_output_command>
978 <scons_output_command>scons -Q hello</scons_output_command>
983 If you don't want to specify &implicit-cache;
984 on the command line each time,
985 you can make it the default behavior for your build
986 by setting the &implicit_cache; option
987 in an &SConscript; file:
992 SetOption('implicit_cache', 1)
997 &SCons; does not cache implicit dependencies like this by default
998 because the &implicit-cache; causes &SCons; to simply use the implicit
999 dependencies stored during the last run, without any checking
1000 for whether or not those dependencies are still correct.
1001 Specifically, this means &implicit-cache; instructs &SCons;
1002 to <emphasis>not</emphasis> rebuild "correctly" in the
1013 When &implicit-cache; is used, &SCons; will ignore any changes that
1014 may have been made to search paths
1015 (like &cv-CPPPATH; or &cv-LIBPATH;,).
1016 This can lead to &SCons; not rebuilding a file if a change to
1017 &cv-CPPPATH; would normally cause a different, same-named file from
1018 a different directory to be used.
1026 When &implicit-cache; is used, &SCons; will not detect if a
1027 same-named file has been added to a directory that is earlier in
1028 the search path than the directory in which the file was found
1037 <title>The &implicit-deps-changed; Option</title>
1041 When using cached implicit dependencies,
1042 sometimes you want to "start fresh"
1043 and have &SCons; re-scan the files
1044 for which it previously cached the dependencies.
1046 if you have recently installed a new version of
1047 external code that you use for compilation,
1048 the external header files will have changed
1049 and the previously-cached implicit dependencies
1050 will be out of date.
1051 You can update them by
1052 running &SCons; with the &implicit-deps-changed; option:
1056 <scons_output example="ex1">
1057 <scons_output_command>scons -Q --implicit-deps-changed hello</scons_output_command>
1058 <scons_output_command>scons -Q hello</scons_output_command>
1063 In this case, &SCons; will re-scan all of the implicit dependencies
1064 and cache updated copies of the information.
1071 <title>The &implicit-deps-unchanged; Option</title>
1075 By default when caching dependencies,
1076 &SCons; notices when a file has been modified
1077 and re-scans the file for any updated
1078 implicit dependency information.
1079 Sometimes, however, you may want
1080 to force &SCons; to use the cached implicit dependencies,
1081 even if the source files changed.
1082 This can speed up a build for example,
1083 when you have changed your source files
1084 but know that you haven't changed
1085 any <literal>#include</literal> lines.
1087 you can use the &implicit-deps-unchanged; option:
1091 <scons_output example="ex1">
1092 <scons_output_command>scons -Q --implicit-deps-unchanged hello</scons_output_command>
1093 <scons_output_command>scons -Q hello</scons_output_command>
1099 &SCons; will assume that the cached implicit
1100 dependencies are correct and
1101 will not bother to re-scan changed files.
1102 For typical builds after small,
1103 incremental changes to source files,
1104 the savings may not be very big,
1105 but sometimes every bit of
1106 improved performance counts.
1115 <title>XXX max drift</title>
1117 XXX SetOption('max_drift')
1126 <title>Explicit Dependencies: the &Depends; Function</title>
1130 Sometimes a file depends on another file
1131 that is not detected by an &SCons; scanner.
1133 &SCons; allows you to specific explicitly that one file
1134 depends on another file,
1135 and must be rebuilt whenever that file changes.
1136 This is specified using the &Depends; method:
1141 hello = Program('hello.c')
1142 Depends(hello, 'other_file')
1145 <!-- XXX mention that you can use arrays for target and source? -->
1148 % <userinput>scons -Q hello</userinput>
1149 cc -c hello.c -o hello.o
1151 % <userinput>scons -Q hello</userinput>
1152 scons: `hello' is up to date.
1153 % <userinput>edit other_file</userinput>
1154 [CHANGE THE CONTENTS OF other_file]
1155 % <userinput>scons -Q hello</userinput>
1156 cc -c hello.c -o hello.o
1163 <title>Ignoring Dependencies: the &Ignore; Function</title>
1167 Sometimes it makes sense
1168 to not rebuild a program,
1169 even if a dependency file changes.
1171 you would tell &SCons; specifically
1172 to ignore a dependency as follows:
1176 <scons_example name="ignore">
1177 <file name="SConstruct" printme="1">
1178 hello = Program('hello.c')
1179 Ignore(hello, 'hello.h')
1181 <file name="hello.c">
1183 int main() { printf("Hello, %s!\n", string); }
1185 <file name="hello.h">
1186 #define string "world"
1190 <!-- XXX mention that you can use arrays for target and source? -->
1193 <scons_output example="ignore">
1194 <scons_output_command>scons -Q hello</scons_output_command>
1195 <scons_output_command>scons -Q hello</scons_output_command>
1196 <scons_output_command output=" [CHANGE THE CONTENTS OF hello.h]">edit hello.h</scons_output_command>
1197 <scons_output_command>scons -Q hello</scons_output_command>
1198 XXX THIS EXAMPLE SHOULD BE UP-TO-DATE! XXX
1203 % <userinput>scons -Q hello</userinput>
1204 cc -c -o hello.o hello.c
1206 % <userinput>scons -Q hello</userinput>
1207 scons: `hello' is up to date.
1208 % <userinput>edit hello.h</userinput>
1209 [CHANGE THE CONTENTS OF hello.h]
1210 % <userinput>scons -Q hello</userinput>
1211 scons: `hello' is up to date.
1216 Now, the above example is a little contrived,
1217 because it's hard to imagine a real-world situation
1218 where you wouldn't want to rebuild &hello;
1219 if the &hello_h; file changed.
1220 A more realistic example
1221 might be if the &hello;
1222 program is being built in a
1223 directory that is shared between multiple systems
1224 that have different copies of the
1225 &stdio_h; include file.
1227 &SCons; would notice the differences between
1228 the different systems' copies of &stdio_h;
1229 and would rebuild &hello;
1230 each time you change systems.
1231 You could avoid these rebuilds as follows:
1236 hello = Program('hello.c')
1237 Ignore(hello, '/usr/include/stdio.h')
1243 <title>The &AlwaysBuild; Function</title>
1247 How &SCons; handles dependencies can also be affected
1248 by the &AlwaysBuild; method.
1249 When a file is passed to the &AlwaysBuild; method,
1254 <scons_example name="AlwaysBuild">
1255 <file name="SConstruct" printme="1">
1256 hello = Program('hello.c')
1259 <file name="hello.c">
1260 int main() { printf("Hello, %s!\n", string); }
1266 Then the specified target file (&hello; in our example)
1267 will always be considered out-of-date and
1268 rebuilt whenever that target file is evaluated
1269 while walking the dependency graph:
1273 <scons_output example="AlwaysBuild">
1274 <scons_output_command>scons -Q</scons_output_command>
1275 <scons_output_command>scons -Q</scons_output_command>
1280 The &AlwaysBuild; function has a somewhat misleading name,
1281 because it does not actually mean the target file will
1282 be rebuilt every single time &SCons; is invoked.
1283 Instead, it means that the target will, in fact,
1284 be rebuilt whenever the target file is encountered
1285 while evaluating the targets specified on
1286 the command line (and their dependencies).
1287 So specifying some other target on the command line,
1288 a target that does <emphasis>not</emphasis>
1289 itself depend on the &AlwaysBuild; target,
1290 will still be rebuilt only if it's out-of-date
1291 with respect to its dependencies:
1295 <scons_output example="AlwaysBuild">
1296 <scons_output_command>scons -Q</scons_output_command>
1297 <scons_output_command>scons -Q hello.o</scons_output_command>
1302 XXX AlwaysBuild() and Alias Nodes
1304 XXX AlwaysBuild() and Dir Nodes
1306 XXX AlwaysBuild() with no sources
1315 <title>The &Salt; Method</title>
1319 XXX Salt() (are we going to implement this ?)
1321 original Cons classic POD documentation:
1323 =head2 The C<Salt> method
1325 The C<Salt> method adds a constant value to the signature calculation
1326 for every derived file. It is invoked as follows:
1330 Changing the Salt value will force a complete rebuild of every derived
1331 file. This can be used to force rebuilds in certain desired
1332 circumstances. For example,
1336 Would force a complete rebuild of every derived file whenever the
1337 operating system on which the build is performed (as reported by C<uname