19.7. Where To Put Your Custom Builders and Tools

The site_scons directory gives you a place to put Python modules you can import into your SConscripts (site_scons), add-on tools that can integrate into SCons (site_scons/site_tools), and a site_scons/site_init.py file that gets read before any SConstruct or SConscript, allowing you to change SCons's default behavior.

If you get a tool from somewhere (the SCons wiki or a third party, for instance) and you'd like to use it in your project, the site_scons dir is the simplest place to put it. Tools come in two flavors; either a Python function that operates on an Environment or a Python file containing two functions, exists() and generate().

A single-function Tool can just be included in your site_scons/site_init.py file where it will be parsed and made available for use. For instance, you could have a site_scons/site_init.py file like this:

      def TOOL_ADD_HEADER(env):
         """A Tool to add a header from $HEADER to the source file"""
         add_header = Builder(action=['echo "$HEADER" > $TARGET',
                                      'cat $SOURCE >> $TARGET'])
         env.Append(BUILDERS = {'AddHeader' : add_header})
         env['HEADER'] = '' # set default value

and a SConstruct like this:

      # Use TOOL_ADD_HEADER from site_scons/site_init.py
      env=Environment(tools=['default', TOOL_ADD_HEADER], HEADER="=====")
      env.AddHeader('tgt', 'src')

The TOOL_ADD_HEADER tool method will be called to add the AddHeader tool to the environment.

Similarly, a more full-fledged tool with exists() and generate() methods can be installed in site_scons/site_tools/toolname.py. Since site_scons/site_tools is automatically added to the head of the tool search path, any tool found there will be available to all environments. Furthermore, a tool found there will override a built-in tool of the same name, so if you need to change the behavior of a built-in tool, site_scons gives you the hook you need.

Many people have a library of utility Python functions they'd like to include in SConscripts; just put that module in site_scons/my_utils.py or any valid Python module name of your choice. For instance you can do something like this in site_scons/my_utils.py to add a build_id method:

      def build_id():
         """Return a build ID (stub version)"""
         return "100"

And then in your SConscript or any sub-SConscript anywhere in your build, you can import my_utils and use it:

      import my_utils
      print "build_id=" + my_utils.build_id()

If you have a machine-wide site dir you'd like to use instead of ./site_scons, use the --site-dir option to point to your dir. site_init.py and site_tools will be located under that dir. To avoid using a site_scons dir at all, even if it exists, use the --no-site-dir option.