Please note:The SCons wiki is now restored from the attack in March 2013. All old passwords have been invalidated. Please reset your password if you have an account. If you note missing pages, please report them to Also, new account creation is currently disabled due to an ongoing spam flood (2013/08/27).
Differences between revisions 4 and 5
Revision 4 as of 2007-12-10 22:36:07
Size: 3161
Editor: 66
Revision 5 as of 2008-03-12 02:47:13
Size: 3162
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 69: Line 69:
 . -- [:MattDoar]  . -- [[MattDoar]]

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

The Function

   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[0]
   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

Example Usage

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.

   1 env = Environment()
   2 conf = env.Configure()
   3 if not conf.CheckLib('somelib'):
   4   add_file_to_emitter(env, 'PROGEMITTER', File('somelibreplacement.c'))
   5 conf.Finish()

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[0].path):
   7         # The source file was generated in the local build directory
   8         return (target, source)
   9     altSrcName = source[0].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[0].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)

AddFilesDynamically (last edited 2008-03-12 02:47:13 by localhost)