summaryrefslogtreecommitdiff
path: root/doc/user/builders-writing.xml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user/builders-writing.xml')
-rw-r--r--doc/user/builders-writing.xml532
1 files changed, 345 insertions, 187 deletions
diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml
index e6b165b..bc7983d 100644
--- a/doc/user/builders-writing.xml
+++ b/doc/user/builders-writing.xml
@@ -1,6 +1,28 @@
+<?xml version='1.0'?>
+<!DOCTYPE sconsdoc [
+ <!ENTITY % scons SYSTEM "../scons.mod">
+ %scons;
+
+ <!ENTITY % builders-mod SYSTEM "../generated/builders.mod">
+ %builders-mod;
+ <!ENTITY % functions-mod SYSTEM "../generated/functions.mod">
+ %functions-mod;
+ <!ENTITY % tools-mod SYSTEM "../generated/tools.mod">
+ %tools-mod;
+ <!ENTITY % variables-mod SYSTEM "../generated/variables.mod">
+ %variables-mod;
+
+]>
+
+<chapter id="chap-builders-writing"
+ xmlns="http://www.scons.org/dbxsd/v1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0/scons.xsd scons.xsd">
+<title>Writing Your Own Builders</title>
+
<!--
- Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 The SCons Foundation
+ Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 The SCons Foundation
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -129,7 +151,7 @@ This functionality could be invoked as in the following example:
</para>
<programlisting>
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
</programlisting>
<para>
@@ -163,12 +185,26 @@ This functionality could be invoked as in the following example:
</para>
-
+ <scons_example name="builderswriting_ex1">
+ <file name="SConstruct">
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $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>
- <programlisting>
- bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
- env = Environment(BUILDERS = {'Foo' : bld})
- </programlisting>
+ <sconstruct>
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
+env = Environment(BUILDERS = {'Foo' : bld})
+ </sconstruct>
<para>
@@ -179,7 +215,7 @@ This functionality could be invoked as in the following example:
</para>
<programlisting>
- env.Foo('file.foo', 'file.input')
+env.Foo('file.foo', 'file.input')
</programlisting>
<para>
@@ -188,10 +224,9 @@ This functionality could be invoked as in the following example:
</para>
- <screen>
- % <userinput>scons -Q</userinput>
- foobuild &lt; file.input &gt; file.foo
- </screen>
+ <scons_output example="builderswriting_ex1" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
<para>
@@ -224,19 +259,30 @@ This functionality could be invoked as in the following example:
in the generated error consistent with what the user will see in the
User's Guide.
-->
- <programlisting>
- bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
- env = Environment(BUILDERS = {'Foo' : bld})
- env.Foo('file.foo', 'file.input')
- env.Program('hello.c')
- </programlisting>
+ <scons_example name="builderswriting_ex2">
+ <file name="SConstruct">
+import SCons.Defaults; SCons.Defaults.ConstructionEnvironment['TOOLS'] = {}; bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $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 &lt; $SOURCE &gt; $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>
- <screen>
- % <userinput>scons -Q</userinput>
- AttributeError: 'SConsEnvironment' object has no attribute 'Program':
- File "/home/my/project/SConstruct", line 4:
- env.Program('hello.c')
- </screen>
+ <scons_output example="builderswriting_ex2" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
<para>
@@ -247,15 +293,34 @@ This functionality could be invoked as in the following example:
</para>
-
+ <scons_example name="builderswriting_ex3">
+ <file name="SConstruct">
+env = Environment()
+import os
+env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $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>
- <programlisting>
- env = Environment()
- bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
- env.Append(BUILDERS = {'Foo' : bld})
- env.Foo('file.foo', 'file.input')
- env.Program('hello.c')
- </programlisting>
+ <sconstruct>
+env = Environment()
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
+env.Append(BUILDERS = {'Foo' : bld})
+env.Foo('file.foo', 'file.input')
+env.Program('hello.c')
+ </sconstruct>
<para>
@@ -264,13 +329,13 @@ This functionality could be invoked as in the following example:
</para>
- <programlisting>
- env = Environment()
- bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
- env['BUILDERS']['Foo'] = bld
- env.Foo('file.foo', 'file.input')
- env.Program('hello.c')
- </programlisting>
+ <sconstruct>
+env = Environment()
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
+env['BUILDERS']['Foo'] = bld
+env.Foo('file.foo', 'file.input')
+env.Program('hello.c')
+ </sconstruct>
<para>
@@ -281,12 +346,9 @@ This functionality could be invoked as in the following example:
</para>
- <screen>
- % <userinput>scons -Q</userinput>
- foobuild &lt; file.input &gt; file.foo
- cc -o hello.o -c hello.c
- cc -o hello hello.o
- </screen>
+ <scons_output example="builderswriting_ex3" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
</section>
@@ -310,22 +372,40 @@ This functionality could be invoked as in the following example:
</para>
-
+ <scons_example name="builderswriting_ex4">
+ <file name="SConstruct">
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $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>
- <programlisting>
- bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET',
- suffix = '.foo',
- src_suffix = '.input')
- env = Environment(BUILDERS = {'Foo' : bld})
- env.Foo('file1')
- env.Foo('file2')
- </programlisting>
+ <sconstruct>
+bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET',
+ suffix = '.foo',
+ src_suffix = '.input')
+env = Environment(BUILDERS = {'Foo' : bld})
+env.Foo('file1')
+env.Foo('file2')
+ </sconstruct>
- <screen>
- % <userinput>scons -Q</userinput>
- foobuild &lt; file1.input &gt; file1.foo
- foobuild &lt; file2.input &gt; file2.foo
- </screen>
+ <scons_output example="builderswriting_ex4" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
<para>
@@ -352,9 +432,9 @@ This functionality could be invoked as in the following example:
</para>
<programlisting>
- def build_function(target, source, env):
- # Code to build "target" from "source"
- return None
+def build_function(target, source, env):
+ # Code to build "target" from "source"
+ return None
</programlisting>
<para>
@@ -439,16 +519,21 @@ This functionality could be invoked as in the following example:
</para>
- <programlisting>
- 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')
- </programlisting>
+ <scons_example name="builderswriting_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>
@@ -459,10 +544,9 @@ This functionality could be invoked as in the following example:
</para>
- <screen>
- % <userinput>scons -Q</userinput>
- build_function(["file.foo"], ["file.input"])
- </screen>
+ <scons_output example="builderswriting_ex5" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
</section>
@@ -481,8 +565,8 @@ This functionality could be invoked as in the following example:
</para>
<programlisting>
- def generate_actions(source, target, env, for_signature):
- return 'foobuild < %s > %s' % (target[0], source[0])
+def generate_actions(source, target, env, for_signature):
+ return 'foobuild &lt; %s &gt; %s' % (target[0], source[0])
</programlisting>
<para>
@@ -582,22 +666,39 @@ This functionality could be invoked as in the following example:
</para>
-
-
- <programlisting>
- def generate_actions(source, target, env, for_signature):
- return 'foobuild &lt; %s &gt; %s' % (source[0], target[0])
- bld = Builder(generator = generate_actions,
- suffix = '.foo',
- src_suffix = '.input')
- env = Environment(BUILDERS = {'Foo' : bld})
- env.Foo('file')
- </programlisting>
+ <scons_example name="builderswriting_ex6">
+ <file name="SConstruct">
+def generate_actions(source, target, env, for_signature):
+ return 'foobuild &lt; %s &gt; %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>
- <screen>
- % <userinput>scons -Q</userinput>
- foobuild &lt; file.input &gt; file.foo
- </screen>
+ <sconstruct>
+def generate_actions(source, target, env, for_signature):
+ return 'foobuild &lt; %s &gt; %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="builderswriting_ex6" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
<para>
@@ -643,20 +744,44 @@ This functionality could be invoked as in the following example:
</para>
-
+ <scons_example name="builderswriting_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>
- <programlisting>
- 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')
- </programlisting>
+ <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>
@@ -664,10 +789,9 @@ This functionality could be invoked as in the following example:
</para>
- <screen>
- % <userinput>scons -Q</userinput>
- foobuild file.foo new_target - file.input new_source
- </screen>
+ <scons_output example="builderswriting_ex7" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
<para>
@@ -685,43 +809,61 @@ This functionality could be invoked as in the following example:
</para>
- <programlisting>
- bld = Builder(action = 'my_command $SOURCES &gt; $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()
+ <scons_example name="builderswriting_MY_EMITTER">
+
+ <file name="SConstruct" printme="1">
+bld = Builder(action = 'my_command $SOURCES &gt; $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>
- </programlisting>
+ </scons_example>
- <programlisting>
- bld = Builder(action = 'my_command $SOURCES &gt; $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')
- </programlisting>
+ <sconstruct>
+bld = Builder(action = 'my_command $SOURCES &gt; $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>
@@ -732,11 +874,9 @@ This functionality could be invoked as in the following example:
</para>
- <screen>
- % <userinput>scons -Q</userinput>
- my_command file1.input modify1.in &gt; file1.foo
- my_command file2.input modify2.in &gt; file2.foo
- </screen>
+ <scons_output example="builderswriting_MY_EMITTER" suffix="1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
</section>
@@ -820,14 +960,23 @@ This functionality could be invoked as in the following example:
</para>
- <programlisting>
- def TOOL_ADD_HEADER(env):
- """A Tool to add a header from $HEADER to the source file"""
- add_header = Builder(action=['echo "$HEADER" &gt; $TARGET',
- 'cat $SOURCE &gt;&gt; $TARGET'])
- env.Append(BUILDERS = {'AddHeader' : add_header})
- env['HEADER'] = '' # set default value
- </programlisting>
+ <scons_example name="builderswriting_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" &gt; $TARGET',
+ 'cat $SOURCE &gt;&gt; $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>
@@ -835,11 +984,11 @@ This functionality could be invoked as in the following example:
</para>
- <programlisting>
- # Use TOOL_ADD_HEADER from site_scons/site_init.py
- env=Environment(tools=['default', TOOL_ADD_HEADER], HEADER="=====")
- env.AddHeader('tgt', 'src')
- </programlisting>
+ <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>
@@ -850,7 +999,7 @@ This functionality could be invoked as in the following example:
</para>
<!--
- <scons_output example="site1" os="posix">
+ <scons_output example="builderswriting_site1" os="posix" suffix="1">
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
-->
@@ -885,15 +1034,22 @@ This functionality could be invoked as in the following example:
functions:
</para>
- <programlisting>
- 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))
- </programlisting>
+ <scons_example name="builderswriting_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>
@@ -902,11 +1058,11 @@ This functionality could be invoked as in the following example:
</para>
- <programlisting>
- import my_utils
- print "build_id=" + my_utils.build_id()
- my_utils.MakeWorkDir('/tmp/work')
- </programlisting>
+ <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
@@ -917,9 +1073,9 @@ This functionality could be invoked as in the following example:
such as &Environment; or &Mkdir; or &Execute; in any file other
than a &SConstruct; or &SConscript; you always need to do
</para>
- <programlisting>
- from SCons.Script import *
- </programlisting>
+ <sconstruct>
+from SCons.Script import *
+ </sconstruct>
<para>
This is true in modules in <filename>site_scons</filename> such as
@@ -954,21 +1110,23 @@ This functionality could be invoked as in the following example:
</para>
- <scons_example name="ex8">
+ <scons_example name="builderswriting_ex8">
<file name="SConstruct" printme="1">
- env = Environment()
- #env.SourceCode('.', env.BitKeeper('my_command'))
- env.Program('hello.c')
+env = Environment()
+#env.SourceCode('.', env.BitKeeper('my_command'))
+env.Program('hello.c')
</file>
<file name="hello.c">
- hello.c
+hello.c
</file>
</scons_example>
- <scons_output example="ex8">
+ <scons_output example="builderswriting_ex8" suffix="1">
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
</section>
-->
+
+</chapter>