The function presented here is useful if:
- You've got one environment used to create many targets (too many to start messing with).
- The environment is configured differently for different platforms/compilers/etc.
- Some platforms/compilers/etc. need an additional source file to be compiled in order to work properly. This can be, for example, a replacement for a library that is not available on a certain platform.
This function wraps a given emitter with another emitter that adds another file to the source nodes.
Replaceable emitters (as of SCons 0.96.90):
PROGEMITTER - emitter for Program builder
SHLIBEMITTER - emitter for SharedLibrary builder
LIBEMITTER - emitter for Library builder
1 def add_file_to_emitter(env, emitter_name, file): 2 try: 3 original_emitter = env[emitter_name] 4 if type(original_emitter) == list: 5 original_emitter = original_emitter 6 except KeyError: 7 original_emitter = None 8 def emitter(target, source, env): 9 if original_emitter: 10 target, source = original_emitter(target, source, env) 11 return target, source + [file] 12 env[emitter_name] = emitter
In this example, the environment is searched for a library called somelib. If this library is not found, add_file_to_emitter is called to add somelibreplacement.c to every program built using the environment.
Changing the Emitter for StaticObject
If you want to change where a builder finds its C/C++ source files, you want to change the emitter for the StaticObject builder, aka Object. Unfortunately, there is no OBJEMITTER currently defined, but another way to do it is shown below.
1 # Assuming the BUILD_DIR is set to the location of the generated files 2 # and some other generated files are in OTHER_BUILD_DIR 3 def my_emitter(target, source, env): 4 ''' Tell SCons about the locations of some generated files. This could 5 be any emitter you want''' 6 if os.path.exists(source.path): 7 # The source file was generated in the local build directory 8 return (target, source) 9 altSrcName = source.abspath.replace(env['BUILD_DIR'] + os.sep, '') 10 if os.path.exists(altSrcName): 11 # The source file is in the source directory 12 return (target, altSrcName) 13 # Assume that the source file is in the other generated files build directory 14 altSrcName = "%s/%s%s" % (File('#'), env['OTHER_BUILD_DIR'], 15 source.path.replace(env['OTHER_BUILD_DIR'], '')) 16 return (target, altSrcName) 17 # This is the part where we override the emitter for the Object builder 18 from SCons.Tool import createObjBuilders 19 # Get the underlying builder objects 20 static_obj, shared_obj = createObjBuilders(env) 21 # Now SCons can find .cpp files in different locations 22 static_obj.add_emitter('.cpp', my_emitter)