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 is specify
use a construction variable to specify
different emitter functions for different
construction variable.
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') import os env1['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd() env2['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd()
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