Attaching a Builder to a Construction Environment

SCons User Guide 0.98.0
Prev | Chapter 17. 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` so attached to our `construction environment` 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 `Builder`s 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: SConsEnvironment instance has no attribute 'Program':
            File "/home/my/project/SConstruct", line 4:
              env.Program('hello.c')

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 | Home | Next
Writing Your Own Builders | Up | Letting SCons Handle The File Suffixes