A construction environment is the basic means by which a software system interacts with the SCons Python API to control a build process.
A construction environment is an object with associated methods for generating target
files of various types (Builder
objects), other associated object
methods for automatically determining dependencies from the contents
of various types of source files (Scanner
objects), and a dictionary
of values used by these methods.
Passing no arguments to the Environment
instantiation creates a
construction environment with default values for the current platform:
env = Environment()
A construction environment has an associated dictionary of construction variables that control how
the build is performed. By default, the Environment
method creates
a construction environment with values that make most software build "out of the box"
on the host system. These default values will be generated at the
time SCons is installed using functionality similar to that provided
by GNU Autoconf.
[1]
At a minimum, there will be pre-configured sets of default values
that will provide reasonable defaults for UNIX and Windows NT.
The default construction environment values may be overridden when a new construction environment is created by specifying keyword arguments:
env = Environment(CC = 'gcc', CCFLAGS = '-g', CPPPATH = ['.', 'src', '/usr/include'], LIBPATH = ['/usr/lib', '.'])
A copy of the dictionary of construction variables can be returned using
the Dictionary
method:
env = Environment() dict = env.Dictionary()
If any arguments are supplied, then just the corresponding value(s) are returned:
ccflags = env.Dictionary('CCFLAGS') cc, ld = env.Dictionary('CC', 'LD')
A method exists to return a copy of an existing environment, with any overridden values specified as keyword arguments to the method:
env = Environment() debug = env.Copy(CCFLAGS = '-g')
Different external objects often require different build characteristics. Multiple construction environments may be defined, each with different values:
env = Environment(CCFLAGS = '') debug = Environment(CCFLAGS = '-g') env.Make(target = 'hello', source = 'hello.c') debug.Make(target = 'hello-debug', source = 'hello.c')
Dictionaries of values from multiple construction environments may be passed to the
Environment
instantiation or the Copy
method, in which case the
last-specified dictionary value wins:
env1 = Environment(CCFLAGS = '-O', LDFLAGS = '-d') env2 = Environment(CCFLAGS = '-g') new = Environment(env1.Dictionary(), env2.Dictionary())
The new
environment in the above example retains
LDFLAGS = '-d'
from the env1
environment, and CCFLAGS = '-g'
from the
env2
environment.
Within a construction command, any variable from the construction environment may be interpolated by prefixing the name of the construction with $:
MyBuilder = Builder(command = "$XX $XXFLAGS -c $_INPUTS -o $target") env.Command(targets = 'bar.out', sources = 'bar.in', command = "sed '1d' < $source > $target")
Variable substitution is recursive: the command line is expanded until no more substitutions can be made.
Variable names following the $ may be enclosed in braces. This can be used to concatenate an interpolated value with an alphanumeric character:
VerboseBuilder = Builder(command = "$XX -${XXFLAGS}v > $target")
The variable within braces may contain a pair of parentheses
after a Python function name to be evaluated (for example,
${map()}
). SCons will interpolate the return
value from the function (presumably a string):
env = Environment(FUNC = myfunc) env.Command(target = 'foo.out', source = 'foo.in', command = "${FUNC($<)}")
If a referenced variable is not defined in the construction environment, the null string is interpolated.
The following special variables can also be used:
$targets
All target file names. If multiple targets are specified in an
array, $targets
expands to the entire list of
targets, separated by a single space.
Individual targets from a list may be extracted by enclosing
the targets
keyword in braces and using the
appropriate Python array index or slice:
${targets[0]} # expands to the first target ${targets[1:]} # expands to all but the first target ${targets[1:-1]} # expands to all but the first and last targets
$target
A synonym for ${targets[0]}
, the first target
specified.
$sources
All input file names. Any input file names that
are used anywhere else on the current command
line (via ${sources[0]}
,
${sources{[1]}
, etc.) are removed from the
expanded list.
Any of the above special variables may be enclosed in braces and followed immediately by one of the following attributes to select just a portion of the expanded path name:
.base
Basename: the directory plus the file name, minus any file suffix.
.dir
The directory in which the file lives. This is a relative path, where appropriate.
.file
The file name, minus any directory portion.
.suffix
The file name suffix (that is, the right-most dot in the file name, and all characters to the right of that).
.filebase
The file name (no directory portion), minus any file suffix.
.abspath
The absolute path to the file.
[1] It would be nice if we could avoid re-inventing the wheel here by using some other Python-based tool Autoconf replacement--like what was supposed to come out of the Software Carpentry configuration tool contest. It will probably be most efficient to roll our own logic initially and convert if something better does come along.