3932181bec17383886f49113eeb48452a8c193ec
[scons.git] / doc / user / builders-writing.xml
1 <!--
2
3   __COPYRIGHT__
4
5   Permission is hereby granted, free of charge, to any person obtaining
6   a copy of this software and associated documentation files (the
7   "Software"), to deal in the Software without restriction, including
8   without limitation the rights to use, copy, modify, merge, publish,
9   distribute, sublicense, and/or sell copies of the Software, and to
10   permit persons to whom the Software is furnished to do so, subject to
11   the following conditions:
12
13   The above copyright notice and this permission notice shall be included
14   in all copies or substantial portions of the Software.
15
16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17   KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18   WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 -->
25
26 <!--
27
28 =head2 Adding new methods
29
30 For slightly more demanding changes, you may wish to add new methods to the
31 C<cons> package. Here's an example of a very simple extension,
32 C<InstallScript>, which installs a tcl script in a requested location, but
33 edits the script first to reflect a platform-dependent path that needs to be
34 installed in the script:
35
36   # cons::InstallScript - Create a platform dependent version of a shell
37   # script by replacing string ``#!your-path-here'' with platform specific
38   # path $BIN_DIR.
39
40   sub cons::InstallScript {
41         my ($env, $dst, $src) = @_;
42         Command $env $dst, $src, qq(
43                 sed s+your-path-here+$BIN_DIR+ %< > %>
44                 chmod oug+x %>
45         );
46   }
47
48 Notice that this method is defined directly in the C<cons> package (by
49 prefixing the name with C<cons::>). A change made in this manner will be
50 globally visible to all environments, and could be called as in the
51 following example:
52
53   InstallScript $env "$BIN/foo", "foo.tcl";
54
55 For a small improvement in generality, the C<BINDIR> variable could be
56 passed in as an argument or taken from the construction environment-,-as
57 C<%BINDIR>.
58
59
60 =head2 Overriding methods
61
62 Instead of adding the method to the C<cons> name space, you could define a
63 new package which inherits existing methods from the C<cons> package and
64 overrides or adds others. This can be done using Perl's inheritance
65 mechanisms.
66
67 The following example defines a new package C<cons::switch> which
68 overrides the standard C<Library> method. The overridden method builds
69 linked library modules, rather than library archives. A new
70 constructor is provided. Environments created with this constructor
71 will have the new library method; others won't.
72
73   package cons::switch;
74   BEGIN {@ISA = 'cons'}
75
76   sub new {
77         shift;
78         bless new cons(@_);
79   }
80
81   sub Library {
82         my($env) = shift;
83         my($lib) = shift;
84         my(@objs) = Objects $env @_;
85         Command $env $lib, @objs, q(
86                 %LD -r %LDFLAGS %< -o %>
87         );
88   }
89
90 This functionality could be invoked as in the following example:
91
92   $env = new cons::switch(@overrides);
93   ...
94   Library $env 'lib.o', 'foo.c', 'bar.c';
95
96 -->
97
98   <para>
99
100   Although &SCons; provides many useful methods
101   for building common software products:
102   programs, libraries, documents.
103   you frequently want to be
104   able to build some other type of file
105   not supported directly by &SCons;.
106   Fortunately, &SCons; makes it very easy
107   to define your own &Builder; objects
108   for any custom file types you want to build.
109   (In fact, the &SCons; interfaces for creating
110   &Builder; objects are flexible enough and easy enough to use
111   that all of the the &SCons; built-in &Builder; objects
112   are created the mechanisms described in this section.)
113
114   </para>
115
116   <section>
117   <title>Writing Builders That Execute External Commands</title>
118
119     <para>
120
121     The simplest &Builder; to create is
122     one that executes an external command.
123     For example, if we want to build
124     an output file by running the contents
125     of the input file through a command named
126     <literal>foobuild</literal>,
127     creating that &Builder; might look like:
128
129     </para>
130
131     <programlisting>
132        bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
133     </programlisting>
134
135     <para>
136
137     All the above line does is create a free-standing
138     &Builder; object.
139     The next section will show us how to actually use it.
140
141     </para>
142
143   </section>
144
145   <section>
146   <title>Attaching a Builder to a &ConsEnv;</title>
147
148     <para>
149
150     A &Builder; object isn't useful
151     until it's attached to a &consenv;
152     so that we can call it to arrange
153     for files to be built.
154     This is done through the &cv-link-BUILDERS;
155     &consvar; in an environment.
156     The &cv-BUILDERS; variable is a Python dictionary
157     that maps the names by which you want to call
158     various &Builder; objects to the objects themselves.
159     For example, if we want to call the
160     &Builder; we just defined by the name
161     <function>Foo</function>,
162     our &SConstruct; file might look like:
163
164     </para>
165
166     
167
168     <programlisting>
169        bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
170        env = Environment(BUILDERS = {'Foo' : bld})
171     </programlisting>
172
173     <para>
174
175     With the &Builder; attached to our &consenv;
176     with the name <function>Foo</function>,
177     we can now actually call it like so:
178
179     </para>
180
181     <programlisting>
182        env.Foo('file.foo', 'file.input')
183     </programlisting>
184
185     <para>
186
187     Then when we run &SCons; it looks like:
188
189     </para>
190
191     <screen>
192       % <userinput>scons -Q</userinput>
193       foobuild &lt; file.input &gt; file.foo
194     </screen>
195
196     <para>
197
198     Note, however, that the default &cv-BUILDERS;
199     variable in a &consenv;
200     comes with a default set of &Builder; objects
201     already defined:
202     &b-link-Program;, &b-link-Library;, etc.
203     And when we explicitly set the &cv-BUILDERS; variable
204     when we create the &consenv;,
205     the default &Builder;s are no longer part of
206     the environment:
207
208     </para>
209
210    <!--
211    The ToolSurrogate stuff that's used to capture output initializes
212    SCons.Defaults.ConstructionEnvironment with its own list of TOOLS.
213    In this next example, we want to show the user that when they
214    set the BUILDERS explicitly, the call to env.Program() generates
215    an AttributeError.  This won't happen with all of the default
216    ToolSurrogates in the default construction environment.  To make the
217    AttributeError show up, we have to overwite the default construction
218    environment's TOOLS variable so Program() builder doesn't show up.
219
220    We do this by executing a slightly different SConstruct file than the
221    one we print in the guide, with two extra statements at the front
222    that overwrite the TOOLS variable as described.  Note that we have
223    to jam those statements on to the first line to keep the line number
224    in the generated error consistent with what the user will see in the
225    User's Guide.
226    -->
227     <programlisting>
228        bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
229        env = Environment(BUILDERS = {'Foo' : bld})
230        env.Foo('file.foo', 'file.input')
231        env.Program('hello.c')
232     </programlisting>
233
234     <screen>
235       % <userinput>scons -Q</userinput>
236       AttributeError: SConsEnvironment instance has no attribute 'Program':
237         File "/home/my/project/SConstruct", line 4:
238           env.Program('hello.c')
239     </screen>
240
241     <para>
242
243     To be able to use both our own defined &Builder; objects
244     and the default &Builder; objects in the same &consenv;,
245     you can either add to the &cv-BUILDERS; variable
246     using the &Append; function:
247
248     </para>
249
250     
251
252     <programlisting>
253        env = Environment()
254        bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
255        env.Append(BUILDERS = {'Foo' : bld})
256        env.Foo('file.foo', 'file.input')
257        env.Program('hello.c')
258     </programlisting>
259
260     <para>
261
262     Or you can explicitly set the appropriately-named
263     key in the &cv-BUILDERS; dictionary:
264
265     </para>
266
267     <programlisting>
268        env = Environment()
269        bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
270        env['BUILDERS']['Foo'] = bld
271        env.Foo('file.foo', 'file.input')
272        env.Program('hello.c')
273     </programlisting>
274
275     <para>
276
277     Either way, the same &consenv;
278     can then use both the newly-defined
279     <function>Foo</function> &Builder;
280     and the default &b-link-Program; &Builder;:
281
282     </para>
283
284     <screen>
285       % <userinput>scons -Q</userinput>
286       foobuild &lt; file.input &gt; file.foo
287       cc -o hello.o -c hello.c
288       cc -o hello hello.o
289     </screen>
290
291   </section>
292
293   <section>
294   <title>Letting &SCons; Handle The File Suffixes</title>
295
296     <para>
297
298     By supplying additional information
299     when you create a &Builder;,
300     you can let &SCons; add appropriate file
301     suffixes to the target and/or the source file.
302     For example, rather than having to specify
303     explicitly that you want the <literal>Foo</literal>
304     &Builder; to build the <literal>file.foo</literal>
305     target file from the <literal>file.input</literal> source file,
306     you can give the <literal>.foo</literal>
307     and <literal>.input</literal> suffixes to the &Builder;,
308     making for more compact and readable calls to
309     the <literal>Foo</literal> &Builder;:
310
311     </para>
312
313     
314
315     <programlisting>
316        bld = Builder(action = 'foobuild < $SOURCE > $TARGET',
317                      suffix = '.foo',
318                      src_suffix = '.input')
319        env = Environment(BUILDERS = {'Foo' : bld})
320        env.Foo('file1')
321        env.Foo('file2')
322     </programlisting>
323
324     <screen>
325       % <userinput>scons -Q</userinput>
326       foobuild &lt; file1.input &gt; file1.foo
327       foobuild &lt; file2.input &gt; file2.foo
328     </screen>
329
330     <para>
331
332     You can also supply a <literal>prefix</literal> keyword argument
333     if it's appropriate to have &SCons; append a prefix
334     to the beginning of target file names.
335
336     </para>
337
338   </section>
339
340   <section>
341   <title>Builders That Execute Python Functions</title>
342
343     <para>
344
345     In &SCons;, you don't have to call an external command
346     to build a file.
347     You can, instead, define a Python function
348     that a &Builder; object can invoke
349     to build your target file (or files).
350     Such a &buildfunc; definition looks like:
351
352     </para>
353
354     <programlisting>
355        def build_function(target, source, env):
356            # Code to build "target" from "source"
357            return None
358     </programlisting>
359
360     <para>
361
362     The arguments of a &buildfunc; are:
363
364     </para>
365
366     <variablelist>
367
368       <varlistentry>
369       <term>target</term>
370
371       <listitem>
372       <para>
373
374       A list of Node objects representing
375       the target or targets to be
376       built by this builder function.
377       The file names of these target(s)
378       may be extracted using the Python &str; function.
379
380       </para>
381       </listitem>
382       </varlistentry>
383
384       <varlistentry>
385       <term>source</term>
386
387       <listitem>
388       <para>
389
390       A list of Node objects representing
391       the sources to be
392       used by this builder function to build the targets.
393       The file names of these source(s)
394       may be extracted using the Python &str; function.
395
396       </para>
397       </listitem>
398       </varlistentry>
399
400       <varlistentry>
401       <term>env</term>
402
403       <listitem>
404       <para>
405
406       The &consenv; used for building the target(s).
407       The builder function may use any of the
408       environment's construction variables
409       in any way to affect how it builds the targets.
410
411       </para>
412       </listitem>
413       </varlistentry>
414
415     </variablelist>
416
417     <para>
418
419     The builder function must
420     return a <literal>0</literal> or <literal>None</literal> value
421     if the target(s) are built successfully.
422     The builder function
423     may raise an exception
424     or return any non-zero value
425     to indicate that the build is unsuccessful,
426
427     </para>
428
429     <para>
430
431     Once you've defined the Python function
432     that will build your target file,
433     defining a &Builder; object for it is as
434     simple as specifying the name of the function,
435     instead of an external command,
436     as the &Builder;'s
437     <literal>action</literal>
438     argument:
439
440     </para>
441
442     <programlisting>
443        def build_function(target, source, env):
444            # Code to build "target" from "source"
445            return None
446        bld = Builder(action = build_function,
447                      suffix = '.foo',
448                      src_suffix = '.input')
449        env = Environment(BUILDERS = {'Foo' : bld})
450        env.Foo('file')
451     </programlisting>
452
453     <para>
454
455     And notice that the output changes slightly,
456     reflecting the fact that a Python function,
457     not an external command,
458     is now called to build the target file:
459
460     </para>
461
462     <screen>
463       % <userinput>scons -Q</userinput>
464       build_function(["file.foo"], ["file.input"])
465     </screen>
466
467   </section>
468
469   <section>
470   <title>Builders That Create Actions Using a &Generator;</title>
471
472     <para>
473
474     &SCons; Builder objects can create an action "on the fly"
475     by using a function called a &generator;.
476     This provides a great deal of flexibility to
477     construct just the right list of commands
478     to build your target.
479     A &generator; looks like:
480
481     </para>
482
483     <programlisting>
484        def generate_actions(source, target, env, for_signature):
485            return 'foobuild < %s > %s' % (target[0], source[0])
486     </programlisting>
487
488     <para>
489
490     The arguments of a &generator; are:
491
492     </para>
493
494     <variablelist>
495
496       <varlistentry>
497       <term>source</term>
498
499       <listitem>
500       <para>
501
502       A list of Node objects representing
503       the sources to be built
504       by the command or other action
505       generated by this function.
506       The file names of these source(s)
507       may be extracted using the Python &str; function.
508
509       </para>
510       </listitem>
511
512       </varlistentry>
513
514       <varlistentry>
515       <term>target</term>
516
517       <listitem>
518       <para>
519
520       A list of Node objects representing
521       the target or targets to be built
522       by the command or other action
523       generated by this function.
524       The file names of these target(s)
525       may be extracted using the Python &str; function.
526
527       </para>
528       </listitem>
529
530       </varlistentry>
531
532       <varlistentry>
533       <term>env</term>
534
535       <listitem>
536       <para>
537
538       The &consenv; used for building the target(s).
539       The generator may use any of the
540       environment's construction variables
541       in any way to determine what command
542       or other action to return.
543
544       </para>
545       </listitem>
546
547       </varlistentry>
548
549       <varlistentry>
550       <term>for_signature</term>
551
552       <listitem>
553       <para>
554
555       A flag that specifies whether the
556       generator is being called to contribute to a build signature,
557       as opposed to actually executing the command.
558
559       <!-- XXX NEED MORE HERE, describe generators use in signatures -->
560
561       </para>
562       </listitem>
563
564       </varlistentry>
565
566     </variablelist>
567
568     <para>
569
570     The &generator; must return a
571     command string or other action that will be used to
572     build the specified target(s) from the specified source(s).
573
574     </para>
575
576     <para>
577
578     Once you've defined a &generator;,
579     you create a &Builder; to use it
580     by specifying the generator keyword argument
581     instead of <literal>action</literal>.
582
583     </para>
584
585     
586
587     <programlisting>
588        def generate_actions(source, target, env, for_signature):
589            return 'foobuild < %s > %s' % (source[0], target[0])
590        bld = Builder(generator = generate_actions,
591                      suffix = '.foo',
592                      src_suffix = '.input')
593        env = Environment(BUILDERS = {'Foo' : bld})
594        env.Foo('file')
595     </programlisting>
596
597     <screen>
598       % <userinput>scons -Q</userinput>
599       foobuild &lt; file.input &gt; file.foo
600     </screen>
601
602     <para>
603
604     Note that it's illegal to specify both an
605     <literal>action</literal>
606     and a
607     <literal>generator</literal>
608     for a &Builder;.
609
610     </para>
611
612   </section>
613
614   <section>
615   <title>Builders That Modify the Target or Source Lists Using an &Emitter;</title>
616
617     <para>
618
619     &SCons; supports the ability for a Builder to modify the
620     lists of target(s) from the specified source(s).
621     You do this by defining an &emitter; function
622     that takes as its arguments
623     the list of the targets passed to the builder,
624     the list of the sources passed to the builder,
625     and the construction environment.
626     The emitter function should return the modified
627     lists of targets that should be built
628     and sources from which the targets will be built.
629
630     </para>
631
632     <para>
633
634     For example, suppose you want to define a Builder
635     that always calls a <filename>foobuild</filename> program,
636     and you want to automatically add
637     a new target file named
638     <filename>new_target</filename>
639     and a new source file named
640     <filename>new_source</filename>
641     whenever it's called.
642     The &SConstruct; file might look like this:
643
644     </para>
645
646     
647
648     <programlisting>
649        def modify_targets(target, source, env):
650            target.append('new_target')
651            source.append('new_source')
652            return target, source
653        bld = Builder(action = 'foobuild $TARGETS - $SOURCES',
654                      suffix = '.foo',
655                      src_suffix = '.input',
656                      emitter = modify_targets)
657        env = Environment(BUILDERS = {'Foo' : bld})
658        env.Foo('file')
659     </programlisting>
660
661     <para>
662     
663     And would yield the following output:
664
665     </para>
666
667     <screen>
668       % <userinput>scons -Q</userinput>
669       foobuild file.foo new_target - file.input new_source
670     </screen>
671
672     <para>
673
674     One very flexible thing that you can do is
675     use a construction variable to specify
676     different emitter functions for different
677     construction variable.
678     To do this, specify a string
679     containing a construction variable
680     expansion as the emitter when you call
681     the &Builder; function,
682     and set that construction variable to
683     the desired emitter function
684     in different construction environments:
685
686     </para>
687
688     <programlisting>
689         bld = Builder(action = 'my_command $SOURCES &gt; $TARGET',
690                       suffix = '.foo',
691                       src_suffix = '.input',
692                       emitter = '$MY_EMITTER')
693         def modify1(target, source, env):
694             return target, source + ['modify1.in']
695         def modify2(target, source, env):
696             return target, source + ['modify2.in']
697         env1 = Environment(BUILDERS = {'Foo' : bld},
698                            MY_EMITTER = modify1)
699         env2 = Environment(BUILDERS = {'Foo' : bld},
700                            MY_EMITTER = modify2)
701         env1.Foo('file1')
702         env2.Foo('file2')
703         import os
704         env1['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd()
705         env2['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd()
706       
707
708     </programlisting>
709
710     <programlisting>
711       bld = Builder(action = 'my_command $SOURCES > $TARGET',
712                     suffix = '.foo',
713                     src_suffix = '.input',
714                     emitter = '$MY_EMITTER')
715       def modify1(target, source, env):
716           return target, source + ['modify1.in']
717       def modify2(target, source, env):
718           return target, source + ['modify2.in']
719       env1 = Environment(BUILDERS = {'Foo' : bld},
720                          MY_EMITTER = modify1)
721       env2 = Environment(BUILDERS = {'Foo' : bld},
722                          MY_EMITTER = modify2)
723       env1.Foo('file1')
724       env2.Foo('file2')
725       
726     </programlisting>
727
728     <para>
729
730     In this example, the <filename>modify1.in</filename>
731     and <filename>modify2.in</filename> files
732     get added to the source lists
733     of the different commands:
734
735     </para>
736
737     <screen>
738       % <userinput>scons -Q</userinput>
739       my_command file1.input modify1.in &gt; file1.foo
740       my_command file2.input modify2.in &gt; file2.foo
741     </screen>
742
743   </section>
744
745   <!--
746
747   <section>
748   <title>target_factor=, source_factory=</title>
749
750   </section>
751
752   <section>
753   <title>target_scanner=, source_scanner=</title>
754
755   </section>
756
757   <section>
758   <title>multi=</title>
759
760   </section>
761
762   <section>
763   <title>single_source=</title>
764
765   </section>
766
767   <section>
768   <title>src_builder=</title>
769
770   </section>
771
772   <section>
773   <title>ensure_suffix=</title>
774
775   </section>
776
777   -->
778
779   <section>
780   <title>Where To Put Your Custom Builders and Tools</title>
781
782     <para>
783
784     The <filename>site_scons</filename> directory gives you a place to
785     put Python modules you can import into your &SConscript; files
786     (<filename>site_scons</filename>),
787     add-on tools that can integrate into &SCons;
788     (<filename>site_scons/site_tools</filename>),
789     and a <filename>site_scons/site_init.py</filename> file that
790     gets read before any &SConstruct; or &SConscript; file,
791     allowing you to change &SCons;'s default behavior.
792
793     </para>
794
795     <para>
796
797     If you get a tool from somewhere (the &SCons; wiki or a third party,
798     for instance) and you'd like to use it in your project, the
799     <filename>site_scons</filename> dir is the simplest place to put it.
800     Tools come in two flavors; either a Python function that operates on
801     an &Environment; or a Python file containing two functions,
802     <function>exists()</function> and <function>generate()</function>.
803
804     </para>
805
806     <para>
807
808     A single-function Tool can just be included in your
809     <filename>site_scons/site_init.py</filename> file where it will be
810     parsed and made available for use.  For instance, you could have a
811     <filename>site_scons/site_init.py</filename> file like this:
812
813     </para>
814
815     <programlisting>
816         def TOOL_ADD_HEADER(env):
817            """A Tool to add a header from $HEADER to the source file"""
818            add_header = Builder(action=['echo "$HEADER" &gt; $TARGET',
819                                         'cat $SOURCE &gt;&gt; $TARGET'])
820            env.Append(BUILDERS = {'AddHeader' : add_header})
821            env['HEADER'] = '' # set default value
822     </programlisting>
823
824     <para>
825
826     and a &SConstruct; like this:
827
828     </para>
829
830     <programlisting>
831         # Use TOOL_ADD_HEADER from site_scons/site_init.py
832         env=Environment(tools=['default', TOOL_ADD_HEADER], HEADER="=====")
833         env.AddHeader('tgt', 'src')
834     </programlisting>
835
836     <para>
837
838       The <function>TOOL_ADD_HEADER</function> tool method will be
839       called to add the <function>AddHeader</function> tool to the
840       environment.
841
842     </para>
843
844     <!-- 
845     <scons_output example="site1" os="posix">
846        <scons_output_command>scons -Q</scons_output_command>
847     </scons_output>
848     -->
849
850     <para>
851       Similarly, a more full-fledged tool with
852       <function>exists()</function> and <function>generate()</function>
853       methods can be installed in
854       <filename>site_scons/site_tools/toolname.py</filename>.  Since
855       <filename>site_scons/site_tools</filename> is automatically added
856       to the head of the tool search path, any tool found there will be
857       available to all environments.  Furthermore, a tool found there
858       will override a built-in tool of the same name, so if you need to
859       change the behavior of a built-in tool, site_scons gives you the
860       hook you need.
861     </para>
862
863     <para>
864       Many people have a library of utility Python functions they'd like
865       to include in &SConscript;s; just put that module in
866       <filename>site_scons/my_utils.py</filename> or any valid Python module name of your
867       choice.  For instance you can do something like this in
868       <filename>site_scons/my_utils.py</filename> to add
869       <function>build_id</function> and <function>MakeWorkDir</function>
870       functions:
871     </para>
872       
873     <programlisting>
874         from SCons.Script import *   # for Execute and Mkdir
875         def build_id():
876            """Return a build ID (stub version)"""
877            return "100"
878         def MakeWorkDir(workdir):
879            """Create the specified dir immediately"""
880            Execute(Mkdir(workdir))
881     </programlisting>
882
883     <para>
884
885     And then in your &SConscript; or any sub-&SConscript; anywhere in
886     your build, you can import <filename>my_utils</filename> and use it:
887
888     </para>
889
890     <programlisting>
891         import my_utils
892         print "build_id=" + my_utils.build_id()
893         my_utils.MakeWorkDir('/tmp/work')
894     </programlisting>
895
896     <para>
897       Note that although you can put this library in
898       <filename>site_scons/site_init.py</filename>,
899       it is no better there than <filename>site_scons/my_utils.py</filename>
900       since you still have to import that module into your &SConscript;.
901       Also note that in order to refer to objects in the SCons namespace
902       such as &Environment; or &Mkdir; or &Execute; in any file other
903       than a &SConstruct; or &SConscript; you always need to do
904     </para>
905     <programlisting>
906         from SCons.Script import *
907     </programlisting>
908
909     <para>
910       This is true in modules in <filename>site_scons</filename> such as
911       <filename>site_scons/site_init.py</filename> as well.
912     </para>
913
914     <para>
915
916       If you have a machine-wide site dir you'd like to use instead of
917       <filename>./site_scons</filename>, use the
918       <literal>--site-dir</literal> option to point to your dir.
919       <filename>site_init.py</filename> and
920       <filename>site_tools</filename> will be located under that dir.
921       To avoid using a <filename>site_scons</filename> dir at all, even
922       if it exists, use the <literal>--no-site-dir</literal> option.
923
924     </para>
925
926   </section>
927
928
929   <!--
930
931   <section>
932   <title>Builders That Use Other Builders</title>
933
934     <para>
935
936     XXX para
937
938     </para>
939
940     <scons_example name="ex8">
941        <file name="SConstruct" printme="1">
942        env = Environment()
943        #env.SourceCode('.', env.BitKeeper('my_command'))
944        env.Program('hello.c')
945        </file>
946        <file name="hello.c">
947        hello.c
948        </file>
949     </scons_example>
950
951     <scons_output example="ex8">
952       <scons_output_command>scons -Q</scons_output_command>
953     </scons_output>
954
955   </section>
956
957   -->