563d63531599e13595f98c09091b962fa36108f0
[scons.git] / doc / user / environments.xml
1 <!--
2
3      __COPYRIGHT__
4
5      Permission is hereby granted, free of charge, to any person obtaining
6      a copy of this software and associated documentation files (the
7      "Software"), to deal in the Software without restriction, including
8      without limitation the rights to use, copy, modify, merge, publish,
9      distribute, sublicense, and/or sell copies of the Software, and to
10      permit persons to whom the Software is furnished to do so, subject to
11      the following conditions:
12
13      The above copyright notice and this permission notice shall be included
14      in all copies or substantial portions of the Software.
15
16      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17      KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18      WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19      NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20      LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21      OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22      WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 -->
25
26 <!--
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    <programlisting>
470      import os
471    </programlisting>
472
473   <para>
474
475   More usefully, you can use the
476   <envar>os.environ</envar>
477   dictionary in your &SConscript;
478   files to initialize &consenvs;
479   with values from the user's external environment.
480   See the next section,
481   <xref linkend="sect-construction-environments"></xref>,
482   for information on how to do this.
483
484   </para>
485
486   </section>
487
488   <section id="sect-construction-environments">
489   <title>Construction Environments</title>
490
491     <para>
492
493       It is rare that all of the software in a large,
494       complicated system needs to be built the same way.
495       For example, different source files may need different options
496       enabled on the command line,
497       or different executable programs need to be linked
498       with different libraries.
499       &SCons; accommodates these different build
500       requirements by allowing you to create and
501       configure multiple &consenvs;
502       that control how the software is built.
503       A &consenv; is an object
504       that has a number of associated
505       &consvars;, each with a name and a value.
506       (A construction environment also has an attached
507       set of &Builder; methods,
508       about which we'll learn more later.)
509
510     </para>
511
512     <section>
513     <title>Creating a &ConsEnv;:  the &Environment; Function</title>
514
515       <para>
516
517         A &consenv; is created by the &Environment; method:
518
519       </para>
520
521        <programlisting>
522          env = Environment()
523        </programlisting>
524
525       <para>
526
527         By default, &SCons; initializes every
528         new construction environment
529         with a set of &consvars;
530         based on the tools that it finds on your system,
531         plus the default set of builder methods
532         necessary for using those tools.
533         The construction variables
534         are initialized with values describing
535         the C compiler,
536         the Fortran compiler,
537         the linker,
538         etc.,
539         as well as the command lines to invoke them.
540
541       </para>
542
543       <para>
544
545         When you initialize a construction environment
546         you can set the values of the
547         environment's &consvars;
548         to control how a program is built.
549         For example:
550
551       </para>
552
553        <programlisting>
554      import os
555
556          env = Environment(CC = 'gcc',
557                            CCFLAGS = '-O2')
558
559          env.Program('foo.c')
560        </programlisting>
561
562       <para>
563
564         The construction environment in this example
565         is still initialized with the same default
566         construction variable values,
567         except that the user has explicitly specified use of the
568         GNU C compiler &gcc;,
569         and further specifies that the <literal>-O2</literal>
570         (optimization level two)
571         flag should be used when compiling the object file.
572         In other words, the explicit initializations of
573         &cv-link-CC; and &cv-link-CCFLAGS;
574         override the default values in the newly-created
575         construction environment.
576         So a run from this example would look like:
577
578       </para>
579
580       <screen>
581          % <userinput>scons -Q</userinput>
582          gcc -o foo.o -c -O2 foo.c
583          gcc -o foo foo.o
584       </screen>
585
586     </section>
587
588     <section>
589     <title>Fetching Values From a &ConsEnv;</title>
590
591       <para>
592
593       You can fetch individual construction variables
594       using the normal syntax
595       for accessing individual named items in a Python dictionary:
596
597       </para>
598
599       <programlisting>
600          env = Environment()
601          print "CC is:", env['CC']
602       </programlisting>
603
604       <para>
605
606       This example &SConstruct; file doesn't build anything,
607       but because it's actually a Python script,
608       it will print the value of &cv-link-CC; for us:
609
610       </para>
611
612       <screen>
613          % <userinput>scons -Q</userinput>
614          CC is: cc
615          scons: `.' is up to date.
616       </screen>
617
618       <para>
619
620       A construction environment, however,
621       is actually an object with associated methods, etc.
622       If you want to have direct access to only the
623       dictionary of construction variables,
624       you can fetch this using the &Dictionary; method:
625
626       </para>
627
628       <programlisting>
629          env = Environment(FOO = 'foo', BAR = 'bar')
630          dict = env.Dictionary()
631          for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']:
632              print "key = %s, value = %s" % (key, dict[key])
633       </programlisting>
634
635       <para>
636
637       This &SConstruct; file
638       will print the specified dictionary items for us on POSIX
639       systems as follows:
640
641       </para>
642
643       <screen>
644          % <userinput>scons -Q</userinput>
645          key = OBJSUFFIX, value = .o
646          key = LIBSUFFIX, value = .a
647          key = PROGSUFFIX, value = 
648          scons: `.' is up to date.
649       </screen>
650
651       <para>
652
653       And on Windows:
654
655       </para>
656
657       <screen>
658          C:\><userinput>scons -Q</userinput>
659          key = OBJSUFFIX, value = .obj
660          key = LIBSUFFIX, value = .lib
661          key = PROGSUFFIX, value = .exe
662          scons: `.' is up to date.
663       </screen>
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       <programlisting>
674          env = Environment()
675          for item in sorted(env.Dictionary().items()):
676              print "construction variable = '%s', value = '%s'" % item
677       </programlisting>
678
679     </section>
680
681     <section>
682     <title>Expanding Values From a &ConsEnv;:  the &subst; Method</title>
683
684       <para>
685
686       Another way to get information from
687       a construction environment.
688       is to use the &subst; method
689       on a string containing <literal>$</literal> expansions
690       of construction variable names.
691       As a simple example,
692       the example from the previous
693       section that used
694       <literal>env['CC']</literal>
695       to fetch the value of &cv-link-CC;
696       could also be written as:
697
698       </para>
699
700       <programlisting>
701         env = Environment()
702         print "CC is:", env.subst('$CC')
703       </programlisting>
704
705       <para>
706
707       One advantage of using
708       &subst; to expand strings is
709       that construction variables
710       in the result get re-expanded until
711       there are no expansions left in the string.
712       So a simple fetch of a value like
713       &cv-link-CCCOM;:
714
715       </para>
716
717       <programlisting>
718         env = Environment(CCFLAGS = '-DFOO')
719         print "CCCOM is:", env['CCCOM']
720       </programlisting>
721
722       <para>
723
724       Will print the unexpanded value of &cv-CCCOM;,
725       showing us the construction
726       variables that still need to be expanded:
727
728       </para>
729
730       <screen>
731         % <userinput>scons -Q</userinput>
732         CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES
733         scons: `.' is up to date.
734       </screen>
735
736       <para>
737
738       Calling the &subst; method on <varname>$CCOM</varname>,
739       however:
740
741       </para>
742
743       <programlisting>
744         env = Environment(CCFLAGS = '-DFOO')
745         print "CCCOM is:", env.subst('$CCCOM')
746       </programlisting>
747
748       <para>
749
750       Will recursively expand all of
751       the construction variables prefixed
752       with <literal>$</literal> (dollar signs),
753       showing us the final output:
754
755       </para>
756
757       <screen>
758         % <userinput>scons -Q</userinput>
759         CCCOM is: gcc -DFOO -c -o
760         scons: `.' is up to date.
761       </screen>
762
763       <para>
764
765       Note that because we're not expanding this
766       in the context of building something
767       there are no target or source files
768       for &cv-link-TARGET; and &cv-link-SOURCES; to expand.
769
770       </para>
771
772     </section>
773
774     <section>
775     <title>Controlling the Default &ConsEnv;:  the &DefaultEnvironment; Function</title>
776
777       <para>
778
779       All of the &Builder; functions that we've introduced so far,
780       like &Program; and &Library;,
781       actually use a default &consenv;
782       that contains settings
783       for the various compilers
784       and other tools that
785       &SCons; configures by default,
786       or otherwise knows about
787       and has discovered on your system.
788       The goal of the default construction environment
789       is to make many configurations to "just work"
790       to build software using
791       readily available tools
792       with a minimum of configuration changes.
793
794       </para>
795
796       <para>
797
798       You can, however, control the settings
799       in the default contstruction environment
800       by using the &DefaultEnvironment; function
801       to initialize various settings:
802
803       </para>
804
805       <programlisting>
806
807       DefaultEnvironment(CC = '/usr/local/bin/gcc')
808
809       </programlisting>
810
811       <para>
812
813       When configured as above,
814       all calls to the &Program;
815       or &Object; Builder
816       will build object files with the
817       <filename>/usr/local/bin/gcc</filename>
818       compiler.
819
820       </para>
821
822       <para>
823
824       Note that the &DefaultEnvironment; function
825       returns the initialized
826       default construction environment object,
827       which can then be manipulated like any
828       other construction environment.
829       So the following
830       would be equivalent to the
831       previous example,
832       setting the &cv-CC;
833       variable to <filename>/usr/local/bin/gcc</filename>
834       but as a separate step after
835       the default construction environment has been initialized:
836
837       </para>
838
839       <programlisting>
840
841       env = DefaultEnvironment()
842       env['CC'] = '/usr/local/bin/gcc'
843
844       </programlisting>
845
846       <para>
847
848       One very common use of the &DefaultEnvironment; function
849       is to speed up &SCons; initialization.
850       As part of trying to make most default
851       configurations "just work,"
852       &SCons; will actually
853       search the local system for installed
854       compilers and other utilities.
855       This search can take time,
856       especially on systems with
857       slow or networked file systems.
858       If you know which compiler(s) and/or
859       other utilities you want to configure,
860       you can control the search
861       that &SCons; performs
862       by specifying some specific
863       tool modules with which to
864       initialize the default construction environment:
865
866       </para>
867
868       <programlisting>
869
870       env = DefaultEnvironment(tools = ['gcc', 'gnulink'],
871                                CC = '/usr/local/bin/gcc')
872
873       </programlisting>
874
875       <para>
876
877       So the above example would tell &SCons;
878       to explicitly configure the default environment
879       to use its normal GNU Compiler and GNU Linker settings
880       (without having to search for them,
881       or any other utilities for that matter),
882       and specifically to use the compiler found at
883       <filename>/usr/local/bin/gcc</filename>.
884
885       </para>
886
887     </section>
888
889     <section>
890     <title>Multiple &ConsEnvs;</title>
891
892       <para>
893
894       The real advantage of construction environments
895       is that you can create as many different construction
896       environments as you need,
897       each tailored to a different way to build
898       some piece of software or other file.
899       If, for example, we need to build
900       one program with the <literal>-O2</literal> flag
901       and another with the <literal>-g</literal> (debug) flag,
902       we would do this like so:
903
904       </para>
905
906       <programlisting>
907          opt = Environment(CCFLAGS = '-O2')
908          dbg = Environment(CCFLAGS = '-g')
909
910          opt.Program('foo', 'foo.c')
911
912          dbg.Program('bar', 'bar.c')
913       </programlisting>
914
915       <screen>
916          % <userinput>scons -Q</userinput>
917          cc -o bar.o -c -g bar.c
918          cc -o bar bar.o
919          cc -o foo.o -c -O2 foo.c
920          cc -o foo foo.o
921       </screen>
922
923       <para>
924
925       We can even use multiple construction environments to build
926       multiple versions of a single program.
927       If you do this by simply trying to use the
928       &b-link-Program; builder with both environments, though,
929       like this:
930
931       </para>
932
933       <programlisting>
934          opt = Environment(CCFLAGS = '-O2')
935          dbg = Environment(CCFLAGS = '-g')
936
937          opt.Program('foo', 'foo.c')
938
939          dbg.Program('foo', 'foo.c')
940       </programlisting>
941
942       <para>
943
944       Then &SCons; generates the following error:
945
946       </para>
947
948       <screen>
949          % <userinput>scons -Q</userinput>
950          
951          scons: *** Two environments with different actions were specified for the same target: foo.o
952          File "/home/my/project/SConstruct", line 6, in &lt;module&gt;
953       </screen>
954
955       <para>
956
957       This is because the two &b-Program; calls have
958       each implicitly told &SCons; to generate an object file named
959       <filename>foo.o</filename>,
960       one with a &cv-link-CCFLAGS; value of
961       <literal>-O2</literal>
962       and one with a &cv-link-CCFLAGS; value of
963       <literal>-g</literal>.
964       &SCons; can't just decide that one of them
965       should take precedence over the other,
966       so it generates the error.
967       To avoid this problem,
968       we must explicitly specify
969       that each environment compile
970       <filename>foo.c</filename>
971       to a separately-named object file
972       using the &b-link-Object; builder, like so:
973
974       </para>
975
976       <programlisting>
977          opt = Environment(CCFLAGS = '-O2')
978          dbg = Environment(CCFLAGS = '-g')
979
980          o = opt.Object('foo-opt', 'foo.c')
981          opt.Program(o)
982
983          d = dbg.Object('foo-dbg', 'foo.c')
984          dbg.Program(d)
985       </programlisting>
986
987       <para>
988
989       Notice that each call to the &b-Object; builder
990       returns a value,
991       an internal &SCons; object that
992       represents the object file that will be built.
993       We then use that object
994       as input to the &b-Program; builder.
995       This avoids having to specify explicitly
996       the object file name in multiple places,
997       and makes for a compact, readable
998       &SConstruct; file.
999       Our &SCons; output then looks like:
1000
1001       </para>
1002
1003       <screen>
1004          % <userinput>scons -Q</userinput>
1005          cc -o foo-dbg.o -c -g foo.c
1006          cc -o foo-dbg foo-dbg.o
1007          cc -o foo-opt.o -c -O2 foo.c
1008          cc -o foo-opt foo-opt.o
1009       </screen>
1010
1011     </section>
1012
1013     <section>
1014     <title>Making Copies of &ConsEnvs;:  the &Clone; Method</title>
1015
1016       <para>
1017
1018       Sometimes you want more than one construction environment
1019       to share the same values for one or more variables.
1020       Rather than always having to repeat all of the common
1021       variables when you create each construction environment,
1022       you can use the &Clone; method
1023       to create a copy of a construction environment.
1024
1025       </para>
1026
1027       <para>
1028
1029       Like the &Environment; call that creates a construction environment,
1030       the &Clone; method takes &consvar; assignments,
1031       which will override the values in the copied construction environment.
1032       For example, suppose we want to use &gcc;
1033       to create three versions of a program,
1034       one optimized, one debug, and one with neither.
1035       We could do this by creating a "base" construction environment
1036       that sets &cv-link-CC; to &gcc;,
1037       and then creating two copies,
1038       one which sets &cv-link-CCFLAGS; for optimization
1039       and the other which sets &cv-CCFLAGS; for debugging:
1040
1041       </para>
1042
1043       <programlisting>
1044          env = Environment(CC = 'gcc')
1045          opt = env.Clone(CCFLAGS = '-O2')
1046          dbg = env.Clone(CCFLAGS = '-g')
1047
1048          env.Program('foo', 'foo.c')
1049
1050          o = opt.Object('foo-opt', 'foo.c')
1051          opt.Program(o)
1052
1053          d = dbg.Object('foo-dbg', 'foo.c')
1054          dbg.Program(d)
1055       </programlisting>
1056
1057       <para>
1058
1059       Then our output would look like:
1060
1061       </para>
1062
1063       <screen>
1064          % <userinput>scons -Q</userinput>
1065          gcc -o foo.o -c foo.c
1066          gcc -o foo foo.o
1067          gcc -o foo-dbg.o -c -g foo.c
1068          gcc -o foo-dbg foo-dbg.o
1069          gcc -o foo-opt.o -c -O2 foo.c
1070          gcc -o foo-opt foo-opt.o
1071       </screen>
1072
1073     </section>
1074
1075     <section>
1076     <title>Replacing Values:  the &Replace; Method</title>
1077
1078       <para>
1079
1080       You can replace existing construction variable values
1081       using the &Replace; method:
1082
1083       </para>
1084
1085       <programlisting>
1086          env = Environment(CCFLAGS = '-DDEFINE1')
1087          env.Replace(CCFLAGS = '-DDEFINE2')
1088          env.Program('foo.c')
1089       </programlisting>
1090
1091       <para>
1092
1093       The replacing value
1094       (<literal>-DDEFINE2</literal> in the above example)
1095       completely replaces the value in the
1096       construction environment:
1097
1098       </para>
1099
1100       <screen>
1101          % <userinput>scons -Q</userinput>
1102          cc -o foo.o -c -DDEFINE2 foo.c
1103          cc -o foo foo.o
1104       </screen>
1105
1106       <para>
1107
1108       You can safely call &Replace;
1109       for construction variables that
1110       don't exist in the construction environment:
1111
1112       </para>
1113
1114       <programlisting>
1115          env = Environment()
1116          env.Replace(NEW_VARIABLE = 'xyzzy')
1117          print "NEW_VARIABLE =", env['NEW_VARIABLE']
1118       </programlisting>
1119
1120       <para>
1121
1122       In this case,
1123       the construction variable simply
1124       gets added to the construction environment:
1125
1126       </para>
1127
1128       <screen>
1129          % <userinput>scons -Q</userinput>
1130          NEW_VARIABLE = xyzzy
1131          scons: `.' is up to date.
1132       </screen>
1133
1134       <para>
1135
1136       Because the variables
1137       aren't expanded until the construction environment
1138       is actually used to build the targets,
1139       and because &SCons; function and method calls
1140       are order-independent,
1141       the last replacement "wins"
1142       and is used to build all targets,
1143       regardless of the order in which
1144       the calls to Replace() are
1145       interspersed with calls to
1146       builder methods:
1147
1148       </para>
1149
1150       <programlisting>
1151          env = Environment(CCFLAGS = '-DDEFINE1')
1152          print "CCFLAGS =", env['CCFLAGS']
1153          env.Program('foo.c')
1154
1155          env.Replace(CCFLAGS = '-DDEFINE2')
1156          print "CCFLAGS =", env['CCFLAGS']
1157          env.Program('bar.c')
1158       </programlisting>
1159
1160       <para>
1161
1162       The timing of when the replacement
1163       actually occurs relative
1164       to when the targets get built
1165       becomes apparent
1166       if we run &scons; without the <literal>-Q</literal>
1167       option:
1168
1169       </para>
1170
1171       <screen>
1172          % <userinput>scons</userinput>
1173          scons: Reading SConscript files ...
1174          CCFLAGS = -DDEFINE1
1175          CCFLAGS = -DDEFINE2
1176          scons: done reading SConscript files.
1177          scons: Building targets ...
1178          cc -o bar.o -c -DDEFINE2 bar.c
1179          cc -o bar bar.o
1180          cc -o foo.o -c -DDEFINE2 foo.c
1181          cc -o foo foo.o
1182          scons: done building targets.
1183       </screen>
1184
1185       <para>
1186
1187       Because the replacement occurs while
1188       the &SConscript; files are being read,
1189       the &cv-link-CCFLAGS;
1190       variable has already been set to
1191       <literal>-DDEFINE2</literal>
1192       by the time the &foo_o; target is built,
1193       even though the call to the &Replace;
1194       method does not occur until later in
1195       the &SConscript; file.
1196
1197       </para>
1198
1199     </section>
1200
1201     <section>
1202     <title>Setting Values Only If They're Not Already Defined:  the &SetDefault; Method</title>
1203
1204       <para>
1205
1206       Sometimes it's useful to be able to specify
1207       that a construction variable should be
1208       set to a value only if the construction environment
1209       does not already have that variable defined
1210       You can do this with the &SetDefault; method,
1211       which behaves similarly to the <function>set_default</function>
1212       method of Python dictionary objects:
1213
1214       </para>
1215
1216       <programlisting>
1217       env.SetDefault(SPECIAL_FLAG = '-extra-option')
1218       </programlisting>
1219
1220       <para>
1221
1222       This is especially useful
1223       when writing your own <literal>Tool</literal> modules
1224       to apply variables to construction environments.
1225       <!--
1226       See <xref linkend="chap-tool-modules"></xref>
1227       for more information about writing
1228       Tool modules.
1229       -->
1230
1231       </para>
1232
1233     </section>
1234
1235     <section>
1236     <title>Appending to the End of Values:  the &Append; Method</title>
1237
1238       <para>
1239
1240       You can append a value to
1241       an existing construction variable
1242       using the &Append; method:
1243
1244       </para>
1245
1246       <programlisting>
1247          env = Environment(CCFLAGS = ['-DMY_VALUE'])
1248          env.Append(CCFLAGS = ['-DLAST'])
1249          env.Program('foo.c')
1250       </programlisting>
1251
1252       <para>
1253
1254       &SCons; then supplies both the <literal>-DMY_VALUE</literal> and
1255       <literal>-DLAST</literal> flags when compiling the object file:
1256
1257       </para>
1258
1259       <screen>
1260          % <userinput>scons -Q</userinput>
1261          cc -o foo.o -c -DMY_VALUE -DLAST foo.c
1262          cc -o foo foo.o
1263       </screen>
1264
1265       <para>
1266
1267       If the construction variable doesn't already exist,
1268       the &Append; method will create it:
1269
1270       </para>
1271
1272       <programlisting>
1273          env = Environment()
1274          env.Append(NEW_VARIABLE = 'added')
1275          print "NEW_VARIABLE =", env['NEW_VARIABLE']
1276       </programlisting>
1277
1278       <para>
1279
1280       Which yields:
1281
1282       </para>
1283
1284       <screen>
1285          % <userinput>scons -Q</userinput>
1286          NEW_VARIABLE = added
1287          scons: `.' is up to date.
1288       </screen>
1289
1290       <para>
1291
1292       Note that the &Append; function tries to be "smart"
1293       about how the new value is appended to the old value.
1294       If both are strings, the previous and new strings
1295       are simply concatenated.
1296       Similarly, if both are lists,
1297       the lists are concatenated.
1298       If, however, one is a string and the other is a list,
1299       the string is added as a new element to the list.
1300
1301       </para>
1302
1303     </section>
1304
1305     <section>
1306     <title>Appending Unique Values:  the &AppendUnique; Method</title>
1307
1308       <para>
1309
1310       Some times it's useful to add a new value
1311       only if the existing construction variable
1312       doesn't already contain the value.
1313       This can be done using the &AppendUnique; method:
1314
1315       </para>
1316
1317       <programlisting>
1318       env.AppendUnique(CCFLAGS=['-g'])
1319       </programlisting>
1320
1321       <para>
1322
1323       In the above example,
1324       the <literal>-g</literal> would be added
1325       only if the &cv-CCFLAGS; variable
1326       does not already contain a <literal>-g</literal> value.
1327
1328       </para>
1329
1330     </section>
1331
1332     <section>
1333     <title>Appending to the Beginning of Values:  the &Prepend; Method</title>
1334
1335       <para>
1336
1337       You can append a value to the beginning of
1338       an existing construction variable
1339       using the &Prepend; method:
1340
1341       </para>
1342
1343       <programlisting>
1344          env = Environment(CCFLAGS = ['-DMY_VALUE'])
1345          env.Prepend(CCFLAGS = ['-DFIRST'])
1346          env.Program('foo.c')
1347       </programlisting>
1348
1349       <para>
1350
1351       &SCons; then supplies both the <literal>-DFIRST</literal> and
1352       <literal>-DMY_VALUE</literal> flags when compiling the object file:
1353
1354       </para>
1355
1356       <screen>
1357          % <userinput>scons -Q</userinput>
1358          cc -o foo.o -c -DFIRST -DMY_VALUE foo.c
1359          cc -o foo foo.o
1360       </screen>
1361
1362       <para>
1363
1364       If the construction variable doesn't already exist,
1365       the &Prepend; method will create it:
1366
1367       </para>
1368
1369       <programlisting>
1370          env = Environment()
1371          env.Prepend(NEW_VARIABLE = 'added')
1372          print "NEW_VARIABLE =", env['NEW_VARIABLE']
1373       </programlisting>
1374
1375       <para>
1376
1377       Which yields:
1378
1379       </para>
1380
1381       <screen>
1382          % <userinput>scons -Q</userinput>
1383          NEW_VARIABLE = added
1384          scons: `.' is up to date.
1385       </screen>
1386
1387       <para>
1388
1389       Like the &Append; function,
1390       the &Prepend; function tries to be "smart"
1391       about how the new value is appended to the old value.
1392       If both are strings, the previous and new strings
1393       are simply concatenated.
1394       Similarly, if both are lists,
1395       the lists are concatenated.
1396       If, however, one is a string and the other is a list,
1397       the string is added as a new element to the list.
1398
1399       </para>
1400
1401     </section>
1402
1403     <section>
1404     <title>Prepending Unique Values:  the &PrependUnique; Method</title>
1405
1406       <para>
1407
1408       Some times it's useful to add a new value
1409       to the beginning of a construction variable
1410       only if the existing value
1411       doesn't already contain the to-be-added value.
1412       This can be done using the &PrependUnique; method:
1413
1414       </para>
1415
1416       <programlisting>
1417       env.PrependUnique(CCFLAGS=['-g'])
1418       </programlisting>
1419
1420       <para>
1421
1422       In the above example,
1423       the <literal>-g</literal> would be added
1424       only if the &cv-CCFLAGS; variable
1425       does not already contain a <literal>-g</literal> value.
1426
1427       </para>
1428
1429     </section>
1430
1431   </section>
1432
1433   <section id="sect-execution-environments">
1434   <title>Controlling the Execution Environment for Issued Commands</title>
1435
1436     <para>
1437
1438       When &SCons; builds a target file,
1439       it does not execute the commands with
1440       the same external environment
1441       that you used to execute &SCons;.
1442       Instead, it uses the dictionary
1443       stored in the &cv-link-ENV; construction variable
1444       as the external environment
1445       for executing commands.
1446
1447     </para>
1448
1449     <para>
1450
1451       The most important ramification of this behavior
1452       is that the &PATH; environment variable,
1453       which controls where the operating system
1454       will look for commands and utilities,
1455       is not the same as in the external environment
1456       from which you called &SCons;.
1457       This means that &SCons; will not, by default,
1458       necessarily find all of the tools
1459       that you can execute from the command line.
1460
1461     </para>
1462
1463     <para>
1464
1465       The default value of the &PATH; environment variable
1466       on a POSIX system
1467       is <literal>/usr/local/bin:/bin:/usr/bin</literal>.
1468       The default value of the &PATH; environment variable
1469       on a Windows system comes from the Windows registry
1470       value for the command interpreter.
1471       If you want to execute any commands--compilers, linkers, etc.--that
1472       are not in these default locations,
1473       you need to set the &PATH; value
1474       in the &cv-ENV; dictionary
1475       in your construction environment.
1476
1477     </para>
1478
1479     <para>
1480
1481       The simplest way to do this is to initialize explicitly
1482       the value when you create the construction environment;
1483       this is one way to do that:
1484
1485     </para>
1486
1487     <programlisting>
1488       path = ['/usr/local/bin', '/bin', '/usr/bin']
1489       env = Environment(ENV = {'PATH' : path})
1490     </programlisting>
1491
1492     <para>
1493
1494     Assign a dictionary to the &cv-ENV;
1495     construction variable in this way
1496     completely resets the external environment
1497     so that the only variable that will be
1498     set when external commands are executed
1499     will be the &PATH; value.
1500     If you want to use the rest of
1501     the values in &cv-ENV; and only
1502     set the value of &PATH;,
1503     the most straightforward way is probably:
1504
1505     </para>
1506
1507     <programlisting>
1508       env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin']
1509     </programlisting>
1510
1511     <para>
1512
1513     Note that &SCons; does allow you to define
1514     the directories in the &PATH; in a string,
1515     separated by the pathname-separator character
1516     for your system (':' on POSIX systems, ';' on Windows):
1517
1518     </para>
1519
1520     <programlisting>
1521       env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'
1522     </programlisting>
1523
1524     <para>
1525
1526     But doing so makes your &SConscript; file less portable,
1527     (although in this case that may not be a huge concern
1528     since the directories you list are likley system-specific, anyway).
1529
1530     </para>
1531
1532     <!--
1533
1534     <scons_example name="ex1">
1535       <file name="SConstruct" printme="1">
1536       env = Environment()
1537       env.Command('foo', [], '__ROOT__/usr/bin/printenv.py')
1538       </file>
1539       <file name="__ROOT__/usr/bin/printenv.py" chmod="0755">
1540       #!/usr/bin/env python
1541       import os
1542       import sys
1543       if len(sys.argv) > 1:
1544           keys = sys.argv[1:]
1545       else:
1546           keys = sorted(os.environ.keys())
1547       for key in keys:
1548           print "    " + key + "=" + os.environ[key]
1549       </file>
1550     </scons_example>
1551
1552     <para>
1553
1554     </para>
1555
1556     <scons_output example="ex1">
1557       <scons_output_command>scons -Q</scons_output_command>
1558     </scons_output>
1559
1560     -->
1561
1562     <section>
1563     <title>Propagating &PATH; From the External Environment</title>
1564
1565       <para>
1566
1567       You may want to propagate the external &PATH;
1568       to the execution environment for commands.
1569       You do this by initializing the &PATH;
1570       variable with the &PATH; value from
1571       the <literal>os.environ</literal>
1572       dictionary,
1573       which is Python's way of letting you
1574       get at the external environment:
1575
1576       </para>
1577
1578       <programlisting>
1579         import os
1580         env = Environment(ENV = {'PATH' : os.environ['PATH']})
1581       </programlisting>
1582
1583       <para>
1584
1585       Alternatively, you may find it easier
1586       to just propagate the entire external
1587       environment to the execution environment
1588       for commands.
1589       This is simpler to code than explicity
1590       selecting the &PATH; value:
1591
1592       </para>
1593
1594       <programlisting>
1595         import os
1596         env = Environment(ENV = os.environ)
1597       </programlisting>
1598
1599       <para>
1600
1601       Either of these will guarantee that
1602       &SCons; will be able to execute
1603       any command that you can execute from the command line.
1604       The drawback is that the build can behave
1605       differently if it's run by people with
1606       different &PATH; values in their environment--for example,
1607       if both the <literal>/bin</literal> and
1608       <literal>/usr/local/bin</literal> directories
1609       have different &cc; commands,
1610       then which one will be used to compile programs
1611       will depend on which directory is listed
1612       first in the user's &PATH; variable.
1613
1614       </para>
1615
1616     </section>
1617
1618     <section>
1619     <title>Adding to <varname>PATH</varname> Values in the Execution Environment</title>
1620
1621       <para>
1622
1623       One of the most common requirements
1624       for manipulating a variable in the execution environment
1625       is to add one or more custom directories to a search
1626       like the <envar>$PATH</envar> variable on Linux or POSIX systems,
1627       or the <envar>%PATH%</envar> variable on Windows,
1628       so that a locally-installed compiler or other utility
1629       can be found when &SCons; tries to execute it to update a target.
1630       &SCons; provides &PrependENVPath; and &AppendENVPath; functions
1631       to make adding things to execution variables convenient.
1632       You call these functions by specifying the variable
1633       to which you want the value added,
1634       and then value itself.
1635       So to add some <filename>/usr/local</filename> directories
1636       to the <envar>$PATH</envar> and <envar>$LIB</envar> variables,
1637       you might:
1638
1639       </para>
1640
1641       <programlisting>
1642         env = Environment(ENV = os.environ)
1643         env.PrependENVPath('PATH', '/usr/local/bin')
1644         env.AppendENVPath('LIB', '/usr/local/lib')
1645       </programlisting>
1646
1647       <para>
1648
1649       Note that the added values are strings,
1650       and if you want to add multiple directories to
1651       a variable like <envar>$PATH</envar>,
1652       you must include the path separate character
1653       (<literal>:</literal> on Linux or POSIX,
1654       <literal>;</literal> on Windows)
1655       in the string.
1656
1657       </para>
1658
1659     </section>
1660
1661   </section>