Search code examples
scons

scons hierarchcal builds: propagating builders


I need to be able to tune a construction environment so that I can either build a static or a shared objects in lower levels. Currently, I came up with the following approach:

top-level SConstruct:

if build_shared:
    env.Replace(ObjectBuilder = env.SharedObject)
    env.Replace(LibraryBuilder = env.SharedLibrary)
else:
    env.Replace(ObjectBuilder = env.StaticObject)
    env.Replace(LibraryBuilder = env.StaticLibrary)

and in lower-level SConstructs I invoke them by name:

env['ObjectBuilder']('foo.c')
env['LibraryBuilder']('lib', objects)

However, I'm not sure how sound this solution is. Is there a more straightforward/proper way to achieve the same functionality?

Thanks in advance.


Solution

  • The easiest way is to declare your own wrapper for env.Library() that simply passes its parameters to either env.StaticLibrary() or env.SharedLibrary().

    Depending on whatever construction variable/scons option, you can have that wrapper alternate between the two.

    def MyLibraryWrapper(self, *args, **kwargs):
      if self['BUILD_SHARED']:
        return self.SharedLibrary(*args, **kwargs)
      else:
        return self.StaticLibrary(*args, **kwargs)
    
    env.SetDefault(BUILD_SHARED = False)
    env.AddMethod(MyLibraryWrapper)
    

    Make sure that snippet is your SConstruct, before any SConscript is parsed. To make it extra clean, create a tool in site_scons/site_tools and load it using env.Tool().