[ci skip] add test framework reformat to .git-blame-ignore-revs
[scons.git] / doc / design / engine.xml
blob37a376a203f9f3887a5e71bdf945719c07eeb447
1 <?xml version='1.0'?>
2 <!DOCTYPE sconsdoc [
3     <!ENTITY % scons SYSTEM "../scons.mod">
4     %scons;
5 ]>
7 <chapter id="chap-engine"
8          xmlns="http://www.scons.org/dbxsd/v1.0"
9          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10          xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">
11 <title>Build Engine API</title>
13 <!--
15   __COPYRIGHT__
17   Permission is hereby granted, free of charge, to any person obtaining
18   a copy of this software and associated documentation files (the
19   "Software"), to deal in the Software without restriction, including
20   without limitation the rights to use, copy, modify, merge, publish,
21   distribute, sublicense, and/or sell copies of the Software, and to
22   permit persons to whom the Software is furnished to do so, subject to
23   the following conditions:
25   The above copyright notice and this permission notice shall be included
26   in all copies or substantial portions of the Software.
28   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
29   KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
30   WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 -->
38 <section id="sect-principles">
39  <title>General Principles</title>
41  <section>
42   <title>Keyword arguments</title>
43   
44   <para>
46    All methods and functions in this API will support the use of keyword
47    arguments in calls, for the sake of explicitness and readability.
48    For brevity in the hands of experts, most methods and functions
49    will also support positional arguments for their most-commonly-used
50    arguments.  As an explicit example, the following two lines will each
51    arrange for an executable program named <filename>foo</filename> (or
52    <filename>foo.exe</filename> on a Win32 system) to be compiled from
53    the <filename>foo.c</filename> source file:
55   </para>
57         <programlisting>
58         env.Program(target = 'foo', source = 'foo.c')
60         env.Program('foo', 'foo.c')
61         </programlisting>
63  </section>
65  <section>
66   <title>Internal object representation</title>
68   <para>
70    All methods and functions use internal (Python) objects that
71    represent the external objects (files, for example) for which they
72    perform dependency analysis.
74   </para>
76   <para>
78    All methods and functions in this API that accept an external object
79    as an argument will accept <emphasis>either</emphasis> a string
80    description or an object reference.  For example, the two following
81    two-line examples are equivalent:
83   </para>
85         <programlisting>
86         env.Object(target = 'foo.o', source = 'foo.c')
87         env.Program(target = 'foo', 'foo.o')    # builds foo from foo.o
89         foo_obj = env.Object(target = 'foo.o', source = 'foo.c')
90         env.Program(target = 'foo', foo_obj)    # builds foo from foo.o
91         </programlisting>
93  </section>
95 </section>
99 <section id="sect-envs">
100  <title>&ConsEnvs;</title>
102  <para>
104   A &consenv; is the basic means by which a software system interacts
105   with the &SCons; Python API to control a build process.
107  </para>
109  <para>
111   A &consenv; is an object with associated methods for generating target
112   files of various types (&Builder; objects), other associated object
113   methods for automatically determining dependencies from the contents
114   of various types of source files (&Scanner; objects), and a dictionary
115   of values used by these methods.
117  </para>
119  <para>
121   Passing no arguments to the &Environment; instantiation creates a
122   &consenv; with default values for the current platform:
124  </para>
126         <programlisting>
127         env = Environment()
128         </programlisting>
130  <section>
131   <title>&Consvars;</title>
133   <para>
135    A &consenv; has an associated dictionary of &consvars; that control how
136    the build is performed.  By default, the &Environment; method creates
137    a &consenv; with values that make most software build "out of the box"
138    on the host system.  These default values will be generated at the
139    time &SCons; is installed using functionality similar to that provided
140    by GNU &Autoconf;.
141    <footnote>
142     <para>
143      It would be nice if we could avoid re-inventing the wheel here by
144      using some other Python-based tool &Autoconf; replacement--like what
145      was supposed to come out of the Software Carpentry configuration
146      tool contest.  It will probably be most efficient to roll our own
147      logic initially and convert if something better does come along.
148     </para>
149    </footnote>
150    At a minimum, there will be pre-configured sets of default values
151    that will provide reasonable defaults for UNIX and Windows NT.
153   </para>
155   <para>
157    The default &consenv; values may be overridden when a new &consenv; is
158    created by specifying keyword arguments:
160   </para>
162         <programlisting>
163         env = Environment(CC =          'gcc',
164                           CCFLAGS =    '-g',
165                           CPPPATH =    ['.', 'src', '/usr/include'],
166                           LIBPATH =    ['/usr/lib', '.'])
167         </programlisting>
169  </section>
171  <section>
172   <title>Fetching &consvars;</title>
174   <para>
176    A copy of the dictionary of &consvars; can be returned using
177    the &Dictionary; method:
179   </para>
181         <programlisting>
182         env = Environment()
183         dict = env.Dictionary()
184         </programlisting>
186   <para>
188    If any arguments are supplied, then just the corresponding value(s)
189    are returned:
191   </para>
193         <programlisting>
194         ccflags = env.Dictionary('CCFLAGS')
195         cc, ld = env.Dictionary('CC', 'LD')
196         </programlisting>
198  </section>
200  <section>
201   <title>Copying a &consenv;</title>
203   <para>
205    A method exists to return a copy of an existing environment, with
206    any overridden values specified as keyword arguments to the method:
208   </para>
210         <programlisting>
211         env = Environment()
212         debug = env.Copy(CCFLAGS = '-g')
213         </programlisting>
215  </section>
217  <section>
218   <title>Multiple &consenvs;</title>
220   <para>
222    Different external objects often require different build
223    characteristics.  Multiple &consenvs; may be defined, each with
224    different values:
226   </para>
228         <programlisting>
229         env = Environment(CCFLAGS = '')
230         debug = Environment(CCFLAGS = '-g')
231         env.Make(target = 'hello', source = 'hello.c')
232         debug.Make(target = 'hello-debug', source = 'hello.c')
233         </programlisting>
235   <para>
237    Dictionaries of values from multiple &consenvs; may be passed to the
238    &Environment; instantiation or the &Copy; method, in which case the
239    last-specified dictionary value wins:
241   </para>
243         <programlisting>
244         env1 = Environment(CCFLAGS = '-O', LDFLAGS = '-d')
245         env2 = Environment(CCFLAGS = '-g')
246         new = Environment(env1.Dictionary(), env2.Dictionary())
247         </programlisting>
249   <para>
251    The <varname>new</varname> environment in the above example retains
252    <literal>LDFLAGS = '-d'</literal> from the <varname>env1</varname>
253    environment, and <literal>CCFLAGS = '-g'</literal> from the
254    <varname>env2</varname> environment.
256   </para>
258   <!--
260         hardware details
261         current directory
262         OS environment variables
263         compilers and options,
264         aliases for commands,
265         versions of tools
267         environment overrides a la Cons
269         compilation options
271         cross compilation via selection of tool+options
273         paths for header files (specify alternate path)
275         accomodate smart compilers that can tell you
276         "I know how to turn .c or .ccp into .o",
277         "I know how to turn .f into .o"
279    -->
281  </section>
283  <section>
284   <title>Variable substitution</title>
286   <para>
288    Within a construction command, any variable from the &consenv; may
289    be interpolated by prefixing the name of the construction with
290    <symbol>$</symbol>:
292   </para>
294         <programlisting>
295         MyBuilder = Builder(command = "$XX $XXFLAGS -c $_INPUTS -o $target")
297         env.Command(targets = 'bar.out', sources = 'bar.in',
298                     command = "sed '1d' &lt; $source > $target")
299         </programlisting>
301   <para>
303    Variable substitution is recursive:  the command line is expanded
304    until no more substitutions can be made.
306   </para>
308   <para>
310    Variable names following the <symbol>$</symbol> may be enclosed in
311    braces.  This can be used to concatenate an interpolated value with an
312    alphanumeric character:
314   </para>
316         <programlisting>
317         VerboseBuilder = Builder(command = "$XX -${XXFLAGS}v > $target")
318         </programlisting>
320   <para>
322    The variable within braces may contain a pair of parentheses
323    after a Python function name to be evaluated (for example,
324    <literal>${map()}</literal>).  &SCons; will interpolate the return
325    value from the function (presumably a string):
327   </para>
329         <programlisting>
330         env = Environment(FUNC = myfunc)
331         env.Command(target = 'foo.out', source = 'foo.in',
332                     command = "${FUNC($&lt;)}")
333         </programlisting>
335   <para>
337    If a referenced variable is not defined in the &consenv;,
338    the null string is interpolated.
340   </para>
342   <para>
344    The following special variables can also be used:
346   </para>
348   <variablelist>
350    <varlistentry>
351     <term><literal>$targets</literal></term>
352     <listitem>
353      <para>
355       All target file names.  If multiple targets are specified in an
356       array, <literal>$targets</literal> expands to the entire list of
357       targets, separated by a single space.
359     </para>
361     <para>
363       Individual targets from a list may be extracted by enclosing
364       the <literal>targets</literal> keyword in braces and using the
365       appropriate Python array index or slice:
367     </para>
369         <programlisting>
370         ${targets[0]}     # expands to the first target
372         ${targets[1:]}    # expands to all but the first target
374         ${targets[1:-1]}  # expands to all but the first and last targets
375         </programlisting>
377     </listitem>
378    </varlistentry>
380    <varlistentry>
381     <term><literal>$target</literal></term>
382     <listitem>
383      <para>
385       A synonym for <literal>${targets[0]}</literal>, the first target
386       specified.
388      </para>
389     </listitem>
390    </varlistentry>
392    <varlistentry>
393     <term><literal>$sources</literal></term>
394     <listitem>
395      <para>
397       All input file names.  Any input file names that
398       are used anywhere else on the current command
399       line (via <literal>${sources[0]}</literal>,
400       <literal>${sources{[1]}</literal>, etc.) are removed from the
401       expanded list.
403      </para>
404     </listitem>
405    </varlistentry>
407   </variablelist>
409   <para>
411    Any of the above special variables may be enclosed in braces and
412    followed immediately by one of the following attributes to select just
413    a portion of the expanded path name:
415   </para>
417   <variablelist>
419    <varlistentry>
420     <term><literal>.base</literal></term>
421     <listitem>
422      <para>
424       Basename: the directory plus the file name, minus any file suffix.
426      </para>
427     </listitem>
428    </varlistentry>
430    <varlistentry>
431     <term><literal>.dir</literal></term>
432     <listitem>
433      <para>
435       The directory in which the file lives.  This is a relative path,
436       where appropriate.
438      </para>
439     </listitem>
440    </varlistentry>
442    <varlistentry>
443     <term><literal>.file</literal></term>
444     <listitem>
445      <para>
447       The file name, minus any directory portion.
449      </para>
450     </listitem>
451    </varlistentry>
453    <varlistentry>
454     <term><literal>.suffix</literal></term>
455     <listitem>
456      <para>
458       The file name suffix (that is, the right-most dot in the file name,
459       and all characters to the right of that).
461      </para>
462     </listitem>
463    </varlistentry>
465    <varlistentry>
466     <term><literal>.filebase</literal></term>
467     <listitem>
468      <para>
470       The file name (no directory portion), minus any file suffix.
472      </para>
473     </listitem>
474    </varlistentry>
476    <varlistentry>
477     <term><literal>.abspath</literal></term>
478     <listitem>
479      <para>
481       The absolute path to the file.
483      </para>
484     </listitem>
485    </varlistentry>
487    <varlistentry>
488     <term><literal>.relpath</literal></term>
489     <listitem>
490      <para>
492       The path to the file relative to the root SConstruct file's directory.
494      </para>
495     </listitem>
496    </varlistentry>
498   </variablelist>
500  </section>
502 </section>
506 <section id="sect-builders">
507  <title>&Builder; Objects</title>
509  <para>
511   By default, &SCons; supplies (and uses) a number of pre-defined
512   &Builder; objects:
514  </para>
516  <informaltable>
517   <tgroup cols="2">
518   <tbody>
520    <row>
521     <entry>&Object;</entry>
522     <entry>compile or assemble an object file</entry>
523    </row>
525    <row>
526     <entry>&Library;</entry>
527     <entry>archive files into a library</entry>
528    </row>
530    <row>
531     <entry>&SharedLibrary;</entry>
532     <entry>archive files into a shared library</entry>
533    </row>
535    <row>
536     <entry>&Program;</entry>
537     <entry>link objects and/or libraries into an executable</entry>
538    </row>
540    <row>
541     <entry>&MakeBuilder;</entry>
542     <entry>build according to file suffixes; see below</entry>
543    </row>
545   </tbody>
546   </tgroup>
547  </informaltable>
549 <!--
550 &Library; and &SharedLibrary; have nearly identical
551 semantics, just different
552 tools and &consenvs (paths, etc.) that they use.
553 In other words, you can construct a shared library
554 using just the &Library; &Builder; object
555 with a different environment.
556 I think that's a better way to do it.
557 Feedback?
560  <para>
562   A &consenv; can be explicitly initialized with associated &Builder;
563   objects that will be bound to the &consenv; object:
565  </para>
567         <programlisting>
568         env = Environment(BUILDERS = ['Object', 'Program'])
569         </programlisting>
571  <para>
573   &Builder; objects bound to a &consenv; can be called directly as
574   methods.  When invoked, a &Builder; object returns a (list of) objects
575   that it will build:
577  </para>
579         <programlisting>
580         obj = env.Object(target ='hello.o', source = 'hello.c')
581         lib = env.Library(target ='libfoo.a',
582                           source = ['aaa.c', 'bbb.c'])
583         slib = env.SharedLibrary(target ='libbar.so',
584                                  source = ['xxx.c', 'yyy.c'])
585         prog = env.Program(target ='hello',
586                            source = ['hello.o', 'libfoo.a', 'libbar.so'])
587         </programlisting>
589  <section>
590   <title>Specifying multiple inputs</title>
592   <para>
594    Multiple input files that go into creating a target file may be passed
595    in as a single string, with the individual file names separated by
596    white space:
598   </para>
600         <programlisting>
601         env.Library(target = 'foo.a', source = 'aaa.c bbb.c ccc.c')
602         env.Object(target = 'yyy.o', source = 'yyy.c')
603         env.Program(target = 'bar', source = 'xxx.c yyy.o foo.a')
604         </programlisting>
606   <para>
608    Alternatively, multiple input files that go into creating a target
609    file may be passed in as an array.  This allows input files to be
610    specified using their object representation:
612   </para>
614         <programlisting>
615         env.Library(target = 'foo.a', source = ['aaa.c', 'bbb.c', 'ccc.c'])
616         yyy_obj = env.Object(target = 'yyy.o', source = 'yyy.c')
617         env.Program(target = 'bar', source = ['xxx.c', yyy_obj, 'foo.a'])
618         </programlisting>
620    <para>
622     Individual string elements within an array of input files are
623     <emphasis>not</emphasis> further split into white-space separated
624     file names.  This allows file names that contain white space to
625     be specified by putting the value into an array:
627         <programlisting>
628         env.Program(target = 'foo', source = ['an input file.c'])
629         </programlisting>
631    </para>
633  </section>
635  <section>
636   <title>Specifying multiple targets</title>
638   <para>
640    Conversely, the generated target may be a string listing multiple
641    files separated by white space:
643   </para>
645         <programlisting>
646         env.Object(target = 'grammar.o y.tab.h', source = 'grammar.y')
647         </programlisting>
649   <para>
651    An array of multiple target files can be used to mix string and object
652    representations, or to accomodate file names that contain white space:
654   </para>
656         <programlisting>
657         env.Program(target = ['my program'], source = 'input.c')
658         </programlisting>
660  </section>
662  <section>
663   <title>File prefixes and suffixes</title>
665   <para>
667    For portability, if the target file name does not already have an
668    appropriate file prefix or suffix, the &Builder; objects will
669    append one appropriate for the file type on the current system:
671   </para>
673         <programlisting>
674         # builds 'hello.o' on UNIX, 'hello.obj' on Windows NT:
675         obj = env.Object(target ='hello', source = 'hello.c')
677         # builds 'libfoo.a' on UNIX, 'foo.lib' on Windows NT:
678         lib = env.Library(target ='foo', source = ['aaa.c', 'bbb.c'])
680         # builds 'libbar.so' on UNIX, 'bar.dll' on Windows NT:
681         slib = env.SharedLibrary(target ='bar', source = ['xxx.c', 'yyy.c'])
683         # builds 'hello' on UNIX, 'hello.exe' on Windows NT:
684         prog = env.Program(target ='hello',
685                            source = ['hello.o', 'libfoo.a', 'libbar.so'])
686         </programlisting>
688  </section>
690  <section>
691   <title>&Builder; object exceptions</title>
693   <para>
695    &Builder; objects raise the following exceptions on error:
697  <!--
698  LIST THESE ONCE WE FIGURE OUT WHAT THEY ARE FROM CODING THEM.
699  -->
701   </para>
702  </section>
704  <section>
705   <title>User-defined &Builder; objects</title>
707   <para>
709    Users can define additional &Builder; objects for specific external
710    object types unknown to &SCons;.  A &Builder; object may build its
711    target by executing an external command:
713   </para>
715         <programlisting>
716         WebPage = Builder(command = 'htmlgen $HTMLGENFLAGS $sources > $target',
717                           suffix = '.html',
718                           src_suffix = '.in')
719         </programlisting>
721   <para>
723    Alternatively, a &Builder; object may also build its target by
724    executing a Python function:
726    </para>
728         <programlisting>
729         def update(dest):
730                 # [code to update the object]
731                 return 1
733         OtherBuilder1 = Builder(function = update,
734                                 src_suffix = ['.in', '.input'])
735         </programlisting>
737    <para>
738    
739    An optional argument to pass to the function may be specified:
741   </para>
743         <programlisting>
744         def update_arg(dest, arg):
745                 # [code to update the object]
746                 return 1
748         OtherBuilder2 = Builder(function = update_arg,
749                                 function_arg = 'xyzzy',
750                                 src_suffix = ['.in', '.input'])
751         </programlisting>
753   <para>
755    Both an external command and an internal function may be specified,
756    in which case the function will be called to build the object first,
757    followed by the command line.
759   </para>
761  <!--
762  NEED AN EXAMPLE HERE.
763  -->
765   <para>
767    User-defined &Builder; objects can be used like the default &Builder;
768    objects to initialize &consenvs;.
770   </para>
772         <programlisting>
773         WebPage = Builder(command = 'htmlgen $HTMLGENFLAGS $sources > $target',
774                           suffix = '.html',
775                           src_suffix = '.in')
776         env = Environment(BUILDERS = ['WebPage'])
777         env.WebPage(target = 'foo.html', source = 'foo.in')
778         # Builds 'bar.html' on UNIX, 'bar.htm' on Windows NT:
779         env.WebPage(target = 'bar', source = 'bar.in')
780         </programlisting>
782   <para>
784    The command-line specification can interpolate variables from the
785    &consenv;; see "Variable substitution," above.
787   </para>
789   <para>
791    A &Builder; object may optionally be initialized with a list of:
793   </para>
795    <itemizedlist>
796      <listitem>
797      <para>
799        the prefix of the target file (e.g., 'lib' for libraries)
801      </para>
802      </listitem>
804      <listitem>
805      <para>
807        the suffix of the target file (e.g., '.a' for libraries)
809      </para>
810      </listitem>
812      <listitem>
813      <para>
815        the expected suffixes of the input files
816        (e.g., '.o' for object files)
818      </para>
819      </listitem>
820    </itemizedlist>
822    <para>
824     These arguments are used in automatic
825     dependency analysis and to generate output file names that don't
826     have suffixes supplied explicitly.
828   </para>
829  </section>
831  <section>
832   <title>Copying &Builder; Objects</title>
834   <para>
836    A &Copy; method exists to return a copy of an existing &Builder;
837    object, with any overridden values specified as keyword arguments to
838    the method:
840   </para>
842         <programlisting>
843         build = Builder(function = my_build)
844         build_out = build.Copy(suffix = '.out')
845         </programlisting>
847   <para>
849    Typically, &Builder; objects will be supplied by a tool-master or
850    administrator through a shared &consenv;.
852   </para>
853  </section>
855  <section>
856   <title>Special-purpose build rules</title>
858   <para>
860    A pre-defined &Command; builder exists to associate a target file with
861    a specific command or list of commands for building the file:
863   </para>
865         <programlisting>
866         env.Command(target = 'foo.out', source = 
867                     command = 'foo.in', "foo.process $sources > $target")
869         commands = [    "bar.process -o .tmpfile $sources",
870                         "mv .tmpfile $target" ]
871         env.Command(target = 'bar.out', source = 'bar.in', command = commands)
872         </programlisting>
874   <para>
875    This is useful when it's too cumbersome to create a &Builder;
876    object just to build a single file in a special way.
878   </para>
879  </section>
881  <section>
882   <title>The &MakeBuilder; &Builder;</title>
884   <para>
886    A pre-defined &Builder; object named &MakeBuilder; exists to make
887    simple builds as easy as possible for users, at the expense of
888    sacrificing some build portability.
890   </para>
892   <para>
894    The following minimal example builds the 'hello' program from the
895    'hello.c' source file:
897   </para>
899         <programlisting>
900         Environment().Make('hello', 'hello.c')
901         </programlisting>
903   <para>
905    Users of the &MakeBuilder; &Builder; object are not required to
906    understand intermediate steps involved in generating a file--for
907    example, the distinction between compiling source code into an object
908    file, and then linking object files into an executable.  The details
909    of intermediate steps are handled by the invoked method.  Users that
910    need to, however, can specify intermediate steps explicitly:
912   </para>
914         <programlisting>
915         env = Environment()
916         env.Make(target = 'hello.o', source = 'hello.c')
917         env.Make(target = 'hello', source = 'hello.o')
918         </programlisting>
920   <para>
922    The &MakeBuilder; method understands the file suffixes specified and
923    "does the right thing" to generate the target object and program
924    files, respectively.  It does this by examining the specified output
925    suffixes for the &Builder; objects bound to the environment.
927   </para>
929   <para>
931    Because file name suffixes in the target and source file names
932    must be specified, the &MakeBuilder; method can't be used
933    portably across operating systems.  In other words, for the
934    example above, the &MakeBuilder; builder will not generate
935    <filename>hello.exe</filename> on Windows NT.
937   </para>
939  </section>
941  <section>
942   <title>&Builder; maps</title>
944 <!--
945 Do we even need this anymore?
946 Now that the individual builders
947 have specified <literal>suffix</literal>
948 and <literal>src_suffix</literal> values,
949 all of the information we need to support
950 the &MakeBuilder; builder is right there in the environment.
951 I think this is a holdover from before I
952 added the <literal>suffix</literal> arguments.
953 If you want &MakeBuilder; to do something different,
954 you set it up with another environment...
957   <para>
959    The <function>env.Make</function> method "does the right thing" to
960    build different file types because it uses a dictionary from the
961    &consenv; that maps file suffixes to the appropriate &Builder; object.
962    This &BUILDERMAP; can be initialized at instantiation:
964   </para>
966         <programlisting>
967         env = Environment(BUILDERMAP = {
968                                 '.o' : Object,
969                                 '.a' : Library,
970                                 '.html' : WebPage,
971                                 '' : Program,
972                         })
973         </programlisting>
975   <para>
977    With the &BUILDERMAP; properly initialized, the
978    <function>env.Make</function> method can be used to build additional
979    file types:
981   </para>
983         <programlisting>
984         env.Make(target = 'index.html', source = 'index.input')
985         </programlisting>
987   <para>
989    &Builder; objects referenced in the &BUILDERMAP; do not need to be
990    listed separately in the <literal>BUILDERS</literal> variable.  The &consenv; will
991    bind the union of the &Builder; objects listed in both variables.
993   </para>
995  <!--
997    YYY support scanners which detect files which haven't been generated yet
999  -->
1001  </section>
1003 </section>
1007 <section id="sect-deps">
1008  <title>Dependencies</title>
1010  <section>
1011   <title>Automatic dependencies</title>
1013   <para>
1015    By default, &SCons; assumes that a target file has <literal>automatic
1016    dependencies</literal> on the:
1018   </para>
1020   <blockquote>
1021    <simplelist>
1023     <member>tool used to build the target file</member>
1025     <member>contents of the input files</member>
1027     <member>command line used to build the target file</member>
1029    </simplelist>
1030   </blockquote>
1032   <para>
1034    If any of these changes, the target file will be rebuilt.
1036   </para>
1037  </section>
1039  <section>
1040   <title>Implicit dependencies</title>
1042   <para>
1044    Additionally, &SCons; can scan the contents of files for
1045    <literal>implicit dependencies</literal> on other files.  For
1046    example, &SCons; will scan the contents of a <filename>.c</filename>
1047    file and determine that any object created from it is
1048    dependent on any <filename>.h</filename> files specified via
1049    <literal>#include</literal>.  &SCons;, therefore, "does the right
1050    thing" without needing to have these dependencies listed explicitly:
1052   </para>
1054         <programlisting>
1055         % cat Construct
1056         env = Environment()
1057         env.Program('hello', 'hello.c')
1058         % cat hello.c
1059         #include "hello_string.h"
1060         main()
1061         {
1062                 printf("%s\n", STRING);
1063         }
1064         % cat > hello_string.h
1065         #define STRING  "Hello, world!\n"
1066         % scons .
1067         gcc -c hello.c -o hello.o
1068         gcc -o hello hello.c
1069         % ./hello
1070         Hello, world!
1071         % cat > hello_string.h
1072         #define STRING  "Hello, world, hello!\n"
1073         % scons .
1074         gcc -c hello.c -o hello.o
1075         gcc -o hello hello.c
1076         % ./hello
1077         Hello, world, hello!
1078         %
1079         </programlisting>
1081  </section>
1083  <section>
1084   <title>Ignoring dependencies</title>
1086   <para>
1088    Undesirable <literal>automatic dependencies</literal> or
1089    <literal>implicit dependencies</literal> may be ignored:
1091   </para>
1093         <programlisting>
1094         env.Program(target = 'bar', source = 'bar.c')
1095         env.Ignore('bar', '/usr/bin/gcc', 'version.h')
1096         </programlisting>
1098   <para>
1100    In the above example, the <filename>bar</filename> program will not
1101    be rebuilt if the <filename>/usr/bin/gcc</filename> compiler or the
1102    <filename>version.h</filename> file change.
1104   </para>
1105  </section>
1107  <section>
1108   <title>Explicit dependencies</title>
1110   <para>
1112    Dependencies that are unknown to &SCons; may be specified explicitly
1113    in an &SCons; configuration file:
1115   </para>
1117         <programlisting>
1118         env.Depends(target = 'output1', dependency = 'input_1 input_2')
1119         env.Depends(target = 'output2', dependency = ['input_1', 'input_2'])
1120         env.Depends(target = 'output3', dependency = ['white space input'])
1122         env.Depends(target = 'output_a output_b', dependency = 'input_3')
1123         env.Depends(target = ['output_c', 'output_d'], dependency = 'input_4')
1124         env.Depends(target = ['white space output'], dependency = 'input_5')
1125         </programlisting>
1127   <para>
1129    Just like the <literal>target</literal> keyword argument, the
1130    <literal>dependency</literal> keyword argument may be specified as a
1131    string of white-space separated file names, or as an array.
1133   </para>
1135   <para>
1137    A dependency on an &SCons; configuration file itself may be specified
1138    explicitly to force a rebuild whenever the configuration file changes:
1140   </para>
1142         <programlisting>
1143         env.Depends(target = 'archive.tar.gz', dependency = 'SConstruct')
1144         </programlisting>
1146  </section>
1148 </section>
1152 <section id="sect-scanners">
1153  <title>&Scanner; Objects</title>
1155  <para>
1157   Analagous to the previously-described &Builder; objects, &SCons;
1158   supplies (and uses) &Scanner; objects to search the contents of
1159   a file for implicit dependency files:
1161  </para>
1163  <informaltable>
1164   <tgroup cols="2">
1165   <tbody>
1167    <row>
1168     <entry>CScan</entry>
1169     <entry>scan .{c,C,cc,cxx,cpp} files for #include dependencies</entry>
1170    </row>
1172   </tbody>
1173   </tgroup>
1174  </informaltable>
1176  <para>
1178   A &consenv; can be explicitly initialized with
1179   associated &Scanner; objects:
1181  </para>
1183         <programlisting>
1184         env = Environment(SCANNERS = ['CScan', 'M4Scan'])
1185         </programlisting>
1187  <para>
1189   &Scanner; objects bound to a &consenv; can be
1190   associated directly with specified files:
1192  </para>
1194         <programlisting>
1195         env.CScan('foo.c', 'bar.c')
1196         env.M4Scan('input.m4')
1197         </programlisting>
1199  <section>
1200   <title>User-defined &Scanner; objects</title>
1202   <para>
1204    A user may define a &Scanner; object to scan a type of file for
1205    implicit dependencies:
1207   </para>
1209         <programlisting>
1210         def scanner1(file_contents):
1211                 # search for dependencies
1212                 return dependency_list
1214         FirstScan = Scanner(function = scanner1)
1215         </programlisting>
1217   <para>
1219    The scanner function must return a list of dependencies that its finds
1220    based on analyzing the file contents it is passed as an argument.
1222   </para>
1224   <para>
1226    The scanner function, when invoked, will be passed the calling
1227    environment.  The scanner function can use &consenvs; from the passed
1228    environment to affect how it performs its dependency scan--the
1229    canonical example being to use some sort of search-path construction
1230    variable to look for dependency files in other directories:
1232   </para>
1234         <programlisting>
1235         def scanner2(file_contents, env):
1236                 path = env.{'SCANNERPATH'}      # XXX
1237                 # search for dependencies using 'path'
1238                 return dependency_list
1240         SecondScan = Scanner(function = scanner2)
1241         </programlisting>
1243   <para>
1245    The user may specify an additional argument when the &Scanner; object
1246    is created.  When the scanner is invoked, the additional argument
1247    will be passed to the scanner funciton, which can be used in any way
1248    the scanner function sees fit:
1250   </para>
1252         <programlisting>
1253         def scanner3(file_contents, env, arg):
1254                 # skip 'arg' lines, then search for dependencies
1255                 return dependency_list
1257         Skip_3_Lines_Scan = Scanner(function = scanner2, argument = 3)
1258         Skip_6_Lines_Scan = Scanner(function = scanner2, argument = 6)
1259         </programlisting>
1261  </section>
1263  <section>
1264   <title>Copying &Scanner; Objects</title>
1266   <para>
1268    A method exists to return a copy of an existing &Scanner; object,
1269    with any overridden values specified as keyword arguments to the
1270    method:
1272   </para>
1274         <programlisting>
1275         scan = Scanner(function = my_scan)
1276         scan_path = scan.Copy(path = '%SCANNERPATH')
1277         </programlisting>
1279   <para>
1281    Typically, &Scanner; objects will be supplied by a tool-master or
1282    administrator through a shared &consenv;.
1284   </para>
1285  </section>
1287  <section>
1288   <title>&Scanner; maps</title>
1290 <!--
1291 If the &BUILDERMAP; proves unnecessary,
1292 we could/should get rid of this one, too,
1293 by adding a parallel <literal>src_suffix</literal>
1294 argument to the &Scanner; factory...
1295 Comments?
1298   <para>
1300    Each &consenv; has a &SCANNERMAP;, a dictionary that associates
1301    different file suffixes with a scanner object that can be used to
1302    generate a list of dependencies from the contents of that file.  This
1303    &SCANNERMAP; can be initialized at instantiation:
1305   </para>
1307         <programlisting>
1308         env = Environment(SCANNERMAP = {
1309                                 '.c' : CScan,
1310                                 '.cc' : CScan,
1311                                 '.m4' : M4Scan,
1312                         })
1313         </programlisting>
1315   <para>
1317    &Scanner; objects referenced in the &SCANNERMAP; do not need to
1318    be listed separately in the <literal>SCANNERS</literal> variable.  The &consenv;
1319    will bind the union of the &Scanner; objects listed
1320    in both variables.
1322   </para>
1324  </section>
1326 </section>
1330 <section id="sect-targets">
1331  <title>Targets</title>
1333  <para>
1335   The methods in the build engine API described so far merely
1336   establish associations that describe file dependencies, how a
1337   file should be scanned, etc.  Since the real point is to actually
1338   <emphasis>build</emphasis> files, &SCons; also has methods that
1339   actually direct the build engine to build, or otherwise manipulate,
1340   target files.
1342  </para>
1344  <section>
1345   <title>Building targets</title>
1346   <para>
1348    One or more targets may be built as follows:
1350   </para>
1352         <programlisting>
1353         env.Build(target = ['foo', 'bar'])
1354         </programlisting>
1356   <para>
1358    Note that specifying a directory (or other collective object) will
1359    cause all subsidiary/dependent objects to be built as well:
1361   </para>
1363         <programlisting>
1364         env.Build(target = '.')
1366         env.Build(target = 'builddir')
1367         </programlisting>
1369   <para>
1371    By default, &SCons; explicitly removes a target file before
1372    invoking the underlying function or command(s) to build it.
1374   </para>
1375  </section>
1377  <section>
1378   <title>Removing targets</title>
1380   <para>
1382    A "cleanup" operation of removing generated (target) files is
1383    performed as follows:
1385   </para>
1387         <programlisting>
1388         env.Clean(target = ['foo', 'bar'])
1389         </programlisting>
1391   <para>
1393    Like the &Build; method, the &Clean; method may be passed a
1394    directory or other collective object, in which case the subsidiary
1395    target objects under the directory will be removed:
1397   </para>
1399         <programlisting>
1400         env.Clean(target = '.')
1402         env.Clean(target = 'builddir')
1403         </programlisting>
1405   <para>
1407    (The directories themselves are not removed.)
1409   </para>
1410  </section>
1412  <section>
1413   <title>Suppressing cleanup removal of build-targets</title>
1415   <para>
1416     
1417     By default, &SCons; explicitly removes all build-targets
1418     when invoked to perform "cleanup". Files that should not be 
1419     removed during "cleanup" can be specified via the
1420     &NoClean; method:
1421     
1422   </para>
1423   
1424   <programlisting>
1425 env.Library(target = 'libfoo.a', source = ['aaa.c', 'bbb.c', 'ccc.c'])
1426 env.NoClean('libfoo.a')
1427   </programlisting>
1428   
1429   <para>
1430     
1431     The NoClean operation has precedence over the Clean operation.
1432     A target that is specified as both Clean and NoClean, will not 
1433     be removed during a clean.
1434     
1435     In the following example, target 'foo' will not be removed 
1436     during "cleanup":
1437     
1438     <programlisting>
1439 env.Clean(target = 'foo')
1440 env.NoClean('foo')
1441     </programlisting>
1442     
1443     
1444   </para>
1445   
1446  </section>
1448  <section>
1449   <title>Suppressing build-target removal</title>
1451   <para>
1453    As mentioned, by default, &SCons; explicitly removes a target
1454    file before invoking the underlying function or command(s) to build
1455    it.  Files that should not be removed before rebuilding can be
1456    specified via the &Precious; method:
1458   </para>
1460         <programlisting>
1461         env.Library(target = 'libfoo.a', source = ['aaa.c', 'bbb.c', 'ccc.c'])
1462         env.Precious('libfoo.a')
1463         </programlisting>
1465  </section>
1467  <section>
1468   <title>Default targets</title>
1470   <para>
1472    The user may specify default targets that will be built if there are no
1473    targets supplied on the command line:
1475   </para>
1477         <programlisting>
1478         env.Default('install', 'src')
1479         </programlisting>
1481   <para>
1483    Multiple calls to the &Default; method (typically one per &SConscript;
1484    file) append their arguments to the list of default targets.
1486   </para>
1487  </section>
1489  <section>
1490   <title>File installation</title>
1492   <para>
1494    Files may be installed in a destination directory:
1496   </para>
1498         <programlisting>
1499         env.Install('/usr/bin', 'program1', 'program2')
1500         </programlisting>
1502   <para>
1504    Files may be renamed on installation:
1506   </para>
1508         <programlisting>
1509         env.InstallAs('/usr/bin/xyzzy', 'xyzzy.in')
1510         </programlisting>
1512   <para>
1514    Multiple files may be renamed on installation by specifying
1515    equal-length lists of target and source files:
1517   </para>
1519         <programlisting>
1520         env.InstallAs(['/usr/bin/foo', '/usr/bin/bar'],
1521                         ['foo.in', 'bar.in'])
1522         </programlisting>
1524  </section>
1526  <section>
1527   <title>Target aliases</title>
1529   <para>
1531    In order to provide convenient "shortcut" target names that expand to
1532    a specified list of targets, aliases may be established:
1534   </para>
1536         <programlisting>
1537         env.Alias(alias = 'install',
1538                   targets = ['/sbin', '/usr/lib', '/usr/share/man'])
1539         </programlisting>
1541   <para>
1543    In this example, specifying a target of <literal>install</literal>
1544    will cause all the files in the associated directories to be built
1545    (that is, installed).
1547   </para>
1549   <para>
1551    An &Alias; may include one or more other &Aliases; in its list:
1553   </para>
1555         <programlisting>
1556         env.Alias(alias = 'libraries', targets = ['lib'])
1557         env.Alias(alias = 'programs', targets = ['libraries', 'src'])
1558         </programlisting>
1560  </section>
1562 </section>
1566 <section id="sect-custom">
1567  <title>Customizing output</title>
1569 <!--
1570 Take this whole section with a grain of salt.
1571 I whipped it up without a great deal of thought
1572 to try to add a "competitive advantage"
1573 for the second round of the Software Carpentry contest.
1574 In particular, hard-coding the
1575 analysis points and the keywords that specify them
1576 feels inflexible,
1577 but I can't think of another way it would be
1578 done effectively.
1579 I dunno, maybe this is fine as it is...
1582  <para>
1584   The &SCons; API supports the ability to customize, redirect, or
1585   suppress its printed output through user-defined functions.
1586   &SCons; has several pre-defined points in its build process at
1587   which it calls a function to (potentially) print output.  User-defined
1588   functions can be specified for these call-back points when &Build;
1589   or &Clean;is invoked:
1591  </para>
1593         <programlisting>
1594         env.Build(target = '.',
1595                on_analysis = dump_dependency,
1596                pre_update = my_print_command,
1597                post_update = my_error_handler)
1598                on_error = my_error_handler)
1599         </programlisting>
1601  <para>
1603   The specific call-back points are:
1605  </para>
1607  <variablelist>
1609   <varlistentry>
1610    <term><literal>on_analysis</literal></term>
1611    <listitem>
1612     <para>
1614      Called for every object, immediately after the object has been
1615      analyzed to see if it's out-of-date.  Typically used to print a
1616      trace of considered objects for debugging of unexpected dependencies.
1618     </para>
1619    </listitem>
1620   </varlistentry>
1622   <varlistentry>
1623    <term><literal>pre_update</literal></term>
1624    <listitem>
1625     <para>
1627      Called for every object that has been determined to be out-of-date
1628      before its update function or command is executed.  Typically used
1629      to print the command being called to update a target.
1631     </para>
1632    </listitem>
1633   </varlistentry>
1635   <varlistentry>
1636    <term><literal>post_update</literal></term>
1637    <listitem>
1638     <para>
1640      Called for every object after its update function or command has
1641      been executed.  Typically used to report that a top-level specified
1642      target is up-to-date or was not remade.
1644     </para>
1645    </listitem>
1646   </varlistentry>
1648   <varlistentry>
1649    <term><literal>on_error</literal></term>
1650    <listitem>
1651     <para>
1653      Called for every error returned by an update function or command.
1654      Typically used to report errors with some string that will be
1655      identifiable to build-analysis tools.
1657     </para>
1658    </listitem>
1659   </varlistentry>
1661  </variablelist>
1663  <para>
1665   Functions for each of these call-back points all take the same
1666   arguments:
1668  </para>
1670         <programlisting>
1671         my_dump_dependency(target, level, status, update, dependencies)
1672         </programlisting>
1674  <para>
1676   where the arguments are:
1678  </para>
1680  <variablelist>
1682   <varlistentry>
1683    <term><literal>target</literal></term>
1684    <listitem>
1685     <para>
1687      The target object being considered.
1689     </para>
1690    </listitem>
1691   </varlistentry>
1693   <varlistentry>
1694    <term><literal>level</literal></term>
1695    <listitem>
1696     <para>
1698      Specifies how many levels the dependency analysis has
1699      recursed in order to consider the <literal>target</literal>.
1700      A value of <literal>0</literal> specifies a top-level
1701      <literal>target</literal> (that is, one passed to the
1702      &Build; or &Clean; method).  Objects which a top-level
1703      <literal>target</literal> is directly dependent upon have a
1704      <literal>level</literal> of &lt;1>, their direct dependencies have a
1705      <literal>level</literal> of &lt;2>, etc.  Typically used to indent
1706      output to reflect the recursive levels.
1708     </para>
1709    </listitem>
1710   </varlistentry>
1712   <varlistentry>
1713    <term><literal>status</literal></term>
1714    <listitem>
1715     <para>
1717      A string specifying the current status of the target
1718      (<literal>"unknown"</literal>, <literal>"built"</literal>,
1719      <literal>"error"</literal>, <literal>"analyzed"</literal>, etc.).  A
1720      complete list will be enumerated and described during implementation.
1722     </para>
1723    </listitem>
1724   </varlistentry>
1726   <varlistentry>
1727    <term><literal>update</literal></term>
1728    <listitem>
1729     <para>
1731      The command line or function name that will be (or has been) executed
1732      to update the <literal>target</literal>.
1734     </para>
1735    </listitem>
1736   </varlistentry>
1738   <varlistentry>
1739    <term><literal>dependencies</literal></term>
1740    <listitem>
1741     <para>
1743      A list of direct dependencies of the target.
1745     </para>
1746    </listitem>
1747   </varlistentry>
1749  </variablelist>
1751 </section>
1755 <section id="separate">
1756  <title>Separate source and build trees</title>
1758 <!--
1759 I've never liked Cons' use of the name <literal>Link</literal>
1760 for this functionality,
1761 mainly because the term is overloaded
1762 with linking object files into an executable.
1763 Yet I've never come up with anything better.
1764 Any suggestions?
1767 <!--
1768 Also, I made this an &Environment; method because
1769 it logically belongs in the API reference
1770 (the build engine needs to know about it),
1771 and I thought it was clean to have
1772 everything in the build-engine API
1773 be called through an &Environment; object.
1774 But <literal>&Link</literal> isn't really
1775 associated with a specific environment
1776 (the &Cons; classic implementation just
1777 leaves it as a bare function call),
1778 so maybe we should just follow that example
1779 and not call it through an environment...
1782  <para>
1784   &SCons; allows target files to be built completely separately from
1785   the source files by "linking" a build directory to an underlying
1786   source directory:
1788  </para>
1790         <programlisting>
1791         env.Link('build', 'src')
1793         SConscript('build/SConscript')
1794         </programlisting>
1796  <para>
1798   &SCons; will copy (or hard link) necessary files (including the
1799   &SConscript; file) into the build directory hierarchy.  This allows the
1800   source directory to remain uncluttered by derived files.
1802  </para>
1804 </section>
1808 <section id="sect-variant">
1809  <title>Variant builds</title>
1811  <para>
1813   The &Link; method may be used in conjunction with multiple
1814   &consenvs; to support variant builds.  The following
1815   &SConstruct; and &SConscript; files would build separate debug and
1816   production versions of the same program side-by-side:
1818  </para>
1820         <programlisting>
1821         % cat SConstruct
1822         env = Environment()
1823         env.Link('build/debug', 'src')
1824         env.Link('build/production', 'src')
1825         flags = '-g'
1826         SConscript('build/debug/SConscript', Export(env))
1827         flags = '-O'
1828         SConscript('build/production/SConscript', Export(env))
1829         % cat src/SConscript
1830         env = Environment(CCFLAGS = flags)
1831         env.Program('hello', 'hello.c')
1832         </programlisting>
1834  <para>
1836   The following example would build the appropriate program for the current
1837   compilation platform, without having to clean any directories of object
1838   or executable files for other architectures:
1840  </para>
1842         <programlisting>
1843         % cat SConstruct
1844         build_platform = os.path.join('build', sys.platform)
1845         Link(build_platform, 'src')
1846         SConscript(os.path.join(build_platform, 'SConscript'))
1847         % cat src/SConscript
1848         env = Environment
1849         env.Program('hello', 'hello.c')
1850         </programlisting>
1852 </section>
1856 <section id="sect-repositories">
1857  <title>Code repositories</title>
1859 <!--
1860 Like &Link;, &Repository; and &Local; are part of the
1861 API reference, but not really tied to any specific environment.
1862 Is it better to be consistent about calling
1863 everything in the API through an environment,
1864 or to leave these independent so as
1865 not to complicate their calling interface?
1868  <para>
1870   &SCons; may use files from one or more shared code repositories in order
1871   to build local copies of changed target files.  A repository would
1872   typically be a central directory tree, maintained by an integrator,
1873   with known good libraries and executables.
1875  </para>
1877         <programlisting>
1878         Repository('/home/source/1.1', '/home/source/1.0')
1879         </programlisting>
1881  <para>
1883   Specified repositories will be searched in-order for any file
1884   (configuration file, input file, target file) that does not exist
1885   in the local directory tree.  When building a local target file,
1886   &SCons; will rewrite path names in the build command to use the
1887   necessary repository files.  This includes modifying lists of
1888   <option>-I</option> or <option>-L</option> flags to specify an
1889   appropriate set of include paths for dependency analysis.
1891  </para>
1892  <para>
1894   &SCons; will modify the Python <varname>sys.path</varname> variable to
1895   reflect the addition of repositories to the search path, so that any
1896   imported modules or packages necessary for the build can be found in a
1897   repository, as well.
1899  </para>
1900  <para>
1902   If an up-to-date target file is found in a code repository, the file
1903   will not be rebuilt or copied locally.  Files that must exist locally
1904   (for example, to run tests) may be specified:
1906  </para>
1908         <programlisting>
1909         Local('program', 'libfoo.a')
1910         </programlisting>
1912  <para>
1914   in which case &SCons; will copy or link an up-to-date copy of the
1915   file from the appropriate repository.
1917  </para>
1919 </section>
1923 <section id="sect-caching">
1924  <title>Derived-file caching</title>
1926 <!--
1927 There should be extensions to this part of the API for
1928 auxiliary functions like cleaning the cache.
1931  <para>
1933   &SCons; can maintain a cache directory of target files which may be
1934   shared among multiple builds.  This reduces build times by allowing
1935   developers working on a project together to share common target
1936   files:
1938  </para>
1940         <programlisting>
1941         Cache('/var/tmp/build.cache/i386')
1942         </programlisting>
1944  <para>
1946   When a target file is generated, a copy is added to the cache.
1947   When generating a target file, if &SCons; determines that a file
1948   that has been built with the exact same dependencies already exists
1949   in the specified cache, &SCons; will copy the cached file rather
1950   than re-building the target.
1952  </para>
1953  <para>
1955   Command-line options exist to modify the &SCons; caching behavior
1956   for a specific build, including disabling caching, building
1957   dependencies in random order, and displaying commands as if cached
1958   files were built.
1960  </para>
1962 </section>
1966 <section id="sect-jobs">
1967  <title>Job management</title>
1969 <!--
1970 This has been completely superseded by
1971 the more sophisticated &Task; manager
1972 that Anthony Roach has contributed.
1973 I need to write that up...
1976  <para>
1978   A simple API exists to inform the Build Engine how many jobs may
1979   be run simultaneously:
1981  </para>
1983         <programlisting>
1984         Jobs(limit = 4)
1985         </programlisting>
1987 </section>
1989 </chapter>