0c0438214963a7b0eb66d353cec456e8ad962b15
[scons.git] / doc / user / environments.in
1 <!--
2
3      __COPYRIGHT__
4
5      Permission is hereby granted, free of charge, to any person obtaining
6      a copy of this software and associated documentation files (the
7      "Software"), to deal in the Software without restriction, including
8      without limitation the rights to use, copy, modify, merge, publish,
9      distribute, sublicense, and/or sell copies of the Software, and to
10      permit persons to whom the Software is furnished to do so, subject to
11      the following conditions:
12
13      The above copyright notice and this permission notice shall be included
14      in all copies or substantial portions of the Software.
15
16      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17      KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18      WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19      NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20      LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21      OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22      WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 -->
25
26 <!--
27
28 =head1 More on construction environments
29
30 As previously mentioned, a B<construction environment> is an object that
31 has a set of keyword/value pairs and a set of methods, and which is used
32 to tell Cons how target files should be built.  This section describes
33 how Cons uses and expands construction environment values to control its
34 build behavior.
35
36 =head2 Construction variable expansion
37
38 Construction variables from a construction environment are expanded
39 by preceding the keyword with a C<%> (percent sign):
40
41      Construction variables:
42         XYZZY => 'abracadabra',
43
44      The string:  "The magic word is:  %XYZZY!"
45      expands to:  "The magic word is:  abracadabra!"
46
47 A construction variable name may be surrounded by C<{> and C<}> (curly
48 braces), which are stripped as part of the expansion.  This can
49 sometimes be necessary to separate a variable expansion from trailing
50 alphanumeric characters:
51
52      Construction variables:
53         OPT    => 'value1',
54         OPTION => 'value2',
55
56      The string:  "%OPT %{OPT}ION %OPTION %{OPTION}"
57      expands to:  "value1 value1ION value2 value2"
58
59 Construction variable expansion is recursive, that is, a string
60 containing C<%->expansions after substitution will be re-expanded until
61 no further substitutions can be made:
62
63      Construction variables:
64         STRING => 'The result is:  %FOO',
65         FOO    => '%BAR',
66         BAR    => 'final value',
67
68      The string:  "The string says:  %STRING"
69      expands to:  "The string says:  The result is:  final value"
70
71 If a construction variable is not defined in an environment, then the
72 null string is substituted:
73
74      Construction variables:
75         FOO => 'value1',
76         BAR => 'value2',
77
78      The string:  "%FOO <%NO_VARIABLE> %BAR"
79      expands to:  "value1 <> value2"
80
81 A doubled C<%%> will be replaced by a single C<%>:
82
83      The string:  "Here is a percent sign:  %%"
84      expands to:  "Here is a percent sign: %"
85
86 =head2 Default construction variables
87
88 When you specify no arguments when creating a new construction
89 environment:
90
91      $env = new cons();
92
93 Cons creates a reference to a new, default construction
94 environment. This contains a number of construction variables and some
95 methods. At the present writing, the default construction variables on a
96 UNIX system are:
97
98      CC            => 'cc',
99      CFLAGS        => '',
100      CCCOM         => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
101      CXX           => '%CC',
102      CXXFLAGS      => '%CFLAGS',
103      CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
104      INCDIRPREFIX  => '-I',
105      INCDIRSUFFIX  => '',
106      LINK          => '%CXX',
107      LINKCOM       => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
108      LINKMODULECOM => '%LD -r -o %> %<',
109      LIBDIRPREFIX  => '-L',
110      LIBDIRSUFFIX  => '',
111      AR         => 'ar',
112      ARFLAGS    => 'r',
113      ARCOM              => ['%AR %ARFLAGS %> %<', '%RANLIB %>'],
114      RANLIB     => 'ranlib',
115      AS         => 'as',
116      ASFLAGS    => '',
117      ASCOM              => '%AS %ASFLAGS %< -o %>',
118      LD         => 'ld',
119      LDFLAGS    => '',
120      PREFLIB    => 'lib',
121      SUFLIB     => '.a',
122      SUFLIBS    => '.so:.a',
123      SUFOBJ     => '.o',
124      SIGNATURE     => [ '*' => 'build' ],
125      ENV                => { 'PATH' => '/bin:/usr/bin' },
126
127
128 And on a Windows system (Windows NT), the default construction variables
129 are (unless the default rule style is set using the B<DefaultRules>
130 method):
131
132      CC         => 'cl',
133      CFLAGS     => '/nologo',
134      CCCOM              => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
135      CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
136      INCDIRPREFIX  => '/I',
137      INCDIRSUFFIX  => '',
138      LINK          => 'link',
139      LINKCOM       => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
140      LINKMODULECOM => '%LD /r /o %> %<',
141      LIBDIRPREFIX  => '/LIBPATH:',
142      LIBDIRSUFFIX  => '',
143      AR            => 'lib',
144      ARFLAGS       => '/nologo ',
145      ARCOM         => "%AR %ARFLAGS /out:%> %<",
146      RANLIB        => '',
147      LD            => 'link',
148      LDFLAGS       => '/nologo ',
149      PREFLIB       => '',
150      SUFEXE     => '.exe',
151      SUFLIB     => '.lib',
152      SUFLIBS    => '.dll:.lib',
153      SUFOBJ     => '.obj',
154      SIGNATURE     => [ '*' => 'build' ],
155
156 These variables are used by the various methods associated with the
157 environment. In particular, any method that ultimately invokes an external
158 command will substitute these variables into the final command, as
159 appropriate. For example, the C<Objects> method takes a number of source
160 files and arranges to derive, if necessary, the corresponding object
161 files:
162
163      Objects $env 'foo.c', 'bar.c';
164
165 This will arrange to produce, if necessary, F<foo.o> and F<bar.o>. The
166 command invoked is simply C<%CCCOM>, which expands, through substitution,
167 to the appropriate external command required to build each object. The
168 substitution rules will be discussed in detail in the next section.
169
170 The construction variables are also used for other purposes. For example,
171 C<CPPPATH> is used to specify a colon-separated path of include
172 directories. These are intended to be passed to the C preprocessor and are
173 also used by the C-file scanning machinery to determine the dependencies
174 involved in a C Compilation.
175
176 Variables beginning with underscore are created by various methods,
177 and should normally be considered ``internal'' variables. For example,
178 when a method is called which calls for the creation of an object from
179 a C source, the variable C<_IFLAGS> is created: this corresponds to the
180 C<-I> switches required by the C compiler to represent the directories
181 specified by C<CPPPATH>.
182
183 Note that, for any particular environment, the value of a variable is set
184 once, and then never reset (to change a variable, you must create a new
185 environment. Methods are provided for copying existing environments for this
186 purpose). Some internal variables, such as C<_IFLAGS> are created on demand,
187 but once set, they remain fixed for the life of the environment.
188
189 The C<CFLAGS>, C<LDFLAGS>, and C<ARFLAGS> variables all supply a place
190 for passing options to the compiler, loader, and archiver, respectively.
191
192 The C<INCDIRPREFIX> and C<INCDIRSUFFIX> variables specify option
193 strings to be appended to the beginning and end, respectively, of each
194 include directory so that the compiler knows where to find F<.h> files.
195 Similarly, the C<LIBDIRPREFIX> and C<LIBDIRSUFFIX> variables specify the
196 option string to be appended to the beginning of and end, respectively,
197 of each directory that the linker should search for libraries.
198
199 Another variable, C<ENV>, is used to determine the system environment during
200 the execution of an external command. By default, the only environment
201 variable that is set is C<PATH>, which is the execution path for a UNIX
202 command. For the utmost reproducibility, you should really arrange to set
203 your own execution path, in your top-level F<Construct> file (or perhaps by
204 importing an appropriate construction package with the Perl C<use>
205 command). The default variables are intended to get you off the ground.
206
207 =head2 Expanding variables in construction commands
208
209 Within a construction command, construction variables will be expanded
210 according to the rules described above.  In addition to normal variable
211 expansion from the construction environment, construction commands also
212 expand the following pseudo-variables to insert the specific input and
213 output files in the command line that will be executed:
214
215 =over 10
216
217 =item %>
218
219 The target file name.  In a multi-target command, this expands to the
220 first target mentioned.)
221
222 =item %0
223
224 Same as C<%E<gt>>.
225
226 =item %1, %2, ..., %9
227
228 These refer to the first through ninth input file, respectively.
229
230 =item %E<lt>
231
232 The full set of input file names. If any of these have been used
233 anywhere else in the current command line (via C<%1>, C<%2>, etc.), then
234 those will be deleted from the list provided by C<%E<lt>>. Consider the
235 following command found in a F<Conscript> file in the F<test> directory:
236
237      Command $env 'tgt', qw(foo bar baz), qq(
238         echo %< -i %1 > %>
239         echo %< -i %2 >> %>
240         echo %< -i %3 >> %>
241      );
242
243 If F<tgt> needed to be updated, then this would result in the execution of
244 the following commands, assuming that no remapping has been established for
245 the F<test> directory:
246
247      echo test/bar test/baz -i test/foo > test/tgt
248      echo test/foo test/baz -i test/bar >> test/tgt
249      echo test/foo test/bar -i test/baz >> test/tgt
250
251 =back
252
253 Any of the above pseudo-variables may be followed immediately by one of
254 the following suffixes to select a portion of the expanded path name:
255
256      :a    the absolute path to the file name
257      :b    the directory plus the file name stripped of any suffix
258      :d    the directory
259      :f    the file name
260      :s    the file name suffix
261      :F    the file name stripped of any suffix
262      :S    the absolute path path to a Linked source file
263
264 Continuing with the above example, C<%E<lt>:f> would expand to C<foo bar baz>,
265 and C<%E<gt>:d> would expand to C<test>.
266
267 There are additional C<%> elements which affect the command line(s):
268
269 =over 10
270
271 =item %[ %]
272
273 It is possible to programmatically rewrite part of the command by
274 enclosing part of it between C<%[> and C<%]>.  This will call the
275 construction variable named as the first word enclosed in the brackets
276 as a Perl code reference; the results of this call will be used to
277 replace the contents of the brackets in the command line.  For example,
278 given an existing input file named F<tgt.in>:
279
280      @keywords = qw(foo bar baz);
281      $env = new cons(X_COMMA => sub { join(",", @_) });
282      Command $env 'tgt', 'tgt.in', qq(
283         echo '# Keywords: %[X_COMMA @keywords %]' > %>
284         cat %< >> %>
285      );
286
287 This will execute:
288
289      echo '# Keywords: foo,bar,baz' > tgt
290      cat tgt.in >> tgt
291
292 =item %( %)
293
294 Cons includes the text of the command line in the MD5 signature for a
295 build, so that targets get rebuilt if you change the command line (to
296 add or remove an option, for example).  Command-line text in between
297 C<%(> and C<%)>, however, will be ignored for MD5 signature calculation.
298
299 Internally, Cons uses C<%(> and C<%)> around include and library
300 directory options (C<-I> and C<-L> on UNIX systems, C</I> and
301 C</LIBPATH> on Windows NT) to avoid rebuilds just because the directory
302 list changes.  Rebuilds occur only if the changed directory list causes
303 any included I<files> to change, and a changed include file is detected
304 by the MD5 signature calculation on the actual file contents.
305
306 =back
307
308 XXX DESCRIBE THE Literal() FUNCTION, TOO XXX
309
310 =head2 Expanding construction variables in file names
311
312 Cons expands construction variables in the source and target file names
313 passed to the various construction methods according to the expansion
314 rules described above:
315
316      $env = new cons(
317         DESTDIR =>      'programs',
318         SRCDIR  =>      'src',
319      );
320      Program $env '%DESTDIR/hello', '%SRCDIR/hello.c';
321
322 This allows for flexible configuration, through the construction
323 environment, of directory names, suffixes, etc.
324
325 -->
326
327   <para>
328
329   An <literal>environment</literal>
330   is a collection of values that
331   can affect how a program executes.
332   &SCons; distinguishes between three
333   different types of environments
334   that can affect the behavior of &SCons; itself
335   (subject to the configuration in the &SConscript; files),
336   as well as the compilers and other tools it executes:
337
338   </para>
339
340   <variablelist>
341
342     <varlistentry>
343     <term>External Environment</term>
344
345     <listitem>
346     <para>
347
348     The <literal>external environment</literal>
349     is the set of variables in the user's environment
350     at the time the user runs &SCons.
351     These variables are available within the &SConscript; files
352     through the Python <literal>os.environ</literal> dictionary.
353     See <xref linkend="sect-external-environments"></xref>, below.
354
355     </para>
356     </listitem>
357     </varlistentry>
358
359     <varlistentry>
360     <term>&ConsEnv;</term>
361
362     <listitem>
363     <para>
364
365     A &consenv;
366     is a distinct object creating within
367     a &SConscript; file and
368     and which contains values that
369     affect how &SCons; decides
370     what action to use to build a target,
371     and even to define which targets
372     should be built from which sources.
373     One of the most powerful features of &SCons;
374     is the ability to create multiple &consenvs;,
375     including the ability to clone a new, customized
376     &consenv; from an existing &consenv;.
377     See <xref linkend="sect-construction-environments"></xref>, below.
378
379     </para>
380     </listitem>
381     </varlistentry>
382
383     <varlistentry>
384     <term>Execution Environment</term>
385
386     <listitem>
387     <para>
388
389     An <literal>execution environment</literal>
390     is the values that &SCons; sets
391     when executing an external
392     command (such as a compiler or linker)
393     to build one or more targets.
394     Note that this is not the same as
395     the <literal>external environment</literal>
396     (see above).
397     See <xref linkend="sect-execution-environments"></xref>, below.
398
399     </para>
400     </listitem>
401     </varlistentry>
402
403   </variablelist>
404
405   <para>
406
407   Unlike &Make;,  &SCons; does not automatically
408   copy or import values between different environments
409   (with the exception of explicit clones of &consenvs,
410   which inherit values from their parent).
411   This is a deliberate design choice
412   to make sure that builds are,
413   by default, repeatable regardless of
414   the values in the user's external environment.
415   This avoids a whole class of problems with builds
416   where a developer's local build works
417   because a custom variable setting
418   causes a different compiler or build option to be used,
419   but the checked-in change breaks the official build
420   because it uses different environment variable settings.
421
422   </para>
423
424   <para>
425
426   Note that the &SConscript; writer can
427   easily arrange for variables to be
428   copied or imported between environments,
429   and this is often very useful
430   (or even downright necessary)
431   to make it easy for developers
432   to customize the build in appropriate ways.
433   The point is <emphasis>not</emphasis>
434   that copying variables between different environments
435   is evil and must always be avoided.
436   Instead, it should be up to the
437   implementer of the build system
438   to make conscious choices
439   about how and when to import
440   a variable from one environment to another,
441   making informed decisions about
442   striking the right balance
443   between making the build
444   repeatable on the one hand
445   and convenient to use on the other.
446
447   </para>
448
449   <section id="sect-external-environments">
450   <title>Using Values From the External Environment</title>
451
452   <para>
453
454   The <literal>external environment</literal>
455   variable settings that
456   the user has in force
457   when executing &SCons;
458   are available through the normal Python
459   <envar>os.environ</envar>
460   dictionary.
461   This means that you must add an
462   <literal>import os</literal> statement
463   to any &SConscript; file
464   in which you want to use
465   values from the user's external environment.
466
467   </para>
468
469    <scons_example name="ex1">
470      <file name="SConstruct" printme="1">
471      import os
472      </file>
473      <file name="foo.c">
474     int main() { }
475      </file>
476    </scons_example>
477
478   <para>
479
480   More usefully, you can use the
481   <envar>os.environ</envar>
482   dictionary in your &SConscript;
483   files to initialize &consenvs;
484   with values from the user's external environment.
485   See the next section,
486   <xref linkend="sect-construction-environments"></xref>,
487   for information on how to do this.
488
489   </para>
490
491   </section>
492
493   <section id="sect-construction-environments">
494   <title>Construction Environments</title>
495
496     <para>
497
498       It is rare that all of the software in a large,
499       complicated system needs to be built the same way.
500       For example, different source files may need different options
501       enabled on the command line,
502       or different executable programs need to be linked
503       with different libraries.
504       &SCons; accommodates these different build
505       requirements by allowing you to create and
506       configure multiple &consenvs;
507       that control how the software is built.
508       A &consenv; is an object
509       that has a number of associated
510       &consvars;, each with a name and a value.
511       (A construction environment also has an attached
512       set of &Builder; methods,
513       about which we'll learn more later.)
514
515     </para>
516
517     <section>
518     <title>Creating a &ConsEnv;:  the &Environment; Function</title>
519
520       <para>
521
522         A &consenv; is created by the &Environment; method:
523
524       </para>
525
526        <sconstruct>
527          env = Environment()
528        </sconstruct>
529
530       <para>
531
532         By default, &SCons; initializes every
533         new construction environment
534         with a set of &consvars;
535         based on the tools that it finds on your system,
536         plus the default set of builder methods
537         necessary for using those tools.
538         The construction variables
539         are initialized with values describing
540         the C compiler,
541         the Fortran compiler,
542         the linker,
543         etc.,
544         as well as the command lines to invoke them.
545
546       </para>
547
548       <para>
549
550         When you initialize a construction environment
551         you can set the values of the
552         environment's &consvars;
553         to control how a program is built.
554         For example:
555
556       </para>
557
558        <scons_example name="ex1">
559          <file name="SConstruct" printme="1">
560          env = Environment(CC = 'gcc',
561                            CCFLAGS = '-O2')
562
563          env.Program('foo.c')
564          </file>
565          <file name="foo.c">
566         int main() { }
567          </file>
568        </scons_example>
569
570       <para>
571
572         The construction environment in this example
573         is still initialized with the same default
574         construction variable values,
575         except that the user has explicitly specified use of the
576         GNU C compiler &gcc;,
577         and further specifies that the <literal>-O2</literal>
578         (optimization level two)
579         flag should be used when compiling the object file.
580         In other words, the explicit initializations of
581         &cv-link-CC; and &cv-link-CCFLAGS;
582         override the default values in the newly-created
583         construction environment.
584         So a run from this example would look like:
585
586       </para>
587
588       <scons_output example="ex1">
589          <scons_output_command>scons -Q</scons_output_command>
590       </scons_output>
591
592     </section>
593
594     <section>
595     <title>Fetching Values From a &ConsEnv;</title>
596
597       <para>
598
599       You can fetch individual construction variables
600       using the normal syntax
601       for accessing individual named items in a Python dictionary:
602
603       </para>
604
605       <scons_example name="ex6">
606         <file name="SConstruct" printme="1">
607          env = Environment()
608          print "CC is:", env['CC']
609         </file>
610       </scons_example>
611
612       <para>
613
614       This example &SConstruct; file doesn't build anything,
615       but because it's actually a Python script,
616       it will print the value of &cv-link-CC; for us:
617
618       </para>
619
620       <scons_output example="ex6">
621          <scons_output_command>scons -Q</scons_output_command>
622       </scons_output>
623
624       <para>
625
626       A construction environment, however,
627       is actually an object with associated methods, etc.
628       If you want to have direct access to only the
629       dictionary of construction variables,
630       you can fetch this using the &Dictionary; method:
631
632       </para>
633
634       <scons_example name="ex6b">
635          <file name="SConstruct" printme="1">
636          env = Environment(FOO = 'foo', BAR = 'bar')
637          dict = env.Dictionary()
638          for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']:
639              print "key = %s, value = %s" % (key, dict[key])
640          </file>
641       </scons_Example>
642
643       <para>
644
645       This &SConstruct; file
646       will print the specified dictionary items for us on POSIX
647       systems as follows:
648
649       </para>
650
651       <scons_output example="ex6b" os="posix">
652          <scons_output_command>scons -Q</scons_output_command>
653       </scons_output>
654
655       <para>
656
657       And on Windows:
658
659       </para>
660
661       <scons_output example="ex6b" os="win32">
662          <scons_output_command>scons -Q</scons_output_command>
663       </scons_output>
664
665       <para>
666
667       If you want to loop and print the values of
668       all of the construction variables in a construction environment,
669       the Python code to do that in sorted order might look something like:
670
671       </para>
672
673       <sconstruct>
674          env = Environment()
675          dict = env.Dictionary()
676          keys = dict.keys()
677          keys.sort()
678          for key in keys:
679              print "construction variable = '%s', value = '%s'" % (key, dict[key])
680       </sconstruct>
681
682     </section>
683
684     <section>
685     <title>Expanding Values From a &ConsEnv;:  the &subst; Method</title>
686
687       <para>
688
689       Another way to get information from
690       a construction environment.
691       is to use the &subst; method
692       on a string containing <literal>$</literal> expansions
693       of construction variable names.
694       As a simple example,
695       the example from the previous
696       section that used
697       <literal>env['CC']</literal>
698       to fetch the value of &cv-link-CC;
699       could also be written as:
700
701       </para>
702
703       <sconstruct>
704         env = Environment()
705         print "CC is:", env.subst('$CC')
706       </sconstruct>
707
708       <para>
709
710       One advantage of using
711       &subst; to expand strings is
712       that construction variables
713       in the result get re-expanded until
714       there are no expansions left in the string.
715       So a simple fetch of a value like
716       &cv-link-CCCOM;:
717
718       </para>
719
720       <sconstruct>
721         env = Environment(CCFLAGS = '-DFOO')
722         print "CCCOM is:", env['CCCOM']
723       </sconstruct>
724
725       <para>
726
727       Will print the unexpanded value of &cv-CCCOM;,
728       showing us the construction
729       variables that still need to be expanded:
730
731       </para>
732
733       <screen>
734         % <userinput>scons -Q</userinput>
735         CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES
736         scons: `.' is up to date.
737       </screen>
738
739       <para>
740
741       Calling the &subst; method on <varname>$CCOM</varname>,
742       however:
743
744       </para>
745
746       <sconstruct>
747         env = Environment(CCFLAGS = '-DFOO')
748         print "CCCOM is:", env.subst('$CCCOM')
749       </sconstruct>
750
751       <para>
752
753       Will recursively expand all of
754       the construction variables prefixed
755       with <literal>$</literal> (dollar signs),
756       showing us the final output:
757
758       </para>
759
760       <screen>
761         % <userinput>scons -Q</userinput>
762         CCCOM is: gcc -DFOO -c -o
763         scons: `.' is up to date.
764       </screen>
765
766       <para>
767
768       Note that because we're not expanding this
769       in the context of building something
770       there are no target or source files
771       for &cv-link-TARGET; and &cv-link-SOURCES; to expand.
772
773       </para>
774
775     </section>
776
777     <section>
778     <title>Controlling the Default &ConsEnv;:  the &DefaultEnvironment; Function</title>
779
780       <para>
781
782       All of the &Builder; functions that we've introduced so far,
783       like &Program; and &Library;,
784       actually use a default &consenv;
785       that contains settings
786       for the various compilers
787       and other tools that
788       &SCons; configures by default,
789       or otherwise knows about
790       and has discovered on your system.
791       The goal of the default construction environment
792       is to make many configurations to "just work"
793       to build software using
794       readily available tools
795       with a minimum of configuration changes.
796
797       </para>
798
799       <para>
800
801       You can, however, control the settings
802       in the default contstruction environment
803       by using the &DefaultEnvironment; function
804       to initialize various settings:
805
806       </para>
807
808       <sconstruct>
809
810       DefaultEnvironment(CC = '/usr/local/bin/gcc')
811
812       </sconstruct>
813
814       <para>
815
816       When configured as above,
817       all calls to the &Program;
818       or &Object; Builder
819       will build object files with the
820       <filename>/usr/local/bin/gcc</filename>
821       compiler.
822
823       </para>
824
825       <para>
826
827       Note that the &DefaultEnvironment; function
828       returns the initialized
829       default construction environment object,
830       which can then be manipulated like any
831       other construction environment.
832       So the following
833       would be equivalent to the
834       previous example,
835       setting the &cv-CC;
836       variable to <filename>/usr/local/bin/gcc</filename>
837       but as a separate step after
838       the default construction environment has been initialized:
839
840       </para>
841
842       <sconstruct>
843
844       env = DefaultEnvironment()
845       env['CC'] = '/usr/local/bin/gcc'
846
847       </sconstruct>
848
849       <para>
850
851       One very common use of the &DefaultEnvironment; function
852       is to speed up &SCons; initialization.
853       As part of trying to make most default
854       configurations "just work,"
855       &SCons; will actually
856       search the local system for installed
857       compilers and other utilities.
858       This search can take time,
859       especially on systems with
860       slow or networked file systems.
861       If you know which compiler(s) and/or
862       other utilities you want to configure,
863       you can control the search
864       that &SCons; performs
865       by specifying some specific
866       tool modules with which to
867       initialize the default construction environment:
868
869       </para>
870
871       <sconstruct>
872
873       env = DefaultEnvironment(tools = ['gcc', 'gnulink'],
874                                CC = '/usr/local/bin/gcc')
875
876       </sconstruct>
877
878       <para>
879
880       So the above example would tell &SCons;
881       to explicitly configure the default environment
882       to use its normal GNU Compiler and GNU Linker settings
883       (without having to search for them,
884       or any other utilities for that matter),
885       and specifically to use the compiler found at
886       <filename>/usr/local/bin/gcc</filename>.
887
888       </para>
889
890     </section>
891
892     <section>
893     <title>Multiple &ConsEnvs;</title>
894
895       <para>
896
897       The real advantage of construction environments
898       is that you can create as many different construction
899       environments as you need,
900       each tailored to a different way to build
901       some piece of software or other file.
902       If, for example, we need to build
903       one program with the <literal>-O2</literal> flag
904       and another with the <literal>-g</literal> (debug) flag,
905       we would do this like so:
906
907       </para>
908
909       <scons_example name="ex2">
910         <file name="SConstruct" printme="1">
911          opt = Environment(CCFLAGS = '-O2')
912          dbg = Environment(CCFLAGS = '-g')
913
914          opt.Program('foo', 'foo.c')
915
916          dbg.Program('bar', 'bar.c')
917         </file>
918         <file name="foo.c">
919         int main() { }
920         </file>
921         <file name="bar.c">
922         int main() { }
923         </file>
924       </scons_example>
925
926       <scons_output example="ex2">
927          <scons_output_command>scons -Q</scons_output_command>
928       </scons_output>
929
930       <para>
931
932       We can even use multiple construction environments to build
933       multiple versions of a single program.
934       If you do this by simply trying to use the
935       &b-link-Program; builder with both environments, though,
936       like this:
937
938       </para>
939
940       <scons_example name="ex3">
941         <file name="SConstruct" printme="1">
942          opt = Environment(CCFLAGS = '-O2')
943          dbg = Environment(CCFLAGS = '-g')
944
945          opt.Program('foo', 'foo.c')
946
947          dbg.Program('foo', 'foo.c')
948         </file>
949         <file name="foo.c">
950         int main() { }
951         </file>
952       </scons_example>
953
954       <para>
955
956       Then &SCons; generates the following error:
957
958       </para>
959
960       <scons_output example="ex3">
961          <scons_output_command>scons -Q</scons_output_command>
962       </scons_output>
963
964       <para>
965
966       This is because the two &b-Program; calls have
967       each implicitly told &SCons; to generate an object file named
968       <filename>foo.o</filename>,
969       one with a &cv-link-CCFLAGS; value of
970       <literal>-O2</literal>
971       and one with a &cv-link-CCFLAGS; value of
972       <literal>-g</literal>.
973       &SCons; can't just decide that one of them
974       should take precedence over the other,
975       so it generates the error.
976       To avoid this problem,
977       we must explicitly specify
978       that each environment compile
979       <filename>foo.c</filename>
980       to a separately-named object file
981       using the &b-link-Object; builder, like so:
982
983       </para>
984
985       <scons_example name="ex4">
986         <file name="SConstruct" printme="1">
987          opt = Environment(CCFLAGS = '-O2')
988          dbg = Environment(CCFLAGS = '-g')
989
990          o = opt.Object('foo-opt', 'foo.c')
991          opt.Program(o)
992
993          d = dbg.Object('foo-dbg', 'foo.c')
994          dbg.Program(d)
995         </file>
996         <file name="foo.c">
997         int main() { }
998         </file>
999       </scons_example>
1000
1001       <para>
1002
1003       Notice that each call to the &b-Object; builder
1004       returns a value,
1005       an internal &SCons; object that
1006       represents the object file that will be built.
1007       We then use that object
1008       as input to the &b-Program; builder.
1009       This avoids having to specify explicitly
1010       the object file name in multiple places,
1011       and makes for a compact, readable
1012       &SConstruct; file.
1013       Our &SCons; output then looks like:
1014
1015       </para>
1016
1017       <scons_output example="ex4">
1018          <scons_output_command>scons -Q</scons_output_command>
1019       </scons_output>
1020
1021     </section>
1022
1023     <section>
1024     <title>Making Copies of &ConsEnvs;:  the &Clone; Method</title>
1025
1026       <para>
1027
1028       Sometimes you want more than one construction environment
1029       to share the same values for one or more variables.
1030       Rather than always having to repeat all of the common
1031       variables when you create each construction environment,
1032       you can use the &Clone; method
1033       to create a copy of a construction environment.
1034
1035       </para>
1036
1037       <para>
1038
1039       Like the &Environment; call that creates a construction environment,
1040       the &Clone; method takes &consvar; assignments,
1041       which will override the values in the copied construction environment.
1042       For example, suppose we want to use &gcc;
1043       to create three versions of a program,
1044       one optimized, one debug, and one with neither.
1045       We could do this by creating a "base" construction environment
1046       that sets &cv-link-CC; to &gcc;,
1047       and then creating two copies,
1048       one which sets &cv-link-CCFLAGS; for optimization
1049       and the other which sets &cv-CCFLAGS; for debugging:
1050
1051       </para>
1052
1053       <scons_example name="ex5">
1054         <file name="SConstruct" printme="1">
1055          env = Environment(CC = 'gcc')
1056          opt = env.Clone(CCFLAGS = '-O2')
1057          dbg = env.Clone(CCFLAGS = '-g')
1058
1059          env.Program('foo', 'foo.c')
1060
1061          o = opt.Object('foo-opt', 'foo.c')
1062          opt.Program(o)
1063
1064          d = dbg.Object('foo-dbg', 'foo.c')
1065          dbg.Program(d)
1066         </file>
1067         <file name="foo.c">
1068         int main() { }
1069         </file>
1070       </scons_example>
1071
1072       <para>
1073
1074       Then our output would look like:
1075
1076       </para>
1077
1078       <scons_output example="ex5">
1079          <scons_output_command>scons -Q</scons_output_command>
1080       </scons_output>
1081
1082     </section>
1083
1084     <section>
1085     <title>Replacing Values:  the &Replace; Method</title>
1086
1087       <para>
1088
1089       You can replace existing construction variable values
1090       using the &Replace; method:
1091
1092       </para>
1093
1094       <scons_example name="Replace1">
1095         <file name="SConstruct" printme="1">
1096          env = Environment(CCFLAGS = '-DDEFINE1')
1097          env.Replace(CCFLAGS = '-DDEFINE2')
1098          env.Program('foo.c')
1099         </file>
1100         <file name="foo.c">
1101         int main() { }
1102         </file>
1103       </scons_example>
1104
1105       <para>
1106
1107       The replacing value
1108       (<literal>-DDEFINE2</literal> in the above example)
1109       completely replaces the value in the
1110       construction environment:
1111
1112       </para>
1113
1114       <scons_output example="Replace1">
1115          <scons_output_command>scons -Q</scons_output_command>
1116       </scons_output>
1117
1118       <para>
1119
1120       You can safely call &Replace;
1121       for construction variables that
1122       don't exist in the construction environment:
1123
1124       </para>
1125
1126       <scons_example name="Replace-nonexistent">
1127         <file name="SConstruct" printme="1">
1128          env = Environment()
1129          env.Replace(NEW_VARIABLE = 'xyzzy')
1130          print "NEW_VARIABLE =", env['NEW_VARIABLE']
1131         </file>
1132       </scons_example>
1133
1134       <para>
1135
1136       In this case,
1137       the construction variable simply
1138       gets added to the construction environment:
1139
1140       </para>
1141
1142       <scons_output example="Replace-nonexistent">
1143          <scons_output_command>scons -Q</scons_output_command>
1144       </scons_output>
1145
1146       <para>
1147
1148       Because the variables
1149       aren't expanded until the construction environment
1150       is actually used to build the targets,
1151       and because &SCons; function and method calls
1152       are order-independent,
1153       the last replacement "wins"
1154       and is used to build all targets,
1155       regardless of the order in which
1156       the calls to Replace() are
1157       interspersed with calls to
1158       builder methods:
1159
1160       </para>
1161
1162       <scons_example name="Replace2">
1163         <file name="SConstruct" printme="1">
1164          env = Environment(CCFLAGS = '-DDEFINE1')
1165          print "CCFLAGS =", env['CCFLAGS']
1166          env.Program('foo.c')
1167
1168          env.Replace(CCFLAGS = '-DDEFINE2')
1169          print "CCFLAGS =", env['CCFLAGS']
1170          env.Program('bar.c')
1171         </file>
1172         <file name="foo.c">
1173         int main() { }
1174         </file>
1175         <file name="bar.c">
1176         int main() { }
1177         </file>
1178       </scons_example>
1179
1180       <para>
1181
1182       The timing of when the replacement
1183       actually occurs relative
1184       to when the targets get built
1185       becomes apparent
1186       if we run &scons; without the <literal>-Q</literal>
1187       option:
1188
1189       </para>
1190
1191       <scons_output example="Replace2">
1192          <scons_output_command>scons</scons_output_command>
1193       </scons_output>
1194
1195       <para>
1196
1197       Because the replacement occurs while
1198       the &SConscript; files are being read,
1199       the &cv-link-CCFLAGS;
1200       variable has already been set to
1201       <literal>-DDEFINE2</literal>
1202       by the time the &foo_o; target is built,
1203       even though the call to the &Replace;
1204       method does not occur until later in
1205       the &SConscript; file.
1206
1207       </para>
1208
1209     </section>
1210
1211     <section>
1212     <title>Setting Values Only If They're Not Already Defined:  the &SetDefault; Method</title>
1213
1214       <para>
1215
1216       Sometimes it's useful to be able to specify
1217       that a construction variable should be
1218       set to a value only if the construction environment
1219       does not already have that variable defined
1220       You can do this with the &SetDefault; method,
1221       which behaves similarly to the <function>set_default</function>
1222       method of Python dictionary objects:
1223
1224       </para>
1225
1226       <sconstruct>
1227       env.SetDefault(SPECIAL_FLAG = '-extra-option')
1228       </sconstruct>
1229
1230       <para>
1231
1232       This is especially useful
1233       when writing your own <literal>Tool</literal> modules
1234       to apply variables to construction environments.
1235       <!--
1236       See <xref linkend="chap-tool-modules"></xref>
1237       for more information about writing
1238       Tool modules.
1239       -->
1240
1241       </para>
1242
1243     </section>
1244
1245     <section>
1246     <title>Appending to the End of Values:  the &Append; Method</title>
1247
1248       <para>
1249
1250       You can append a value to
1251       an existing construction variable
1252       using the &Append; method:
1253
1254       </para>
1255
1256       <scons_example name="ex8">
1257         <file name="SConstruct" printme="1">
1258          env = Environment(CCFLAGS = ['-DMY_VALUE'])
1259          env.Append(CCFLAGS = ['-DLAST'])
1260          env.Program('foo.c')
1261         </file>
1262         <file name="foo.c">
1263         int main() { }
1264         </file>
1265       </scons_example>
1266
1267       <para>
1268
1269       &SCons; then supplies both the <literal>-DMY_VALUE</literal> and
1270       <literal>-DLAST</literal> flags when compiling the object file:
1271
1272       </para>
1273
1274       <scons_output example="ex8">
1275          <scons_output_command>scons -Q</scons_output_command>
1276       </scons_output>
1277
1278       <para>
1279
1280       If the construction variable doesn't already exist,
1281       the &Append; method will create it:
1282
1283       </para>
1284
1285       <scons_example name="Append-nonexistent">
1286         <file name="SConstruct" printme="1">
1287          env = Environment()
1288          env.Append(NEW_VARIABLE = 'added')
1289          print "NEW_VARIABLE =", env['NEW_VARIABLE']
1290         </file>
1291       </scons_example>
1292
1293       <para>
1294
1295       Which yields:
1296
1297       </para>
1298
1299       <scons_output example="Append-nonexistent">
1300          <scons_output_command>scons -Q</scons_output_command>
1301       </scons_output>
1302
1303       <para>
1304
1305       Note that the &Append; function tries to be "smart"
1306       about how the new value is appended to the old value.
1307       If both are strings, the previous and new strings
1308       are simply concatenated.
1309       Similarly, if both are lists,
1310       the lists are concatenated.
1311       If, however, one is a string and the other is a list,
1312       the string is added as a new element to the list.
1313
1314       </para>
1315
1316     </section>
1317
1318     <section>
1319     <title>Appending Unique Values:  the &AppendUnique; Method</title>
1320
1321       <para>
1322
1323       Some times it's useful to add a new value
1324       only if the existing construction variable
1325       doesn't already contain the value.
1326       This can be done using the &AppendUnique; method:
1327
1328       </para>
1329
1330       <sconstruct>
1331       env.AppendUnique(CCFLAGS=['-g'])
1332       </sconstruct>
1333
1334       <para>
1335
1336       In the above example,
1337       the <literal>-g</literal> would be added
1338       only if the &cv-CCFLAGS; variable
1339       does not already contain a <literal>-g</literal> value.
1340
1341       </para>
1342
1343     </section>
1344
1345     <section>
1346     <title>Appending to the Beginning of Values:  the &Prepend; Method</title>
1347
1348       <para>
1349
1350       You can append a value to the beginning of
1351       an existing construction variable
1352       using the &Prepend; method:
1353
1354       </para>
1355
1356       <scons_example name="ex9">
1357         <file name="SConstruct" printme="1">
1358          env = Environment(CCFLAGS = ['-DMY_VALUE'])
1359          env.Prepend(CCFLAGS = ['-DFIRST'])
1360          env.Program('foo.c')
1361         </file>
1362         <file name="foo.c">
1363         int main() { }
1364         </file>
1365       </scons_example>
1366
1367       <para>
1368
1369       &SCons; then supplies both the <literal>-DFIRST</literal> and
1370       <literal>-DMY_VALUE</literal> flags when compiling the object file:
1371
1372       </para>
1373
1374       <scons_output example="ex9">
1375          <scons_output_command>scons -Q</scons_output_command>
1376       </scons_output>
1377
1378       <para>
1379
1380       If the construction variable doesn't already exist,
1381       the &Prepend; method will create it:
1382
1383       </para>
1384
1385       <scons_example name="Prepend-nonexistent">
1386         <file name="SConstruct" printme="1">
1387          env = Environment()
1388          env.Prepend(NEW_VARIABLE = 'added')
1389          print "NEW_VARIABLE =", env['NEW_VARIABLE']
1390         </file>
1391       </scons_example>
1392
1393       <para>
1394
1395       Which yields:
1396
1397       </para>
1398
1399       <scons_output example="Prepend-nonexistent">
1400          <scons_output_command>scons -Q</scons_output_command>
1401       </scons_output>
1402
1403       <para>
1404
1405       Like the &Append; function,
1406       the &Prepend; function tries to be "smart"
1407       about how the new value is appended to the old value.
1408       If both are strings, the previous and new strings
1409       are simply concatenated.
1410       Similarly, if both are lists,
1411       the lists are concatenated.
1412       If, however, one is a string and the other is a list,
1413       the string is added as a new element to the list.
1414
1415       </para>
1416
1417     </section>
1418
1419     <section>
1420     <title>Prepending Unique Values:  the &PrependUnique; Method</title>
1421
1422       <para>
1423
1424       Some times it's useful to add a new value
1425       to the beginning of a construction variable
1426       only if the existing value
1427       doesn't already contain the to-be-added value.
1428       This can be done using the &PrependUnique; method:
1429
1430       </para>
1431
1432       <sconstruct>
1433       env.PrependUnique(CCFLAGS=['-g'])
1434       </sconstruct>
1435
1436       <para>
1437
1438       In the above example,
1439       the <literal>-g</literal> would be added
1440       only if the &cv-CCFLAGS; variable
1441       does not already contain a <literal>-g</literal> value.
1442
1443       </para>
1444
1445     </section>
1446
1447   </section>
1448
1449   <section id="sect-execution-environments">
1450   <title>Controlling the Execution Environment for Issued Commands</title>
1451
1452     <para>
1453
1454       When &SCons; builds a target file,
1455       it does not execute the commands with
1456       the same external environment
1457       that you used to execute &SCons;.
1458       Instead, it uses the dictionary
1459       stored in the &cv-link-ENV; construction variable
1460       as the external environment
1461       for executing commands.
1462
1463     </para>
1464
1465     <para>
1466
1467       The most important ramification of this behavior
1468       is that the &PATH; environment variable,
1469       which controls where the operating system
1470       will look for commands and utilities,
1471       is not the same as in the external environment
1472       from which you called &SCons;.
1473       This means that &SCons; will not, by default,
1474       necessarily find all of the tools
1475       that you can execute from the command line.
1476
1477     </para>
1478
1479     <para>
1480
1481       The default value of the &PATH; environment variable
1482       on a POSIX system
1483       is <literal>/usr/local/bin:/bin:/usr/bin</literal>.
1484       The default value of the &PATH; environment variable
1485       on a Windows system comes from the Windows registry
1486       value for the command interpreter.
1487       If you want to execute any commands--compilers, linkers, etc.--that
1488       are not in these default locations,
1489       you need to set the &PATH; value
1490       in the &cv-ENV; dictionary
1491       in your construction environment.
1492
1493     </para>
1494
1495     <para>
1496
1497       The simplest way to do this is to initialize explicitly
1498       the value when you create the construction environment;
1499       this is one way to do that:
1500
1501     </para>
1502
1503     <sconstruct>
1504       path = ['/usr/local/bin', '/bin', '/usr/bin']
1505       env = Environment(ENV = {'PATH' : path})
1506     </sconstruct>
1507
1508     <para>
1509
1510     Assign a dictionary to the &cv-ENV;
1511     construction variable in this way
1512     completely resets the external environment
1513     so that the only variable that will be
1514     set when external commands are executed
1515     will be the &PATH; value.
1516     If you want to use the rest of
1517     the values in &cv-ENV; and only
1518     set the value of &PATH;,
1519     the most straightforward way is probably:
1520
1521     </para>
1522
1523     <sconstruct>
1524       env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin']
1525     </sconstruct>
1526
1527     <para>
1528
1529     Note that &SCons; does allow you to define
1530     the directories in the &PATH; in a string,
1531     separated by the pathname-separator character
1532     for your system (':' on POSIX systems, ';' on Windows):
1533
1534     </para>
1535
1536     <sconstruct>
1537       env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'
1538     </sconstruct>
1539
1540     <para>
1541
1542     But doing so makes your &SConscript; file less portable,
1543     (although in this case that may not be a huge concern
1544     since the directories you list are likley system-specific, anyway).
1545
1546     </para>
1547
1548     <!--
1549
1550     <scons_example name="ex1">
1551       <file name="SConstruct" printme="1">
1552       env = Environment()
1553       env.Command('foo', [], '__ROOT__/usr/bin/printenv.py')
1554       </file>
1555       <file name="__ROOT__/usr/bin/printenv.py" chmod="0755">
1556       #!/usr/bin/env python
1557       import os
1558       import sys
1559       if len(sys.argv) > 1:
1560           keys = sys.argv[1:]
1561       else:
1562           keys = os.environ.keys()
1563           keys.sort()
1564       for key in keys:
1565           print "    " + key + "=" + os.environ[key]
1566       </file>
1567     </scons_example>
1568
1569     <para>
1570
1571     </para>
1572
1573     <scons_output example="ex1">
1574       <scons_output_command>scons -Q</scons_output_command>
1575     </scons_output>
1576
1577     -->
1578
1579     <section>
1580     <title>Propagating &PATH; From the External Environment</title>
1581
1582       <para>
1583
1584       You may want to propagate the external &PATH;
1585       to the execution environment for commands.
1586       You do this by initializing the &PATH;
1587       variable with the &PATH; value from
1588       the <literal>os.environ</literal>
1589       dictionary,
1590       which is Python's way of letting you
1591       get at the external environment:
1592
1593       </para>
1594
1595       <sconstruct>
1596         import os
1597         env = Environment(ENV = {'PATH' : os.environ['PATH']})
1598       </sconstruct>
1599
1600       <para>
1601
1602       Alternatively, you may find it easier
1603       to just propagate the entire external
1604       environment to the execution environment
1605       for commands.
1606       This is simpler to code than explicity
1607       selecting the &PATH; value:
1608
1609       </para>
1610
1611       <sconstruct>
1612         import os
1613         env = Environment(ENV = os.environ)
1614       </sconstruct>
1615
1616       <para>
1617
1618       Either of these will guarantee that
1619       &SCons; will be able to execute
1620       any command that you can execute from the command line.
1621       The drawback is that the build can behave
1622       differently if it's run by people with
1623       different &PATH; values in their environment--for example,
1624       if both the <literal>/bin</literal> and
1625       <literal>/usr/local/bin</literal> directories
1626       have different &cc; commands,
1627       then which one will be used to compile programs
1628       will depend on which directory is listed
1629       first in the user's &PATH; variable.
1630
1631       </para>
1632
1633     </section>
1634
1635     <section>
1636     <title>Adding to <varname>PATH</varname> Values in the Execution Environment</title>
1637
1638       <para>
1639
1640       One of the most common requirements
1641       for manipulating a variable in the execution environment
1642       is to add one or more custom directories to a search
1643       like the <envar>$PATH</envar> variable on Linux or POSIX systems,
1644       or the <envar>%PATH%</envar> variable on Windows,
1645       so that a locally-installed compiler or other utility
1646       can be found when &SCons; tries to execute it to update a target.
1647       &SCons; provides &PrependENVPath; and &AppendENVPath; functions
1648       to make adding things to execution variables convenient.
1649       You call these functions by specifying the variable
1650       to which you want the value added,
1651       and then value itself.
1652       So to add some <filename>/usr/local</filename> directories
1653       to the <envar>$PATH</envar> and <envar>$LIB</envar> variables,
1654       you might:
1655
1656       </para>
1657
1658       <sconstruct>
1659         env = Environment(ENV = os.environ)
1660         env.PrependENVPath('PATH', '/usr/local/bin')
1661         env.AppendENVPath('LIB', '/usr/local/lib')
1662       </sconstruct>
1663
1664       <para>
1665
1666       Note that the added values are strings,
1667       and if you want to add multiple directories to
1668       a variable like <envar>$PATH</envar>,
1669       you must include the path separate character
1670       (<literal>:</literal> on Linux or POSIX,
1671       <literal>;</literal> on Windows)
1672       in the string.
1673
1674       </para>
1675
1676     </section>
1677
1678   </section>