By default, SCons supplies (and uses) a number of pre-defined
Builder
objects:
Object | compile or assemble an object file |
Library | archive files into a library |
SharedLibrary | archive files into a shared library |
Program | link objects and/or libraries into an executable |
Make | build according to file suffixes; see below |
A construction environment can be explicitly initialized with associated Builder
objects that will be bound to the construction environment object:
env = Environment(BUILDERS = ['Object', 'Program'])
Builder
objects bound to a construction environment can be called directly as
methods. When invoked, a Builder
object returns a (list of) objects
that it will build:
obj = env.Object(target ='hello.o', source = 'hello.c') lib = env.Library(target ='libfoo.a', source = ['aaa.c', 'bbb.c']) slib = env.SharedLibrary(target ='libbar.so', source = ['xxx.c', 'yyy.c']) prog = env.Program(target ='hello', source = ['hello.o', 'libfoo.a', 'libbar.so'])
Multiple input files that go into creating a target file may be passed in as a single string, with the individual file names separated by white space:
env.Library(target = 'foo.a', source = 'aaa.c bbb.c ccc.c') env.Object(target = 'yyy.o', source = 'yyy.c') env.Program(target = 'bar', source = 'xxx.c yyy.o foo.a')
Alternatively, multiple input files that go into creating a target file may be passed in as an array. This allows input files to be specified using their object representation:
env.Library(target = 'foo.a', source = ['aaa.c', 'bbb.c', 'ccc.c']) yyy_obj = env.Object(target = 'yyy.o', source = 'yyy.c') env.Program(target = 'bar', source = ['xxx.c', yyy_obj, 'foo.a'])
Individual string elements within an array of input files are not further split into white-space separated file names. This allows file names that contain white space to be specified by putting the value into an array:
env.Program(target = 'foo', source = ['an input file.c'])
Conversely, the generated target may be a string listing multiple files separated by white space:
env.Object(target = 'grammar.o y.tab.h', source = 'grammar.y')
An array of multiple target files can be used to mix string and object representations, or to accomodate file names that contain white space:
env.Program(target = ['my program'], source = 'input.c')
For portability, if the target file name does not already have an
appropriate file prefix or suffix, the Builder
objects will
append one appropriate for the file type on the current system:
# builds 'hello.o' on UNIX, 'hello.obj' on Windows NT: obj = env.Object(target ='hello', source = 'hello.c') # builds 'libfoo.a' on UNIX, 'foo.lib' on Windows NT: lib = env.Library(target ='foo', source = ['aaa.c', 'bbb.c']) # builds 'libbar.so' on UNIX, 'bar.dll' on Windows NT: slib = env.SharedLibrary(target ='bar', source = ['xxx.c', 'yyy.c']) # builds 'hello' on UNIX, 'hello.exe' on Windows NT: prog = env.Program(target ='hello', source = ['hello.o', 'libfoo.a', 'libbar.so'])
Users can define additional Builder
objects for specific external
object types unknown to SCons. A Builder
object may build its
target by executing an external command:
WebPage = Builder(command = 'htmlgen $HTMLGENFLAGS $sources > $target', suffix = '.html', src_suffix = '.in')
Alternatively, a Builder
object may also build its target by
executing a Python function:
def update(dest): # [code to update the object] return 1 OtherBuilder1 = Builder(function = update, src_suffix = ['.in', '.input'])
An optional argument to pass to the function may be specified:
def update_arg(dest, arg): # [code to update the object] return 1 OtherBuilder2 = Builder(function = update_arg, function_arg = 'xyzzy', src_suffix = ['.in', '.input'])
Both an external command and an internal function may be specified, in which case the function will be called to build the object first, followed by the command line.
User-defined Builder
objects can be used like the default Builder
objects to initialize construction environments.
WebPage = Builder(command = 'htmlgen $HTMLGENFLAGS $sources > $target', suffix = '.html', src_suffix = '.in') env = Environment(BUILDERS = ['WebPage']) env.WebPage(target = 'foo.html', source = 'foo.in') # Builds 'bar.html' on UNIX, 'bar.htm' on Windows NT: env.WebPage(target = 'bar', source = 'bar.in')
The command-line specification can interpolate variables from the construction environment; see "Variable substitution," above.
A Builder
object may optionally be initialized with a list of:
the prefix of the target file (e.g., 'lib' for libraries)
the suffix of the target file (e.g., '.a' for libraries)
the expected suffixes of the input files (e.g., '.o' for object files)
These arguments are used in automatic dependency analysis and to generate output file names that don't have suffixes supplied explicitly.
A Copy
method exists to return a copy of an existing Builder
object, with any overridden values specified as keyword arguments to
the method:
build = Builder(function = my_build) build_out = build.Copy(suffix = '.out')
Typically, Builder
objects will be supplied by a tool-master or
administrator through a shared construction environment.
A pre-defined Command
builder exists to associate a target file with
a specific command or list of commands for building the file:
env.Command(target = 'foo.out', source = command = 'foo.in', "foo.process $sources > $target") commands = [ "bar.process -o .tmpfile $sources", "mv .tmpfile $target" ] env.Command(target = 'bar.out', source = 'bar.in', command = commands)
This is useful when it's too cumbersome to create a Builder
object just to build a single file in a special way.
A pre-defined Builder
object named Make
exists to make
simple builds as easy as possible for users, at the expense of
sacrificing some build portability.
The following minimal example builds the 'hello' program from the 'hello.c' source file:
Environment().Make('hello', 'hello.c')
Users of the Make
Builder
object are not required to
understand intermediate steps involved in generating a file--for
example, the distinction between compiling source code into an object
file, and then linking object files into an executable. The details
of intermediate steps are handled by the invoked method. Users that
need to, however, can specify intermediate steps explicitly:
env = Environment() env.Make(target = 'hello.o', source = 'hello.c') env.Make(target = 'hello', source = 'hello.o')
The Make
method understands the file suffixes specified and
"does the right thing" to generate the target object and program
files, respectively. It does this by examining the specified output
suffixes for the Builder
objects bound to the environment.
Because file name suffixes in the target and source file names
must be specified, the Make
method can't be used
portably across operating systems. In other words, for the
example above, the Make
builder will not generate
hello.exe
on Windows NT.
The env.Make
method "does the right thing" to
build different file types because it uses a dictionary from the
construction environment that maps file suffixes to the appropriate Builder
object.
This BUILDERMAP
can be initialized at instantiation:
env = Environment(BUILDERMAP = { '.o' : Object, '.a' : Library, '.html' : WebPage, '' : Program, })
With the BUILDERMAP
properly initialized, the
env.Make
method can be used to build additional
file types:
env.Make(target = 'index.html', source = 'index.input')
Builder
objects referenced in the BUILDERMAP
do not need to be
listed separately in the BUILDERS
variable. The construction environment will
bind the union of the Builder
objects listed in both variables.