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