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