17.6. Builders That Modify the Target or Source Lists Using an Emitter
Prev | Chapter 17. Extending SCons: Writing Your Own Builders | Next

## 17.6. Builders That Modify the Target or Source Lists Using an Emitter

SCons supports the ability for a Builder to modify the lists of target(s) from the specified source(s). You do this by defining an emitter function that takes as its arguments the list of the targets passed to the builder, the list of the sources passed to the builder, and the construction environment. The emitter function should return the modified lists of targets that should be built and sources from which the targets will be built.

For example, suppose you want to define a Builder that always calls a foobuild program, and you want to automatically add a new target file named `new_target` and a new source file named `new_source` whenever it's called. The `SConstruct` file might look like this:

    def modify_targets(target, source, env):
        target.append('new_target')
        source.append('new_source')
        return target, source

    bld = Builder(
        action='foobuild $TARGETS - $SOURCES',
        suffix='.foo',
        src_suffix='.input',
        emitter=modify_targets,
    )
    env = Environment(BUILDERS={'Foo': bld})
    env.Foo('file')

And would yield the following output:

    % scons -Q
    foobuild file.foo new_target - file.input new_source

One very flexible thing that you can do is use a construction variable to specify different emitter functions for different construction environments. To do this, specify a string containing a construction variable expansion as the emitter when you call the `Builder` function, and set that construction variable to the desired emitter function in different construction environments:

    bld = Builder(
        action='./my_command $SOURCES > $TARGET',
        suffix='.foo',
        src_suffix='.input',
        emitter='$MY_EMITTER',
    )

    def modify1(target, source, env):
        return target, source + ['modify1.in']

    def modify2(target, source, env):
        return target, source + ['modify2.in']

    env1 = Environment(BUILDERS={'Foo': bld}, MY_EMITTER=modify1)
    env2 = Environment(BUILDERS={'Foo': bld}, MY_EMITTER=modify2)
    env1.Foo('file1')
    env2.Foo('file2')

In this example, the `modify1.in` and `modify2.in` files get added to the source lists of the different commands:

    % scons -Q
    ./my_command file1.input modify1.in > file1.foo
    ./my_command file2.input modify2.in > file2.foo

Prev | Up | Next
17.5. Builders That Create Actions Using a Generator | Home | 17.7. Modifying a Builder by adding an Emitter