diff options
author | Dirk Baechle <dl9obn@darc.de> | 2013-05-03 22:08:59 (GMT) |
---|---|---|
committer | Dirk Baechle <dl9obn@darc.de> | 2013-05-03 22:08:59 (GMT) |
commit | 9e7cf970a730549348fd22a0921ea0ed2e894a69 (patch) | |
tree | 0bbe0e399fa2f8bb9328c012c5931e0172ea4547 /doc/user/builders-writing.in | |
parent | e3827a98511acc0d208193920bc40d5e2724bf12 (diff) | |
download | SCons-9e7cf970a730549348fd22a0921ea0ed2e894a69.zip SCons-9e7cf970a730549348fd22a0921ea0ed2e894a69.tar.gz SCons-9e7cf970a730549348fd22a0921ea0ed2e894a69.tar.bz2 |
- removed *.in files from the user guide
Diffstat (limited to 'doc/user/builders-writing.in')
-rw-r--r-- | doc/user/builders-writing.in | 1108 |
1 files changed, 0 insertions, 1108 deletions
diff --git a/doc/user/builders-writing.in b/doc/user/builders-writing.in deleted file mode 100644 index 749a8ba..0000000 --- a/doc/user/builders-writing.in +++ /dev/null @@ -1,1108 +0,0 @@ -<!-- - - __COPYRIGHT__ - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY - KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---> - -<!-- - -=head2 Adding new methods - -For slightly more demanding changes, you may wish to add new methods to the -C<cons> package. Here's an example of a very simple extension, -C<InstallScript>, which installs a tcl script in a requested location, but -edits the script first to reflect a platform-dependent path that needs to be -installed in the script: - - # cons::InstallScript - Create a platform dependent version of a shell - # script by replacing string ``#!your-path-here'' with platform specific - # path $BIN_DIR. - - sub cons::InstallScript { - my ($env, $dst, $src) = @_; - Command $env $dst, $src, qq( - sed s+your-path-here+$BIN_DIR+ %< > %> - chmod oug+x %> - ); - } - -Notice that this method is defined directly in the C<cons> package (by -prefixing the name with C<cons::>). A change made in this manner will be -globally visible to all environments, and could be called as in the -following example: - - InstallScript $env "$BIN/foo", "foo.tcl"; - -For a small improvement in generality, the C<BINDIR> variable could be -passed in as an argument or taken from the construction environment-,-as -C<%BINDIR>. - - -=head2 Overriding methods - -Instead of adding the method to the C<cons> name space, you could define a -new package which inherits existing methods from the C<cons> package and -overrides or adds others. This can be done using Perl's inheritance -mechanisms. - -The following example defines a new package C<cons::switch> which -overrides the standard C<Library> method. The overridden method builds -linked library modules, rather than library archives. A new -constructor is provided. Environments created with this constructor -will have the new library method; others won't. - - package cons::switch; - BEGIN {@ISA = 'cons'} - - sub new { - shift; - bless new cons(@_); - } - - sub Library { - my($env) = shift; - my($lib) = shift; - my(@objs) = Objects $env @_; - Command $env $lib, @objs, q( - %LD -r %LDFLAGS %< -o %> - ); - } - -This functionality could be invoked as in the following example: - - $env = new cons::switch(@overrides); - ... - Library $env 'lib.o', 'foo.c', 'bar.c'; - ---> - - <para> - - Although &SCons; provides many useful methods - for building common software products - (programs, libraries, documents, etc.), - you frequently want to be - able to build some other type of file - not supported directly by &SCons;. - Fortunately, &SCons; makes it very easy - to define your own &Builder; objects - for any custom file types you want to build. - (In fact, the &SCons; interfaces for creating - &Builder; objects are flexible enough and easy enough to use - that all of the the &SCons; built-in &Builder; objects - are created using the mechanisms described in this section.) - - </para> - - <section> - <title>Writing Builders That Execute External Commands</title> - - <para> - - The simplest &Builder; to create is - one that executes an external command. - For example, if we want to build - an output file by running the contents - of the input file through a command named - <literal>foobuild</literal>, - creating that &Builder; might look like: - - </para> - - <programlisting> - bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - </programlisting> - - <para> - - All the above line does is create a free-standing - &Builder; object. - The next section will show us how to actually use it. - - </para> - - </section> - - <section> - <title>Attaching a Builder to a &ConsEnv;</title> - - <para> - - A &Builder; object isn't useful - until it's attached to a &consenv; - so that we can call it to arrange - for files to be built. - This is done through the &cv-link-BUILDERS; - &consvar; in an environment. - The &cv-BUILDERS; variable is a Python dictionary - that maps the names by which you want to call - various &Builder; objects to the objects themselves. - For example, if we want to call the - &Builder; we just defined by the name - <function>Foo</function>, - our &SConstruct; file might look like: - - </para> - - <scons_example name="ex1"> - <file name="SConstruct"> - bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - env = Environment(BUILDERS = {'Foo' : bld}) - import os - env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd() - env.Foo('file.foo', 'file.input') - </file> - <file name="file.input"> - file.input - </file> - <file name="foobuild" chmod="0755"> - cat - </file> - </scons_example> - - <sconstruct> - bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - env = Environment(BUILDERS = {'Foo' : bld}) - </sconstruct> - - <para> - - With the &Builder; attached to our &consenv; - with the name <function>Foo</function>, - we can now actually call it like so: - - </para> - - <programlisting> - env.Foo('file.foo', 'file.input') - </programlisting> - - <para> - - Then when we run &SCons; it looks like: - - </para> - - <scons_output example="ex1"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - <para> - - Note, however, that the default &cv-BUILDERS; - variable in a &consenv; - comes with a default set of &Builder; objects - already defined: - &b-link-Program;, &b-link-Library;, etc. - And when we explicitly set the &cv-BUILDERS; variable - when we create the &consenv;, - the default &Builder;s are no longer part of - the environment: - - </para> - - <!-- - The ToolSurrogate stuff that's used to capture output initializes - SCons.Defaults.ConstructionEnvironment with its own list of TOOLS. - In this next example, we want to show the user that when they - set the BUILDERS explicitly, the call to env.Program() generates - an AttributeError. This won't happen with all of the default - ToolSurrogates in the default construction environment. To make the - AttributeError show up, we have to overwite the default construction - environment's TOOLS variable so Program() builder doesn't show up. - - We do this by executing a slightly different SConstruct file than the - one we print in the guide, with two extra statements at the front - that overwrite the TOOLS variable as described. Note that we have - to jam those statements on to the first line to keep the line number - in the generated error consistent with what the user will see in the - User's Guide. - --> - <scons_example name="ex2"> - <file name="SConstruct"> - import SCons.Defaults; SCons.Defaults.ConstructionEnvironment['TOOLS'] = {}; bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - env = Environment(BUILDERS = {'Foo' : bld}) - env.Foo('file.foo', 'file.input') - env.Program('hello.c') - </file> - <file name="SConstruct.printme" printme="1"> - bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - env = Environment(BUILDERS = {'Foo' : bld}) - env.Foo('file.foo', 'file.input') - env.Program('hello.c') - </file> - <file name="file.input"> - file.input - </file> - <file name="hello.c"> - hello.c - </file> - </scons_example> - - <scons_output example="ex2"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - <para> - - To be able to use both our own defined &Builder; objects - and the default &Builder; objects in the same &consenv;, - you can either add to the &cv-BUILDERS; variable - using the &Append; function: - - </para> - - <scons_example name="ex3"> - <file name="SConstruct"> - env = Environment() - import os - env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd() - bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - env.Append(BUILDERS = {'Foo' : bld}) - env.Foo('file.foo', 'file.input') - env.Program('hello.c') - </file> - <file name="file.input"> - file.input - </file> - <file name="hello.c"> - hello.c - </file> - <file name="foobuild" chmod="0755"> - cat - </file> - </scons_example> - - <sconstruct> - env = Environment() - bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - env.Append(BUILDERS = {'Foo' : bld}) - env.Foo('file.foo', 'file.input') - env.Program('hello.c') - </sconstruct> - - <para> - - Or you can explicitly set the appropriately-named - key in the &cv-BUILDERS; dictionary: - - </para> - - <sconstruct> - env = Environment() - bld = Builder(action = 'foobuild < $SOURCE > $TARGET') - env['BUILDERS']['Foo'] = bld - env.Foo('file.foo', 'file.input') - env.Program('hello.c') - </sconstruct> - - <para> - - Either way, the same &consenv; - can then use both the newly-defined - <function>Foo</function> &Builder; - and the default &b-link-Program; &Builder;: - - </para> - - <scons_output example="ex3"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - </section> - - <section> - <title>Letting &SCons; Handle The File Suffixes</title> - - <para> - - By supplying additional information - when you create a &Builder;, - you can let &SCons; add appropriate file - suffixes to the target and/or the source file. - For example, rather than having to specify - explicitly that you want the <literal>Foo</literal> - &Builder; to build the <literal>file.foo</literal> - target file from the <literal>file.input</literal> source file, - you can give the <literal>.foo</literal> - and <literal>.input</literal> suffixes to the &Builder;, - making for more compact and readable calls to - the <literal>Foo</literal> &Builder;: - - </para> - - <scons_example name="ex4"> - <file name="SConstruct"> - bld = Builder(action = 'foobuild < $SOURCE > $TARGET', - suffix = '.foo', - src_suffix = '.input') - env = Environment(BUILDERS = {'Foo' : bld}) - import os - env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd() - env.Foo('file1') - env.Foo('file2') - </file> - <file name="file1.input"> - file1.input - </file> - <file name="file2.input"> - file2.input - </file> - <file name="foobuild" chmod="0755"> - cat - </file> - </scons_example> - - <sconstruct> - bld = Builder(action = 'foobuild < $SOURCE > $TARGET', - suffix = '.foo', - src_suffix = '.input') - env = Environment(BUILDERS = {'Foo' : bld}) - env.Foo('file1') - env.Foo('file2') - </sconstruct> - - <scons_output example="ex4"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - <para> - - You can also supply a <literal>prefix</literal> keyword argument - if it's appropriate to have &SCons; append a prefix - to the beginning of target file names. - - </para> - - </section> - - <section> - <title>Builders That Execute Python Functions</title> - - <para> - - In &SCons;, you don't have to call an external command - to build a file. - You can, instead, define a Python function - that a &Builder; object can invoke - to build your target file (or files). - Such a &buildfunc; definition looks like: - - </para> - - <programlisting> - def build_function(target, source, env): - # Code to build "target" from "source" - return None - </programlisting> - - <para> - - The arguments of a &buildfunc; are: - - </para> - - <variablelist> - - <varlistentry> - <term>target</term> - - <listitem> - <para> - - A list of Node objects representing - the target or targets to be - built by this builder function. - The file names of these target(s) - may be extracted using the Python &str; function. - - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>source</term> - - <listitem> - <para> - - A list of Node objects representing - the sources to be - used by this builder function to build the targets. - The file names of these source(s) - may be extracted using the Python &str; function. - - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>env</term> - - <listitem> - <para> - - The &consenv; used for building the target(s). - The builder function may use any of the - environment's construction variables - in any way to affect how it builds the targets. - - </para> - </listitem> - </varlistentry> - - </variablelist> - - <para> - - The builder function must - return a <literal>0</literal> or <literal>None</literal> value - if the target(s) are built successfully. - The builder function - may raise an exception - or return any non-zero value - to indicate that the build is unsuccessful, - - </para> - - <para> - - Once you've defined the Python function - that will build your target file, - defining a &Builder; object for it is as - simple as specifying the name of the function, - instead of an external command, - as the &Builder;'s - <literal>action</literal> - argument: - - </para> - - <scons_example name="ex5"> - <file name="SConstruct" printme="1"> - def build_function(target, source, env): - # Code to build "target" from "source" - return None - bld = Builder(action = build_function, - suffix = '.foo', - src_suffix = '.input') - env = Environment(BUILDERS = {'Foo' : bld}) - env.Foo('file') - </file> - <file name="file.input"> - file.input - </file> - </scons_example> - - <para> - - And notice that the output changes slightly, - reflecting the fact that a Python function, - not an external command, - is now called to build the target file: - - </para> - - <scons_output example="ex5"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - </section> - - <section> - <title>Builders That Create Actions Using a &Generator;</title> - - <para> - - &SCons; Builder objects can create an action "on the fly" - by using a function called a &generator;. - This provides a great deal of flexibility to - construct just the right list of commands - to build your target. - A &generator; looks like: - - </para> - - <programlisting> - def generate_actions(source, target, env, for_signature): - return 'foobuild < %s > %s' % (target[0], source[0]) - </programlisting> - - <para> - - The arguments of a &generator; are: - - </para> - - <variablelist> - - <varlistentry> - <term>source</term> - - <listitem> - <para> - - A list of Node objects representing - the sources to be built - by the command or other action - generated by this function. - The file names of these source(s) - may be extracted using the Python &str; function. - - </para> - </listitem> - - </varlistentry> - - <varlistentry> - <term>target</term> - - <listitem> - <para> - - A list of Node objects representing - the target or targets to be built - by the command or other action - generated by this function. - The file names of these target(s) - may be extracted using the Python &str; function. - - </para> - </listitem> - - </varlistentry> - - <varlistentry> - <term>env</term> - - <listitem> - <para> - - The &consenv; used for building the target(s). - The generator may use any of the - environment's construction variables - in any way to determine what command - or other action to return. - - </para> - </listitem> - - </varlistentry> - - <varlistentry> - <term>for_signature</term> - - <listitem> - <para> - - A flag that specifies whether the - generator is being called to contribute to a build signature, - as opposed to actually executing the command. - - <!-- XXX NEED MORE HERE, describe generators use in signatures --> - - </para> - </listitem> - - </varlistentry> - - </variablelist> - - <para> - - The &generator; must return a - command string or other action that will be used to - build the specified target(s) from the specified source(s). - - </para> - - <para> - - Once you've defined a &generator;, - you create a &Builder; to use it - by specifying the generator keyword argument - instead of <literal>action</literal>. - - </para> - - <scons_example name="ex6"> - <file name="SConstruct"> - def generate_actions(source, target, env, for_signature): - return 'foobuild < %s > %s' % (source[0], target[0]) - bld = Builder(generator = generate_actions, - suffix = '.foo', - src_suffix = '.input') - env = Environment(BUILDERS = {'Foo' : bld}) - import os - env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd() - env.Foo('file') - </file> - <file name="file.input"> - file.input - </file> - <file name="foobuild" chmod="0755"> - cat - </file> - </scons_example> - - <sconstruct> - def generate_actions(source, target, env, for_signature): - return 'foobuild < %s > %s' % (source[0], target[0]) - bld = Builder(generator = generate_actions, - suffix = '.foo', - src_suffix = '.input') - env = Environment(BUILDERS = {'Foo' : bld}) - env.Foo('file') - </sconstruct> - - <scons_output example="ex6"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - <para> - - Note that it's illegal to specify both an - <literal>action</literal> - and a - <literal>generator</literal> - for a &Builder;. - - </para> - - </section> - - <section> - <title>Builders That Modify the Target or Source Lists Using an &Emitter;</title> - - <para> - - &SCons; supports the ability for a Builder to modify the - lists of target(s) from the specified source(s). - You do this by defining an &emitter; function - that takes as its arguments - the list of the targets passed to the builder, - the list of the sources passed to the builder, - and the construction environment. - The emitter function should return the modified - lists of targets that should be built - and sources from which the targets will be built. - - </para> - - <para> - - For example, suppose you want to define a Builder - that always calls a <filename>foobuild</filename> program, - and you want to automatically add - a new target file named - <filename>new_target</filename> - and a new source file named - <filename>new_source</filename> - whenever it's called. - The &SConstruct; file might look like this: - - </para> - - <scons_example name="ex7"> - <file name="SConstruct"> - def modify_targets(target, source, env): - target.append('new_target') - source.append('new_source') - return target, source - bld = Builder(action = 'foobuild $TARGETS - $SOURCES', - suffix = '.foo', - src_suffix = '.input', - emitter = modify_targets) - env = Environment(BUILDERS = {'Foo' : bld}) - import os - env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd() - env.Foo('file') - </file> - <file name="file.input"> - file.input - </file> - <file name="new_source"> - new_source - </file> - <file name="foobuild" chmod="0755"> - cat - </file> - </scons_example> - - <sconstruct> - def modify_targets(target, source, env): - target.append('new_target') - source.append('new_source') - return target, source - bld = Builder(action = 'foobuild $TARGETS - $SOURCES', - suffix = '.foo', - src_suffix = '.input', - emitter = modify_targets) - env = Environment(BUILDERS = {'Foo' : bld}) - env.Foo('file') - </sconstruct> - - <para> - - And would yield the following output: - - </para> - - <scons_output example="ex7"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - <para> - - One very flexible thing that you can do is - use a construction variable to specify - different emitter functions for different - construction variable. - To do this, specify a string - containing a construction variable - expansion as the emitter when you call - the &Builder; function, - and set that construction variable to - the desired emitter function - in different construction environments: - - </para> - - <scons_example name="MY_EMITTER"> - - <file name="SConstruct" printme="1"> - bld = Builder(action = 'my_command $SOURCES > $TARGET', - suffix = '.foo', - src_suffix = '.input', - emitter = '$MY_EMITTER') - def modify1(target, source, env): - return target, source + ['modify1.in'] - def modify2(target, source, env): - return target, source + ['modify2.in'] - env1 = Environment(BUILDERS = {'Foo' : bld}, - MY_EMITTER = modify1) - env2 = Environment(BUILDERS = {'Foo' : bld}, - MY_EMITTER = modify2) - env1.Foo('file1') - env2.Foo('file2') - import os - env1['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd() - env2['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd() - </file> - <file name="file1.input"> - file1.input - </file> - <file name="file2.input"> - file2.input - </file> - <file name="modify1.in"> - modify1.input - </file> - <file name="modify2.in"> - modify2.input - </file> - <file name="my_command" chmod="0755"> - cat - </file> - - </scons_example> - - <sconstruct> - bld = Builder(action = 'my_command $SOURCES > $TARGET', - suffix = '.foo', - src_suffix = '.input', - emitter = '$MY_EMITTER') - def modify1(target, source, env): - return target, source + ['modify1.in'] - def modify2(target, source, env): - return target, source + ['modify2.in'] - env1 = Environment(BUILDERS = {'Foo' : bld}, - MY_EMITTER = modify1) - env2 = Environment(BUILDERS = {'Foo' : bld}, - MY_EMITTER = modify2) - env1.Foo('file1') - env2.Foo('file2') - </sconstruct> - - <para> - - In this example, the <filename>modify1.in</filename> - and <filename>modify2.in</filename> files - get added to the source lists - of the different commands: - - </para> - - <scons_output example="MY_EMITTER"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - </section> - - <!-- - - <section> - <title>target_factor=, source_factory=</title> - - </section> - - <section> - <title>target_scanner=, source_scanner=</title> - - </section> - - <section> - <title>multi=</title> - - </section> - - <section> - <title>single_source=</title> - - </section> - - <section> - <title>src_builder=</title> - - </section> - - <section> - <title>ensure_suffix=</title> - - </section> - - --> - - <section> - <title>Where To Put Your Custom Builders and Tools</title> - - <para> - - The <filename>site_scons</filename> directories give you a place to - put Python modules and packages that you can import into your &SConscript; files - (<filename>site_scons</filename>), - add-on tools that can integrate into &SCons; - (<filename>site_scons/site_tools</filename>), - and a <filename>site_scons/site_init.py</filename> file that - gets read before any &SConstruct; or &SConscript; file, - allowing you to change &SCons;'s default behavior. - - </para> - - <para> - - Each system type (Windows, Mac, Linux, etc.) searches a canonical - set of directories for site_scons; see the man page for details. - The top-level SConstruct's site_scons dir is always searched last, - and its dir is placed first in the tool path so it overrides all - others. - - </para> - - <para> - - 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, a - <filename>site_scons</filename> 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 module or package containing two functions, - <function>exists()</function> and <function>generate()</function>. - - </para> - - <para> - - A single-function Tool can just be included in your - <filename>site_scons/site_init.py</filename> file where it will be - parsed and made available for use. For instance, you could have a - <filename>site_scons/site_init.py</filename> file like this: - - </para> - - <scons_example name="site1"> - <file name="site_scons/site_init.py" printme="1"> - 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 - </file> - <file name="SConstruct"> - env=Environment(tools=['default', TOOL_ADD_HEADER], HEADER="=====") - env.AddHeader('tgt', 'src') - </file> - <file name="src"> - hi there - </file> - </scons_example> - - <para> - - and a &SConstruct; like this: - - </para> - - <sconstruct> - # Use TOOL_ADD_HEADER from site_scons/site_init.py - env=Environment(tools=['default', TOOL_ADD_HEADER], HEADER="=====") - env.AddHeader('tgt', 'src') - </sconstruct> - - <para> - - The <function>TOOL_ADD_HEADER</function> tool method will be - called to add the <function>AddHeader</function> tool to the - environment. - - </para> - - <!-- - <scons_output example="site1" os="posix"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - --> - - <para> - A more full-fledged tool with - <function>exists()</function> and <function>generate()</function> - methods can be installed either as a module in the file - <filename>site_scons/site_tools/toolname.py</filename> or as a - package in the - directory <filename>site_scons/site_tools/toolname</filename>. In - the case of using a package, the <function>exists()</function> - and <function>generate()</function> are in the - file <filename>site_scons/site_tools/toolname/__init__.py</filename>. - (In all the above case <filename>toolname</filename> is replaced - by the name of the tool.) - Since <filename>site_scons/site_tools</filename> 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, <filename>site_scons</filename> gives you the hook you need. - </para> - - <para> - Many people have a library of utility Python functions they'd like - to include in &SConscript;s; just put that module in - <filename>site_scons/my_utils.py</filename> or any valid Python module name of your - choice. For instance you can do something like this in - <filename>site_scons/my_utils.py</filename> to add - <function>build_id</function> and <function>MakeWorkDir</function> - functions: - </para> - - <scons_example name="site2"> - <file name="site_scons/my_utils.py" printme="1"> - from SCons.Script import * # for Execute and Mkdir - def build_id(): - """Return a build ID (stub version)""" - return "100" - def MakeWorkDir(workdir): - """Create the specified dir immediately""" - Execute(Mkdir(workdir)) - </file> - <file name="SConscript"> - import my_utils - MakeWorkDir('/tmp/work') - print "build_id=" + my_utils.build_id() - </file> - </scons_example> - - <para> - - And then in your &SConscript; or any sub-&SConscript; anywhere in - your build, you can import <filename>my_utils</filename> and use it: - - </para> - - <sconstruct> - import my_utils - print "build_id=" + my_utils.build_id() - my_utils.MakeWorkDir('/tmp/work') - </sconstruct> - - <para> - Note that although you can put this library in - <filename>site_scons/site_init.py</filename>, - it is no better there than <filename>site_scons/my_utils.py</filename> - since you still have to import that module into your &SConscript;. - Also note that in order to refer to objects in the SCons namespace - such as &Environment; or &Mkdir; or &Execute; in any file other - than a &SConstruct; or &SConscript; you always need to do - </para> - <sconstruct> - from SCons.Script import * - </sconstruct> - - <para> - This is true in modules in <filename>site_scons</filename> such as - <filename>site_scons/site_init.py</filename> as well. - </para> - - <para> - - You can use any of the user- or machine-wide site dirs such as - <filename>~/.scons/site_scons</filename> instead of - <filename>./site_scons</filename>, or use the - <literal>--site-dir</literal> option to point to your own dir. - <filename>site_init.py</filename> and - <filename>site_tools</filename> will be located under that dir. - To avoid using a <filename>site_scons</filename> dir at all, - even if it exists, use the <literal>--no-site-dir</literal> - option. - - </para> - - </section> - - - <!-- - - <section> - <title>Builders That Use Other Builders</title> - - <para> - - XXX para - - </para> - - <scons_example name="ex8"> - <file name="SConstruct" printme="1"> - env = Environment() - #env.SourceCode('.', env.BitKeeper('my_command')) - env.Program('hello.c') - </file> - <file name="hello.c"> - hello.c - </file> - </scons_example> - - <scons_output example="ex8"> - <scons_output_command>scons -Q</scons_output_command> - </scons_output> - - </section> - - --> |