Fix XML in documentation, and in the bin/scons-doc.py script that generates
[scons.git] / doc / user / environments.in
index 3fcec02fa0a4673cadf3e7fa8961311eed06ec96..7bb9d01e320754038982c62d810508f7788bdc5d 100644 (file)
@@ -1,25 +1,25 @@
 <!--
 
-  __COPYRIGHT__
-
-  Permission is hereby granted, free of charge, to any person obtaining
-  a copy of this software and associated documentation files (the
-  "Software"), to deal in the Software without restriction, including
-  without limitation the rights to use, copy, modify, merge, publish,
-  distribute, sublicense, and/or sell copies of the Software, and to
-  permit persons to whom the Software is furnished to do so, subject to
-  the following conditions:
-
-  The above copyright notice and this permission notice shall be included
-  in all copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-  KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+     __COPYRIGHT__
+
+     Permission is hereby granted, free of charge, to any person obtaining
+     a copy of this software and associated documentation files (the
+     "Software"), to deal in the Software without restriction, including
+     without limitation the rights to use, copy, modify, merge, publish,
+     distribute, sublicense, and/or sell copies of the Software, and to
+     permit persons to whom the Software is furnished to do so, subject to
+     the following conditions:
+
+     The above copyright notice and this permission notice shall be included
+     in all copies or substantial portions of the Software.
+
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+     KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+     LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+     OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
 
@@ -38,120 +38,120 @@ build behavior.
 Construction variables from a construction environment are expanded
 by preceding the keyword with a C<%> (percent sign):
 
-  Construction variables:
+     Construction variables:
        XYZZY => 'abracadabra',
 
-  The string:  "The magic word is:  %XYZZY!"
-  expands to:  "The magic word is:  abracadabra!"
+     The string:  "The magic word is:  %XYZZY!"
+     expands to:  "The magic word is:  abracadabra!"
 
 A construction variable name may be surrounded by C<{> and C<}> (curly
 braces), which are stripped as part of the expansion.  This can
 sometimes be necessary to separate a variable expansion from trailing
 alphanumeric characters:
 
-  Construction variables:
+     Construction variables:
        OPT    => 'value1',
        OPTION => 'value2',
 
-  The string:  "%OPT %{OPT}ION %OPTION %{OPTION}"
-  expands to:  "value1 value1ION value2 value2"
+     The string:  "%OPT %{OPT}ION %OPTION %{OPTION}"
+     expands to:  "value1 value1ION value2 value2"
 
 Construction variable expansion is recursive, that is, a string
 containing C<%->expansions after substitution will be re-expanded until
 no further substitutions can be made:
 
-  Construction variables:
+     Construction variables:
        STRING => 'The result is:  %FOO',
        FOO    => '%BAR',
        BAR    => 'final value',
 
-  The string:  "The string says:  %STRING"
-  expands to:  "The string says:  The result is:  final value"
+     The string:  "The string says:  %STRING"
+     expands to:  "The string says:  The result is:  final value"
 
 If a construction variable is not defined in an environment, then the
 null string is substituted:
 
-  Construction variables:
+     Construction variables:
        FOO => 'value1',
        BAR => 'value2',
 
-  The string:  "%FOO <%NO_VARIABLE> %BAR"
-  expands to:  "value1 <> value2"
+     The string:  "%FOO <%NO_VARIABLE> %BAR"
+     expands to:  "value1 <> value2"
 
 A doubled C<%%> will be replaced by a single C<%>:
 
-  The string:  "Here is a percent sign:  %%"
-  expands to:  "Here is a percent sign: %"
+     The string:  "Here is a percent sign:  %%"
+     expands to:  "Here is a percent sign: %"
 
 =head2 Default construction variables
 
 When you specify no arguments when creating a new construction
 environment:
 
-  $env = new cons();
+     $env = new cons();
 
 Cons creates a reference to a new, default construction
 environment. This contains a number of construction variables and some
 methods. At the present writing, the default construction variables on a
 UNIX system are:
 
-  CC            => 'cc',
-  CFLAGS        => '',
-  CCCOM         => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
-  CXX           => '%CC',
-  CXXFLAGS      => '%CFLAGS',
-  CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
-  INCDIRPREFIX  => '-I',
-  INCDIRSUFFIX  => '',
-  LINK          => '%CXX',
-  LINKCOM       => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
-  LINKMODULECOM => '%LD -r -o %> %<',
-  LIBDIRPREFIX  => '-L',
-  LIBDIRSUFFIX  => '',
-  AR           => 'ar',
-  ARFLAGS      => 'r',
-  ARCOM                => ['%AR %ARFLAGS %> %<', '%RANLIB %>'],
-  RANLIB       => 'ranlib',
-  AS           => 'as',
-  ASFLAGS      => '',
-  ASCOM                => '%AS %ASFLAGS %< -o %>',
-  LD           => 'ld',
-  LDFLAGS      => '',
-  PREFLIB      => 'lib',
-  SUFLIB       => '.a',
-  SUFLIBS      => '.so:.a',
-  SUFOBJ       => '.o',
-  SIGNATURE     => [ '*' => 'build' ],
-  ENV          => { 'PATH' => '/bin:/usr/bin' },
+     CC            => 'cc',
+     CFLAGS        => '',
+     CCCOM         => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
+     CXX           => '%CC',
+     CXXFLAGS      => '%CFLAGS',
+     CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
+     INCDIRPREFIX  => '-I',
+     INCDIRSUFFIX  => '',
+     LINK          => '%CXX',
+     LINKCOM       => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
+     LINKMODULECOM => '%LD -r -o %> %<',
+     LIBDIRPREFIX  => '-L',
+     LIBDIRSUFFIX  => '',
+     AR                => 'ar',
+     ARFLAGS   => 'r',
+     ARCOM             => ['%AR %ARFLAGS %> %<', '%RANLIB %>'],
+     RANLIB    => 'ranlib',
+     AS                => 'as',
+     ASFLAGS   => '',
+     ASCOM             => '%AS %ASFLAGS %< -o %>',
+     LD                => 'ld',
+     LDFLAGS   => '',
+     PREFLIB   => 'lib',
+     SUFLIB    => '.a',
+     SUFLIBS   => '.so:.a',
+     SUFOBJ    => '.o',
+     SIGNATURE     => [ '*' => 'build' ],
+     ENV               => { 'PATH' => '/bin:/usr/bin' },
 
 
 And on a Windows system (Windows NT), the default construction variables
 are (unless the default rule style is set using the B<DefaultRules>
 method):
 
-  CC           => 'cl',
-  CFLAGS       => '/nologo',
-  CCCOM                => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
-  CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
-  INCDIRPREFIX  => '/I',
-  INCDIRSUFFIX  => '',
-  LINK          => 'link',
-  LINKCOM       => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
-  LINKMODULECOM => '%LD /r /o %> %<',
-  LIBDIRPREFIX  => '/LIBPATH:',
-  LIBDIRSUFFIX  => '',
-  AR            => 'lib',
-  ARFLAGS       => '/nologo ',
-  ARCOM         => "%AR %ARFLAGS /out:%> %<",
-  RANLIB        => '',
-  LD            => 'link',
-  LDFLAGS       => '/nologo ',
-  PREFLIB       => '',
-  SUFEXE       => '.exe',
-  SUFLIB       => '.lib',
-  SUFLIBS      => '.dll:.lib',
-  SUFOBJ       => '.obj',
-  SIGNATURE     => [ '*' => 'build' ],
+     CC                => 'cl',
+     CFLAGS    => '/nologo',
+     CCCOM             => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
+     CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
+     INCDIRPREFIX  => '/I',
+     INCDIRSUFFIX  => '',
+     LINK          => 'link',
+     LINKCOM       => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
+     LINKMODULECOM => '%LD /r /o %> %<',
+     LIBDIRPREFIX  => '/LIBPATH:',
+     LIBDIRSUFFIX  => '',
+     AR            => 'lib',
+     ARFLAGS       => '/nologo ',
+     ARCOM         => "%AR %ARFLAGS /out:%> %<",
+     RANLIB        => '',
+     LD            => 'link',
+     LDFLAGS       => '/nologo ',
+     PREFLIB       => '',
+     SUFEXE    => '.exe',
+     SUFLIB    => '.lib',
+     SUFLIBS   => '.dll:.lib',
+     SUFOBJ    => '.obj',
+     SIGNATURE     => [ '*' => 'build' ],
 
 These variables are used by the various methods associated with the
 environment. In particular, any method that ultimately invokes an external
@@ -160,7 +160,7 @@ appropriate. For example, the C<Objects> method takes a number of source
 files and arranges to derive, if necessary, the corresponding object
 files:
 
-  Objects $env 'foo.c', 'bar.c';
+     Objects $env 'foo.c', 'bar.c';
 
 This will arrange to produce, if necessary, F<foo.o> and F<bar.o>. The
 command invoked is simply C<%CCCOM>, which expands, through substitution,
@@ -234,32 +234,32 @@ anywhere else in the current command line (via C<%1>, C<%2>, etc.), then
 those will be deleted from the list provided by C<%E<lt>>. Consider the
 following command found in a F<Conscript> file in the F<test> directory:
 
-  Command $env 'tgt', qw(foo bar baz), qq(
+     Command $env 'tgt', qw(foo bar baz), qq(
        echo %< -i %1 > %>
        echo %< -i %2 >> %>
        echo %< -i %3 >> %>
-  );
+     );
 
 If F<tgt> needed to be updated, then this would result in the execution of
 the following commands, assuming that no remapping has been established for
 the F<test> directory:
 
-  echo test/bar test/baz -i test/foo > test/tgt
-  echo test/foo test/baz -i test/bar >> test/tgt
-  echo test/foo test/bar -i test/baz >> test/tgt
+     echo test/bar test/baz -i test/foo > test/tgt
+     echo test/foo test/baz -i test/bar >> test/tgt
+     echo test/foo test/bar -i test/baz >> test/tgt
 
 =back
 
 Any of the above pseudo-variables may be followed immediately by one of
 the following suffixes to select a portion of the expanded path name:
 
-  :a    the absolute path to the file name
-  :b    the directory plus the file name stripped of any suffix
-  :d    the directory
-  :f    the file name
-  :s    the file name suffix
-  :F    the file name stripped of any suffix
-  :S    the absolute path path to a Linked source file
+     :a    the absolute path to the file name
+     :b    the directory plus the file name stripped of any suffix
+     :d    the directory
+     :f    the file name
+     :s    the file name suffix
+     :F    the file name stripped of any suffix
+     :S    the absolute path path to a Linked source file
 
 Continuing with the above example, C<%E<lt>:f> would expand to C<foo bar baz>,
 and C<%E<gt>:d> would expand to C<test>.
@@ -277,17 +277,17 @@ as a Perl code reference; the results of this call will be used to
 replace the contents of the brackets in the command line.  For example,
 given an existing input file named F<tgt.in>:
 
-  @keywords = qw(foo bar baz);
-  $env = new cons(X_COMMA => sub { join(",", @_) });
-  Command $env 'tgt', 'tgt.in', qq(
+     @keywords = qw(foo bar baz);
+     $env = new cons(X_COMMA => sub { join(",", @_) });
+     Command $env 'tgt', 'tgt.in', qq(
        echo '# Keywords: %[X_COMMA @keywords %]' > %>
        cat %< >> %>
-  );
+     );
 
 This will execute:
 
-  echo '# Keywords: foo,bar,baz' > tgt
-  cat tgt.in >> tgt
+     echo '# Keywords: foo,bar,baz' > tgt
+     cat tgt.in >> tgt
 
 =item %( %)
 
@@ -313,843 +313,1362 @@ Cons expands construction variables in the source and target file names
 passed to the various construction methods according to the expansion
 rules described above:
 
-  $env = new cons(
+     $env = new cons(
        DESTDIR =>      'programs',
        SRCDIR  =>      'src',
-  );
-  Program $env '%DESTDIR/hello', '%SRCDIR/hello.c';
+     );
+     Program $env '%DESTDIR/hello', '%SRCDIR/hello.c';
 
 This allows for flexible configuration, through the construction
 environment, of directory names, suffixes, etc.
 
-=head1 Default construction methods
+-->
 
-The list of default construction methods includes the following:
+  <para>
+
+  An <literal>environment</literal>
+  is a collection of values that
+  can affect how a program executes.
+  &SCons; distinguishes between three
+  different types of environments
+  that can affect the behavior of &SCons; itself
+  (subject to the configuration in the &SConscript; files),
+  as well as the compilers and other tools it executes:
+
+  </para>
+
+  <variablelist>
+
+    <varlistentry>
+    <term>External Environment</term>
+
+    <listitem>
+    <para>
+
+    The <literal>external environment</literal>
+    is the set of variables in the user's environment
+    at the time the user runs &SCons.
+    These variables are available within the &SConscript; files
+    through the Python <literal>os.environ</literal> dictionary.
+    See <xref linkend="sect-external-environments"></xref>, below.
+
+    </para>
+    </listitem>
+    </varlistentry>
+
+    <varlistentry>
+    <term>&ConsEnv;</term>
+
+    <listitem>
+    <para>
+
+    A &consenv;
+    is a distinct object creating within
+    a &SConscript; file and
+    and which contains values that
+    affect how &SCons; decides
+    what action to use to build a target,
+    and even to define which targets
+    should be built from which sources.
+    One of the most powerful features of &SCons;
+    is the ability to create multiple &consenvs;,
+    including the ability to clone a new, customized
+    &consenv; from an existing &consenv;.
+    See <xref linkend="sect-construction-environments"></xref>, below.
+
+    </para>
+    </listitem>
+    </varlistentry>
+
+    <varlistentry>
+    <term>Execution Environment</term>
+
+    <listitem>
+    <para>
+
+    An <literal>execution environment</literal>
+    is the values that &SCons; sets
+    when executing an external
+    command (such as a compiler or linker)
+    to build one or more targets.
+    Note that this is not the same as
+    the <literal>external environment</literal>
+    (see above).
+    See <xref linkend="sect-execution-environments"></xref>, below.
+
+    </para>
+    </listitem>
+    </varlistentry>
+
+  </variablelist>
+
+  <para>
+
+  Unlike &Make;,  &SCons; does not automatically
+  copy or import values between different environments
+  (with the exception of explicit clones of &consenvs,
+  which inherit values from their parent).
+  This is a deliberate design choice
+  to make sure that builds are,
+  by default, repeatable regardless of
+  the values in the user's external environment.
+  This avoids a whole class of problems with builds
+  where a developer's local build works
+  because a custom variable setting
+  causes a different compiler or build option to be used,
+  but the checked-in change breaks the official build
+  because it uses different environment variable settings.
+
+  </para>
+
+  <para>
+
+  Note that the &SConscript; writer can
+  easily arrange for variables to be
+  copied or imported between environments,
+  and this is often very useful
+  (or even downright necessary)
+  to make it easy for developers
+  to customize the build in appropriate ways.
+  The point is <emphasis>not</emphasis>
+  that copying variables between different environments
+  is evil and must always be avoided.
+  Instead, it should be up to the
+  implementer of the build system
+  to make conscious choices
+  about how and when to import
+  a variable from one environment to another,
+  making informed decisions about
+  striking the right balance
+  between making the build
+  repeatable on the one hand
+  and convenient to use on the other.
+
+  </para>
+
+  <section id="sect-external-environments">
+  <title>Using Values From the External Environment</title>
+
+  <para>
+
+  The <literal>external environment</literal>
+  variable settings that
+  the user has in force
+  when executing &SCons;
+  are available through the normal Python
+  <envar>os.environ</envar>
+  dictionary.
+  This means that you must add an
+  <literal>import os</literal> statement
+  to any &SConscript; file
+  in which you want to use
+  values from the user's external environment.
+
+  </para>
+
+   <scons_example name="ex1">
+     <file name="SConstruct" printme="1">
+     import os
+     </file>
+     <file name="foo.c">
+    int main() { }
+     </file>
+   </scons_example>
 
+  <para>
+
+  More usefully, you can use the
+  <envar>os.environ</envar>
+  dictionary in your &SConscript;
+  files to initialize &consenvs;
+  with values from the user's external environment.
+  See the next section,
+  <xref linkend="sect-construction-environments"></xref>,
+  for information on how to do this.
+
+  </para>
+
+  </section>
+
+  <section id="sect-construction-environments">
+  <title>Construction Environments</title>
+
+    <para>
+
+      It is rare that all of the software in a large,
+      complicated system needs to be built the same way.
+      For example, different source files may need different options
+      enabled on the command line,
+      or different executable programs need to be linked
+      with different libraries.
+      &SCons; accommodates these different build
+      requirements by allowing you to create and
+      configure multiple &consenvs;
+      that control how the software is built.
+      A &consenv; is an object
+      that has a number of associated
+      &consvars;, each with a name and a value.
+      (A construction environment also has an attached
+      set of &Builder; methods,
+      about which we'll learn more later.)
+
+    </para>
+
+    <section>
+    <title>Creating a &ConsEnv;:  the &Environment; Function</title>
 
-=head2 The C<new> constructor
+      <para>
+
+        A &consenv; is created by the &Environment; method:
 
-The C<new> method is a Perl object constructor. That is, it is not invoked
-via a reference to an existing construction environment B<reference>, but,
-rather statically, using the name of the Perl B<package> where the
-constructor is defined. The method is invoked like this:
+      </para>
 
-  $env = new cons(<overrides>);
+       <sconstruct>
+         env = Environment()
+       </sconstruct>
+
+      <para>
 
-The environment you get back is blessed into the package C<cons>, which
-means that it will have associated with it the default methods described
-below. Individual construction variables can be overridden by providing
-name/value pairs in an override list. Note that to override any command
-environment variable (i.e. anything under C<ENV>), you will have to override
-all of them. You can get around this difficulty by using the C<copy> method
-on an existing construction environment.
+        By default, &SCons; initializes every
+        new construction environment
+        with a set of &consvars;
+        based on the tools that it finds on your system,
+        plus the default set of builder methods
+        necessary for using those tools.
+        The construction variables
+        are initialized with values describing
+        the C compiler,
+        the Fortran compiler,
+        the linker,
+        etc.,
+        as well as the command lines to invoke them.
+
+      </para>
+
+      <para>
+
+        When you initialize a construction environment
+        you can set the values of the
+        environment's &consvars;
+        to control how a program is built.
+        For example:
 
+      </para>
 
-=head2 The C<clone> method
+       <scons_example name="ex1">
+         <file name="SConstruct" printme="1">
+         env = Environment(CC = 'gcc',
+                           CCFLAGS = '-O2')
 
-The C<clone> method creates a clone of an existing construction environment,
-and can be called as in the following example:
+         env.Program('foo.c')
+         </file>
+         <file name="foo.c">
+        int main() { }
+         </file>
+       </scons_example>
 
-  $env2 = $env1->clone(<overrides>);
+      <para>
 
-You can provide overrides in the usual manner to create a different
-environment from the original. If you just want a new name for the same
-environment (which may be helpful when exporting environments to existing
-components), you can just use simple assignment.
+        The construction environment in this example
+        is still initialized with the same default
+        construction variable values,
+        except that the user has explicitly specified use of the
+        GNU C compiler &gcc;,
+        and further specifies that the <literal>-O2</literal>
+        (optimization level two)
+        flag should be used when compiling the object file.
+        In other words, the explicit initializations of
+        &cv-link-CC; and &cv-link-CCFLAGS;
+        override the default values in the newly-created
+        construction environment.
+        So a run from this example would look like:
 
+      </para>
 
-=head2 The C<copy> method
+      <scons_output example="ex1">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-The C<copy> method extracts the externally defined construction variables
-from an environment and returns them as a list of name/value
-pairs. Overrides can also be provided, in which case, the overridden values
-will be returned, as appropriate. The returned list can be assigned to a
-hash, as shown in the prototype, below, but it can also be manipulated in
-other ways:
+    </section>
 
-  %env = $env1->copy(<overrides>);
+    <section>
+    <title>Fetching Values From a &ConsEnv;</title>
+
+      <para>
+
+      You can fetch individual construction variables
+      using the normal syntax
+      for accessing individual named items in a Python dictionary:
 
-The value of C<ENV>, which is itself a hash, is also copied to a new hash,
-so this may be changed without fear of affecting the original
-environment. So, for example, if you really want to override just the
-C<PATH> variable in the default environment, you could do the following:
+      </para>
 
-  %cons = new cons()->copy();
-  $cons{ENV}{PATH} = "<your path here>";
-  $cons = new cons(%cons);
+      <scons_example name="ex6">
+        <file name="SConstruct" printme="1">
+         env = Environment()
+         print "CC is:", env['CC']
+        </file>
+      </scons_example>
 
-This will leave anything else that might be in the default execution
-environment undisturbed.
+      <para>
 
--->
+      This example &SConstruct; file doesn't build anything,
+      but because it's actually a Python script,
+      it will print the value of &cv-link-CC; for us:
 
- <para>
-
-   It is rare that all of the software in a large,
-   complicated system needs to be built the same way.
-   For example, different source files may need different options
-   enabled on the command line,
-   or different executable programs need to be linked
-   with different libraries.
-   &SCons; accommodates these different build
-   requirements by allowing you to create and
-   configure multiple &consenvs;
-   that control how the software is built.
-   Technically, a &consenv; is an object
-   that has a number of associated
-   &consvars;, each with a name and a value.
-   (A construction environment also has an attached
-   set of &Builder; methods,
-   about which we'll learn more later.)
-
- </para>
-
- <para>
-
-   A &consenv; is created by the &Environment; method:
-
- </para>
-
-  <sconstruct>
-    env = Environment()
-  </sconstruct>
-
- <para>
-
-   By default, &SCons; initializes every
-   new construction environment
-   with a set of &consvars;
-   based on the tools that it finds on your system,
-   plus the default set of builder methods
-   necessary for using those tools.
-   The construction variables
-   are initialized with values describing
-   the C compiler,
-   the Fortran compiler,
-   the linker,
-   etc.,
-   as well as the command lines to invoke them.
-
- </para>
-
- <para>
-
-   When you initialize a construction environment
-   you can set the values of the
-   environment's &consvars;
-   to control how a program is built.
-   For example:
-
- </para>
-
-  <scons_example name="ex1">
-    <file name="SConstruct" printme="1">
-    env = Environment(CC = 'gcc',
-                      CCFLAGS = '-O2')
-
-    env.Program('foo.c')
-    </file>
-    <file name="foo.c">
-   int main() { }
-    </file>
-  </scons_example>
-
- <para>
-
-   The construction environment in this example
-   is still initialized with the same default
-   construction variable values,
-   except that the user has explicitly specified use of the
-   GNU C compiler &gcc;,
-   and further specifies that the <literal>-O2</literal>
-   (optimization level two)
-   flag should be used when compiling the object file.
-   In other words, the explicit initializations of
-   &cv-link-CC; and &cv-link-CCFLAGS;
-   override the default values in the newly-created
-   construction environment.
-   So a run from this example would look like:
-
- </para>
-
- <scons_output example="ex1">
-    <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- <section>
- <title>Multiple &ConsEnvs;</title>
-
-   <para>
-
-   The real advantage of construction environments
-   is that you can create as many different construction
-   environments as you need,
-   each tailored to a different way to build
-   some piece of software or other file.
-   If, for example, we need to build
-   one program with the <literal>-O2</literal> flag
-   and another with the <literal>-g</literal> (debug) flag,
-   we would do this like so:
-
-   </para>
-
-   <scons_example name="ex2">
-     <file name="SConstruct" printme="1">
-      opt = Environment(CCFLAGS = '-O2')
-      dbg = Environment(CCFLAGS = '-g')
+      </para>
 
-      opt.Program('foo', 'foo.c')
+      <scons_output example="ex6">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-      dbg.Program('bar', 'bar.c')
-     </file>
-     <file name="foo.c">
-     int main() { }
-     </file>
-     <file name="bar.c">
-     int main() { }
-     </file>
-   </scons_example>
+      <para>
 
-   <scons_output example="ex2">
-      <scons_output_command>scons -Q</scons_output_command>
-   </scons_output>
+      A construction environment, however,
+      is actually an object with associated methods, etc.
+      If you want to have direct access to only the
+      dictionary of construction variables,
+      you can fetch this using the &Dictionary; method:
 
-   <para>
+      </para>
 
-   We can even use multiple construction environments to build
-   multiple versions of a single program.
-   If you do this by simply trying to use the
-   &b-link-Program; builder with both environments, though,
-   like this:
+      <scons_example name="ex6b">
+         <file name="SConstruct" printme="1">
+         env = Environment(FOO = 'foo', BAR = 'bar')
+         dict = env.Dictionary()
+         for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']:
+             print "key = %s, value = %s" % (key, dict[key])
+         </file>
+      </scons_Example>
 
-   </para>
+      <para>
 
-   <scons_example name="ex3">
-     <file name="SConstruct" printme="1">
-      opt = Environment(CCFLAGS = '-O2')
-      dbg = Environment(CCFLAGS = '-g')
+      This &SConstruct; file
+      will print the specified dictionary items for us on POSIX
+      systems as follows:
 
-      opt.Program('foo', 'foo.c')
+      </para>
 
-      dbg.Program('foo', 'foo.c')
-     </file>
-     <file name="foo.c">
-     int main() { }
-     </file>
-   </scons_example>
+      <scons_output example="ex6b" os="posix">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-   <para>
+      <para>
 
-   Then &SCons; generates the following error:
+      And on Windows:
 
-   </para>
+      </para>
 
-   <scons_output example="ex3">
-      <scons_output_command>scons -Q</scons_output_command>
-   </scons_output>
-
-   <para>
-
-   This is because the two &b-Program; calls have
-   each implicitly told &SCons; to generate an object file named
-   <filename>foo.o</filename>,
-   one with a &cv-link-CCFLAGS; value of
-   <literal>-O2</literal>
-   and one with a &cv-link-CCFLAGS; value of
-   <literal>-g</literal>.
-   &SCons; can't just decide that one of them
-   should take precedence over the other,
-   so it generates the error.
-   To avoid this problem,
-   we must explicitly specify
-   that each environment compile
-   <filename>foo.c</filename>
-   to a separately-named object file
-   using the &b-link-Object; builder, like so:
-
-   </para>
-
-   <scons_example name="ex4">
-     <file name="SConstruct" printme="1">
-      opt = Environment(CCFLAGS = '-O2')
-      dbg = Environment(CCFLAGS = '-g')
+      <scons_output example="ex6b" os="win32">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-      o = opt.Object('foo-opt', 'foo.c')
-      opt.Program(o)
+      <para>
 
-      d = dbg.Object('foo-dbg', 'foo.c')
-      dbg.Program(d)
-     </file>
-     <file name="foo.c">
-     int main() { }
-     </file>
-   </scons_example>
+      If you want to loop and print the values of
+      all of the construction variables in a construction environment,
+      the Python code to do that in sorted order might look something like:
 
-   <para>
+      </para>
 
-   Notice that each call to the &b-Object; builder
-   returns a value,
-   an internal &SCons; object that
-   represents the object file that will be built.
-   We then use that object
-   as input to the &b-Program; builder.
-   This avoids having to specify explicitly
-   the object file name in multiple places,
-   and makes for a compact, readable
-   &SConstruct; file.
-   Our &SCons; output then looks like:
+      <sconstruct>
+         env = Environment()
+         for item in sorted(env.Dictionary().items()):
+             print "construction variable = '%s', value = '%s'" % item
+      </sconstruct>
 
-   </para>
+    </section>
 
-   <scons_output example="ex4">
-      <scons_output_command>scons -Q</scons_output_command>
-   </scons_output>
+    <section>
+    <title>Expanding Values From a &ConsEnv;:  the &subst; Method</title>
 
</section>
     <para>
 
- <section>
- <title>Copying &ConsEnvs;</title>
+      Another way to get information from
+      a construction environment.
+      is to use the &subst; method
+      on a string containing <literal>$</literal> expansions
+      of construction variable names.
+      As a simple example,
+      the example from the previous
+      section that used
+      <literal>env['CC']</literal>
+      to fetch the value of &cv-link-CC;
+      could also be written as:
 
-   <para>
+      </para>
 
-   Sometimes you want more than one construction environment
-   to share the same values for one or more variables.
-   Rather than always having to repeat all of the common
-   variables when you create each construction environment,
-   you can use the &Clone; method
-   to create a copy of a construction environment.
+      <sconstruct>
+        env = Environment()
+        print "CC is:", env.subst('$CC')
+      </sconstruct>
 
-   </para>
+      <para>
 
-   <para>
+      One advantage of using
+      &subst; to expand strings is
+      that construction variables
+      in the result get re-expanded until
+      there are no expansions left in the string.
+      So a simple fetch of a value like
+      &cv-link-CCCOM;:
 
-   Like the &Environment; call that creates a construction environment,
-   the &Clone; method takes &consvar; assignments,
-   which will override the values in the copied construction environment.
-   For example, suppose we want to use &gcc;
-   to create three versions of a program,
-   one optimized, one debug, and one with neither.
-   We could do this by creating a "base" construction environment
-   that sets &cv-link-CC; to &gcc;,
-   and then creating two copies,
-   one which sets &cv-link-CCFLAGS; for optimization
-   and the other which sets &cv-CCFLAGS; for debugging:
+      </para>
 
-   </para>
+      <sconstruct>
+        env = Environment(CCFLAGS = '-DFOO')
+        print "CCCOM is:", env['CCCOM']
+      </sconstruct>
 
-   <scons_example name="ex5">
-     <file name="SConstruct" printme="1">
-      env = Environment(CC = 'gcc')
-      opt = env.Clone(CCFLAGS = '-O2')
-      dbg = env.Clone(CCFLAGS = '-g')
+      <para>
 
-      env.Program('foo', 'foo.c')
+      Will print the unexpanded value of &cv-CCCOM;,
+      showing us the construction
+      variables that still need to be expanded:
 
-      o = opt.Object('foo-opt', 'foo.c')
-      opt.Program(o)
+      </para>
 
-      d = dbg.Object('foo-dbg', 'foo.c')
-      dbg.Program(d)
-     </file>
-     <file name="foo.c">
-     int main() { }
-     </file>
-   </scons_example>
+      <screen>
+        % <userinput>scons -Q</userinput>
+        CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES
+        scons: `.' is up to date.
+      </screen>
 
-   <para>
+      <para>
 
-   Then our output would look like:
+      Calling the &subst; method on <varname>$CCOM</varname>,
+      however:
 
-   </para>
+      </para>
 
-   <scons_output example="ex5">
-      <scons_output_command>scons -Q</scons_output_command>
-   </scons_output>
+      <sconstruct>
+        env = Environment(CCFLAGS = '-DFOO')
+        print "CCCOM is:", env.subst('$CCCOM')
+      </sconstruct>
 
</section>
     <para>
 
- <section>
- <title>Fetching Values From a &ConsEnv;</title>
+      Will recursively expand all of
+      the construction variables prefixed
+      with <literal>$</literal> (dollar signs),
+      showing us the final output:
 
-   <para>
+      </para>
 
-   You can fetch individual construction variables
-   using the normal syntax
-   for accessing individual named items in a Python dictionary:
+      <screen>
+        % <userinput>scons -Q</userinput>
+        CCCOM is: gcc -DFOO -c -o
+        scons: `.' is up to date.
+      </screen>
 
-   </para>
+      <para>
 
-   <scons_example name="ex6">
-     <file name="SConstruct" printme="1">
-      env = Environment()
-      print "CC is:", env['CC']
-     </file>
-   </scons_example>
+      Note that because we're not expanding this
+      in the context of building something
+      there are no target or source files
+      for &cv-link-TARGET; and &cv-link-SOURCES; to expand.
 
-   <para>
+      </para>
 
-   This example &SConstruct; file doesn't build anything,
-   but because it's actually a Python script,
-   it will print the value of &cv-link-CC; for us:
+    </section>
 
-   </para>
+    <section>
+    <title>Controlling the Default &ConsEnv;:  the &DefaultEnvironment; Function</title>
 
-   <scons_output example="ex6">
-      <scons_output_command>scons -Q</scons_output_command>
-   </scons_output>
+      <para>
 
-   <para>
+      All of the &Builder; functions that we've introduced so far,
+      like &Program; and &Library;,
+      actually use a default &consenv;
+      that contains settings
+      for the various compilers
+      and other tools that
+      &SCons; configures by default,
+      or otherwise knows about
+      and has discovered on your system.
+      The goal of the default construction environment
+      is to make many configurations to "just work"
+      to build software using
+      readily available tools
+      with a minimum of configuration changes.
 
-   A construction environment, however,
-   is actually an object with associated methods, etc.
-   If you want to have direct access to only the
-   dictionary of construction variables,
-   you can fetch this using the &Dictionary; method:
+      </para>
 
-   </para>
+      <para>
 
-   <scons_example name="ex6b">
-      <file name="SConstruct" printme="1">
-      env = Environment(FOO = 'foo', BAR = 'bar')
-      dict = env.Dictionary()
-      for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']:
-          print "key = %s, value = %s" % (key, dict[key])
-      </file>
-   </scons_Example>
+      You can, however, control the settings
+      in the default contstruction environment
+      by using the &DefaultEnvironment; function
+      to initialize various settings:
 
-   <para>
+      </para>
 
-   This &SConstruct; file
-   will print the specified dictionary items for us on POSIX
-   systems as follows:
+      <sconstruct>
 
-   </para>
+      DefaultEnvironment(CC = '/usr/local/bin/gcc')
 
-   <scons_output example="ex6b" os="posix">
-      <scons_output_command>scons -Q</scons_output_command>
-   </scons_output>
+      </sconstruct>
 
-   <para>
+      <para>
 
-   And on Windows:
+      When configured as above,
+      all calls to the &Program;
+      or &Object; Builder
+      will build object files with the
+      <filename>/usr/local/bin/gcc</filename>
+      compiler.
 
-   </para>
+      </para>
 
-   <scons_output example="ex6b" os="win32">
-      <scons_output_command>scons -Q</scons_output_command>
-   </scons_output>
+      <para>
 
-   <para>
+      Note that the &DefaultEnvironment; function
+      returns the initialized
+      default construction environment object,
+      which can then be manipulated like any
+      other construction environment.
+      So the following
+      would be equivalent to the
+      previous example,
+      setting the &cv-CC;
+      variable to <filename>/usr/local/bin/gcc</filename>
+      but as a separate step after
+      the default construction environment has been initialized:
 
-   If you want to loop through and print the values of
-   all of the construction variables in a construction environment,
-   the Python code to do that in sorted order might look something like:
+      </para>
 
-   </para>
+      <sconstruct>
 
-   <sconstruct>
-      env = Environment()
-      dict = env.Dictionary()
-      keys = dict.keys()
-      keys.sort()
-      for key in keys:
-          print "construction variable = '%s', value = '%s'" % (key, dict[key])
-   </sconstruct>
+      env = DefaultEnvironment()
+      env['CC'] = '/usr/local/bin/gcc'
 
</section>
     </sconstruct>
 
- <section>
- <title>Expanding Values From a &ConsEnv;</title>
+      <para>
 
-   <para>
+      One very common use of the &DefaultEnvironment; function
+      is to speed up &SCons; initialization.
+      As part of trying to make most default
+      configurations "just work,"
+      &SCons; will actually
+      search the local system for installed
+      compilers and other utilities.
+      This search can take time,
+      especially on systems with
+      slow or networked file systems.
+      If you know which compiler(s) and/or
+      other utilities you want to configure,
+      you can control the search
+      that &SCons; performs
+      by specifying some specific
+      tool modules with which to
+      initialize the default construction environment:
 
-   Another way to get information from
-   a construction environment.
-   is to use the &subst; method
-   on a string containing $-expansions
-   of construction variable names.
-   As a simple example,
-   the example from the previous
-   section that used
-   <literal>env['CC']</literal>
-   to fetch the value of &cv-link-CC;
-   could also be written as:
+      </para>
 
-   </para>
+      <sconstruct>
 
-   <sconstruct>
-     env = Environment()
-     print "CC is:", env.subst('$CC')
-   </sconstruct>
+      env = DefaultEnvironment(tools = ['gcc', 'gnulink'],
+                               CC = '/usr/local/bin/gcc')
+
+      </sconstruct>
+
+      <para>
+
+      So the above example would tell &SCons;
+      to explicitly configure the default environment
+      to use its normal GNU Compiler and GNU Linker settings
+      (without having to search for them,
+      or any other utilities for that matter),
+      and specifically to use the compiler found at
+      <filename>/usr/local/bin/gcc</filename>.
+
+      </para>
+
+    </section>
+
+    <section>
+    <title>Multiple &ConsEnvs;</title>
 
-   <para>
+      <para>
 
-   The real advantage of using
-   &subst; to expand strings is
-   that construction variables
-   in the result get
-   re-expanded until
-   there are no expansions left in the string.
-   So a simple fetch of a value like
-   &cv-link-CCCOM;:
+      The real advantage of construction environments
+      is that you can create as many different construction
+      environments as you need,
+      each tailored to a different way to build
+      some piece of software or other file.
+      If, for example, we need to build
+      one program with the <literal>-O2</literal> flag
+      and another with the <literal>-g</literal> (debug) flag,
+      we would do this like so:
+
+      </para>
+
+      <scons_example name="ex2">
+        <file name="SConstruct" printme="1">
+         opt = Environment(CCFLAGS = '-O2')
+         dbg = Environment(CCFLAGS = '-g')
+
+         opt.Program('foo', 'foo.c')
+
+         dbg.Program('bar', 'bar.c')
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+        <file name="bar.c">
+        int main() { }
+        </file>
+      </scons_example>
+
+      <scons_output example="ex2">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
+
+      <para>
+
+      We can even use multiple construction environments to build
+      multiple versions of a single program.
+      If you do this by simply trying to use the
+      &b-link-Program; builder with both environments, though,
+      like this:
+
+      </para>
+
+      <scons_example name="ex3">
+        <file name="SConstruct" printme="1">
+         opt = Environment(CCFLAGS = '-O2')
+         dbg = Environment(CCFLAGS = '-g')
+
+         opt.Program('foo', 'foo.c')
+
+         dbg.Program('foo', 'foo.c')
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+      </scons_example>
+
+      <para>
+
+      Then &SCons; generates the following error:
+
+      </para>
+
+      <scons_output example="ex3">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
+
+      <para>
+
+      This is because the two &b-Program; calls have
+      each implicitly told &SCons; to generate an object file named
+      <filename>foo.o</filename>,
+      one with a &cv-link-CCFLAGS; value of
+      <literal>-O2</literal>
+      and one with a &cv-link-CCFLAGS; value of
+      <literal>-g</literal>.
+      &SCons; can't just decide that one of them
+      should take precedence over the other,
+      so it generates the error.
+      To avoid this problem,
+      we must explicitly specify
+      that each environment compile
+      <filename>foo.c</filename>
+      to a separately-named object file
+      using the &b-link-Object; builder, like so:
+
+      </para>
+
+      <scons_example name="ex4">
+        <file name="SConstruct" printme="1">
+         opt = Environment(CCFLAGS = '-O2')
+         dbg = Environment(CCFLAGS = '-g')
+
+         o = opt.Object('foo-opt', 'foo.c')
+         opt.Program(o)
+
+         d = dbg.Object('foo-dbg', 'foo.c')
+         dbg.Program(d)
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+      </scons_example>
+
+      <para>
+
+      Notice that each call to the &b-Object; builder
+      returns a value,
+      an internal &SCons; object that
+      represents the object file that will be built.
+      We then use that object
+      as input to the &b-Program; builder.
+      This avoids having to specify explicitly
+      the object file name in multiple places,
+      and makes for a compact, readable
+      &SConstruct; file.
+      Our &SCons; output then looks like:
+
+      </para>
+
+      <scons_output example="ex4">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
+
+    </section>
+
+    <section>
+    <title>Making Copies of &ConsEnvs;:  the &Clone; Method</title>
 
-   </para>
+      <para>
 
-   <sconstruct>
-     env = Environment(CCFLAGS = '-DFOO')
-     print "CCCOM is:", env['CCCOM']
-   </sconstruct>
+      Sometimes you want more than one construction environment
+      to share the same values for one or more variables.
+      Rather than always having to repeat all of the common
+      variables when you create each construction environment,
+      you can use the &Clone; method
+      to create a copy of a construction environment.
+
+      </para>
 
-   <para>
+      <para>
+
+      Like the &Environment; call that creates a construction environment,
+      the &Clone; method takes &consvar; assignments,
+      which will override the values in the copied construction environment.
+      For example, suppose we want to use &gcc;
+      to create three versions of a program,
+      one optimized, one debug, and one with neither.
+      We could do this by creating a "base" construction environment
+      that sets &cv-link-CC; to &gcc;,
+      and then creating two copies,
+      one which sets &cv-link-CCFLAGS; for optimization
+      and the other which sets &cv-CCFLAGS; for debugging:
 
-   Will print the unexpanded value of &cv-CCCOM;,
-   showing us the construction
-   variables that still need to be expanded:
+      </para>
 
-   </para>
+      <scons_example name="ex5">
+        <file name="SConstruct" printme="1">
+         env = Environment(CC = 'gcc')
+         opt = env.Clone(CCFLAGS = '-O2')
+         dbg = env.Clone(CCFLAGS = '-g')
+
+         env.Program('foo', 'foo.c')
+
+         o = opt.Object('foo-opt', 'foo.c')
+         opt.Program(o)
+
+         d = dbg.Object('foo-dbg', 'foo.c')
+         dbg.Program(d)
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+      </scons_example>
+
+      <para>
+
+      Then our output would look like:
+
+      </para>
+
+      <scons_output example="ex5">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
+
+    </section>
+
+    <section>
+    <title>Replacing Values:  the &Replace; Method</title>
+
+      <para>
+
+      You can replace existing construction variable values
+      using the &Replace; method:
+
+      </para>
+
+      <scons_example name="Replace1">
+        <file name="SConstruct" printme="1">
+         env = Environment(CCFLAGS = '-DDEFINE1')
+         env.Replace(CCFLAGS = '-DDEFINE2')
+         env.Program('foo.c')
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+      </scons_example>
+
+      <para>
+
+      The replacing value
+      (<literal>-DDEFINE2</literal> in the above example)
+      completely replaces the value in the
+      construction environment:
 
-   <screen>
-     % <userinput>scons -Q</userinput>
-     CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES
-     scons: `.' is up to date.
-   </screen>
+      </para>
 
-   <para>
+      <scons_output example="Replace1">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-   Calling the &subst; method on <varname>$CCOM</varname>,
-   however:
+      <para>
 
-   </para>
+      You can safely call &Replace;
+      for construction variables that
+      don't exist in the construction environment:
+
+      </para>
 
-   <sconstruct>
-     env = Environment(CCFLAGS = '-DFOO')
-     print "CCCOM is:", env.subst('$CCCOM')
-   </sconstruct>
+      <scons_example name="Replace-nonexistent">
+        <file name="SConstruct" printme="1">
+         env = Environment()
+         env.Replace(NEW_VARIABLE = 'xyzzy')
+         print "NEW_VARIABLE =", env['NEW_VARIABLE']
+        </file>
+      </scons_example>
 
-   <para>
+      <para>
+
+      In this case,
+      the construction variable simply
+      gets added to the construction environment:
+
+      </para>
+
+      <scons_output example="Replace-nonexistent">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-   Will recursively expand all of
-   the $-prefixed construction variables,
-   showing us the final output:
+      <para>
 
-   </para>
+      Because the variables
+      aren't expanded until the construction environment
+      is actually used to build the targets,
+      and because &SCons; function and method calls
+      are order-independent,
+      the last replacement "wins"
+      and is used to build all targets,
+      regardless of the order in which
+      the calls to Replace() are
+      interspersed with calls to
+      builder methods:
 
-   <screen>
-     % <userinput>scons -Q</userinput>
-     CCCOM is: gcc -DFOO -c -o
-     scons: `.' is up to date.
-   </screen>
+      </para>
 
-   <para>
+      <scons_example name="Replace2">
+        <file name="SConstruct" printme="1">
+         env = Environment(CCFLAGS = '-DDEFINE1')
+         print "CCFLAGS =", env['CCFLAGS']
+         env.Program('foo.c')
 
-   (Note that because we're not expanding this
-   in the context of building something
-   there are no target or source files
-   for &cv-link-TARGET; and &cv-link-SOURCES; to expand.)
+         env.Replace(CCFLAGS = '-DDEFINE2')
+         print "CCFLAGS =", env['CCFLAGS']
+         env.Program('bar.c')
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+        <file name="bar.c">
+        int main() { }
+        </file>
+      </scons_example>
 
-   </para>
+      <para>
 
- </section>
+      The timing of when the replacement
+      actually occurs relative
+      to when the targets get built
+      becomes apparent
+      if we run &scons; without the <literal>-Q</literal>
+      option:
 
- <section>
- <title>Modifying a &ConsEnv;</title>
+      </para>
+
+      <scons_output example="Replace2">
+         <scons_output_command>scons</scons_output_command>
+      </scons_output>
+
+      <para>
 
-   <para>
+      Because the replacement occurs while
+      the &SConscript; files are being read,
+      the &cv-link-CCFLAGS;
+      variable has already been set to
+      <literal>-DDEFINE2</literal>
+      by the time the &foo_o; target is built,
+      even though the call to the &Replace;
+      method does not occur until later in
+      the &SConscript; file.
 
-   &SCons; provides various methods that
-   support modifying existing values in a construction environment.
+      </para>
 
-   </para>
+    </section>
 
-   <section>
-   <title>Replacing Values in a &ConsEnv;</title>
+    <section>
+    <title>Setting Values Only If They're Not Already Defined:  the &SetDefault; Method</title>
 
-     <para>
+      <para>
 
-     You can replace existing construction variable values
-     using the &Replace; method:
+      Sometimes it's useful to be able to specify
+      that a construction variable should be
+      set to a value only if the construction environment
+      does not already have that variable defined
+      You can do this with the &SetDefault; method,
+      which behaves similarly to the <function>set_default</function>
+      method of Python dictionary objects:
 
-     </para>
+      </para>
 
-     <scons_example name="Replace1">
-       <file name="SConstruct" printme="1">
-        env = Environment(CCFLAGS = '-DDEFINE1')
-        env.Replace(CCFLAGS = '-DDEFINE2')
-        env.Program('foo.c')
-       </file>
-       <file name="foo.c">
-       int main() { }
-       </file>
-     </scons_example>
+      <sconstruct>
+      env.SetDefault(SPECIAL_FLAG = '-extra-option')
+      </sconstruct>
 
-     <para>
+      <para>
 
-     The replacing value
-     (<literal>-DDEFINE2</literal> in the above example)
-     completely replaces the value in the
-     construction environment:
+      This is especially useful
+      when writing your own <literal>Tool</literal> modules
+      to apply variables to construction environments.
+      <!--
+      See <xref linkend="chap-tool-modules"></xref>
+      for more information about writing
+      Tool modules.
+      -->
 
-     </para>
+      </para>
 
-     <scons_output example="Replace1">
-        <scons_output_command>scons -Q</scons_output_command>
-     </scons_output>
+    </section>
 
-     <para>
+    <section>
+    <title>Appending to the End of Values:  the &Append; Method</title>
 
-     You can safely call &Replace;
-     for construction variables that
-     don't exist in the construction environment:
+      <para>
 
-     </para>
+      You can append a value to
+      an existing construction variable
+      using the &Append; method:
 
-     <scons_example name="Replace-nonexistent">
-       <file name="SConstruct" printme="1">
-        env = Environment()
-        env.Replace(NEW_VARIABLE = 'xyzzy')
-        print "NEW_VARIABLE =", env['NEW_VARIABLE']
-       </file>
-     </scons_example>
+      </para>
 
-     <para>
+      <scons_example name="ex8">
+        <file name="SConstruct" printme="1">
+         env = Environment(CCFLAGS = ['-DMY_VALUE'])
+         env.Append(CCFLAGS = ['-DLAST'])
+         env.Program('foo.c')
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+      </scons_example>
 
-     In this case,
-     the construction variable simply
-     gets added to the construction environment:
+      <para>
 
-     </para>
+      &SCons; then supplies both the <literal>-DMY_VALUE</literal> and
+      <literal>-DLAST</literal> flags when compiling the object file:
 
-     <scons_output example="Replace-nonexistent">
-        <scons_output_command>scons -Q</scons_output_command>
-     </scons_output>
+      </para>
 
-     <para>
+      <scons_output example="ex8">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-     Because the variables
-     aren't expanded until the construction environment
-     is actually used to build the targets,
-     and because &SCons; function and method calls
-     are order-independent,
-     the last replacement "wins"
-     and is used to build all targets,
-     regardless of the order in which
-     the calls to Replace() are
-     interspersed with calls to
-     builder methods:
+      <para>
 
-     </para>
+      If the construction variable doesn't already exist,
+      the &Append; method will create it:
 
-     <scons_example name="Replace2">
-       <file name="SConstruct" printme="1">
-        env = Environment(CCFLAGS = '-DDEFINE1')
-        print "CCFLAGS =", env['CCFLAGS']
-        env.Program('foo.c')
+      </para>
 
-        env.Replace(CCFLAGS = '-DDEFINE2')
-        print "CCFLAGS =", env['CCFLAGS']
-        env.Program('bar.c')
-       </file>
-       <file name="foo.c">
-       int main() { }
-       </file>
-       <file name="bar.c">
-       int main() { }
-       </file>
-     </scons_example>
+      <scons_example name="Append-nonexistent">
+        <file name="SConstruct" printme="1">
+         env = Environment()
+         env.Append(NEW_VARIABLE = 'added')
+         print "NEW_VARIABLE =", env['NEW_VARIABLE']
+        </file>
+      </scons_example>
 
-     <para>
+      <para>
 
-     The timing of when the replacement
-     actually occurs relative
-     to when the targets get built
-     becomes apparent
-     if we run &scons; without the <literal>-Q</literal>
-     option:
+      Which yields:
 
-     </para>
+      </para>
 
-     <scons_output example="Replace2">
-        <scons_output_command>scons</scons_output_command>
-     </scons_output>
+      <scons_output example="Append-nonexistent">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-     <para>
+      <para>
 
-     Because the replacement occurs while
-     the &SConscript; files are being read,
-     the &cv-link-CCFLAGS;
-     variable has already been set to
-     <literal>-DDEFINE2</literal>
-     by the time the &foo_o; target is built,
-     even though the call to the &Replace;
-     method does not occur until later in
-     the &SConscript; file.
+      Note that the &Append; function tries to be "smart"
+      about how the new value is appended to the old value.
+      If both are strings, the previous and new strings
+      are simply concatenated.
+      Similarly, if both are lists,
+      the lists are concatenated.
+      If, however, one is a string and the other is a list,
+      the string is added as a new element to the list.
 
-     </para>
+      </para>
 
-   </section>
+    </section>
 
-   <!--
+    <section>
+    <title>Appending Unique Values:  the &AppendUnique; Method</title>
 
-   <section>
-   <title>Setting Values Only If They're Not Already Defined</title>
+      <para>
 
-     <para>
+      Some times it's useful to add a new value
+      only if the existing construction variable
+      doesn't already contain the value.
+      This can be done using the &AppendUnique; method:
 
-     XXX SetDefault()
+      </para>
 
-     </para>
+      <sconstruct>
+      env.AppendUnique(CCFLAGS=['-g'])
+      </sconstruct>
 
-   </section>
+      <para>
 
-   -->
+      In the above example,
+      the <literal>-g</literal> would be added
+      only if the &cv-CCFLAGS; variable
+      does not already contain a <literal>-g</literal> value.
 
-   <section>
-   <title>Appending to the End of Values in a &ConsEnv;</title>
+      </para>
 
-     <para>
+    </section>
 
-     You can append a value to
-     an existing construction variable
-     using the &Append; method:
+    <section>
+    <title>Appending to the Beginning of Values:  the &Prepend; Method</title>
 
-     </para>
+      <para>
 
-     <scons_example name="ex8">
-       <file name="SConstruct" printme="1">
-        env = Environment(CCFLAGS = '-DMY_VALUE')
-        env.Append(CCFLAGS = ' -DLAST')
-        env.Program('foo.c')
-       </file>
-       <file name="foo.c">
-       int main() { }
-       </file>
-     </scons_example>
+      You can append a value to the beginning of
+      an existing construction variable
+      using the &Prepend; method:
 
-     <para>
+      </para>
 
-     &SCons; then supplies both the <literal>-DMY_VALUE</literal> and
-     <literal>-DLAST</literal> flags when compiling the object file:
+      <scons_example name="ex9">
+        <file name="SConstruct" printme="1">
+         env = Environment(CCFLAGS = ['-DMY_VALUE'])
+         env.Prepend(CCFLAGS = ['-DFIRST'])
+         env.Program('foo.c')
+        </file>
+        <file name="foo.c">
+        int main() { }
+        </file>
+      </scons_example>
 
-     </para>
+      <para>
 
-     <scons_output example="ex8">
-        <scons_output_command>scons -Q</scons_output_command>
-     </scons_output>
+      &SCons; then supplies both the <literal>-DFIRST</literal> and
+      <literal>-DMY_VALUE</literal> flags when compiling the object file:
 
-     <para>
+      </para>
 
-     If the construction variable doesn't already exist,
-     the &Append; method will create it:
+      <scons_output example="ex9">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-     </para>
+      <para>
 
-     <scons_example name="Append-nonexistent">
-       <file name="SConstruct" printme="1">
-        env = Environment()
-        env.Append(NEW_VARIABLE = 'added')
-        print "NEW_VARIABLE =", env['NEW_VARIABLE']
-       </file>
-     </scons_example>
+      If the construction variable doesn't already exist,
+      the &Prepend; method will create it:
 
-     <para>
+      </para>
 
-     Which yields:
+      <scons_example name="Prepend-nonexistent">
+        <file name="SConstruct" printme="1">
+         env = Environment()
+         env.Prepend(NEW_VARIABLE = 'added')
+         print "NEW_VARIABLE =", env['NEW_VARIABLE']
+        </file>
+      </scons_example>
 
-     </para>
+      <para>
 
-     <scons_output example="Append-nonexistent">
-        <scons_output_command>scons -Q</scons_output_command>
-     </scons_output>
+      Which yields:
 
-     <!--
+      </para>
 
-     XXX AppendUnique()
+      <scons_output example="Prepend-nonexistent">
+         <scons_output_command>scons -Q</scons_output_command>
+      </scons_output>
 
-     -->
+      <para>
 
-   </section>
+      Like the &Append; function,
+      the &Prepend; function tries to be "smart"
+      about how the new value is appended to the old value.
+      If both are strings, the previous and new strings
+      are simply concatenated.
+      Similarly, if both are lists,
+      the lists are concatenated.
+      If, however, one is a string and the other is a list,
+      the string is added as a new element to the list.
 
-   <section>
-   <title>Appending to the Beginning of Values in a &ConsEnv;</title>
+      </para>
 
-     <para>
+    </section>
 
-     You can append a value to the beginning of
-     an existing construction variable
-     using the &Prepend; method:
+    <section>
+    <title>Prepending Unique Values:  the &PrependUnique; Method</title>
 
-     </para>
+      <para>
 
-     <scons_example name="ex9">
-       <file name="SConstruct" printme="1">
-        env = Environment(CCFLAGS = '-DMY_VALUE')
-        env.Prepend(CCFLAGS = '-DFIRST ')
-        env.Program('foo.c')
-       </file>
-       <file name="foo.c">
-       int main() { }
-       </file>
-     </scons_example>
+      Some times it's useful to add a new value
+      to the beginning of a construction variable
+      only if the existing value
+      doesn't already contain the to-be-added value.
+      This can be done using the &PrependUnique; method:
 
-     <para>
+      </para>
 
-     &SCons; then supplies both the <literal>-DFIRST</literal> and
-     <literal>-DMY_VALUE</literal> flags when compiling the object file:
+      <sconstruct>
+      env.PrependUnique(CCFLAGS=['-g'])
+      </sconstruct>
 
-     </para>
+      <para>
 
-     <scons_output example="ex9">
-        <scons_output_command>scons -Q</scons_output_command>
-     </scons_output>
+      In the above example,
+      the <literal>-g</literal> would be added
+      only if the &cv-CCFLAGS; variable
+      does not already contain a <literal>-g</literal> value.
 
-     <para>
+      </para>
 
-     If the construction variable doesn't already exist,
-     the &Prepend; method will create it:
+    </section>
 
-     </para>
+  </section>
 
-     <scons_example name="Prepend-nonexistent">
-       <file name="SConstruct" printme="1">
-        env = Environment()
-        env.Prepend(NEW_VARIABLE = 'added')
-        print "NEW_VARIABLE =", env['NEW_VARIABLE']
-       </file>
-     </scons_example>
+  <section id="sect-execution-environments">
+  <title>Controlling the Execution Environment for Issued Commands</title>
+
+    <para>
+
+      When &SCons; builds a target file,
+      it does not execute the commands with
+      the same external environment
+      that you used to execute &SCons;.
+      Instead, it uses the dictionary
+      stored in the &cv-link-ENV; construction variable
+      as the external environment
+      for executing commands.
 
-     <para>
+    </para>
 
-     Which yields:
+    <para>
 
-     </para>
+      The most important ramification of this behavior
+      is that the &PATH; environment variable,
+      which controls where the operating system
+      will look for commands and utilities,
+      is not the same as in the external environment
+      from which you called &SCons;.
+      This means that &SCons; will not, by default,
+      necessarily find all of the tools
+      that you can execute from the command line.
 
-     <scons_output example="Prepend-nonexistent">
-        <scons_output_command>scons -Q</scons_output_command>
-     </scons_output>
+    </para>
 
-     <!--
+    <para>
 
-     XXX PrependUnique()
+      The default value of the &PATH; environment variable
+      on a POSIX system
+      is <literal>/usr/local/bin:/bin:/usr/bin</literal>.
+      The default value of the &PATH; environment variable
+      on a Windows system comes from the Windows registry
+      value for the command interpreter.
+      If you want to execute any commands--compilers, linkers, etc.--that
+      are not in these default locations,
+      you need to set the &PATH; value
+      in the &cv-ENV; dictionary
+      in your construction environment.
 
-     -->
+    </para>
 
-   </section>
+    <para>
 
-   <!--
+      The simplest way to do this is to initialize explicitly
+      the value when you create the construction environment;
+      this is one way to do that:
 
-   <section>
-   <title>Adding to Values in the Execution Environment</title>
+    </para>
 
-     <para>
+    <sconstruct>
+      path = ['/usr/local/bin', '/bin', '/usr/bin']
+      env = Environment(ENV = {'PATH' : path})
+    </sconstruct>
 
-     XXX AppendENVPath()
+    <para>
 
-     XXX PrependENVPath()
+    Assign a dictionary to the &cv-ENV;
+    construction variable in this way
+    completely resets the external environment
+    so that the only variable that will be
+    set when external commands are executed
+    will be the &PATH; value.
+    If you want to use the rest of
+    the values in &cv-ENV; and only
+    set the value of &PATH;,
+    the most straightforward way is probably:
 
-     </para>
+    </para>
 
-   </section>
+    <sconstruct>
+      env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin']
+    </sconstruct>
 
-   -->
+    <para>
 
- </section>
+    Note that &SCons; does allow you to define
+    the directories in the &PATH; in a string,
+    separated by the pathname-separator character
+    for your system (':' on POSIX systems, ';' on Windows):
+
+    </para>
+
+    <sconstruct>
+      env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'
+    </sconstruct>
+
+    <para>
+
+    But doing so makes your &SConscript; file less portable,
+    (although in this case that may not be a huge concern
+    since the directories you list are likley system-specific, anyway).
+
+    </para>
+
+    <!--
+
+    <scons_example name="ex1">
+      <file name="SConstruct" printme="1">
+      env = Environment()
+      env.Command('foo', [], '__ROOT__/usr/bin/printenv.py')
+      </file>
+      <file name="__ROOT__/usr/bin/printenv.py" chmod="0755">
+      #!/usr/bin/env python
+      import os
+      import sys
+      if len(sys.argv) &gt; 1:
+          keys = sys.argv[1:]
+      else:
+          keys = sorted(os.environ.keys())
+      for key in keys:
+          print "    " + key + "=" + os.environ[key]
+      </file>
+    </scons_example>
+
+    <para>
+
+    </para>
+
+    <scons_output example="ex1">
+      <scons_output_command>scons -Q</scons_output_command>
+    </scons_output>
+
+    -->
+
+    <section>
+    <title>Propagating &PATH; From the External Environment</title>
+
+      <para>
+
+      You may want to propagate the external &PATH;
+      to the execution environment for commands.
+      You do this by initializing the &PATH;
+      variable with the &PATH; value from
+      the <literal>os.environ</literal>
+      dictionary,
+      which is Python's way of letting you
+      get at the external environment:
+
+      </para>
+
+      <sconstruct>
+        import os
+        env = Environment(ENV = {'PATH' : os.environ['PATH']})
+      </sconstruct>
+
+      <para>
+
+      Alternatively, you may find it easier
+      to just propagate the entire external
+      environment to the execution environment
+      for commands.
+      This is simpler to code than explicity
+      selecting the &PATH; value:
+
+      </para>
+
+      <sconstruct>
+        import os
+        env = Environment(ENV = os.environ)
+      </sconstruct>
+
+      <para>
+
+      Either of these will guarantee that
+      &SCons; will be able to execute
+      any command that you can execute from the command line.
+      The drawback is that the build can behave
+      differently if it's run by people with
+      different &PATH; values in their environment--for example,
+      if both the <literal>/bin</literal> and
+      <literal>/usr/local/bin</literal> directories
+      have different &cc; commands,
+      then which one will be used to compile programs
+      will depend on which directory is listed
+      first in the user's &PATH; variable.
+
+      </para>
+
+    </section>
+
+    <section>
+    <title>Adding to <varname>PATH</varname> Values in the Execution Environment</title>
+
+      <para>
+
+      One of the most common requirements
+      for manipulating a variable in the execution environment
+      is to add one or more custom directories to a search
+      like the <envar>$PATH</envar> variable on Linux or POSIX systems,
+      or the <envar>%PATH%</envar> variable on Windows,
+      so that a locally-installed compiler or other utility
+      can be found when &SCons; tries to execute it to update a target.
+      &SCons; provides &PrependENVPath; and &AppendENVPath; functions
+      to make adding things to execution variables convenient.
+      You call these functions by specifying the variable
+      to which you want the value added,
+      and then value itself.
+      So to add some <filename>/usr/local</filename> directories
+      to the <envar>$PATH</envar> and <envar>$LIB</envar> variables,
+      you might:
+
+      </para>
+
+      <sconstruct>
+        env = Environment(ENV = os.environ)
+        env.PrependENVPath('PATH', '/usr/local/bin')
+        env.AppendENVPath('LIB', '/usr/local/lib')
+      </sconstruct>
+
+      <para>
+
+      Note that the added values are strings,
+      and if you want to add multiple directories to
+      a variable like <envar>$PATH</envar>,
+      you must include the path separate character
+      (<literal>:</literal> on Linux or POSIX,
+      <literal>;</literal> on Windows)
+      in the string.
+
+      </para>
+
+    </section>
+
+  </section>