The heart of SCons is its Build Engine. The SCons Build Engine is a Python module that manages dependencies between external objects such as files or database records. The Build Engine is designed to be interface-neutral and easily embeddable in any software system that needs dependency analysis between updatable objects.
The key parts of the Build Engine architecture are captured in the following quasi-UML diagram:
The point of SCons is to manage
dependencies between arbitrary external objects.
Consequently, the Build Engine does not restrict or specify
the nature of the external objects it manages,
but instead relies on subclass of the Node
class to interact with the external system or systems
(file systems, database management systems)
that maintain the objects being examined or updated.
The Build Engine presents to the software system in which it is embedded a Python API for specifying source (input) and target (output) objects, rules for building/updating objects, rules for scanning objects for dependencies, etc. Above its Python API, the Build Engine is completely interface-independent, and can be encapsulated by any other software that supports embedded Python.
Software that chooses to use the Build Engine
for dependency management
interacts with it
through Construction Environments.
A Construction Environment consists
of a dictionary of environment variables,
and one or more associated
Scanner objects
and Builder objects.
The Python API is used to
form these associations.
A Scanner object specifies
how to examine a type of source object
(C source file, database record)
for dependency information.
A Scanner object may use
variables from the associated
Construction Environment
to modify how it scans an object:
specifying a search path for included files,
which field in a database record to consult,
etc.
A Builder object specifies
how to update a type of target object:
executable program, object file, database field, etc.
Like a Scanner object,
a Builder object may use
variables from the associated
Construction Environment
to modify how it builds an object:
specifying flags to a compiler,
using a different update function,
etc.
Scanner and Builder objects will return one or more
Node objects that represent external objects.
Node objects are the means by which the
Build Engine tracks dependencies:
A Node may represent a source (input) object that
should already exist,
or a target (output) object which may be built,
or both.
The Node class is sub-classed to
represent external objects of specific type:
files, directories, database fields or records, etc.
Because dependency information, however,
is tracked by the top-level Node methods and attributes,
dependencies can exist
between nodes representing different external object types.
For example,
building a file could be made
dependent on the value of a given
field in a database record,
or a database table could depend
on the contents of an external file.
The Build Engine uses a Job class (not displayed)
to manage the actual work of updating external target objects:
spawning commands to build files,
submitting the necessary commands to update a database record,
etc.
The Job class has sub-classes
to handle differences between spawning
jobs in parallel and serially.
The Build Engine also uses a
Signature class (not displayed)
to maintain information about whether
an external object is up-to-date.
Target objects with out-of-date signatures
are updated using the appropriate
Builder object.