The &AddMethod; function is used to add a method
to an environment. It's typically used to add a "pseudo-builder,"
a function that looks like a &Builder; but
wraps up calls to multiple other &Builder;s
or otherwise processes its arguments
before calling one or more &Builder;s.
In the following example,
we want to install the program into the standard
/usr/bin directory hierarchy,
but also copy it into a local install/bin
directory from which a package might be built:
def install_in_bin_dirs(env, source):
"""Install source in both bin dirs"""
i1 = env.Install("$BIN", source)
i2 = env.Install("$LOCALBIN", source)
return [i1[0], i2[0]] # Return a list, like a normal builder
env = Environment(BIN='__ROOT__/usr/bin', LOCALBIN='#install/bin')
env.AddMethod(install_in_bin_dirs, "InstallInBinDirs")
env.InstallInBinDirs(Program('hello.c')) # installs hello in both bin dirs
int main() { printf("Hello, world!\n"); }
This produces the following:
scons -Q /
As mentioned, a psuedo-builder also provides more flexibility
in parsing arguments than you can get with a &Builder;.
The next example shows a pseudo-builder with a
named argument that modifies the filename, and a separate argument
for the resource file (rather than having the builder figure it out
by file extension). This example also demonstrates using the global
&AddMethod; function to add a method to the global Environment class,
so it will be used in all subsequently created environments.
def BuildTestProg(env, testfile, resourcefile, testdir="tests"):
"""Build the test program;
prepends "test_" to src and target,
and puts target into testdir."""
srcfile = "test_%s.c" % testfile
target = "%s/test_%s" % (testdir, testfile)
if env['PLATFORM'] == 'win32':
resfile = env.RES(resourcefile)
p = env.Program(target, [srcfile, resfile])
else:
p = env.Program(target, srcfile)
return p
AddMethod(Environment, BuildTestProg)
env = Environment()
env.BuildTestProg('stuff', resourcefile='res.rc')
int main() { printf("Hello, world!\n"); }
res.rc
This produces the following on Linux:
scons -Q
And the following on Windows:
scons -Q
Using &AddMethod; is better than just adding an instance method
to a &consenv; because it gets called as a proper method,
and because &AddMethod; provides for copying the method
to any clones of the &consenv; instance.