How to write a scons wrapper function.

NOTE: as of SCons 0.98 (actually available as of the 0.97.0d20070809 checkpoint release), there will be a new API function AddMethod that is better (more portable and API-safe) than having to import SConsEnvironment and add your function to it.

If you have a sequence of SCons operations that's not well-captured by a Builder, or you just want to wrap up some SCons functions into a neat callable package, you probably want to make it look like a regular SCons environment method. Here's how to do that:

Let's say you have this (just for example):

   1 sources = ["foo.c", "bar.c", "main.c"]
   2 env = Environment()
   3 BuildDir("build", ".", duplicate=0)
   4 build_sources = ["build/" + filename for filename in sources]
   5 prog = env.Program("build/program", build_sources)
   6 Default(prog)

and you want to wrap it up so you can do that kind of thing in several places. Write a normal python function making sure an Environment is its first arg:

   1 def BuildProgramInDir(env, program, sources):
   2    BuildDir("build", ".", duplicate=0)
   3    build_sources = ["build/" + filename for filename in sources]
   4    prog = env.Program("build/"+program, build_sources)
   5    Default(prog)

then to make it callable as an Environment method, do this (pre-0.98; otherwise use AddMethod):

   1 from SCons.Script.SConscript import SConsEnvironment # just do this once
   2 SConsEnvironment.BuildProgramInDir = BuildProgramInDir

then you can call it as usual:

   1 env=Environment()
   2 sources = ["foo.c", "bar.c", "main.c"]
   3 env.BuildProgramInDir('program', sources)

There are many more useful things you can do with this, from simple renaming of standard methods to complex pathname manipulations to automatically building and installing in one command. Have fun!

Here's another wrapper example that handles targets, sources, and overrides in the same way that ordinary SCons builders do. In this example, I want to define a wrapper that will automatically add a certain library when building my test programs.

   1 from SCons.Script.SConscript import SConsEnvironment
   2 # Define _null (used to detect missing target arg in wrapper functions)
   3 class _Null:
   4     pass
   5 _null = _Null
   6 def MyTestProgram( env, target=None, source=_null, **kw ):
   7     '''Build a test program, adding utest library to link automatically.'''
   8     # Reassign args if no target specified
   9     if source is _null:
  10         source = target
  11         target = None
  12    # Add utest to the list of libraries
  13     if 'LIBS' in kw:
  14         libs = kw.pop( 'LIBS' )
  15     else:
  16         libs = []
  17     kw['LIBS'] = [ 'utest' ] + libs
  18     # Use ordinary Program builder to build the program
  19     program = env.Program( target, source, **kw )
  20     # Must build the utest library first
  21     env.Depends( program, env['LIBPREFIX'] + 'utest' + env['LIBSUFFIX'] )
  22     return program
  23 # Add wrapper to environment
  24 SConsEnvironment.MyTestProgram = MyTestProgram
  25 env = Environment()
  26 env.Library( 'utest', 'usub1.c' )
  27 # Specify just the source
  28 env.MyTestProgram( 'test1.c' )
  29 # Specify both target and source
  30 env.MyTestProgram( 'renamed_test2', 'test2.c' )
  31 # Specify just source with an override for CCFLAGS
  32 env.MyTestProgram( 'test3.c', CCFLAGS='/nologo /O1' )

WrapperFunctions (last edited 2010-01-17 06:50:56 by s235-200)