Merged revisions 2454-2525 via svnmerge from
[scons.git] / doc / user / depends.in
1 <!--
2
3   __COPYRIGHT__
4
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:
12
13   The above copyright notice and this permission notice shall be included
14   in all copies or substantial portions of the Software.
15
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.
23
24 -->
25
26   <para>
27
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:
36
37   </para>
38
39   <scons_example name="ex1">
40     <file name="SConstruct">
41     Program('hello.c')
42     </file>
43     <file name="hello.c">
44     int main() { printf("Hello, world!\n"); }
45     </file>
46   </scons_example>
47
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>
51   </scons_output>
52
53   <para>
54
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:
61
62   </para>
63
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>
67   </scons_output>
68
69   <para>
70
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.
74
75   </para>
76
77   <section>
78   <title>Deciding When an Input File Has Changed:  the &Decider; Function</title>
79
80     <para>
81
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.
87     By default,
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
91     &SCons; to use the
92     modification times (or time stamps)
93     instead.
94     You can even specify your own Python function
95     for deciding if an input file has changed.
96
97     </para>
98
99     <section>
100     <title>Using MD5 Signatures to Decide if a File Has Changed</title>
101
102       <para>
103
104       By default,
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):
113
114       </para>
115
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>
120       </scons_output>
121
122       <para>
123
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
128       need not be rebuilt.
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:
135
136       </para>
137
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>
142       </scons_output>
143
144       <para>
145
146       Note that you can, if you wish,
147       specify this default behavior
148       (MD5 signatures) explicitly
149       using the &Decider; function as follows:
150
151       </para>
152
153       <sconstruct>
154         Program('hello.c')
155         Decider('MD5')
156       </sconstruct>
157
158       <para>
159
160       You can also use the string <literal>'content'</literal>
161       as a synonym for <literal>'MD5'</literal>
162       when calling the &Decider; function.
163
164       </para>
165
166       <section>
167       <title>Ramifications of Using MD5 Signatures</title>
168
169         <para>
170
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
177         the file was built,
178         then any "downstream" target files
179         that depend on the rebuilt-but-not-changed target
180         file actually need not be rebuilt.
181
182         </para>
183
184         <para>
185
186         So if, for example,
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:
194
195         </para>
196
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>
201         </scons_output>
202
203         <para>
204
205         In essence, &SCons;
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.
213
214         </para>
215
216       </section>
217
218     </section>
219
220     <section>
221     <title>Using Time Stamps to Decide If a File Has Changed</title>
222
223       <para>
224
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.
232
233       </para>
234
235       <para>
236
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;
245       function as follows:
246
247       </para>
248
249       <scons_example name="newer">
250         <file name="SConstruct" printme="1">
251         Program('hello.c')
252         Decider('timestamp-newer')
253         </file>
254         <file name="hello.c">
255         int main() { printf("Hello, world!\n"); }
256         </file>
257       </scons_example>
258
259       <para>
260
261       This makes &SCons; act like &Make;
262       when a file's modification time is updated
263       (using the &touch; command, for example):
264
265       </para>
266
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>
271       </scons_output>
272
273       <para>
274
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:
280
281       </para>
282
283       <sconstruct>
284         Program('hello.c')
285         Decider('make')
286       </sconstruct>
287
288       <para>
289
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.
301
302       </para>
303
304       <para>
305
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:
315
316       </para>
317
318       <scons_example name="match">
319         <file name="SConstruct" printme="1">
320         Program('hello.c')
321         Decider('timestamp-match')
322         </file>
323         <file name="hello.c">
324         int main() { printf("Hello, world!\n"); }
325         </file>
326       </scons_example>
327
328       <para>
329
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:
337
338       </para>
339
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>
344       </scons_output>
345
346       <para>
347
348       In general, the only reason to prefer
349       <literal>timestamp-newer</literal>
350       instead of
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.
356
357       </para>
358
359     </section>
360
361     <section>
362     <title>Deciding If a File Has Changed Using Both MD Signatures and Time Stamps</title>
363
364       <para>
365
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>
373       argument as follows:
374
375       </para>
376
377       <scons_example name="MD5-timestamp">
378         <file name="SConstruct" printme="1">
379         Program('hello.c')
380         Decider('MD5-timestamp')
381         </file>
382         <file name="hello.c">
383         int main() { printf("Hello, world!\n"); }
384         </file>
385       </scons_example>
386
387       <para>
388
389       So configured, &SCons will still behave like
390       it does when using <literal>Decider('MD5')</literal>:
391
392       </para>
393
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>
400       </scons_output>
401
402       <para>
403
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.
411
412       </para>
413
414       <para>
415
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,
430       in which case use of
431       <literal>Decider('MD5-timestamp')</literal>
432       may not be appropriate.
433
434       </para>
435
436     </section>
437
438     <section>
439     <title>Writing Your Own Custom &Decider; Function</title>
440
441       <para>
442
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.
449       As it turns out,
450       you can also supply your own function
451       to decide if a dependency has changed.
452
453       </para>
454
455       <para>
456
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:
469
470       </para>
471
472       <scons_example name="function">
473         <file name="SConstruct" printme="1">
474         Program('hello.c')
475         def decide_if_changed(dependency, target, prev_ni):
476             if self.get_timestamp() != prev_ni.timestamp:
477                 dep = str(dependency)
478                 tgt = str(target)
479                 if specific_part_of_file_has_changed(dep, tgt):
480                     return True
481             return False
482         Decider(decide_if_changed)
483         </file>
484         <file name="hello.c">
485         int main() { printf("Hello, world!\n"); }
486         </file>
487       </scons_example>
488
489       <para>
490
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.
504
505       </para>
506
507       <para>
508
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.
514
515       </para>
516
517     </section>
518
519     <section>
520     <title>Mixing Different Ways of Deciding If a File Has Changed</title>
521
522       <para>
523
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.
534
535       </para>
536
537       <para>
538
539       For example, if we arbitrarily want to build
540       one program using MD5 checkums
541       and another use file modification times
542       from the same source
543       we might configure it this way:
544
545       </para>
546
547       <scons_example name="mixing">
548         <file name="SConstruct" printme="1">
549         env1 = Environment(CPPPATH = ['.'])
550         env2 = env1.Clone()
551         env2.Decider('timestamp-match')
552         env1.Program('prog-MD5', 'program1.c')
553         env2.Program('prog-timestamp', 'program2.c')
554         </file>
555         <file name="program1.c">
556         #include "inc.h"
557         int main() { printf("Hello, world!\n"); }
558         </file>
559         <file name="program2.c">
560         #include "inc.h"
561         int main() { printf("Hello, world!\n"); }
562         </file>
563         <file name="inc.h">
564         #define INC     1
565         </file>
566       </scons_example>
567
568       <para>
569
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>
576       to be rebuilt:
577
578       </para>
579
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>
584       </scons_output>
585
586     </section>
587
588   </section>
589
590   <section>
591   <title>Older Functions for Deciding When an Input File Has Changed</title>
592
593     <para>
594
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.
605
606     </para>
607   
608     <section>
609     <title>The &SourceSignatures; Function</title>
610
611       <para>
612
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:
617
618       </para>
619
620       <sconstruct>
621         Program('hello.c')
622         SourceSignatures('MD5')
623       </sconstruct>
624
625       <para>
626
627       Or using time stamps:
628
629       </para>
630
631       <sconstruct>
632         Program('hello.c')
633         SourceSignatures('timestamp')
634       </sconstruct>
635
636       <para>
637
638       These are roughly equivalent to specifying
639       <function>Decider('MD5')</function>
640       or
641       <function>Decider('timestamp-match')</function>,
642       respectively,
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.
647
648       </para>
649
650     </section>
651
652     <section>
653     <title>The &TargetSignatures; Function</title>
654
655       <para>
656
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
665       must be rebuilt.
666       <footnote><para>
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.
674       </para></footnote>
675
676       </para>
677
678       <para>
679
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:
685
686       </para>
687
688       <sconstruct>
689         Program('hello.c')
690         TargetSignatures('MD5')
691       </sconstruct>
692
693       <para>
694
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.
698       And in the example:
699       
700       </para>
701
702       <sconstruct>
703         Program('hello.c')
704         TargetSignatures('timestamp')
705       </sconstruct>
706
707       <para>
708
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.
712
713       </para>
714
715       <para>
716
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).
727       So in the example:
728
729       </para>
730
731       <sconstruct>
732         Program('hello.c')
733         TargetSignatures('source')
734         SourceSignatures('timestamp')
735       </sconstruct>
736
737       <para>
738
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.
744
745       </para>
746
747       <para>
748
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.
762
763       </para>
764
765       <para>
766
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>.
779
780       </para>
781
782     </section>
783
784   </section>
785
786   <section>
787   <title>Implicit Dependencies:  The &cv-CPPPATH; Construction Variable</title>
788
789     <para>
790
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:
794
795     </para>
796
797     <scons_example name="include">
798       <file name="SConstruct">
799        Program('hello.c', CPPPATH = '.')
800       </file>
801       <file name="hello.c" printme="1">
802        #include &lt;hello.h&gt;
803        int
804        main()
805        {
806            printf("Hello, %s!\n", string);
807        }
808       </file>
809       <file name="hello.h">
810        #define string    "world"
811       </file>
812     </scons_example>
813
814     <para>
815
816     And, for completeness, the &hello_h; file looks like this:
817
818     </para>
819
820     <scons_example_file example="include"  name="hello.h">
821     </scons_example_file>
822
823     <para>
824
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:
830
831     </para>
832
833     <scons_example_file example="include"  name="SConstruct">
834     </scons_example_file>
835
836     <para>
837
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:
844
845     </para>
846
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>
852     </scons_output>
853
854     <para>
855
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.
861
862     </para>
863
864     <para>
865
866     Second, realize that &SCons; knows that the &hello;
867     program must be rebuilt
868     because it scans the contents of
869     the &hello_c; file
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>
874     of the target file,
875     Consequently,
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.
880
881     </para>
882
883     <para>
884
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:
894
895     </para>
896
897     <scons_example name="ex5">
898       <file name="SConstruct" printme="1">
899        Program('hello.c', CPPPATH = ['include', '/home/project/inc'])
900       </file>
901       <file name="hello.c">
902       int main() { printf("Hello, world!\n"); }
903       </file>
904     </scons_example>
905
906     <para>
907
908     Will look like this on POSIX or Linux:
909
910     </para>
911
912     <scons_output example="ex5" os="posix">
913        <scons_output_command>scons -Q hello</scons_output_command>
914     </scons_output>
915
916     <para>
917
918     And like this on Windows:
919
920     </para>
921
922     <scons_output example="ex5" os="win32">
923        <scons_output_command>scons -Q hello.exe</scons_output_command>
924     </scons_output>
925
926   </section>
927
928   <section>
929   <title>Caching Implicit Dependencies</title>
930
931     <para>
932
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
943     first build command
944     (or decides that everything is up to date
945     and nothing must be rebuilt).
946
947  <!--
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.
954  -->
955
956     </para>
957
958     <para>
959
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:
973
974     </para>
975
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>
979     </scons_output>
980
981     <para>
982
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:
988
989     </para>
990
991     <sconstruct>
992        SetOption('implicit_cache', 1)
993     </sconstruct>
994
995     <para>
996
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
1003     following cases:
1004
1005
1006     </para>
1007
1008     <itemizedlist>
1009
1010       <listitem>
1011         <para>
1012
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.
1019
1020         </para>
1021       </listitem>
1022
1023       <listitem>
1024         <para>
1025
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
1029         last time.
1030
1031         </para>
1032       </listitem>
1033
1034     </itemizedlist>
1035
1036     <section>
1037     <title>The &implicit-deps-changed; Option</title>
1038
1039       <para>
1040
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.
1045       For example,
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:
1053
1054       </para>
1055
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>
1059       </scons_output>
1060
1061       <para>
1062
1063       In this case, &SCons; will re-scan all of the implicit dependencies
1064       and cache updated copies of the information.
1065
1066       </para>
1067
1068     </section>
1069
1070     <section>
1071     <title>The &implicit-deps-unchanged; Option</title>
1072
1073       <para>
1074
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.
1086       In this case,
1087       you can use the &implicit-deps-unchanged; option:
1088
1089       </para>
1090
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>
1094       </scons_output>
1095
1096       <para>
1097
1098       In this case,
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.
1107
1108       </para>
1109
1110     </section>
1111
1112     <!--
1113
1114     <section>
1115     <title>XXX max drift</title>
1116
1117       XXX SetOption('max_drift')
1118
1119     </section>
1120
1121     -->
1122
1123   </section>
1124
1125   <section>
1126   <title>Explicit Dependencies:  the &Depends; Function</title>
1127
1128     <para>
1129
1130     Sometimes a file depends on another file
1131     that is not detected by an &SCons; scanner.
1132     For this situation,
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:
1137
1138     </para>
1139
1140     <programlisting>
1141        hello = Program('hello.c')
1142        Depends(hello, 'other_file')
1143     </programlisting>
1144
1145     <!-- XXX mention that you can use arrays for target and source? -->
1146
1147     <screen>
1148        % <userinput>scons -Q hello</userinput>
1149        cc -c hello.c -o hello.o
1150        cc -o hello 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
1157        cc -o hello hello.o
1158     </screen>
1159
1160   </section>
1161
1162   <section>
1163   <title>Ignoring Dependencies:  the &Ignore; Function</title>
1164
1165     <para>
1166
1167     Sometimes it makes sense
1168     to not rebuild a program,
1169     even if a dependency file changes.
1170     In this case,
1171     you would tell &SCons; specifically
1172     to ignore a dependency as follows:
1173
1174     </para>
1175
1176     <scons_example name="ignore">
1177       <file name="SConstruct" printme="1">
1178       hello = Program('hello.c')
1179       Ignore(hello, 'hello.h')
1180       </file>
1181       <file name="hello.c">
1182       #include "hello.h"
1183       int main() { printf("Hello, %s!\n", string); }
1184       </file>
1185       <file name="hello.h">
1186       #define string    "world"
1187       </file>
1188     </scons_example>
1189
1190     <!-- XXX mention that you can use arrays for target and source? -->
1191
1192     <!--
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
1199     </scons_output>
1200     -->
1201
1202     <screen>
1203       % <userinput>scons -Q hello</userinput>
1204       cc -c -o hello.o hello.c
1205       cc -o hello hello.o
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.
1212     </screen>
1213
1214     <para>
1215
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.
1226     In that case,
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:
1232
1233     </para>
1234
1235     <programlisting>
1236        hello = Program('hello.c')
1237        Ignore(hello, '/usr/include/stdio.h')
1238     </programlisting>
1239
1240   </section>
1241
1242   <section>
1243   <title>The &AlwaysBuild; Function</title>
1244
1245     <para>
1246
1247     How &SCons; handles dependencies can also be affected
1248     by the &AlwaysBuild; method.
1249     When a file is passed to the &AlwaysBuild; method,
1250     like so:
1251
1252     </para>
1253
1254     <scons_example name="AlwaysBuild">
1255       <file name="SConstruct" printme="1">
1256       hello = Program('hello.c')
1257       AlwaysBuild(hello)
1258       </file>
1259       <file name="hello.c">
1260       int main() { printf("Hello, %s!\n", string); }
1261       </file>
1262     </scons_example>
1263
1264     <para>
1265
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:
1270
1271     </para>
1272
1273     <scons_output example="AlwaysBuild">
1274       <scons_output_command>scons -Q</scons_output_command>
1275       <scons_output_command>scons -Q</scons_output_command>
1276     </scons_output>
1277
1278     <para>
1279
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:
1292
1293     </para>
1294
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>
1298     </scons_output>
1299
1300     <!--
1301
1302       XXX AlwaysBuild() and Alias Nodes
1303
1304       XXX AlwaysBuild() and Dir Nodes
1305
1306       XXX AlwaysBuild() with no sources
1307
1308     -->
1309
1310   </section>
1311
1312   <!--
1313
1314   <section>
1315   <title>The &Salt; Method</title>
1316
1317     <para>
1318
1319     XXX Salt() (are we going to implement this ?)
1320
1321         original Cons classic POD documentation:
1322
1323 =head2 The C<Salt> method
1324
1325 The C<Salt> method adds a constant value to the signature calculation
1326 for every derived file.  It is invoked as follows:
1327
1328   Salt $string;
1329
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,
1333
1334   Salt `uname -s`;
1335
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
1338 -s>) changes.
1339
1340     </para>
1341
1342   </section>
1343
1344   -->