17.2. Attaching a Builder to a Construction Environment
Prev | Chapter 17. Extending SCons: Writing Your Own Builders | Next

## 17.2. Attaching a Builder to a Construction Environment

A Builder object isn't useful until it's attached to a construction environment so that we can call it to arrange for files to be built. This is done through the `$BUILDERS` construction variable in an environment. The `$BUILDERS` variable is a Python dictionary that maps the names by which you want to call various Builder objects to the objects themselves. For example, if we want to call the Builder we just defined by the name `Foo`, our `SConstruct` file might look like:

    bld = Builder(action='foobuild < $SOURCE > $TARGET')
    env = Environment(BUILDERS={'Foo': bld})

With the Builder attached to our construction environment with the name `Foo`, we can now actually call it like so:

    env.Foo('file.foo', 'file.input')

Then, when we run SCons it looks like:

    % scons -Q
    foobuild < file.input > file.foo

Note, however, that the default `$BUILDERS` variable in a construction environment comes with a default set of Builder objects already defined: `Program`, `Library`, etc. And when we explicitly set the `$BUILDERS` variable when we create the construction environment, the default Builders are no longer part of the environment:

    bld = Builder(action='foobuild < $SOURCE > $TARGET')
    env = Environment(BUILDERS={'Foo': bld})
    env.Foo('file.foo', 'file.input')
    env.Program('hello.c')

    % scons -Q
    AttributeError: Builder or other environment method 'Program' not found.
    Check spelling, check external program exists in env['ENV']['PATH'],
    and check that a suitable tool is being loaded:
      File "/home/my/project/SConstruct", line 7:
        env.Program('hello.c')
      File "SCons/Environment.py", line 1309:
        raise AttributeError(

To be able to use both our own defined Builder objects and the default Builder objects in the same construction environment, you can either add to the `$BUILDERS` variable using the `Append` function:

    env = Environment()
    bld = Builder(action='foobuild < $SOURCE > $TARGET')
    env.Append(BUILDERS={'Foo': bld})
    env.Foo('file.foo', 'file.input')
    env.Program('hello.c')

Or you can explicitly set the appropriately-named key in the `$BUILDERS` dictionary:

    env = Environment()
    bld = Builder(action='foobuild < $SOURCE > $TARGET')
    env['BUILDERS']['Foo'] = bld
    env.Foo('file.foo', 'file.input')
    env.Program('hello.c')

Either way, the same construction environment can then use both the newly-defined `Foo` Builder and the default `Program` Builder:

    % scons -Q
    foobuild < file.input > file.foo
    cc -o hello.o -c hello.c
    cc -o hello hello.o

Prev | Up | Next
Chapter 17. Extending SCons: Writing Your Own Builders | Home | 17.3. Letting SCons Handle The File Suffixes