Accumulated documentation changes.
[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 <!--
27
28 =head2 The C<Salt> method
29
30 The C<Salt> method adds a constant value to the signature calculation
31 for every derived file.  It is invoked as follows:
32
33   Salt $string;
34
35 Changing the Salt value will force a complete rebuild of every derived
36 file.  This can be used to force rebuilds in certain desired
37 circumstances.  For example,
38
39   Salt `uname -s`;
40
41 Would force a complete rebuild of every derived file whenever the
42 operating system on which the build is performed (as reported by C<uname
43 -s>) changes.
44
45 -->
46
47   <para>
48
49   So far we've seen how &SCons; handles one-time builds.
50   But the real point of a build tool like &SCons;
51   is to rebuild only the necessary things
52   when source files change--or, put another way,
53   &SCons; should <emphasis>not</emphasis>
54   waste time rebuilding things that have already been built.
55   You can see this at work simply be re-invoking &SCons;
56   after building our simple &hello; example:
57
58   </para>
59
60   <scons_example name="ex1">
61     <file name="SConstruct">
62     Program('hello.c')
63     </file>
64     <file name="hello.c">
65     int main() { printf("Hello, world!\n"); }
66     </file>
67   </scons_example>
68
69   <scons_output example="ex1" os="posix">
70      <scons_output_command>scons -Q</scons_output_command>
71      <scons_output_command>scons -Q</scons_output_command>
72   </scons_output>
73
74   <para>
75
76   The second time it is executed,
77   &SCons; realizes that the &hello; program
78   is up-to-date with respect to the current &hello_c; source file,
79   and avoids rebuilding it.
80   You can see this more clearly by naming
81   the &hello; program explicitly on the command line:
82
83   </para>
84
85   <scons_output example="ex1" os="posix">
86      <scons_output_command>scons -Q hello</scons_output_command>
87      <scons_output_command>scons -Q hello</scons_output_command>
88   </scons_output>
89
90   <para>
91
92   Note that &SCons; reports <literal>"...is up to date"</literal>
93   only for target files named explicitly on the command line,
94   to avoid cluttering the output.
95
96   </para>
97
98   <section>
99   <title>Deciding When a Source File Has Changed:  the &SourceSignatures; Function</title>
100
101     <para>
102
103     The other side of avoiding unnecessary rebuilds
104     is the fundamental build tool behavior
105     of <emphasis>rebuilding</emphasis>
106     things when a source file changes,
107     so that the built software is up to date.
108     &SCons; keeps track of this through a
109     &signature; for each source file,
110     and allows you to configure
111     whether you want to use the source
112     file contents or the modification time (timestamp)
113     as the signature.
114
115     </para>
116
117     <section>
118     <title>MD5 Source File Signatures</title>
119
120       <para>
121
122       By default,
123       &SCons; keeps track of whether a source file has changed
124       based on the file's contents,
125       not the modification time.
126       This means that you may be surprised by the
127       default &SCons; behavior if you are used to the
128       &Make; convention of forcing
129       a rebuild by updating the file's modification time
130       (using the &touch; command, for example):
131
132       </para>
133
134       <scons_output example="ex1" os="posix">
135          <scons_output_command>scons -Q hello</scons_output_command>
136          <scons_output_command>touch hello.c</scons_output_command>
137          <scons_output_command>scons -Q hello</scons_output_command>
138       </scons_output>
139
140       <para>
141
142       Even though the file's modification time has changed,
143       &SCons; realizes that the contents of the
144       &hello_c; file have <emphasis>not</emphasis> changed,
145       and therefore that the &hello; program
146       need not be rebuilt.
147       This avoids unnecessary rebuilds when,
148       for example, someone rewrites the
149       contents of a file without making a change.
150       But if the contents of the file really do change,
151       then &SCons; detects the change
152       and rebuilds the program as required:
153
154       </para>
155
156       <scons_output example="ex1" os="posix">
157          <scons_output_command>scons -Q hello</scons_output_command>
158          <scons_output_command output="    [CHANGE THE CONTENTS OF hello.c]">edit hello.c</scons_output_command>
159          <scons_output_command>scons -Q hello</scons_output_command>
160       </scons_output>
161
162       <para>
163
164       Note that you can, if you wish,
165       specify this default behavior
166       (MD5 signatures) explicitly
167       using the &SourceSignatures; function as follows:
168
169       </para>
170
171       <sconstruct>
172         Program('hello.c')
173         SourceSignatures('MD5')
174       </sconstruct>
175
176     </section>
177
178     <section>
179     <title>Source File Time Stamps</title>
180
181       <para>
182
183       If you prefer, you can
184       configure &SCons; to use the modification time
185       of source files,
186       not the file contents,
187       when deciding if something needs to be rebuilt.
188       To do this, call the &SourceSignatures;
189       function as follows:
190
191       </para>
192
193       <scons_example name="ex2">
194         <file name="SConstruct" printme="1">
195         Program('hello.c')
196         SourceSignatures('timestamp')
197         </file>
198         <file name="hello.c">
199         int main() { printf("Hello, world!\n"); }
200         </file>
201       </scons_example>
202
203       <para>
204
205       This makes &SCons; act like &Make;
206       when a file's modification time is updated
207       (using the &touch; command, for example):
208
209       </para>
210
211       <scons_output example="ex2" os="posix">
212          <scons_output_command>scons -Q hello</scons_output_command>
213          <scons_output_command>touch hello.c</scons_output_command>
214          <scons_output_command>scons -Q hello</scons_output_command>
215       </scons_output>
216
217     </section>
218
219   </section>
220
221   <section>
222   <title>Deciding When a Target File Has Changed:  the &TargetSignatures; Function</title>
223
224     <para>
225
226     As you've just seen,
227     &SCons; uses signatures to decide whether a 
228     target file is up to date or must be rebuilt.
229     When a target file depends on another target file,
230     &SCons; allows you to configure separately
231     how the signatures of "intermediate" target files
232     are used when deciding if a dependent target file
233     must be rebuilt.
234
235     </para>
236
237     <section>
238     <title>Build Signatures</title>
239
240       <para>
241
242       Modifying a source file
243       will cause not only its direct target file to be rebuilt,
244       but also the target file(s)
245       that depend on that direct target file.
246       In our example,
247       changing the contents of the &hello_c; file causes
248       the &hello_o; file to be rebuilt,
249       which in turn causes the
250       &hello; program to be rebuilt:
251
252       </para>
253
254       <scons_output example="ex1" os="posix">
255          <scons_output_command>scons -Q hello</scons_output_command>
256          <scons_output_command output="    [CHANGE THE CONTENTS OF hello.c]">edit hello.c</scons_output_command>
257          <scons_output_command>scons -Q hello</scons_output_command>
258       </scons_output>
259
260       <para>
261
262       What's not obvious, though,
263       is that &SCons; internally handles the signature of
264       the target file(s)
265       (&hello_o; in the above example)
266       differently from the signature of the source file
267       (&hello_c;).
268       By default,
269       &SCons; tracks whether a target file must be rebuilt
270       by using a &buildsignature;
271       that consists of the combined
272       signatures of all the files
273       that go into making the target file.
274       This is efficient because
275       the accumulated signatures
276       actually give &SCons; all of the
277       information it needs
278       to decide if the target file is out of date.
279
280       </para>
281
282       <para>
283
284       If you wish, you can
285       specify this default behavior
286       (build signatures) explicitly
287       using the &TargetSignatures; function:
288
289       </para>
290
291       <sconstruct>
292         Program('hello.c')
293         TargetSignatures('build')
294       </sconstruct>
295
296     </section>
297
298     <section>
299     <title>File Contents</title>
300
301       <para>
302
303       Sometimes a source file can be changed
304       in such a way that the contents of the
305       rebuilt target file(s)
306       will be exactly the same as the last time
307       the file was built.
308       If so, then any other target files
309       that depend on such a built-but-not-changed target
310       file actually need not be rebuilt.
311       You can make &SCons;
312       realize that it does not need to rebuild
313       a dependent target file in this situation
314       using the &TargetSignatures; function as follows:
315
316       </para>
317
318       <scons_example name="ex3">
319         <file name="SConstruct" printme="1">
320         Program('hello.c')
321         TargetSignatures('content')
322         </file>
323         <file name="hello.c">
324         int main() { printf("Hello, world!\n"); }
325         </file>
326       </scons_example>
327
328       <para>
329
330       So if, for example,
331       a user were to only change a comment in a C file,
332       then the rebuilt &hello_o; file
333       would be exactly the same as the one previously built
334       (assuming the compiler doesn't put any build-specific
335       information in the object file).
336       &SCons; would then realize that it would not
337       need to rebuild the &hello; program as follows:
338
339       </para>
340
341       <scons_output example="ex3" os="posix">
342          <scons_output_command>scons -Q hello</scons_output_command>
343          <scons_output_command output="  [CHANGE A COMMENT IN hello.c]" edit="STRIP CCCOM line">edit hello.c</scons_output_command>
344          <scons_output_command>scons -Q hello</scons_output_command>
345       </scons_output>
346
347       <para>
348
349       In essence, &SCons; has
350       "short-circuited" any dependent builds
351       when it realizes that a target file
352       has been rebuilt to exactly the same file as the last build.
353       So configured,
354       &SCons; does take some extra processing time
355       to scan the contents of the target (&hello_o;) file,
356       but this may save time
357       if the rebuild that was avoided
358       would have been very time-consuming and expensive.
359
360       </para>
361
362     </section>
363
364   </section>
365
366   <section>
367   <title>Implicit Dependencies:  The &cv-CPPPATH; Construction Variable</title>
368
369     <para>
370
371     Now suppose that our "Hello, World!" program
372     actually has a <literal>#include</literal> line
373     to include the &hello_h; file in the compilation:
374
375     </para>
376
377     <scons_example name="ex4">
378       <file name="SConstruct">
379        Program('hello.c', CPPPATH = '.')
380       </file>
381       <file name="hello.c" printme="1">
382        #include &lt;hello.h&gt;
383        int
384        main()
385        {
386            printf("Hello, %s!\n", string);
387        }
388       </file>
389       <file name="hello.h">
390        #define string    "world"
391       </file>
392     </scons_example>
393
394     <para>
395
396     And, for completeness, the &hello_h; file looks like this:
397
398     </para>
399
400     <scons_example_file example="ex4"  name="hello.h">
401     </scons_example_file>
402
403     <para>
404
405     In this case, we want &SCons; to recognize that,
406     if the contents of the &hello_h; file change,
407     the &hello; program must be recompiled.
408     To do this, we need to modify the
409     &SConstruct; file like so:
410
411     </para>
412
413     <scons_example_file example="ex4"  name="SConstruct">
414     </scons_example_file>
415
416     <para>
417
418     The &cv-CPPPATH; value
419     tells &SCons; to look in the current directory
420     (<literal>'.'</literal>)
421     for any files included by C source files
422     (<filename>.c</filename> or <filename>.h</filename> files).
423     With this assignment in the &SConstruct; file:
424
425     </para>
426
427     <scons_output example="ex4" os="posix">
428        <scons_output_command>scons -Q hello</scons_output_command>
429        <scons_output_command>scons -Q hello</scons_output_command>
430        <scons_output_command output="    [CHANGE THE CONTENTS OF hello.h]">edit hello.h</scons_output_command>
431        <scons_output_command>scons -Q hello</scons_output_command>
432     </scons_output>
433
434     <para>
435
436     First, notice that &SCons;
437     added the <literal>-I.</literal> argument
438     from the &cv-CPPPATH; variable
439     so that the compilation would find the
440     &hello_h; file in the local directory.
441
442     </para>
443
444     <para>
445
446     Second, realize that &SCons; knows that the &hello;
447     program must be rebuilt
448     because it scans the contents of
449     the &hello_c; file
450     for the <literal>#include</literal> lines that indicate
451     another file is being included in the compilation.
452     &SCons; records these as
453     <emphasis>implicit dependencies</emphasis>
454     of the target file,
455     Consequently,
456     when the &hello_h; file changes,
457     &SCons; realizes that the &hello_c; file includes it,
458     and rebuilds the resulting &hello; program
459     that depends on both the &hello_c; and &hello_h; files.
460
461     </para>
462
463     <para>
464
465     Like the &cv-LIBPATH; variable,
466     the &cv-CPPPATH; variable
467     may be a list of directories,
468     or a string separated by
469     the system-specific path separate character
470     (':' on POSIX/Linux, ';' on Windows).
471     Either way, &SCons; creates the
472     right command-line options
473     so that the following example:
474
475     </para>
476
477     <scons_example name="ex5">
478       <file name="SConstruct" printme="1">
479        Program('hello.c', CPPPATH = ['include', '/home/project/inc'])
480       </file>
481       <file name="hello.c">
482       int main() { printf("Hello, world!\n"); }
483       </file>
484     </scons_example>
485
486     <para>
487
488     Will look like this on POSIX or Linux:
489
490     </para>
491
492     <scons_output example="ex5" os="posix">
493        <scons_output_command>scons -Q hello</scons_output_command>
494     </scons_output>
495
496     <para>
497
498     And like this on Windows:
499
500     </para>
501
502     <scons_output example="ex5" os="win32">
503        <scons_output_command>scons -Q hello.exe</scons_output_command>
504     </scons_output>
505
506   </section>
507
508   <section>
509   <title>Caching Implicit Dependencies</title>
510
511     <para>
512
513     Scanning each file for <literal>#include</literal> lines
514     does take some extra processing time.
515     When you're doing a full build of a large system,
516     the scanning time is usually a very small percentage
517     of the overall time spent on the build.
518     You're most likely to notice the scanning time,
519     however, when you <emphasis>rebuild</emphasis>
520     all or part of a large system:
521     &SCons; will likely take some extra time to "think about"
522     what must be built before it issues the
523     first build command
524     (or decides that everything is up to date
525     and nothing must be rebuilt).
526
527  <!--
528  Isn't this expensive? The answer is, it depends. If you do a full build of a
529  large system, the scanning time is insignificant. If you do a rebuild of a
530  large system, then Cons will spend a fair amount of time thinking about it
531  before it decides that nothing has to be done (although not necessarily more
532  time than make!). The good news is that Cons makes it very easy to
533  intelligently subset your build, when you are working on localized changes.
534  -->
535
536     </para>
537
538     <para>
539
540     In practice, having &SCons; scan files saves time
541     relative to the amount of potential time
542     lost to tracking down subtle problems
543     introduced by incorrect dependencies.
544     Nevertheless, the "waiting time"
545     while &SCons; scans files can annoy
546     individual developers waiting for their builds to finish.
547     Consequently, &SCons; lets you cache
548     the implicit dependencies
549     that its scanners find,
550     for use by later builds.
551     You can do this by specifying the
552     &implicit-cache; option on the command line:
553
554     </para>
555
556     <scons_output example="ex1">
557        <scons_output_command>scons -Q --implicit-cache hello</scons_output_command>
558        <scons_output_command>scons -Q hello</scons_output_command>
559     </scons_output>
560
561     <para>
562
563     If you don't want to specify &implicit-cache;
564     on the command line each time,
565     you can make it the default behavior for your build
566     by setting the &implicit_cache; option
567     in an &SConscript; file:
568
569     </para>
570
571     <sconstruct>
572        SetOption('implicit_cache', 1)
573     </sconstruct>
574
575     <!--
576
577     <para>
578     
579     XXX
580
581     </para>
582
583     <para>
584
585     &SCons; does not cache implicit dependencies like this by default
586     because XXX
587     
588     </para>
589
590     -->
591
592     <section>
593     <title>The &implicit-deps-changed; Option</title>
594
595       <para>
596
597       When using cached implicit dependencies,
598       sometimes you want to "start fresh"
599       and have &SCons; re-scan the files
600       for which it previously cached the dependencies.
601       For example,
602       if you have recently installed a new version of
603       external code that you use for compilation,
604       the external header files will have changed
605       and the previously-cached implicit dependencies
606       will be out of date.
607       You can update them by
608       running &SCons; with the &implicit-deps-changed; option:
609
610       </para>
611
612       <scons_output example="ex1">
613          <scons_output_command>scons -Q --implicit-deps-changed hello</scons_output_command>
614          <scons_output_command>scons -Q hello</scons_output_command>
615       </scons_output>
616
617       <para>
618
619       In this case, &SCons; will re-scan all of the implicit dependencies
620       and cache updated copies of the information.
621
622       </para>
623
624     </section>
625
626     <section>
627     <title>The &implicit-deps-unchanged; Option</title>
628
629       <para>
630
631       By default when caching dependencies,
632       &SCons; notices when a file has been modified
633       and re-scans the file for any updated
634       implicit dependency information.
635       Sometimes, however, you may want
636       to force &SCons; to use the cached implicit dependencies, 
637       even if the source files changed.
638       This can speed up a build for example,
639       when you have changed your source files
640       but know that you haven't changed
641       any <literal>#include</literal> lines.
642       In this case,
643       you can use the &implicit-deps-unchanged; option:
644
645       </para>
646
647       <scons_output example="ex1">
648          <scons_output_command>scons -Q --implicit-deps-unchanged hello</scons_output_command>
649          <scons_output_command>scons -Q hello</scons_output_command>
650       </scons_output>
651
652       <para>
653
654       In this case,
655       &SCons; will assume that the cached implicit
656       dependencies are correct and
657       will not bother to re-scan changed files.
658       For typical builds after small,
659       incremental changes to source files,
660       the savings may not be very big,
661       but sometimes every bit of
662       improved performance counts.
663
664       </para>
665
666     </section>
667
668   </section>
669
670   <section>
671   <title>Ignoring Dependencies:  the &Ignore; Method</title>
672
673     <para>
674
675     Sometimes it makes sense 
676     to not rebuild a program,
677     even if a dependency file changes.
678     In this case,
679     you would tell &SCons; specifically
680     to ignore a dependency as follows:
681
682     </para>
683
684     <scons_example name="ignore">
685       <file name="SConstruct" printme="1">
686       hello = Program('hello.c')
687       Ignore(hello, 'hello.h')
688       </file>
689       <file name="hello.c">
690       #include "hello.h" 
691       int main() { printf("Hello, %s!\n", string); }
692       </file>
693       <file name="hello.h">
694       #define string    "world"
695       </file>
696     </scons_example>
697
698     <!-- XXX mention that you can use arrays for target and source? -->
699
700     <!--
701     <scons_output example="ignore">
702       <scons_output_command>scons -Q hello</scons_output_command>
703       <scons_output_command>scons -Q hello</scons_output_command>
704       <scons_output_command output="    [CHANGE THE CONTENTS OF hello.h]">edit hello.h</scons_output_command>
705       <scons_output_command>scons -Q hello</scons_output_command>
706       XXX THIS EXAMPLE SHOULD BE UP-TO-DATE! XXX
707     </scons_output>
708     -->
709
710     <screen>
711       % <userinput>scons -Q hello</userinput>
712       cc -c -o hello.o hello.c
713       cc -o hello hello.o
714       % <userinput>scons -Q hello</userinput>
715       scons: `hello' is up to date.
716       % <userinput>edit hello.h</userinput>
717         [CHANGE THE CONTENTS OF hello.h]
718       % <userinput>scons -Q hello</userinput>
719       scons: `hello' is up to date.
720     </screen>
721
722     <para>
723
724     Now, the above example is a little contrived,
725     because it's hard to imagine a real-world situation
726     where you wouldn't to rebuild &hello;
727     if the &hello_h; file changed.
728     A more realistic example
729     might be if the &hello;
730     program is being built in a
731     directory that is shared between multiple systems
732     that have different copies of the
733     &stdio_h; include file.
734     In that case,
735     &SCons; would notice the differences between
736     the different systems' copies of &stdio_h;
737     and would rebuild &hello;
738     each time you change systems.
739     You could avoid these rebuilds as follows:
740
741     </para>
742
743     <programlisting>
744        hello = Program('hello.c')
745        Ignore(hello, '/usr/include/stdio.h')
746     </programlisting>
747
748   </section>
749
750   <section>
751   <title>Explicit Dependencies:  the &Depends; Method</title>
752
753     <para>
754
755     On the other hand,
756     sometimes a file depends on another file
757     that is not detected by an &SCons; scanner.
758     For this situation,
759     &SCons; allows you to specific explicitly that one file
760     depends on another file,
761     and must be rebuilt whenever that file changes.
762     This is specified using the &Depends; method:
763
764     </para>
765
766     <programlisting>
767        hello = Program('hello.c')
768        Depends(hello, 'other_file')
769     </programlisting>
770
771     <!-- XXX mention that you can use arrays for target and source? -->
772
773     <screen>
774        % <userinput>scons -Q hello</userinput>
775        cc -c hello.c -o hello.o
776        cc -o hello hello.o
777        % <userinput>scons -Q hello</userinput>
778        scons: `hello' is up to date.
779        % <userinput>edit other_file</userinput>
780            [CHANGE THE CONTENTS OF other_file]
781        % <userinput>scons -Q hello</userinput>
782        cc -c hello.c -o hello.o
783        cc -o hello hello.o
784     </screen>
785
786   </section>
787
788   <!-->
789
790   <section>
791   <title>The &Salt; Method</title>
792
793     <para>
794
795     XXX
796
797     </para>
798
799   </section>
800
801   -->