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:
13 The above copyright notice and this permission notice shall be included
14 in all copies or substantial portions of the Software.
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.
28 =head1 More on construction environments
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
36 =head2 Construction variable expansion
38 Construction variables from a construction environment are expanded
39 by preceding the keyword with a C<%> (percent sign):
41 Construction variables:
42 XYZZY => 'abracadabra',
44 The string: "The magic word is: %XYZZY!"
45 expands to: "The magic word is: abracadabra!"
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:
52 Construction variables:
56 The string: "%OPT %{OPT}ION %OPTION %{OPTION}"
57 expands to: "value1 value1ION value2 value2"
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:
63 Construction variables:
64 STRING => 'The result is: %FOO',
68 The string: "The string says: %STRING"
69 expands to: "The string says: The result is: final value"
71 If a construction variable is not defined in an environment, then the
72 null string is substituted:
74 Construction variables:
78 The string: "%FOO <%NO_VARIABLE> %BAR"
79 expands to: "value1 <> value2"
81 A doubled C<%%> will be replaced by a single C<%>:
83 The string: "Here is a percent sign: %%"
84 expands to: "Here is a percent sign: %"
86 =head2 Default construction variables
88 When you specify no arguments when creating a new construction
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
100 CCCOM => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
102 CXXFLAGS => '%CFLAGS',
103 CXXCOM => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
104 INCDIRPREFIX => '-I',
107 LINKCOM => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
108 LINKMODULECOM => '%LD -r -o %> %<',
109 LIBDIRPREFIX => '-L',
113 ARCOM => ['%AR %ARFLAGS %> %<', '%RANLIB %>'],
117 ASCOM => '%AS %ASFLAGS %< -o %>',
124 SIGNATURE => [ '*' => 'build' ],
125 ENV => { 'PATH' => '/bin:/usr/bin' },
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>
134 CCCOM => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
135 CXXCOM => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
136 INCDIRPREFIX => '/I',
139 LINKCOM => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
140 LINKMODULECOM => '%LD /r /o %> %<',
141 LIBDIRPREFIX => '/LIBPATH:',
144 ARFLAGS => '/nologo ',
145 ARCOM => "%AR %ARFLAGS /out:%> %<",
148 LDFLAGS => '/nologo ',
152 SUFLIBS => '.dll:.lib',
154 SIGNATURE => [ '*' => 'build' ],
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
163 Objects $env 'foo.c', 'bar.c';
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.
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.
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>.
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.
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.
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.
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.
207 =head2 Expanding variables in construction commands
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:
219 The target file name. In a multi-target command, this expands to the
220 first target mentioned.)
226 =item %1, %2, ..., %9
228 These refer to the first through ninth input file, respectively.
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:
237 Command $env 'tgt', qw(foo bar baz), qq(
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:
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
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:
256 :a the absolute path to the file name
257 :b the directory plus the file name stripped of any suffix
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
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>.
267 There are additional C<%> elements which affect the command line(s):
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>:
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 %]' > %>
289 echo '# Keywords: foo,bar,baz' > tgt
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.
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.
308 XXX DESCRIBE THE Literal() FUNCTION, TOO XXX
310 =head2 Expanding construction variables in file names
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:
317 DESTDIR => 'programs',
320 Program $env '%DESTDIR/hello', '%SRCDIR/hello.c';
322 This allows for flexible configuration, through the construction
323 environment, of directory names, suffixes, etc.
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:
343 <term>External Environment</term>
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.
360 <term>&ConsEnv;</term>
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.
384 <term>Execution Environment</term>
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>
397 See <xref linkend="sect-execution-environments"></xref>, below.
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 comiler or build option to be used,
419 but the checked-in change breaks the official build
420 because it uses different environment variable settings.
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.
449 <section id="sect-external-environments">
450 <title>Using Values From the External Environment</title>
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>
461 This means that you must add an
462 <literal>import os</literal> statuement
463 to any &SConscript; file
464 in which you want to use
465 values from the user's external environment.
469 <scons_example name="ex1">
470 <file name="SConstruct" printme="1">
480 More usefully, you can use the
481 <envar>os.environ</envar>
482 dictionary in your &SConscript;
483 files to initialize &consenvs;
484 with values from the user's external environment.
485 See the next section,
486 <xref linkend="sect-construction-environments"></xref>,
487 for information on how to do this.
493 <section id="sect-construction-environments">
494 <title>Construction Environments</title>
498 It is rare that all of the software in a large,
499 complicated system needs to be built the same way.
500 For example, different source files may need different options
501 enabled on the command line,
502 or different executable programs need to be linked
503 with different libraries.
504 &SCons; accommodates these different build
505 requirements by allowing you to create and
506 configure multiple &consenvs;
507 that control how the software is built.
508 A &consenv; is an object
509 that has a number of associated
510 &consvars;, each with a name and a value.
511 (A construction environment also has an attached
512 set of &Builder; methods,
513 about which we'll learn more later.)
518 <title>Creating a &ConsEnv;: the &Environment; Function</title>
522 A &consenv; is created by the &Environment; method:
532 By default, &SCons; initializes every
533 new construction environment
534 with a set of &consvars;
535 based on the tools that it finds on your system,
536 plus the default set of builder methods
537 necessary for using those tools.
538 The construction variables
539 are initialized with values describing
541 the Fortran compiler,
544 as well as the command lines to invoke them.
550 When you initialize a construction environment
551 you can set the values of the
552 environment's &consvars;
553 to control how a program is built.
558 <scons_example name="ex1">
559 <file name="SConstruct" printme="1">
560 env = Environment(CC = 'gcc',
572 The construction environment in this example
573 is still initialized with the same default
574 construction variable values,
575 except that the user has explicitly specified use of the
576 GNU C compiler &gcc;,
577 and further specifies that the <literal>-O2</literal>
578 (optimization level two)
579 flag should be used when compiling the object file.
580 In other words, the explicit initializations of
581 &cv-link-CC; and &cv-link-CCFLAGS;
582 override the default values in the newly-created
583 construction environment.
584 So a run from this example would look like:
588 <scons_output example="ex1">
589 <scons_output_command>scons -Q</scons_output_command>
595 <title>Fetching Values From a &ConsEnv;</title>
599 You can fetch individual construction variables
600 using the normal syntax
601 for accessing individual named items in a Python dictionary:
605 <scons_example name="ex6">
606 <file name="SConstruct" printme="1">
608 print "CC is:", env['CC']
614 This example &SConstruct; file doesn't build anything,
615 but because it's actually a Python script,
616 it will print the value of &cv-link-CC; for us:
620 <scons_output example="ex6">
621 <scons_output_command>scons -Q</scons_output_command>
626 A construction environment, however,
627 is actually an object with associated methods, etc.
628 If you want to have direct access to only the
629 dictionary of construction variables,
630 you can fetch this using the &Dictionary; method:
634 <scons_example name="ex6b">
635 <file name="SConstruct" printme="1">
636 env = Environment(FOO = 'foo', BAR = 'bar')
637 dict = env.Dictionary()
638 for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']:
639 print "key = %s, value = %s" % (key, dict[key])
645 This &SConstruct; file
646 will print the specified dictionary items for us on POSIX
651 <scons_output example="ex6b" os="posix">
652 <scons_output_command>scons -Q</scons_output_command>
661 <scons_output example="ex6b" os="win32">
662 <scons_output_command>scons -Q</scons_output_command>
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:
675 dict = env.Dictionary()
679 print "construction variable = '%s', value = '%s'" % (key, dict[key])
685 <title>Expanding Values From a &ConsEnv;: the &subst; Method</title>
689 Another way to get information from
690 a construction environment.
691 is to use the &subst; method
692 on a string containing <literal>$</literal> expansions
693 of construction variable names.
695 the example from the previous
697 <literal>env['CC']</literal>
698 to fetch the value of &cv-link-CC;
699 could also be written as:
705 print "CC is:", env.subst('$CC')
710 One advantage of using
711 &subst; to expand strings is
712 that construction variables
713 in the result get re-expanded until
714 there are no expansions left in the string.
715 So a simple fetch of a value like
721 env = Environment(CCFLAGS = '-DFOO')
722 print "CCCOM is:", env['CCCOM']
727 Will print the unexpanded value of &cv-CCCOM;,
728 showing us the construction
729 variables that still need to be expanded:
734 % <userinput>scons -Q</userinput>
735 CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES
736 scons: `.' is up to date.
741 Calling the &subst; method on <varname>$CCOM</varname>,
747 env = Environment(CCFLAGS = '-DFOO')
748 print "CCCOM is:", env.subst('$CCCOM')
753 Will recursively expand all of
754 the construction variables prefixed
755 with <literal>$</literal> (dollar signs),
756 showing us the final output:
761 % <userinput>scons -Q</userinput>
762 CCCOM is: gcc -DFOO -c -o
763 scons: `.' is up to date.
768 Note that because we're not expanding this
769 in the context of building something
770 there are no target or source files
771 for &cv-link-TARGET; and &cv-link-SOURCES; to expand.
778 <title>Controlling the Default &ConsEnv;: the &DefaultEnvironment; Function</title>
782 All of the &Builder; functions that we've introduced so far,
783 like &Program; and &Library;,
784 actually use a default &consenv;
785 that contains settings
786 for the various compilers
788 &SCons; configures by default,
789 or otherwise knows about
790 and has discovered on your system.
791 The goal of the default construction environment
792 is to make many configurations to "just work"
793 to build software using
794 readily available tools
795 with a minimum of configuration changes.
801 You can, however, control the settings
802 in the default contstruction environment
803 by using the &DefaultEnvironment; function
804 to initialize various settings:
810 DefaultEnvironment(CC = '/usr/local/bin/gcc')
816 When configured as above,
817 all calls to the &Program;
819 will build object files with the
820 <filename>/usr/local/bin/gcc</filename>
827 Note that the &DefaultEnvironment; function
828 returns the initialized
829 default construction environment object,
830 which can then be manipulated like any
831 other construction environment.
833 would be equivalent to the
836 variable to <filename>/usr/local/bin/gcc</filename>
837 but as a separate step after
838 the default construction environment has been initialized:
844 env = DefaultEnvironment()
845 env['CC'] = '/usr/local/bin/gcc'
851 One very common use of the &DefaultEnvironment; function
852 is to speed up &SCons; initialization.
853 As part of trying to make most default
854 configurations "just work,"
855 &SCons; will actually
856 search the local system for installed
857 compilers and other utilities.
858 This search can take time,
859 especially on systems with
860 slow or networked file systems.
861 If you know which compiler(s) and/or
862 other utilities you want to configure,
863 you can control the search
864 that &SCons; performs
865 by specifying some specific
866 tool modules with which to
867 initialize the default construction environment:
873 env = DefaultEnvironment(tools = ['gcc', 'gnulink'],
874 CC = '/usr/local/bin/gcc')
880 So the above example would tell &SCons;
881 to explicitly configure the default environment
882 to use its normal GNU Compiler and GNU Linker settings
883 (without having to search for them,
884 or any other utilities for that matter),
885 and specifically to use the compiler found at
886 <filename>/usr/local/bin/gcc</filename>.
893 <title>Multiple &ConsEnvs;</title>
897 The real advantage of construction environments
898 is that you can create as many different construction
899 environments as you need,
900 each tailored to a different way to build
901 some piece of software or other file.
902 If, for example, we need to build
903 one program with the <literal>-O2</literal> flag
904 and another with the <literal>-g</literal> (debug) flag,
905 we would do this like so:
909 <scons_example name="ex2">
910 <file name="SConstruct" printme="1">
911 opt = Environment(CCFLAGS = '-O2')
912 dbg = Environment(CCFLAGS = '-g')
914 opt.Program('foo', 'foo.c')
916 dbg.Program('bar', 'bar.c')
926 <scons_output example="ex2">
927 <scons_output_command>scons -Q</scons_output_command>
932 We can even use multiple construction environments to build
933 multiple versions of a single program.
934 If you do this by simply trying to use the
935 &b-link-Program; builder with both environments, though,
940 <scons_example name="ex3">
941 <file name="SConstruct" printme="1">
942 opt = Environment(CCFLAGS = '-O2')
943 dbg = Environment(CCFLAGS = '-g')
945 opt.Program('foo', 'foo.c')
947 dbg.Program('foo', 'foo.c')
956 Then &SCons; generates the following error:
960 <scons_output example="ex3">
961 <scons_output_command>scons -Q</scons_output_command>
966 This is because the two &b-Program; calls have
967 each implicitly told &SCons; to generate an object file named
968 <filename>foo.o</filename>,
969 one with a &cv-link-CCFLAGS; value of
970 <literal>-O2</literal>
971 and one with a &cv-link-CCFLAGS; value of
972 <literal>-g</literal>.
973 &SCons; can't just decide that one of them
974 should take precedence over the other,
975 so it generates the error.
976 To avoid this problem,
977 we must explicitly specify
978 that each environment compile
979 <filename>foo.c</filename>
980 to a separately-named object file
981 using the &b-link-Object; builder, like so:
985 <scons_example name="ex4">
986 <file name="SConstruct" printme="1">
987 opt = Environment(CCFLAGS = '-O2')
988 dbg = Environment(CCFLAGS = '-g')
990 o = opt.Object('foo-opt', 'foo.c')
993 d = dbg.Object('foo-dbg', 'foo.c')
1003 Notice that each call to the &b-Object; builder
1005 an internal &SCons; object that
1006 represents the object file that will be built.
1007 We then use that object
1008 as input to the &b-Program; builder.
1009 This avoids having to specify explicitly
1010 the object file name in multiple places,
1011 and makes for a compact, readable
1013 Our &SCons; output then looks like:
1017 <scons_output example="ex4">
1018 <scons_output_command>scons -Q</scons_output_command>
1024 <title>Making Copies of &ConsEnvs;: the &Clone; Method</title>
1028 Sometimes you want more than one construction environment
1029 to share the same values for one or more variables.
1030 Rather than always having to repeat all of the common
1031 variables when you create each construction environment,
1032 you can use the &Clone; method
1033 to create a copy of a construction environment.
1039 Like the &Environment; call that creates a construction environment,
1040 the &Clone; method takes &consvar; assignments,
1041 which will override the values in the copied construction environment.
1042 For example, suppose we want to use &gcc;
1043 to create three versions of a program,
1044 one optimized, one debug, and one with neither.
1045 We could do this by creating a "base" construction environment
1046 that sets &cv-link-CC; to &gcc;,
1047 and then creating two copies,
1048 one which sets &cv-link-CCFLAGS; for optimization
1049 and the other which sets &cv-CCFLAGS; for debugging:
1053 <scons_example name="ex5">
1054 <file name="SConstruct" printme="1">
1055 env = Environment(CC = 'gcc')
1056 opt = env.Clone(CCFLAGS = '-O2')
1057 dbg = env.Clone(CCFLAGS = '-g')
1059 env.Program('foo', 'foo.c')
1061 o = opt.Object('foo-opt', 'foo.c')
1064 d = dbg.Object('foo-dbg', 'foo.c')
1074 Then our output would look like:
1078 <scons_output example="ex5">
1079 <scons_output_command>scons -Q</scons_output_command>
1085 <title>Replacing Values: the &Replace; Method</title>
1089 You can replace existing construction variable values
1090 using the &Replace; method:
1094 <scons_example name="Replace1">
1095 <file name="SConstruct" printme="1">
1096 env = Environment(CCFLAGS = '-DDEFINE1')
1097 env.Replace(CCFLAGS = '-DDEFINE2')
1098 env.Program('foo.c')
1108 (<literal>-DDEFINE2</literal> in the above example)
1109 completely replaces the value in the
1110 construction environment:
1114 <scons_output example="Replace1">
1115 <scons_output_command>scons -Q</scons_output_command>
1120 You can safely call &Replace;
1121 for construction variables that
1122 don't exist in the construction environment:
1126 <scons_example name="Replace-nonexistent">
1127 <file name="SConstruct" printme="1">
1129 env.Replace(NEW_VARIABLE = 'xyzzy')
1130 print "NEW_VARIABLE =", env['NEW_VARIABLE']
1137 the construction variable simply
1138 gets added to the construction environment:
1142 <scons_output example="Replace-nonexistent">
1143 <scons_output_command>scons -Q</scons_output_command>
1148 Because the variables
1149 aren't expanded until the construction environment
1150 is actually used to build the targets,
1151 and because &SCons; function and method calls
1152 are order-independent,
1153 the last replacement "wins"
1154 and is used to build all targets,
1155 regardless of the order in which
1156 the calls to Replace() are
1157 interspersed with calls to
1162 <scons_example name="Replace2">
1163 <file name="SConstruct" printme="1">
1164 env = Environment(CCFLAGS = '-DDEFINE1')
1165 print "CCFLAGS =", env['CCFLAGS']
1166 env.Program('foo.c')
1168 env.Replace(CCFLAGS = '-DDEFINE2')
1169 print "CCFLAGS =", env['CCFLAGS']
1170 env.Program('bar.c')
1182 The timing of when the replacement
1183 actually occurs relative
1184 to when the targets get built
1186 if we run &scons; without the <literal>-Q</literal>
1191 <scons_output example="Replace2">
1192 <scons_output_command>scons</scons_output_command>
1197 Because the replacement occurs while
1198 the &SConscript; files are being read,
1199 the &cv-link-CCFLAGS;
1200 variable has already been set to
1201 <literal>-DDEFINE2</literal>
1202 by the time the &foo_o; target is built,
1203 even though the call to the &Replace;
1204 method does not occur until later in
1205 the &SConscript; file.
1212 <title>Setting Values Only If They're Not Already Defined: the &SetDefault; Method</title>
1216 Sometimes it's useful to be able to specify
1217 that a construction variable should be
1218 set to a value only if the construction environment
1219 does not already have that variable defined
1220 You can do this with the &SetDefault; method,
1221 which behaves similarly to the <function>set_default</function>
1222 method of Python dictionary objects:
1227 env.SetDefault(SPECIAL_FLAG = '-extra-option')
1232 This is especially useful
1233 when writing your own <literal>Tool</literal> modules
1234 to apply variables to construction environments.
1236 See <xref linkend="chap-tool-modules"></xref>
1237 for more information about writing
1246 <title>Appending to the End of Values: the &Append; Method</title>
1250 You can append a value to
1251 an existing construction variable
1252 using the &Append; method:
1256 <scons_example name="ex8">
1257 <file name="SConstruct" printme="1">
1258 env = Environment(CCFLAGS = ['-DMY_VALUE'])
1259 env.Append(CCFLAGS = ['-DLAST'])
1260 env.Program('foo.c')
1269 &SCons; then supplies both the <literal>-DMY_VALUE</literal> and
1270 <literal>-DLAST</literal> flags when compiling the object file:
1274 <scons_output example="ex8">
1275 <scons_output_command>scons -Q</scons_output_command>
1280 If the construction variable doesn't already exist,
1281 the &Append; method will create it:
1285 <scons_example name="Append-nonexistent">
1286 <file name="SConstruct" printme="1">
1288 env.Append(NEW_VARIABLE = 'added')
1289 print "NEW_VARIABLE =", env['NEW_VARIABLE']
1299 <scons_output example="Append-nonexistent">
1300 <scons_output_command>scons -Q</scons_output_command>
1305 Note that the &Append; function tries to be "smart"
1306 about how the new value is appended to the old value.
1307 If both are strings, the previous and new strings
1308 are simply concatenated.
1309 Similarly, if both are lists,
1310 the lists are concatenated.
1311 If, however, one is a string and the other is a list,
1312 the string is added as a new element to the list.
1319 <title>Appending Unique Values: the &AppendUnique; Method</title>
1323 Some times it's useful to add a new value
1324 only if the existing construction variable
1325 doesn't already contain the value.
1326 This can be done using the &AppendUnique; method:
1331 env.AppendUnique(CCFLAGS=['-g'])
1336 In the above example,
1337 the <literal>-g</literal> would be added
1338 only if the &cv-CCFLAGS; variable
1339 does not already contain a <literal>-g</literal> value.
1346 <title>Appending to the Beginning of Values: the &Prepend; Method</title>
1350 You can append a value to the beginning of
1351 an existing construction variable
1352 using the &Prepend; method:
1356 <scons_example name="ex9">
1357 <file name="SConstruct" printme="1">
1358 env = Environment(CCFLAGS = ['-DMY_VALUE'])
1359 env.Prepend(CCFLAGS = ['-DFIRST'])
1360 env.Program('foo.c')
1369 &SCons; then supplies both the <literal>-DFIRST</literal> and
1370 <literal>-DMY_VALUE</literal> flags when compiling the object file:
1374 <scons_output example="ex9">
1375 <scons_output_command>scons -Q</scons_output_command>
1380 If the construction variable doesn't already exist,
1381 the &Prepend; method will create it:
1385 <scons_example name="Prepend-nonexistent">
1386 <file name="SConstruct" printme="1">
1388 env.Prepend(NEW_VARIABLE = 'added')
1389 print "NEW_VARIABLE =", env['NEW_VARIABLE']
1399 <scons_output example="Prepend-nonexistent">
1400 <scons_output_command>scons -Q</scons_output_command>
1405 Like the &Append; function,
1406 the &Prepend; function tries to be "smart"
1407 about how the new value is appended to the old value.
1408 If both are strings, the previous and new strings
1409 are simply concatenated.
1410 Similarly, if both are lists,
1411 the lists are concatenated.
1412 If, however, one is a string and the other is a list,
1413 the string is added as a new element to the list.
1420 <title>Prepending Unique Values: the &PrependUnique; Method</title>
1424 Some times it's useful to add a new value
1425 to the beginning of a construction variable
1426 only if the existing value
1427 doesn't already contain the to-be-added value.
1428 This can be done using the &PrependUnique; method:
1433 env.PrependUnique(CCFLAGS=['-g'])
1438 In the above example,
1439 the <literal>-g</literal> would be added
1440 only if the &cv-CCFLAGS; variable
1441 does not already contain a <literal>-g</literal> value.
1449 <section id="sect-execution-environments">
1450 <title>Controlling the Execution Environment for Issued Commands</title>
1454 When &SCons; builds a target file,
1455 it does not execute the commands with
1456 the same external environment
1457 that you used to execute &SCons;.
1458 Instead, it uses the dictionary
1459 stored in the &cv-link-ENV; construction variable
1460 as the external environment
1461 for executing commands.
1467 The most important ramification of this behavior
1468 is that the &PATH; environment variable,
1469 which controls where the operating system
1470 will look for commands and utilities,
1471 is not the same as in the external environment
1472 from which you called &SCons;.
1473 This means that &SCons; will not, by default,
1474 necessarily find all of the tools
1475 that you can execute from the command line.
1481 The default value of the &PATH; environment variable
1483 is <literal>/usr/local/bin:/bin:/usr/bin</literal>.
1484 The default value of the &PATH; environment variable
1485 on a Windows system comes from the Windows registry
1486 value for the command interpreter.
1487 If you want to execute any commands--compilers, linkers, etc.--that
1488 are not in these default locations,
1489 you need to set the &PATH; value
1490 in the &cv-ENV; dictionary
1491 in your construction environment.
1497 The simplest way to do this is to initialize explicitly
1498 the value when you create the construction environment;
1499 this is one way to do that:
1504 path = ['/usr/local/bin', '/bin', '/usr/bin']
1505 env = Environment(ENV = {'PATH' : path})
1510 Assign a dictionary to the &cv-ENV;
1511 construction variable in this way
1512 completely resets the external environment
1513 so that the only variable that will be
1514 set when external commands are executed
1515 will be the &PATH; value.
1516 If you want to use the rest of
1517 the values in &cv-ENV; and only
1518 set the value of &PATH;,
1519 the most straightforward way is probably:
1524 env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin']
1529 Note that &SCons; does allow you to define
1530 the directories in the &PATH; in a string,
1531 separated by the pathname-separator character
1532 for your system (':' on POSIX systems, ';' on Windows):
1537 env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'
1542 But doing so makes your &SConscript; file less portable,
1543 (although in this case that may not be a huge concern
1544 since the directories you list are likley system-specific, anyway).
1550 <scons_example name="ex1">
1551 <file name="SConstruct" printme="1">
1553 env.Command('foo', [], '__ROOT__/usr/bin/printenv.py')
1555 <file name="__ROOT__/usr/bin/printenv.py" chmod="0755">
1556 #!/usr/bin/env python
1559 if len(sys.argv) > 1:
1562 keys = os.environ.keys()
1565 print " " + key + "=" + os.environ[key]
1573 <scons_output example="ex1">
1574 <scons_output_command>scons -Q</scons_output_command>
1580 <title>Propagating &PATH; From the External Environment</title>
1584 You may want to propagate the external &PATH;
1585 to the execution environment for commands.
1586 You do this by initializing the &PATH;
1587 variable with the &PATH; value from
1588 the <literal>os.environ</literal>
1590 which is Python's way of letting you
1591 get at the external environment:
1597 env = Environment(ENV = {'PATH' : os.environ['PATH']})
1602 Alternatively, you may find it easier
1603 to just propagate the entire external
1604 environment to the execution environment
1606 This is simpler to code than explicity
1607 selecting the &PATH; value:
1613 env = Environment(ENV = os.environ)
1618 Either of these will guarantee that
1619 &SCons; will be able to execute
1620 any command that you can execute from the command line.
1621 The drawback is that the build can behave
1622 differently if it's run by people with
1623 different &PATH; values in their environment--for example,
1624 if both the <literal>/bin</literal> and
1625 <literal>/usr/local/bin</literal> directories
1626 have different &cc; commands,
1627 then which one will be used to compile programs
1628 will depend on which directory is listed
1629 first in the user's &PATH; variable.
1636 <title>Adding to <varname>PATH</varname> Values in the Execution Environment</title>
1640 One of the most common requirements
1641 for manipulating a variable in the execution environment
1642 is to add one or more custom directories to a search
1643 like the <envar>$PATH</envar> variable on Linux or POSIX systems,
1644 or the <envar>%PATH%</envar> variable on Windows,
1645 so that a locally-installed compiler or other utility
1646 can be found when &SCons; tries to execute it to update a target.
1647 &SCons; provides &PrependENVPath; and &AppendENVPath; functions
1648 to make adding things to execution variables convenient.
1649 You call these functions by specifying the variable
1650 to which you want the value added,
1651 and then value itself.
1652 So to add some <filename>/usr/local</filename> directories
1653 to the <envar>$PATH</envar> and <envar>$LIB</envar> variables,
1659 env = Environment(ENV = os.environ)
1660 env.PrependENVPath('PATH', '/usr/local/bin')
1661 env.AppendENVPath('LIB', '/usr/local/lib')
1666 Note that the added values are strings,
1667 and if you want to add multiple directories to
1668 a variable like <envar>$PATH</envar>,
1669 you must include the path separate character
1670 (<literal>:</literal> on Linux or POSIX,
1671 <literal>;</literal> on Windows)