Branch for User's Guide updates.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 21 May 2003 13:01:13 +0000 (13:01 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 21 May 2003 13:01:13 +0000 (13:01 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@692 fdb21ef1-2011-0410-befe-b5e4ea1792b1

28 files changed:
SConstruct
doc/scons.mod
doc/user/actions.sgml
doc/user/ant.sgml [new file with mode: 0644]
doc/user/builders-built-in.sgml [new file with mode: 0644]
doc/user/builders-commands.sgml [moved from doc/user/command.sgml with 75% similarity]
doc/user/builders-writing.sgml [moved from doc/user/builders.sgml with 69% similarity]
doc/user/caching.sgml
doc/user/cons.sgml
doc/user/default.sgml
doc/user/depends.sgml
doc/user/environments.sgml
doc/user/errors.sgml
doc/user/example.sgml
doc/user/hierarchy.sgml
doc/user/install.sgml
doc/user/libraries.sgml [new file with mode: 0644]
doc/user/main.sgml
doc/user/make.sgml
doc/user/preface.sgml
doc/user/repositories.sgml
doc/user/run.sgml
doc/user/scanners.sgml
doc/user/separate.sgml
doc/user/simple.sgml
doc/user/sourcecode.sgml
doc/user/troubleshoot.sgml
doc/user/variants.sgml

index 87eafb04175a8e9edcac6c53e74e741e675da83e..b1af6918d7d47dc6591fe9f56a8f4cbc51a7ab7b 100644 (file)
@@ -865,7 +865,10 @@ if change:
     for f in pf + cf:
         u[f] = 1
     for f in df:
-        del u[f]
+        try:
+            del u[f]
+        except KeyError:
+            pass
     sfiles = filter(lambda x: x[-9:] != '.aeignore' and x[-9:] != '.sconsign',
                     u.keys())
 
index 32283c31d2ca278a4e16b29dc9f0a5a90bdd05fa..f9deaa1e276286fa253d7f41d8ba7c3e826fefe7 100644 (file)
 
 -->
 
+<!ENTITY Aegis "<application>Aegis</application>">
 <!ENTITY Autoconf "<application>Autoconf</application>">
 <!ENTITY Cons "<application>Cons</application>">
 <!ENTITY gcc "<application>gcc</application>">
+<!ENTITY Jam "<application>Jam</application>">
 <!ENTITY Make "<application>Make</application>">
 <!ENTITY Makepp "<application>Make++</application>">
+<!ENTITY ranlib "<application>ranlib</application>">
 <!ENTITY SCons "<application>SCons</application>">
 <!ENTITY scons "<application>scons</application>">
 <!ENTITY ScCons "<application>ScCons</application>">
+<!ENTITY tar "<application>tar</application>">
+<!ENTITY touch "<application>touch</application>">
+<!ENTITY zip "<application>zip</application>">
 
 
 <!--
 
 <!--
 
-  File names.
+  File and directory names.
 
 -->
 
+<!ENTITY build "<filename>build</filename>">
 <!ENTITY Makefile "<filename>Makefile</filename>">
 <!ENTITY Makefiles "<filename>Makefiles</filename>">
 <!ENTITY SConscript "<filename>SConscript</filename>">
@@ -68,6 +75,7 @@
 <!ENTITY Sconstruct "<filename>Sconstruct</filename>">
 <!ENTITY sconstruct "<filename>sconstruct</filename>">
 <!ENTITY sconsign "<filename>.sconsign</filename>">
+<!ENTITY src "<filename>src</filename>">
 
 
 
 <!ENTITY Repository "<function>Repository</function>">
 <!ENTITY RuleSet "<function>RuleSet</function>">
 <!ENTITY Salt "<function>Salt</function>">
+<!ENTITY SetBuildSignatureType "<function>SetBuildSignatureType</function>">
+<!ENTITY SetContentSignatureType "<function>SetContentSignatureType</function>">
 <!ENTITY SourceSignature "<function>SourceSignature</function>">
+<!ENTITY SourceSignatures "<function>SourceSignatures</function>">
 <!ENTITY Split "<function>Split</function>">
+<!ENTITY TargetSignatures "<function>TargetSignatures</function>">
 <!ENTITY Task "<function>Task</function>">
 
+<!ENTITY str "<function>str</function>">
+<!ENTITY zipfile "<function>zipfile</function>">
+
 <!-- Obsolete, but referenced in old documents.  -->
 <!ENTITY Cache "<function>Cache</function>">
 
 <!ENTITY BUILDERS "<varname>BUILDERS</varname>">
 <!ENTITY SCANNERMAP "<varname>SCANNERMAP</varname>">
 <!ENTITY SCANNERS "<varname>SCANNERS</varname>">
+<!ENTITY TARFLAGS "<varname>TARFLAGS</varname>">
+<!ENTITY TARSUFFIX "<varname>TARSUFFIX</varname>">
 
 
 
 <!ENTITY CC "<varname>CC</varname>">
 <!ENTITY CCFLAGS "<varname>CCFLAGS</varname>">
 <!ENTITY LIBPATH "<varname>LIBPATH</varname>">
+<!ENTITY LIBS "<varname>LIBS</varname>">
 <!ENTITY PYTHONPATH "<varname>PYTHONPATH</varname>">
 <!ENTITY SCONSFLAGS "<varname>SCONSFLAGS</varname>">
 
 
 
+<!--
+
+  Function and method arguments.
+
+-->
+
+<!ENTITY build_dir "<varname>build_dir</varname>">
+<!ENTITY source "<varname>source</varname>">
+<!ENTITY target "<varname>target</varname>">
+
+
+
 <!--
 
   Builder and Scanner objects.
 <!ENTITY BuildDir "<function>BuildDir</function>">
 <!ENTITY CFile "<function>CFile</function>">
 <!ENTITY CXXFile "<function>CXXFile</function>">
+<!ENTITY DVI "<function>DVI</function>">
+<!ENTITY Jar "<function>Jar</function>">
+<!ENTITY Java "<function>Java</function>">
+<!ENTITY JavaH "<function>JavaH</function>">
 <!ENTITY Library "<function>Library</function>">
 <!ENTITY Object "<function>Object</function>">
 <!ENTITY PCH "<function>PCH</function>">
 <!ENTITY PostScript "<function>PostScript</function>">
 <!ENTITY Program "<function>Program</function>">
 <!ENTITY RES "<function>RES</function>">
+<!ENTITY RMIC "<function>RMIC</function>">
 <!ENTITY SharedLibrary "<function>SharedLibrary</function>">
 <!ENTITY SharedObject "<function>SharedObject</function>">
 <!ENTITY StaticLibrary "<function>StaticLibrary</function>">
 <!ENTITY StaticObject "<function>StaticObject</function>">
+<!ENTITY Tar "<function>Tar</function>">
+<!ENTITY Zip "<function>Zip</function>">
 
 <!-- Obsolete, but referenced in old documents.  -->
 <!ENTITY MakeBuilder "<function>Make</function>">
 
 -->
 
+<!ENTITY buildfunc "<literal>builder function</literal>">
+
 <!ENTITY ConsEnv "<literal>Construction Environment</literal>">
 <!ENTITY ConsEnvs "<literal>Construction Environments</literal>">
 <!ENTITY Consenv "<literal>Construction environment</literal>">
 
 <!ENTITY Dictionary "<literal>Dictionary</literal>">
 
+<!ENTITY Emitter "<literal>Emitter</literal>">
+<!ENTITY emitter "<literal>emitter</literal>">
+<!ENTITY Generator "<literal>Generator</literal>">
+<!ENTITY generator "<literal>generator</literal>">
+
+<!ENTITY signature "<literal>signature</literal>">
+<!ENTITY buildsignature "<literal>build signature</literal>">
+
 <!--
 
   File and program names used in examples.
 
 -->
 
+<!ENTITY common1_c "<application>common1.c</application>">
+<!ENTITY common2_c "<application>common2.c</application>">
 <!ENTITY goodbye "<application>goodbye</application>">
 <!ENTITY hello "<application>hello</application>">
 <!ENTITY hello_c "<filename>hello.c</filename>">
+<!ENTITY hello_exe "<filename>hello.exe</filename>">
 <!ENTITY hello_h "<filename>hello.h</filename>">
+<!ENTITY hello_o "<filename>hello.o</filename>">
+<!ENTITY prog "<filename>prog</filename>">
+<!ENTITY prog_c "<filename>prog.c</filename>">
+<!ENTITY prog_exe "<filename>prog.exe</filename>">
 <!ENTITY stdio_h "<filename>stdio.h</filename>">
index 447b331e3177983d2334ccf65351be98db6c6d6d..c35ccdda6b43c9d86ee9ccac554f64912e1e9851 100644 (file)
@@ -224,16 +224,16 @@ solutions to the above limitations.
 
  <para>
 
-   X
+   XXX
 
  </para>
 
  <section>
- <title>X</title>
+ <title>XXX</title>
 
    <para>
 
-   X
+   XXX
 
    </para>
 
diff --git a/doc/user/ant.sgml b/doc/user/ant.sgml
new file mode 100644 (file)
index 0000000..f83ab63
--- /dev/null
@@ -0,0 +1,41 @@
+<!--
+
+  Copyright (c) 2001, 2002, 2003 Steven Knight
+
+  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.
+
+-->
+
+ <para>
+
+   XXX
+
+ </para>
+
+ <section>
+ <title>XXX</title>
+
+   <para>
+
+   XXX
+
+   </para>
+
+ </section>
diff --git a/doc/user/builders-built-in.sgml b/doc/user/builders-built-in.sgml
new file mode 100644 (file)
index 0000000..bb29cc4
--- /dev/null
@@ -0,0 +1,628 @@
+<!--
+
+  Copyright (c) 2001, 2002, 2003 Steven Knight
+
+  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.
+
+-->
+
+  <para>
+
+  &SCons; provides the ability to build a lot of different
+  types of files right "out of the box."
+  So far, we've been using &SCons;' ability to build
+  programs, objects and libraries to
+  illustrate much of the underlying functionality of &SCons;
+  This section will describe all of the different
+  types of files that you can build with &SCons;,
+  and the built-in &Builder; objects used to build them.
+
+  </para>
+
+  <section>
+  <title>Programs:  the &Program; Builder</title>
+
+    <para>
+
+    As we've seen, the &Program; Builder
+    is used to build an executable program.
+    The &source; argument is one or more
+    source-code files or object files,
+    and the &target; argument is the
+    name of the executable program name to be created.
+    For example:
+
+    </para>
+
+    <programlisting>
+      env = Environment()
+      env.Program('prog', 'file1.o')
+    </programlisting>
+
+    <para>
+
+    Will create the &prog;
+    executable on a POSIX system,
+    the &prog_exe; executable on a Windows system.
+
+    </para>
+
+    <para>
+
+    The target file's prefix and suffix may be omitted,
+    and the values from the
+    $PROGPREFIX
+    and
+    $PROGSUFFIX
+    construction variables
+    will be appended appropriately.
+    For example:
+
+    </para>
+
+    <programlisting>
+      env = Environment(PROGPREFIX='my', PROGSUFFIX='.xxx')
+      env.Program('prog', ['file1.o', 'file2.o'])
+    </programlisting>
+
+    <para>
+
+    Will create a program named
+    <filename>myprog.xxx</filename>
+    regardless of the system on which it is run.
+
+    </para>
+
+    <para>
+
+    If you omit the &target;,
+    the base of the first input
+    file name specified
+    because the base of the target
+    program created.
+    For example:
+
+    </para>
+
+    <programlisting>
+      env = Environment()
+      env.Program(['hello.c', 'goodbye.c'])
+    </programlisting>
+
+    <para>
+
+    Will create the &hello;
+    executable on a POSIX system,
+    the &hello_exe; executable on a Windows system.
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Object-File Builders</title>
+
+    <para>
+
+    &SCons; provides separate Builder objects
+    to create both static and shared object files.
+
+    </para>
+
+    <section>
+    <title>The &StaticObject; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>The &SharedObject; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>The &Object; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <para>
+
+      Creates a static object file.
+
+      </para>
+
+    </section>
+
+  </section>
+
+  <section>
+  <title>Library Builders</title>
+
+    <para>
+
+    &SCons; provides separate Builder objects
+    to create both static and shared libraries.
+
+    </para>
+
+    <section>
+    <title>The &StaticLibrary; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>The &SharedLibrary; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+    </section>
+
+    <section>
+    <title>The &Library; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+      <para>
+
+      Creates a static library file.
+
+      </para>
+
+    </section>
+
+  </section>
+
+  <section>
+  <title>Pre-Compiled Headers:  the &PCH; Builder</title>
+
+    <para>
+
+    XXX
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Microsoft Visual C++ Resource Files: the &RES; Builder</title>
+
+    <para>
+
+    XXX
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Source Files</title>
+
+    <para>
+
+    By default
+    &SCons; supports two Builder objects
+    that know how to build source files
+    from other input files.
+
+    </para>
+
+    <section>
+    <title>The &CFile; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>The &CXXFile; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+  </section>
+
+  <section>
+  <title>Documents</title>
+
+    <para>
+
+    &SCons; provides a number of Builder objects
+    for creating different types of documents.
+
+    </para>
+
+    <section>
+    <title>The &DVI; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>The &PDF; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+    </section>
+
+    <section>
+    <title>The &PostScript; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+  </section>
+
+  <section>
+  <title>Archives</title>
+
+    <para>
+
+    &SCons; provides Builder objects
+    for creating two different types of archive files.
+
+    </para>
+
+    <section>
+    <title>The &Tar; Builder</title>
+
+      <para>
+
+      The &Tar; Builder object uses the &tar;
+      utility to create archives of files
+      and/or directory trees:
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Tar('out1.tar', ['file1', 'file2'])
+        env.Tar('out2', 'directory')
+      </programlisting>
+
+      <literallayout>
+        % <userinput>scons .</userinput>
+        tar -c -f out1.tar file1 file2
+        tar -c -f out2.tar directory
+      </literallayout>
+
+      <para>
+
+      One common requirement when creating a &tar; archive
+      is to create a compressed archive using the
+      <option>-z</option> option.
+      This is easily handled by specifying
+      the value of the &TARFLAGS; variable
+      when you create the construction environment.
+      Note, however, that the <option>-c</option> used to
+      to instruct &tar; to create the archive
+      is part of the default value of &TARFLAGS;,
+      so you need to set it both options:
+
+      </para>
+
+      <programlisting>
+        env = Environment(TARFLAGS = '-c -z')
+        env.Tar('out.tar.gz', 'directory')
+      </programlisting>
+
+      <literallayout>
+        % <userinput>scons .</userinput>
+        tar -c -z -f out.tar.gz directory
+      </literallayout>
+
+      <para>
+
+      you may also wish to set the value of the
+      &TARSUFFIX; construction variable
+      to your desired suffix for compress &tar; archives,
+      so that &SCons; can append it to the target file name
+      without your having to specify it explicitly:
+
+      </para>
+
+      <programlisting>
+        env = Environment(TARFLAGS = '-c -z',
+                          TARSUFFIX = '.tgz')
+        env.Tar('out', 'directory')
+      </programlisting>
+
+      <literallayout>
+        % <userinput>scons .</userinput>
+        tar -c -z -f out.tgz directory
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>The &Zip; Builder</title>
+
+      <para>
+
+      The &Zip; Builder object creates archives of files
+      and/or directory trees in the ZIP file format.
+      Python versions 1.6 or later
+      contain an internal &zipfile; module
+      that &SCons; will use.
+      In this case, given the following
+      &SConstruct; file:
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Zip('out', ['file1', 'file2'])
+      </programlisting>
+
+      <para>
+
+      Your output will reflect the fact
+      that an internal Python function
+      is being used to create the output ZIP archive:
+
+      </para>
+
+      <literallayout>
+        % <userinput>scons .</userinput>
+        zip("out.zip", ["file1", "file2"])
+      </literallayout>
+
+      <para>
+
+      If you're using Python version 1.5.2 to run &SCons;,
+      then &SCons; will try to use an external
+      &zip; program as follows:
+
+      </para>
+
+      <literallayout>
+        % <userinput>scons .</userinput>
+        zip /home/my/project/zip.out file1 file2
+      </literallayout>
+
+    </section>
+
+  </section>
+
+  <section>
+  <title>Java</title>
+
+    <para>
+
+    &SCons; provides Builder objects
+    for creating various types of Java output files.
+
+    </para>
+
+    <section>
+    <title>Building Class Files:  the &Java; Builder</title>
+
+      <para>
+
+      The &Java; builder takes one or more input
+      <filename>.java</filename> files
+      and turns them into one or more
+      <filename>.class</filename> files
+      Unlike most builders, however,
+      the &Java; builder takes
+      target and source <emphasis>directories</emphasis>,
+      not files, as input.
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Java(target = 'classes', source = 'src')
+      </programlisting>
+
+      <para>
+
+      The &Java; builder will then
+      search the specified source directory
+      tree for all <filename>.java</filename> files,
+      and pass any out-of-date
+
+      </para>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>The &Jar; Builder</title>
+
+      <para>
+
+      The &Jar; builder object XXX
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Java(target = 'classes', source = 'src')
+        env.Jar(target = '', source = 'classes')
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>Building C header and stub files:  the &JavaH; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+    <section>
+    <title>Building RMI stub and skeleton class files:  the &RMIC; Builder</title>
+
+      <para>
+
+      XXX
+
+      </para>
+
+      <programlisting>
+        XXX
+      </programlisting>
+
+      <literallayout>
+        XXX
+      </literallayout>
+
+    </section>
+
+  </section>
similarity index 75%
rename from doc/user/command.sgml
rename to doc/user/builders-commands.sgml
index 945c6565b6a9d8bba107eff41ba758254dc6fd38..e21f6d0179056753064661061ce0a9015bfe29f5 100644 (file)
 
 -->
 
-<!--
+  <!--
 
-=head2 The C<Command> method
+  =head2 The C<Command> method
 
 
-The C<Command> method is called as follows:
+  The C<Command> method is called as follows:
 
-  Command $env <target>, <inputs>, <build action>;
+    Command $env <target>, <inputs>, <build action>;
 
-The target is made dependent upon the list of input files specified, and the
-inputs must be built successfully or Cons will not attempt to build the
-target.
+  The target is made dependent upon the list of input files specified, and the
+  inputs must be built successfully or Cons will not attempt to build the
+  target.
 
-To specify a command with multiple targets, you can specify a reference to a
-list of targets. In Perl, a list reference can be created by enclosing a
-list in square brackets. Hence the following command:
+  To specify a command with multiple targets, you can specify a reference to a
+  list of targets. In Perl, a list reference can be created by enclosing a
+  list in square brackets. Hence the following command:
 
-  Command $env ['foo.h', 'foo.c'], 'foo.template', q(
-       gen %1
-  );
+    Command $env ['foo.h', 'foo.c'], 'foo.template', q(
+       gen %1
+    );
 
-could be used in a case where the command C<gen> creates two files, both
-F<foo.h> and F<foo.c>.
+  could be used in a case where the command C<gen> creates two files, both
+  F<foo.h> and F<foo.c>.
 
--->
+  -->
 
   <para>
 
   Creating a &Builder; and attaching it to a &consenv;
   allows for a lot of flexibility when you
-  want to re-use the same actions
+  want to re-use actions
   to build multiple files of the same type.
   This can, however, be cumbersome
   if you only need to execute one specific command
-  to build a single file (or single group of files).
+  to build a single file (or group of files).
   For these situations, &SCons; supports a
   &Command; &Builder; that arranges
   for a specific action to be executed
@@ -90,7 +90,7 @@ F<foo.h> and F<foo.c>.
 
   <para>
 
-  Note that the action you
+  Note that the action you 
 
   </para>
 
similarity index 69%
rename from doc/user/builders.sgml
rename to doc/user/builders-writing.sgml
index c1b426943da5c797fad966e5b341eed39adea650..27a48b97ef34f5015cd1be42eb1a36d404595cb3 100644 (file)
@@ -97,20 +97,24 @@ This functionality could be invoked as in the following example:
 
   <para>
 
-    &SCons; provides many useful methods
-    for building common software products:
-    programs, libraries, documents.
-    Frequently, however, you 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.
+  Although &SCons; provides many useful methods
+  for building common software products:
+  programs, libraries, documents.
+  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 the mechanisms described in this section.)
 
   </para>
 
   <section>
-  <title>Builders That Execute External Commands</title>
+  <title>Writing Builders That Execute External Commands</title>
 
     <para>
 
@@ -128,6 +132,14 @@ This functionality could be invoked as in the following example:
        bld = Builder(action = 'foobuild < $TARGET > $SOURCE')
     </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>
@@ -135,17 +147,17 @@ This functionality could be invoked as in the following example:
 
     <para>
 
-    A &Builder; object by itself, though,
-    isn't useful until it's attached to a &consenv;
+    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 &BUILDERS;
     &consvar; in an environment.
     The &BUILDERS; variable is a Python dictionary
-    that maps the names by which you want to call various &Builder;
-    to the &Builder; objects themselves.
+    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 defined by the name
+    &Builder; we just defined by the name
     <function>Foo</function>,
     our &SConstruct; file might look like:
 
@@ -154,6 +166,16 @@ This functionality could be invoked as in the following example:
     <programlisting>
        bld = Builder(action = 'foobuild < $TARGET > $SOURCE')
        env = Environment(BUILDERS = {'Foo' : bld})
+    </programlisting>
+
+    <para>
+
+    With the &Builder; so attached to our &consenv;
+    we can now actually call it like so:
+
+    </para>
+
+    <programlisting>
        env.Foo('file.foo', 'file.input')
     </programlisting>
 
@@ -310,6 +332,7 @@ This functionality could be invoked as in the following example:
     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>
 
@@ -321,8 +344,70 @@ This functionality could be invoked as in the following example:
 
     <para>
 
-    XXX explain the function
-    XXX define the arguments
+    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; funcion.
+
+      </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; funcion.
+
+      </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>
 
@@ -367,17 +452,120 @@ This functionality could be invoked as in the following example:
   </section>
 
   <section>
-  <title>Builders That Generate Actions</title>
+  <title>Builders That Create Actions Using a &Generator;</title>
 
     <para>
 
-    X
+    &SCons; Builder objects can create an action "on the fly"
+    by using a function called a &generator;.
+    This provides a great deal of flexibility XXX
+    A &generator; looks like:
 
     </para>
 
     <programlisting>
-       def generate_actions(XXX):
+       def generate_actions(source, target, env, for_signature):
            return XXX
+    </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; funcion.
+
+      </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; funcion.
+
+      </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
+
+      </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>
+
+    <programlisting>
        bld = Builder(generator = generate_actions,
                      suffix = '.foo',
                      src_suffix = '.input')
@@ -403,11 +591,12 @@ This functionality could be invoked as in the following example:
   </section>
 
   <section>
-  <title>Builders That Modify the Target List</title>
+  <title>Builders That Modify the Target or Source Lists Using an &Emitter;</title>
 
     <para>
 
-    X
+    &SCons; supports the ability for a Builder to modify the
+    lists of target(s) from the specified source(s).
 
     </para>
 
@@ -451,7 +640,7 @@ This functionality could be invoked as in the following example:
 
     <para>
 
-    X
+    XXX
 
     </para>
 
index ed72c1e000fab038741aca20de07056b59ad2597..3d9158efcf529278b085b62cee228ef5beae6363 100644 (file)
@@ -85,6 +85,8 @@
       cc -c hello.c -o hello.o
       cc -o hello hello.o
       % <userinput>scons -c</userinput>
+      Removed hello.o
+      Removed hello
       % <userinput>scons</userinput>
       Retrieved `hello.o' from cache
       Retrieved `hello' from cache
index 448777f1d175d658030520276bbdc59c6bb1b986..f83ab6399791fdefbc6cabb832d886ad4c4a2e32 100644 (file)
 
  <para>
 
-   X
+   XXX
 
  </para>
 
  <section>
- <title>X</title>
+ <title>XXX</title>
 
    <para>
 
-   X
+   XXX
 
    </para>
 
index 981ac426dd6de1ac5e6fb461ce06afdde807bf8c..f44719f9fc57bb0f5e9cb3fb15b686d5e4fcd321 100644 (file)
@@ -87,7 +87,7 @@ default list.
    This &SConstruct; file knows how to build two programs,
    &hello; and &goodbye;,
    but only builds the
-   &hello program by default:
+   &hello; program by default:
 
    </para>
 
index bc466181615f752205b23e26d291dd0eab9a1553..fbbb54aeb3b06e7c9b8a060227276101c07462d7 100644 (file)
@@ -25,8 +25,6 @@
 
 <!--
 
-
-
 =head2 The C<Salt> method
 
 The C<Salt> method adds a constant value to the signature calculation
@@ -97,58 +95,282 @@ operating system on which the build is performed (as reported by C<uname
   </para>
 
   <section>
-  <title>MD5 Signatures</title>
+  <title>Source File Signatures</title>
 
     <para>
 
-    &SCons; keeps track of whether a file has changed
-    based on the file's contents,
-    not the modification time.
-    This means that you may be surprised by the
-    behavior of &SCons; if you are used to the
-    &Make; convention of forcing
-    a rebuild by updating the file's
-    modification time like so:
+    The other side of avoiding unnecessary rebuilds
+    is the fundamental build tool behavior
+    of <emphasis>rebuilding</emphasis>
+    things when a source file changes.
+    &SCons; keeps track of this through a
+    &signature; for each source file,
+    and allows you to configure
+    whether you want to use the source
+    file contents or the modification time (timestamp)
+    as the signature.
 
     </para>
 
-    <literallayout>
-       % <userinput>scons hello</userinput>
-       cc -c hello.c -o hello.o
-       cc -o hello hello.o
-       % <userinput>touch hello.c</userinput>
-       % <userinput>scons hello</userinput>
-       scons: `hello' is up to date.
-       %
-    </literallayout>
-
-    <para>
-
-    This avoids unnecessary rebuilds when,
-    for example, someone rewrites the
-    contents of a file without making a change.
-    But if the contents of the file really change,
-    then &SCons; detects the change
-    and rebuilds the program as required:
+    <section>
+    <title>MD5 Signatures</title>
+
+      <para>
+
+      By default,
+      &SCons; keeps track of whether a source file has changed
+      based on the file's contents,
+      not the modification time.
+      This means that you may be surprised by the
+      default &SCons; behavior if you are used to the
+      &Make; convention of forcing
+      a rebuild by updating the file's modification time
+      (using the &touch; command, for example):
+
+      </para>
+
+      <literallayout>
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         % <userinput>touch hello.c</userinput>
+         % <userinput>scons hello</userinput>
+         scons: `hello' is up to date.
+         %
+      </literallayout>
+
+      <para>
+
+      Even though the file's modification time has changed,
+      &SCons; realizes that the contents of the
+      &hello_c; file have <emphasis>not</emphasis> changed,
+      and therefore that the &hello; program
+      need not be rebuilt.
+      This avoids unnecessary rebuilds when,
+      for example, someone rewrites the
+      contents of a file without making a change.
+      But if the contents of the file really do change,
+      then &SCons; detects the change
+      and rebuilds the program as required:
+
+      </para>
+
+      <literallayout>
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         % <userinput>edit hello.c</userinput>
+             [CHANGE THE CONTENTS OF hello.c]
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         %
+      </literallayout>
+
+      <para>
+
+      Note that you can, if you wish,
+      specify this default behavior
+      (MD5 signatures) explicitly
+      using the &SourceSignatures; function as follows:
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Program('hello.c')
+        SourceSignatures('MD5')
+      </programlisting>
+
+    </section>
+
+    <section>
+    <title>Time Stamps</title>
+
+      <para>
+
+      If you prefer, you can
+      configure &SCons; to use the modification time
+      of source files,
+      not the file contents,
+      when deciding if something needs to be rebuilt.
+      To do this, call the &SourceSignatures;
+      function as follows:
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Program('hello.c')
+        SourceSignatures('timestamp')
+      </programlisting>
+
+      <para>
+
+      This makes &SCons; act like &Make;
+      when a file's modification time is updated
+      (using the &touch; command, for example):
+
+      </para>
+
+      <literallayout>
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         % <userinput>touch hello.c</userinput>
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         %
+      </literallayout>
+
+    </section>
 
-    </para>
+  </section>
 
-    <literallayout>
-       % <userinput>scons hello</userinput>
-       cc -c hello.c -o hello.o
-       cc -o hello hello.o
-       % <userinput>edit hello.c</userinput>
+  <section>
+  <title>Target File Signatures</title>
+
+    <section>
+    <title>Build Signatures</title>
+
+      <para>
+
+      We've already seen how modifying a source file
+      will cause not only its direct target file to be rebuilt,
+      but also the target file(s)
+      that depend on that direct target file.
+      In our example,
+      changing the contents of &hello_c; cause
+      the &hello_o; file to be rebuilt,
+      which in turn causes the
+      &hello; program to be rebuilt:
+
+      </para>
+
+      <literallayout>
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         % <userinput>edit hello.c</userinput>
            [CHANGE THE CONTENTS OF hello.c]
-       % <userinput>scons hello</userinput>
-       cc -c hello.c -o hello.o
-       cc -o hello hello.o
-       %
-    </literallayout>
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         %
+      </literallayout>
+
+      <para>
+
+      What's not obvious, though,
+      is that &SCons; internally handles the signature of
+      the target file(s)
+      (&hello_o; in the above example)
+      differently from the signature of the source file
+      (&hello_c;).
+      By default,
+      &SCons; tracks whether a target file must be rebuilt
+      by using a &buildsignature;
+      that consists of the combined
+      signatures of all the files
+      that go into making the target file.
+      This is efficient because
+      the accumulated signatures
+      actually give &SCons; all of the
+      information it needs
+      to decide if the target file is out of date.
+
+      </para>
+
+      <para>
+
+      If you wish, you can
+      specify this default behavior
+      (build signatures) explicitly
+      using the &TargetSignatures; function:
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Program('hello.c')
+        TargetSignatures('build')
+      </programlisting>
+
+    </section>
+
+    <section>
+    <title>File Contents</title>
+
+      <para>
+
+      Sometimes, however,
+      a source file can be changed
+      in such a way that the
+      target file(s) built from it
+      will be rebuilt
+      exactly the same as the last time.
+      If so, then any target files
+      that depend on built-but-not-changed target
+      file actually need not be rebuilt.
+      You can have &SCons;
+      realize that a dependent target file
+      need not be rebuilt in this situation
+      using the &TargetSignatures; function as follows:
+
+      </para>
+
+      <programlisting>
+        env = Environment()
+        env.Program('hello.c')
+        TargetSignatures('content')
+      </programlisting>
+
+      <para>
+
+      So if, for example,
+      a user were to only change a comment in a C file,
+      then the rebuilt &hello_o; file
+      would be exactly the same as the one previously built
+      (assuming the compiler doesn't put any build-specific
+      information in the object file).
+      &SCons; would then realize that it would not
+      need to rebuild the &hello; program as follows:
+
+      </para>
+
+      <literallayout>
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         cc -o hello hello.o
+         % <userinput>edit hello.c</userinput>
+           [CHANGE A COMMENT IN hello.c]
+         % <userinput>scons hello</userinput>
+         cc -c hello.c -o hello.o
+         %
+      </literallayout>
+
+      <para>
+
+      In essence, &SCons; has
+      "short-circuited" any dependent builds
+      when it realizes that a target file
+      has been rebuilt to exactly the same file as the last build.
+      So configured,
+      &SCons; does take some extra processing time
+      to scan the contents of the target (&hello_o;) file,
+      but this may save time
+      if the rebuild that was avoided
+      would have been very time-consuming and expensive.
+
+      </para>
+
+    </section>
 
   </section>
 
   <section>
-  <title>Implicit Dependencies</title>
+  <title>Implicit Dependencies:  The &CPPPATH; Construction Variable</title>
 
     <para>
 
@@ -188,7 +410,7 @@ operating system on which the build is performed (as reported by C<uname
     </para>
 
     <programlisting>
-       env = Environment(CPPPATH = '.')  XXX IS CPPPATH NECESSARY?
+       env = Environment(CPPPATH = '.')
        hello = env.Program('hello.c')
     </programlisting>
 
@@ -199,27 +421,37 @@ operating system on which the build is performed (as reported by C<uname
     (<literal>'.'</literal>)
     for any files included by C source files
     (<filename>.c</filename> or <filename>.h</filename> files).
-    With this assignment in the &SConstruct file:
+    With this assignment in the &SConstruct; file:
 
     </para>
 
     <literallayout>
        % <userinput>scons hello</userinput>
-       cc -c hello.c -o hello.o
+       cc -I. -c hello.c -o hello.o
        cc -o hello hello.o
        % <userinput>scons hello</userinput>
        scons: `hello' is up to date.
        % <userinput>edit hello.h</userinput>
            [CHANGE THE CONTENTS OF hello.h]
        % <userinput>scons hello</userinput>
-       cc -c hello.c -o hello.o
+       cc -I. -c hello.c -o hello.o
        cc -o hello hello.o
        %
     </literallayout>
 
     <para>
 
-    &SCons; knows that the &hello;
+    First, notice that &SCons;
+    added the <literal>-I.</literal> argument
+    from the &CPPPATH; variable
+    so that the compilation would find the
+    &hello_h; file in the local directory.
+
+    </para>
+
+    <para>
+
+    Second, realize that &SCons; knows that the &hello;
     program must be rebuilt
     because it scans the contents of
     the &hello_c; file
@@ -236,6 +468,49 @@ operating system on which the build is performed (as reported by C<uname
 
     </para>
 
+    <para>
+
+    Like the &LIBPATH; variable,
+    the &CPPPATH; variable
+    may be a list of directories,
+    or a string separated by
+    the system-specific path separate character
+    (':' on POSIX/Linux, ';' on Windows).
+    Either way, &SCons; creates the
+    right command-line options
+    so that the followin example:
+
+    </para>
+
+    <programlisting>
+       env = Environment(CPPPATH = ['include', '/home/project/inc'])
+       hello = env.Program('hello.c')
+    </programlisting>
+
+    <para>
+
+    Will look like this on POSIX or Linux:
+
+    </para>
+
+    <literallayout>
+       % <userinput>scons hello</userinput>
+       cc -Iinclude -I/home/project/inc -c hello.c -o hello.o
+       cc -o hello hello.o
+    </literallayout>
+
+    <para>
+
+    And like this on Windows:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons hello</userinput>
+      cl /Iinclude /I\home\project\inc /Fohello.obj hello.c
+      link /OUT:hello.exe hello.obj
+    </literallayout>
+
   </section>
 
   <section>
@@ -246,7 +521,7 @@ operating system on which the build is performed (as reported by C<uname
     Scanning each file for <literal>#include</literal> lines
     does take some extra processing time.
     When you're doing a full build of a large system,
-    the scanning time is a small percentage
+    the scanning time is usually a very small percentage
     of the overall time spent on the build.
     You're most likely to notice the scanning time,
     however, when you rebuild all or part of a large system:
@@ -406,32 +681,10 @@ operating system on which the build is performed (as reported by C<uname
 
     <para>
 
-    X
+    XXX
 
     </para>
 
   </section>
 
   -->
-
-  <section>
-  <title>Time Stamps</title>
-
-    <para>
-
-    X
-
-    </para>
-
-  </section>
-
-  <section>
-  <title>The &SourceSignature; Method</title>
-
-    <para>
-
-    X
-
-    </para>
-
-  </section>
index 77d9c6b970caf4a59240e6703d99eb53435a25dc..d3c3b0cd43a63107fb2239465060540442f408fb 100644 (file)
@@ -452,18 +452,20 @@ environment undisturbed.
 
    <para>
 
-   So far, we've always created a &consenv; named
+   So far,
+   all of our examples have
+   created a single &consenv; named
    <literal>env</literal>.
    <literal>env</literal>, however,
    is simply a Python variable name,
-   and you can use any other variable name that we like.
+   and you can use any other variable name that you like.
    For example:
 
    </para>
 
    <programlisting>
       my_env = Environment(CC = 'gcc',
-                        CCFLAGS = '-O2')
+                           CCFLAGS = '-O2')
 
       my_env.Program('foo.c')
    </programlisting>
@@ -535,7 +537,7 @@ environment undisturbed.
    <literal>-O2</literal>
    and one with a &CCFLAGS; value of
    <literal>-g</literal>.
-   To work around this,
+   To avoid this problem,
    we must explicitly specify
    that each environment compile
    <filename>foo.c</filename>
@@ -566,7 +568,7 @@ environment undisturbed.
    This avoids having to specify explicitly
    the object file name in multiple places,
    and makes for a compact, readable
-   &SConstruct file.
+   &SConstruct; file.
    Our &SCons; output then looks like:
 
    </para>
@@ -586,8 +588,8 @@ environment undisturbed.
 
    <para>
 
-   Sometimes you want to more than one &consenv;
-   to use the same values for one or more variables.
+   Sometimes you want more than one &consenv;
+   to share the same values for one or more variables.
    Rather than always having to repeat all of the common
    variables when you create each &consenv;,
    you can use the &Copy; method
index 448777f1d175d658030520276bbdc59c6bb1b986..f83ab6399791fdefbc6cabb832d886ad4c4a2e32 100644 (file)
 
  <para>
 
-   X
+   XXX
 
  </para>
 
  <section>
- <title>X</title>
+ <title>XXX</title>
 
    <para>
 
-   X
+   XXX
 
    </para>
 
index 448777f1d175d658030520276bbdc59c6bb1b986..f83ab6399791fdefbc6cabb832d886ad4c4a2e32 100644 (file)
 
  <para>
 
-   X
+   XXX
 
  </para>
 
  <section>
- <title>X</title>
+ <title>XXX</title>
 
    <para>
 
-   X
+   XXX
 
    </para>
 
index 617eb5921b28291ebbba2a8ef88b687a10573245..e39da8f2d7929c49b0749d552f9a7263b76b92c2 100644 (file)
@@ -274,7 +274,7 @@ make no difference to the build.
 
     <para>
 
-    X
+    XXX
 
     </para>
 
@@ -290,7 +290,7 @@ make no difference to the build.
 
     <para>
 
-    X
+    XXX
 
     </para>
 
@@ -304,7 +304,7 @@ make no difference to the build.
 
       <para>
 
-      X
+      XXX
 
       </para>
 
@@ -320,7 +320,7 @@ make no difference to the build.
 
       <para>
 
-      X
+      XXX
 
       </para>
 
@@ -336,7 +336,7 @@ make no difference to the build.
 
       <para>
 
-      X
+      XXX
 
       </para>
 
index 2cebbd4568cbeb157d82af63c87f305975201ea2..7f522e568a07219111a1d99937ee24b573da913b 100644 (file)
@@ -72,7 +72,7 @@
   should be installed.
   This is an area where the &Alias;
   function comes in handy,
-  allowing you, if you wish,
+  allowing you, for example,
   to create a pseudo-target named <literal>install</literal>
   that can expand to the specified destination directory:
 
     <para>
 
     You can install multiple files into a directory
-    simploy by calling the &Install; function multiple times:
+    simply by calling the &Install; function multiple times:
 
     </para>
 
diff --git a/doc/user/libraries.sgml b/doc/user/libraries.sgml
new file mode 100644 (file)
index 0000000..ea41f5d
--- /dev/null
@@ -0,0 +1,250 @@
+<!--
+
+  Copyright (c) 2001, 2002, 2003 Steven Knight
+
+  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.
+
+-->
+
+  <para>
+
+  One of the more useful ways in which you can use multiple
+  construction environments is to link programs
+  with different sets of libraries.
+
+  </para>
+
+  <section>
+  <title>Building Libraries</title>
+
+    <para>
+
+    You build your own libraries by specifying &Library;
+    instead of &Program;:
+
+    </para>
+
+    <programlisting>
+      env = Environment()
+      env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
+    </programlisting>
+
+    <para>
+
+    &SCons; uses the appropriate library prefix and suffix for your system.
+    So on POSIX or Linux systems,
+    the above example would build as follows
+    (although &ranlib may not be called on all systems):
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      cc -c f1.c -o f1.o
+      cc -c f2.c -o f2.o
+      cc -c f3.c -o f3.o
+      ar r libfoo.a f1.o f2.o f3.o
+      ranlib libfoo.a
+    </literallayout>
+
+    <para>
+
+    On a Windows system,
+    a build of the above example would look like:
+
+    </para>
+
+    <literallayout>
+      C:\><userinput>scons</userinput>
+      cl /Fof1.obj f1.c
+      cl /Fof2.obj f2.c
+      cl /Fof3.obj f3.c
+      lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj
+    </literallayout>
+
+    <para>
+
+    The rules for the target name of the library
+    are similar to those for programs:
+    if you don't explicitly specify a target library name,
+    &SCons; will deduce one from the
+    name of the first source file specified,
+    and &SCons; will add an appropriate
+    file prefix and suffix if you leave them off.
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Linking with Libraries</title>
+
+    <para>
+
+    Usually, the goal of building a library
+    is to link it with one or more programs.
+    You link libraries with a program by specifying
+    the libraries in the &LIBS; construction variable,
+    and by specifying the directory in which
+    the library will be found in the 
+    &LIBPATH; construction variable:
+
+    </para>
+
+    <programlisting>
+      env = Environment(LIBS = 'foo', LIBPATH = '.')
+      env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
+      env.Program('prog.c')
+    </programlisting>
+
+    <para>
+
+    Notice, of course, that you don't need to specify a library
+    prefix (like <literal>lib</literal>)
+    or suffix (like <literal>.a</literal> or <literal>.lib</literal>).
+    &SCons; uses the correct prefix or suffix for the current system.
+
+    </para>
+
+    <para>
+
+    On a POSIX or Linux system,
+    a build of the above example would look like:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      cc -c f1.c -o f1.o
+      cc -c f2.c -o f2.o
+      cc -c f3.c -o f3.o
+      ar r libfoo.a f1.o f2.o f3.o
+      ranlib libfoo.a
+      cc -c prog.c -o prog.o
+      cc -o prog -L. -lfoo prog.o
+    </literallayout>
+
+    <para>
+
+    On a Windows system,
+    a build of the above example would look like:
+
+    </para>
+
+    <literallayout>
+      C:\><userinput>scons</userinput>
+      cl /Fof1.obj f1.c
+      cl /Fof2.obj f2.c
+      cl /Fof3.obj f3.c
+      lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj
+      cl /Foprog.obj prog.c
+      link /OUT:prog.exe /LIBPATH:. foo.lib prog.obj
+    </literallayout>
+
+    <para>
+
+    As usual, notice that &SCons; has taken care
+    of constructing the correct command lines
+    to link with the specified library on each system.
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Finding Libraries:  the &LIBPATH; Construction Variable</title>
+
+    <para>
+
+    By default, the linker will only look in
+    certain system-defined directories for libraries.
+    &SCons; knows how to look for libraries
+    in directories that you specify with the
+    &LIBPATH; construction variable.
+    &LIBPATH; consists of a list of
+    directory names, like so:
+
+    </para>
+
+    <programlisting>
+      env = Environment(LIBS = 'm',
+                        LIBPATH = ['/usr/lib', '/usr/local/lib'])
+      env.Program('prog.c')
+    </programlisting>
+
+    <para>
+
+    Using a Python list is preferred because it's portable
+    across systems.  Alternatively, you could put all of
+    the directory names in a single string, separated by the
+    system-specific path separator character:
+    a colon on POSIX systems:
+
+    </para>
+
+    <programlisting>
+      LIBPATH = '/usr/lib:/usr/local/lib'
+    </programlisting>
+
+    <para>
+
+    or a semi-colon on Windows systems:
+
+    </para>
+
+    <programlisting>
+      LIBPATH = 'C:\lib;D:\lib'
+    </programlisting>
+
+    <para>
+
+    On a POSIX or Linux system,
+    a build of the above example would look like:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      cc -c prog.c -o prog.o
+      cc -o prog -L/usr/lib -L/usr/local/lib -lm prog.o
+    </literallayout>
+
+    <para>
+
+    On a Windows system,
+    a build of the above example would look like:
+
+    </para>
+
+    <literallayout>
+      C:\><userinput>scons</userinput>
+      cl /Foprog.obj prog.c
+      link /nologo /OUT:program.exe /LIBPATH:\usr\lib;\usr\local\lib m.lib prog.obj
+    </literallayout>
+
+    <para>
+
+    Note again that &SCons; has taken care of
+    the system-specific details of creating
+    the right command-line options.
+
+    </para>
+
+  </section>
index 9ea4dd5af0aa3f2eca4685f94b051517e63c5beb..12b0480b8974f39fe37aadef99b380c97469e3af 100644 (file)
 
     <!ENTITY actions SYSTEM "actions.sgml">
     <!ENTITY alias SYSTEM "alias.sgml">
-    <!ENTITY builders SYSTEM "builders.sgml">
+    <!ENTITY ant SYSTEM "ant.sgml">
+    <!ENTITY builders-built-in SYSTEM "builders-built-in.sgml">
+    <!ENTITY builders-commands SYSTEM "builders-commands.sgml">
+    <!ENTITY builders-writing SYSTEM "builders-writing.sgml">
     <!ENTITY caching SYSTEM "caching.sgml">
-    <!ENTITY command SYSTEM "command.sgml">
     <!ENTITY cons SYSTEM "cons.sgml">
     <!ENTITY copyright SYSTEM "copyright.sgml">
     <!ENTITY default SYSTEM "default.sgml">
@@ -47,6 +49,7 @@
     <!ENTITY help SYSTEM "help.sgml">
     <!ENTITY hierarchy SYSTEM "hierarchy.sgml">
     <!ENTITY install SYSTEM "install.sgml">
+    <!ENTITY libraries SYSTEM "libraries.sgml">
     <!ENTITY make SYSTEM "make.sgml">
     <!ENTITY precious SYSTEM "precious.sgml">
     <!ENTITY preface SYSTEM "preface.sgml">
     &environments;
   </chapter>
 
+  <chapter id="chap-libraries">
+    <title>Building and Linking with Libraries</title>
+    &libraries;
+  </chapter>
+
   <chapter id="chap-depends">
     <title>Dependencies</title>
     &depends;
     &variants;
   </chapter>
 
-  <chapter id="chap-builders">
-    <title>Writing Builders</title>
-    &builders;
+  <chapter id="chap-builders-built-in">
+    <title>Built-In Builders</title>
+    &builders-built-in;
+  </chapter>
+
+  <chapter id="chap-builders-writing">
+    <title>Writing Your Own Builders</title>
+    &builders-writing;
   </chapter>
 
-  <chapter id="chap-command">
-    <title>Not Writing a Builder (for One-Time Builds)</title>
-    &command;
+  <chapter id="chap-builders-commands">
+    <title>Not Writing a Builder:  The &Command; Builder</title>
+    &builders-commands;
   </chapter>
 
   <chapter id="chap-actions">
     &cons;
   </appendix>
 
+  <appendix id="app-ant">
+    <title>Converting From Ant</title>
+    &ant;
+  </appendix>
+
 </book>
index 5666ea64e5e9f399292af2a41d8c419cfca8f412..c7ecc6309a2d1820d3487e0c25ffa2f248b867c4 100644 (file)
@@ -94,16 +94,16 @@ the makefiles.
 
  <para>
 
-   X
+   XXX
 
  </para>
 
  <section>
- <title>X</title>
+ <title>XXX</title>
 
    <para>
 
-   X
+   XXX
 
    </para>
 
index 82ea44a1c3dd1223eb306b0b1b5bbf8794246eec..bba7f49dfccbb3b01a5b859e259ad520ed4c561c 100644 (file)
 
 -->
 
- <para>
 <para>
 
-   X
+  XXX
 
- </para>
 </para>
 
- <section>
- <title>Why &SCons;?</title>
 <section>
 <title>Why &SCons;?</title>
 
-   <para>
+    <para>
 
-   X
+    XXX
 
-   </para>
+    </para>
 
- </section>
 </section>
 
- <section>
<title>History</title>
 <section>
 <title>&SCons; Principles</title>
 
-   <para>
+    <para>
 
-   X
+    By default, &SCons; guarantees a correct build
+    regardless of what end case you may have.
 
-   </para>
+    </para>
 
</section>
   <para>
 
- <section>
- <title>Conventions</title>
+    &SCons; makes it easy to speed up the build through
+    optimization options that trade off
+    guaranteed correctness for speed.
 
-   <para>
+    </para>
 
-   X
+    <para>
 
-   </para>
+    &SCons; tries to do as much for you out of the box as reasonable.
 
</section>
   </para>
 
- <section>
- <title>Acknowledgements</title>
+  </section>
 
-   <para>
+  <section>
+  <title>History</title>
 
-   X
+    <para>
 
-   </para>
+    &SCons; originated with a design
+    that was submitted to the Software Carpentry
+    design competition in 2000.
 
</section>
   </para>
 
- <section>
- <title>Contact</title>
+    <para>
 
-   <para>
+    &SCons; is the direct descendant
+    of a Perl utility called &Cons;.
+    &Cons; in turn based some of its ideas on &Jam;,
+    a build tool from Perforce Systems.
 
-   X
+    </para>
 
-   </para>
+  </section>
 
- </section>
+  <section>
+  <title>Conventions</title>
+
+    <para>
+
+    XXX
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Acknowledgements</title>
+
+    <para>
+
+    &SCons; would not exist without a lot of help
+    from a lot of people,
+    many of whom may not even be aware
+    that they helped or served as inspiration.
+    So in no particular order,
+    and at the risk of leaving out someone:
+
+    </para>
+
+    <para>
+
+    First and foremost,
+    &SCons; owes a tremendous debt to Bob Sidebotham,
+    the original author of the classic Perl-based &Cons; tool
+    which Bob first released to the world back around 1996.
+    Bob's work on Cons classic provided the underlying architecture
+    and model of specifying a build configuration
+    using a real scripting language.
+    My real-world experience working on Cons
+    informed many of the design decisions in SCons,
+    including the improved parallel build support,
+    making Builder objects easily definable by users,
+    and separating the build engine from the wrapping interface.
+
+    </para>
+
+    <para>
+
+    Greg Wilson was instrumental in getting
+    &SCons; started as a real project
+    when he initiated the Software Carpentry design
+    competition in February 2000.
+    Without that nudge,
+    marrying the advantages of the Cons classic
+    architecture with the readability of Python
+    might have just stayed no more than a nice idea.
+
+    </para>
+
+    <para>
+
+    The entire &SCons; team have been
+    absolutely wonderful to work with,
+    and &SCons; would be nowhere near as useful a
+    tool without the energy, enthusiasm
+    and time people have contributed over the past few years.
+    The "core team"
+    of Chad Austin, Anthony Roach, Charles Crain, and Steve Leblanc
+    have been great about reviewing my (and other) changes
+    and catching problems before they get in the code base.
+    Technically,
+    Anthony's outstanding and innovative work on the tasking engine
+    has given &SCons; a vastly superior parallel build model,
+    and Charles has been the master of the crucial Node infrastructure.
+    &SCons; has received contributions
+    from many other people, of course:
+    Matt Balvin (extending long command-line support on Win32),
+    Michael Cook (avoiding losing signal bits from executed commands),
+    Derrick 'dman' Hudson (),
+    Alex Jacques (work on the Win32 scons.bat file),
+    Stephen Kennedy (performance enhancements),
+    Lachlan O'Dea (SharedObject() support for masm
+    and normalized paths for the WhereIs() function),
+    Jeff Petkau (fixes for CacheDir and other areas),
+    Zed Shaw (Append() and Replace() environment methods),
+    Terrel Shumway (build and test fixes, as well as the SCons Wiki),
+    sam th (dynamic checks for utilities)
+    and Moshe Zadke (Debian packaging).
+
+    </para>
+
+    <para>
+
+    Thanks to Peter Miller
+    for his splendid change management system, &Aegis;,
+    which has provided the &SCons; project
+    with a robust development methodology from day one,
+    and which showed me how you could
+    integrate incremental regression tests into
+    a practical development cycle
+    (years before eXtreme Programming arrived on the scene).
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Contact</title>
+
+    <para>
+
+    The best way to contact people involved with SCons,
+    including the author,
+    is through the SCons mailing lists.
+
+    </para>
+
+  </section>
index 616e9031985fc7ac18b5ab65b73c1d34d12fdd0c..07af1156bd848f684dbf70999d0e3bcee52491d7 100644 (file)
@@ -288,7 +288,7 @@ subdirectories under the repository tree.
     about the pathname of the repository?
     To solve this problem, &SCons; allows you
     to specify repository directories
-    on the command line using the <literal>-Y</literal>:
+    on the command line using the <literal>-Y</literal> option:
 
     </para>
 
index 30b61ca5b6d3637dcff58096da32a97ff13c84cd..83ca3d2d27bff9b626c7a69b3c6ad50f674e8116 100644 (file)
@@ -266,48 +266,6 @@ rebuilt, if necessary, and then installed there. Note that C<cons build>
 might build files that C<cons export> doesn't build, and vice-versa.
 
 
-=head2 No ``special'' targets
-
-With Cons, make-style ``special'' targets are not required. The simplest
-analog with Cons is to use special F<export> directories, instead. Let's
-suppose, for example, that you have a whole series of unit tests that are
-associated with your code. The tests live in the source directory near the
-code. Normally, however, you don't want to build these tests. One solution
-is to provide all the build instructions for creating the tests, and then to
-install the tests into a separate part of the tree. If we install the tests
-in a top-level directory called F<tests>, then:
-
-  % cons tests
-
-will build all the tests.
-
-  % cons export
-
-will build the production version of the system (but not the tests), and:
-
-  % cons build
-
-should probably be avoided (since it will compile tests unnecessarily).
-
-If you want to build just a single test, then you could explicitly name the
-test (in either the F<tests> directory or the F<build> directory). You could
-also aggregate the tests into a convenient hierarchy within the tests
-directory. This hierarchy need not necessarily match the source hierarchy,
-in much the same manner that the include hierarchy probably doesn't match
-the source hierarchy (the include hierarchy is unlikely to be more than two
-levels deep, for C programs).
-
-If you want to build absolutely everything in the tree (subject to whatever
-options you select), you can use:
-
-  % cons .
-
-This is not particularly efficient, since it will redundantly walk all the
-trees, including the source tree. The source tree, of course, may have
-buildable objects in it-,-nothing stops you from doing this, even if you
-normally build in a separate build tree.
-
-
 =head1 Build Pruning
 
 In conjunction with target selection, B<build pruning> can be used to reduce
@@ -351,52 +309,56 @@ do an unconstrained build before committing the integration).
 
 -->
 
- <para>
+  <para>
+
+    XXX
+
+  </para>
 
-   X
+  <section>
+  <title>Selective Builds</title>
 
</para>
   <para>
 
- <section>
- <title>Selective Builds</title>
+    XXX
 
-   <para>
+    </para>
 
-   X
+  </section>
 
-   </para>
+  <!--
 
- </section>
+  <section>
+  <title>Build Pruning</title>
 
- <section>
- <title>Build Pruning</title>
+    <para>
 
-   <para>
+    XXX
 
-   X
+    </para>
 
-   </para>
+  </section>
 
</section>
 -->
 
- <section>
- <title>Overriding Construction Variables</title>
 <section>
 <title>Overriding Construction Variables</title>
 
-   <para>
+    <para>
 
-   X
+    XXX
 
-   </para>
+    </para>
 
- </section>
 </section>
 
- <section>
- <title>The &SCONSFLAGS; Environment Variable</title>
 <section>
 <title>The &SCONSFLAGS; Environment Variable</title>
 
-   <para>
+    <para>
 
-   X
+    XXX
 
-   </para>
+    </para>
 
- </section>
 </section>
index 8d13b0c1f316329b62b580d58ee89dba209d7740..76b2a1af7a7ea373a9b5fd6d07d1c3ab6eba2dfc 100644 (file)
@@ -123,16 +123,16 @@ over the file scanning rather than being called for each input line:
 
  <para>
 
-   X
+   XXX
 
  </para>
 
  <section>
- <title>X</title>
+ <title>XXX</title>
 
    <para>
 
-   X
+   XXX
 
    </para>
 
index 21fcabc37eabca018d8cb0b62d3bc5bb1095a025..ac3c0f33510264538206a1cf652610d233ac0a7e 100644 (file)
@@ -110,228 +110,322 @@ program using the F<build/foo.c> path name.
 
 -->
 
- <para>
 <para>
 
- It's often useful to keep any built files completely
- separate from the source files.
- This is usually done by creating one or more separate
- <emphasis>build directories</emphasis>
- that are used to hold the built objects files, libraries,
- and executable programs, etc.
- for a specific flavor of build.
- &SCons; provides two ways of doing this,
- one with a little more flexibility.
+  It's often useful to keep any built files completely
+  separate from the source files.
+  This is usually done by creating one or more separate
+  <emphasis>build directories</emphasis>
+  that are used to hold the built objects files, libraries,
+  and executable programs, etc.
+  for a specific flavor of build.
+  &SCons; provides two ways to do this,
+  one through the &SConscript; function that we've already seen,
+  and the second through a more flexible &BuildDir; function.
 
- </para>
 </para>
 
- <section>
<title>The &BuildDir; Function</title>
 <section>
 <title>Specifying a Build Directory as Part of an &SConscript; Call</title>
 
-   <para>
+    <para>
 
-   Use the &BuildDir; function to establish that target
-   files should be built in a separate directory
-   from the source files:
+    The most straightforward way to establish a build directory
+    uses the fact that the usual way to
+    set up a build hierarcy is to have an
+    &SConscript; file in the source subdirectory.
+    If you then pass a &build_dir; argument to the
+    &SConscript; function call:
 
-   </para>
+    </para>
 
-   <programlisting>
-     BuildDir('build', 'src')
-     env = Environment()
-     env.Program('build/hello.c')
-   </programlisting>
+    <programlisting>
+      SConscript('src/SConscript', build_dir='build')
+    </programlisting>
 
-   <para>
+    <para>
 
-   Note that XXX
+    &SCons; will then build all of the files in
+    the &build; subdirectory:
 
-   </para>
+    </para>
 
-   <literallayout>
-     % <userinput>ls src</userinput>
-     hello.c
-     % <userinput>scons</userinput>
-     cc -c build/hello.c -o build/hello.o
-     cc -o build/hello build/hello.o
-     % <userinput>ls -1 build</userinput>
-     hello
-     hello.c
-     hello.o
-   </literallayout>
+    <literallayout>
+      % <userinput>ls -1 src</userinput>
+      SConscript
+      hello.c
+      % <userinput>scons</userinput>
+      cc -c build/hello.c -o build/hello.o
+      cc -o build/hello build/hello.o
+      % <userinput>ls -1 build</userinput>
+      hello
+      hello.c
+      hello.o
+    </literallayout>
 
</section>
   <para>
 
- <section>
- <title>Avoiding Duplicate Source Files in the Build Directory</title>
+    But wait a minute--what's going on here?
+    &SCons; created the object file
+    <filename>build/hello.o</filename>
+    in the &build; subdirectory,
+    as expected.
+    But even though our &hello_c; file lives in the &src; subdirectory,
+    &SCons; has actually compiled a
+    <filename>build/hello.c</filename> file
+    to create the object file.
 
-   <para>
+    </para>
 
-   X
+    <para>
 
-   </para>
+    What's happened is that &SCons; has <emphasis>duplicated</emphasis>
+    the &hello_c; file from the &src; subdirectory
+    to the &build; subdirectory,
+    and built the program from there.
+    The next section explains why &SCons; does this.
 
-   <programlisting>
-     BuildDir('build', 'src', duplicate=0)
-     env = Environment()
-     env.Program('build/hello.c')
-   </programlisting>
+    </para>
 
-   <para>
+  </section>
 
-   X
+  <section>
+  <title>Why &SCons; Duplicates Source Files in a Build Directory</title>
 
-   </para>
+    <para>
 
-   <literallayout>
-     % <userinput>ls -1 src</userinput>
-     hello.c
-     % <userinput>scons</userinput>
-     cc -c src/hello.c -o build/hello.o
-     cc -o build/hello build/hello.o
-     % <userinput>ls -1 build</userinput>
-     hello
-     hello.o
-   </literallayout>
+    &SCons; duplicates source files in build directories
+    because it's the most straightforward way to guarantee a correct build
+     <emphasis>regardless of include-file directory paths</emphasis>,
+    and the &SCons; philosophy is to, by default,
+    guarantee a correct build in all cases.
+    Here is an example of an end case where duplicating
+    source files in a build directory
+    is necessary for a correct build:
 
-   <para>
+    </para>
 
-   X
+    <para>
 
-   </para>
+    XXX
 
</section>
   </para>
 
- <section>
- <title>Why &SCons; Duplicates Source Files by Default</title>
+    <programlisting>
+      env = Environmnet()
+    </programlisting>
 
-   <para>
+    <para>
 
-   X
+    XXX
 
-   </para>
+    </para>
 
-   <programlisting>
-     env = Environmnet()
-   </programlisting>
+    <literallayout>
+      % <userinput>scons</userinput>
+      cc -c build/hello.c -o build/hello.o
+      cc -o build/hello build/hello.o
+    </literallayout>
 
-   <para>
+  </section>
 
-   X
+  <section>
+  <title>Telling &SCons; to Not Duplicate Source Files in the Build Directory</title>
 
-   </para>
+    <para>
 
-   <literallayout>
-     % <userinput>scons</userinput>
-     cc -c build/hello.c -o build/hello.o
-     cc -o build/hello build/hello.o
-   </literallayout>
+    In most cases, however,
+    having &SCons; place its target files in a build subdirectory
+    <emphasis>without</emphasis>
+    duplicating the source files works just fine.
+    You can disable the default &SCons; behavior
+    by specifying <literal>duplicate=0</literal>
+    when you call the &SConscript; function:
 
</section>
   </para>
 
- <section>
- <title>Using &BuildDir; With an &SConscript; File</title>
+    <programlisting>
+      SConscript('src/SConscript', build_dir='build', duplicate=0)
+    </programlisting>
 
-   <para>
+    <para>
 
-   X
+    When this flag is specified,
+    &SCons; uses the build directory
+    like most people expect--that is,
+    the output files are placed in the build directory
+    while the source files stay in the source directory:
 
-   </para>
+    </para>
 
-   <programlisting>
-     env = Environment()
-     env.Program('hello.c')
-   </programlisting>
+    <literallayout>
+      % <userinput>ls -1 src</userinput>
+      SConscript
+      hello.c
+      % <userinput>scons</userinput>
+      cc -c src/hello.c -o build/hello.o
+      cc -o build/hello build/hello.o
+      % <userinput>ls -1 build</userinput>
+      hello
+      hello.o
+    </literallayout>
 
-   <para>
+  </section>
 
-   X
+  <section>
+  <title>The &BuildDir; Function</title>
 
-   </para>
+    <para>
 
-   <programlisting>
-     BuildDir('build', 'src')
-     SConscript('build/SConscript')
-   </programlisting>
+    Use the &BuildDir; function to establish that target
+    files should be built in a separate directory
+    from the source files:
 
-   <para>
+    </para>
 
-   X
+    <programlisting>
+      BuildDir('build', 'src')
+      env = Environment()
+      env.Program('build/hello.c')
+    </programlisting>
 
-   </para>
+    <para>
 
-   <literallayout>
-     % <userinput>ls -1 src</userinput>
-     SConscript
-     hello.c
-     % <userinput>scons</userinput>
-     cc -c build/hello.c -o build/hello.o
-     cc -o build/hello build/hello.o
-     % <userinput>ls -1 build</userinput>
-     hello
-     hello.c
-     hello.o
-   </literallayout>
+    Note that when you're not using
+    an &SConscript; file in the &src; subdirectory,
+    you must actually specify that
+    the program must be built from
+    the <filename>build/hello.c</filename>
+    file that &SCons; will duplicate in the
+    &build; subdirectory.
 
</section>
   </para>
 
- <section>
- <title>Specifying a Build Directory as Part of an &SConscript; Call</title>
+    <para>
 
-   <para>
+    XXX
 
-   X
+    </para>
 
-   </para>
+    <para>
 
-   <programlisting>
-     SConscript('src/SConscript', build_dir='build')
-   </programlisting>
+    When using the &BuildDir; function directly,
+    &SCons; still duplicates the source files
+    in the build directory by default:
 
-   <para>
+    </para>
 
-   X
+    <literallayout>
+      % <userinput>ls src</userinput>
+      hello.c
+      % <userinput>scons</userinput>
+      cc -c build/hello.c -o build/hello.o
+      cc -o build/hello build/hello.o
+      % <userinput>ls -1 build</userinput>
+      hello
+      hello.c
+      hello.o
+    </literallayout>
 
-   </para>
+    <para>
 
-   <literallayout>
-     % <userinput>ls -1 src</userinput>
-     SConscript
-     hello.c
-     % <userinput>scons</userinput>
-     cc -c build/hello.c -o build/hello.o
-     cc -o build/hello build/hello.o
-     % <userinput>ls -1 build</userinput>
-     hello
-     hello.c
-     hello.o
-   </literallayout>
+    You can specify the same <literal>duplicate=0</literal> argument
+    that you can specify for an &SConscript; call:
 
-   <para>
+    </para>
 
-   X
+    <programlisting>
+      BuildDir('build', 'src', duplicate=0)
+      env = Environment()
+      env.Program('build/hello.c')
+    </programlisting>
 
-   </para>
+    <para>
 
-   <programlisting>
-     SConscript('src/SConscript', build_dir='build', duplicate=0)
-   </programlisting>
+    In which case &SCons;
+    will disable duplication of the source files:
 
-   <para>
+    </para>
 
-   X
+    <literallayout>
+      % <userinput>ls src</userinput>
+      hello.c
+      % <userinput>scons</userinput>
+      cc -c src/hello.c -o build/hello.o
+      cc -o build/hello build/hello.o
+      % <userinput>ls -1 build</userinput>
+      hello
+      hello.o
+    </literallayout>
 
-   </para>
+  </section>
 
-   <literallayout>
-     % <userinput>ls -1 src</userinput>
-     SConscript
-     hello.c
-     % <userinput>scons</userinput>
-     cc -c src/hello.c -o build/hello.o
-     cc -o build/hello build/hello.o
-     % <userinput>ls -1 build</userinput>
-     hello
-     hello.o
-   </literallayout>
+  <section>
+  <title>Using &BuildDir; With an &SConscript; File</title>
 
- </section>
+    <para>
+
+    Even when using the &BuildDir; function,
+    it's much more natural to use it with
+    a subsidiary &SConscript; file.
+    For example, if the
+    <filename>src/SConscript</filename>
+    looks like this:
+
+    </para>
+
+    <programlisting>
+      env = Environment()
+      env.Program('hello.c')
+    </programlisting>
+
+    <para>
+
+    Then our &SConscript; file could look like:
+
+    </para>
+
+    <programlisting>
+      BuildDir('build', 'src')
+      SConscript('build/SConscript')
+    </programlisting>
+
+    <para>
+
+    Yielding the following output:
+
+    </para>
+
+    <literallayout>
+      % <userinput>ls -1 src</userinput>
+      SConscript
+      hello.c
+      % <userinput>scons</userinput>
+      cc -c build/hello.c -o build/hello.o
+      cc -o build/hello build/hello.o
+      % <userinput>ls -1 build</userinput>
+      hello
+      hello.c
+      hello.o
+    </literallayout>
+
+    <para>
+
+    Notice that this is completely equivalent
+    to the use of &SConscript; that we
+    learned about in the previous section.
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Why You'd Want to Call &BuildDir; Instead of &SConscript;</title>
+
+    <para>
+    
+    XXX
+
+    </para>
+
+  </section>
index 2acd669e8b3e0df3ac37ad155e27b5cead8a193f..8f76f2aa3e40bb5328d043de24ce048c75a75ff6 100644 (file)
@@ -43,7 +43,7 @@ requirements of a build.
 
  <para>
 
- Here's how to build the famous "Hello, World!" example using &SCons;.
+ Here's the famous "Hello, World!" program in C:
 
  </para>
 
@@ -57,7 +57,8 @@ requirements of a build.
 
  <para>
 
- Enter the following into a file name &SConstruct;:
+ And here's how to build it using &SCons;.
+ Enter the following into a file named &SConstruct;:
 
  </para>
 
@@ -144,7 +145,7 @@ requirements of a build.
 
    What may not be obvious, though, is that
    there's an important difference between
-   an &SConstruct; file and a &Makefile:
+   an &SConstruct; file and a &Makefile;:
    the &SConstruct; file is actually a Python script.
    If you're not already familiar with Python, don't worry;
    Python is very easy to learn,
@@ -193,29 +194,58 @@ requirements of a build.
    To do this, you need to put the
    source files in a Python list
    (enclosed in square brackets),
-   and slide that list over to to the right
-   to make room for the output program file name.
-   For example:
+   like so:
 
    </para>
 
    <programlisting>
       env = Environment()
-      env.Program('program', ['main.c', 'file1.c', 'file2.'])
+      env.Program(['prog.c', 'file1.c', 'file2.'])
    </programlisting>
 
    <para>
 
+   A build of the above example would look like:
+
+   </para>
+
+   <literallayout>
+      % <userinput>scons</userinput>
+      cc -c file1.c -o file1.o
+      cc -c file2.c -o file2.o
+      cc -c prog.c -o prog.o
+      cc -o prog prog.o file1.o file2.o
+   </literallayout>
+
+   <para>
+
+   Notice that &SCons;
+   deduces the output program name
+   from the first source file specified
+   in the list--that is,
+   because the first source file was &prog_c;,
+   &SCons; will name the resulting program &prog;
+   (or &prog_exe; on a Windows system).
+   If you want to specify a different program name,
+   then you slide the list of source files
+   over to the right
+   to make room for the output program file name.
    (&SCons; puts the output file name to the left
    of the source file names
    so that the order mimics that of an
    assignment statement:  "program = source files".)
+   This makes our example:
 
    </para>
 
+   <programlisting>
+      env = Environment()
+      env.Program('program', ['main.c', 'file1.c', 'file2.'])
+   </programlisting>
+
    <para>
 
-   A build of the above example would look:
+   On Linux, a build of this example would look like:
 
    </para>
 
@@ -227,11 +257,7 @@ requirements of a build.
       cc -o program main.o file1.o file2.o
    </literallayout>
 
-   <!--
-
-   XXX DO WE NEED WINDOWS EXAMPLE OUTPUT HERE?
-
-   </para>
+   <para>
 
    Or on Windows:
 
@@ -245,8 +271,6 @@ requirements of a build.
       link /Foprogram.exe main.obj file1.obj file2.obj
    </literallayout>
 
-   -->
-
  </section>
 
  <section>
@@ -260,8 +284,8 @@ requirements of a build.
    (either single quotes or double quotes).
    This can get cumbersome and difficult to read
    when the list of file names is long.
-   Fortunately, there are a number of things
-   we can do to make sure that
+   Fortunately, &SCons; and Python provide a number of ways
+   to make sure that
    the &SConstruct; file stays easy to read.
 
    </para>
@@ -363,7 +387,7 @@ requirements of a build.
 
    In order to compile multiple programs
    within the same &SConstruct; file,
-   simply call <function>env.Program</function>
+   simply call the <function>env.Program</function> method
    multiple times,
    once for each program you need to build:
 
@@ -390,6 +414,19 @@ requirements of a build.
       cc -o foo foo.o
    </literallayout>
 
+   <para>
+
+   Notice that &SCons; does not necessarily build the
+   programs in the same order in which you specify
+   them in the &SConstruct; file.
+   &SCons; does, however, recognize that
+   the individual object files must be built
+   before the resulting program can be built.
+   We'll discuss this in greater detail in
+   the "Dependencies" section, below.
+
+   </para>
+
  </section>
 
  <section>
@@ -397,17 +434,40 @@ requirements of a build.
 
    <para>
 
-   XXX
+   It's common to re-use code by sharing source files
+   between multiple programs.
+   One way to do this is to create a library
+   from the common source files,
+   which can then be linked into resulting programs.
+   (Creating libraries is discussed in
+   section XXX, below.)
+
+   </para>
+
+   <para>
+
+   A more straightforward, but perhaps less convenient,
+   way to share source files between multiple programs
+   is to simply include the common source files
+   when listing the source files for each program:
 
    </para>
 
    <programlisting>
-      common = ['common1.c', 'common2.c']
       env = Environment()
-      env.Program(['foo.c'] + common)
-      env.Program('bar', ['bar1.c', 'bar2.c'] + common)
+      env.Program(Split('foo.c common1.c common2.c'))
+      env.Program('bar', Split('bar1.c bar2.c common1.c common2.c'))
    </programlisting>
 
+   <para>
+
+   &SCons; recognizes that the object files for
+   the &common1_c; and &common2_c; source files
+   each only need to be built once,
+   even though the files are listed multiple times:
+
+   </para>
+
    <literallayout>
       % <userinput>scons</userinput>
       cc -c bar1.c -o bar1.o
@@ -419,4 +479,33 @@ requirements of a build.
       cc -o foo foo.o common1.o common2.o
    </literallayout>
 
+   <para>
+
+   If two or more programs
+   share a lot of common source files,
+   repeating the common files in the list for each program
+   a maintenance problem if you need to change the
+   list of common files.
+   You can simplify this by creating a separate Python list
+   to hold the common file names,
+   and concatenating it with other lists
+   using the Python &+; operator:
+
+   </para>
+
+   <programlisting>
+      common = ['common1.c', 'common2.c']
+      foo_files = ['foo.c'] + common
+      bar_files = ['bar1.c', 'bar2.c'] + common
+      env = Environment()
+      env.Program('foo', foo_files)
+      env.Program('bar', bar_files)
+   </programlisting>
+
+   <para>
+
+   This is functionally equivalent to the previous example.
+
+   </para>
+
  </section>
index 4ee49d44314d47a86d1a7e75f7b12c6b6f14d643..6bbcceedc87a389fa3c53d24f8673550f411b4ae 100644 (file)
@@ -44,7 +44,7 @@
 
    <programlisting>
       env = Environment()
-      env.SourceCode('.', env.BitKeeper('XXX')
+      env.SourceCode('.', env.BitKeeper('XXX'))
       env.Program('hello.c')
    </programlisting>
 
@@ -66,7 +66,7 @@
 
    <programlisting>
       env = Environment()
-      env.SourceCode('.', env.CVS('XXX')
+      env.SourceCode('.', env.CVS('XXX'))
       env.Program('hello.c')
    </programlisting>
 
@@ -88,7 +88,7 @@
 
    <programlisting>
       env = Environment()
-      env.SourceCode('.', env.RCS()
+      env.SourceCode('.', env.RCS())
       env.Program('hello.c')
    </programlisting>
 
 
    <programlisting>
       env = Environment()
-      env.SourceCode('.', env.SCCS()
+      env.SourceCode('.', env.SCCS())
       env.Program('hello.c')
    </programlisting>
 
 
    <programlisting>
       env = Environment()
-      env.SourceCode('.', env.Subversion('XXX')
+      env.SourceCode('.', env.Subversion('XXX'))
       env.Program('hello.c')
    </programlisting>
 
index 448777f1d175d658030520276bbdc59c6bb1b986..f83ab6399791fdefbc6cabb832d886ad4c4a2e32 100644 (file)
 
  <para>
 
-   X
+   XXX
 
  </para>
 
  <section>
- <title>X</title>
+ <title>XXX</title>
 
    <para>
 
-   X
+   XXX
 
    </para>
 
index 6ad936094639728170ea5646de94ee64706e3559..09dd16d11846a99d11b06e3a110a23c22031c774 100644 (file)
@@ -107,40 +107,89 @@ is pretty smart about rebuilding things when you change options.
 
 -->
 
- <para>
-
-   X
-
- </para>
-
- <section>
- <title>X</title>
-
-   <para>
-
-   X
-
-   </para>
-
-   <programlisting>
-     env = Environment(OS = ARGUMENT['os'])
-     SConscript('src/SConscript', build_dir='build/$OS')
-   </programlisting>
-
-   <para>
-
-   X
-
-   </para>
-
-   <programlisting>
-     env = Environment(OS = )
-     for os in ['newell', 'post']:
-         SConscript('src/SConscript', build_dir='build/' + os)
-   </programlisting>
-
-   <literallayout>
-     % <userinput>scons</userinput>
-   </literallayout>
-
- </section>
+  <para>
+
+  The &BuildDir; function now gives us everything
+  we need to show how easy it is to create
+  variant builds using &SCons;.
+  Suppose, for example, that we want to
+  build a program for both Windows and Linux platforms,
+  but that we want to build it in a shared directory
+  with separate side-by-side build directories
+  for the Windows and Linux versions of the program.
+
+  </para>
+
+  <programlisting>
+    platform = ARGUMENT.get('OS', Platform())
+
+    include = "#export/$PLATFORM/include"
+    lib = "#export/$PLATFORM/lib"
+    bin = "#export/$PLATFORM/bin"
+
+    env = Environment(PLATFORM = platform,
+                      CPPPATH = [include],
+                      LIB = lib,
+                      LIBS = '-lworld')
+
+    Export('env')
+
+    SConscript('src/SConscript', build_dir='build/$PLATFORM')
+
+    #
+    #BuildDir("#build/$PLATFORM", 'src')
+    #SConscript("build/$PLATFORM/hello/SConscript")
+    #SConscript("build/$PLATFORM/world/SConscript")
+  </programlisting>
+
+  <para>
+
+  This SConstruct file,
+  when run on a Linux system, yields:
+
+  </para>
+
+  <literallayout>
+    $ <userinput>scons OS=linux</userinput>
+    Install build/linux/world/world.h as export/linux/include/world.h
+    cc -Iexport/linux/include -c build/linux/hello/hello.c -o build/linux/hello/hello.o
+    cc -Iexport/linux/include -c build/linux/world/world.c -o build/linux/world/world.o
+    ar r build/linux/world/libworld.a build/linux/world/world.o
+    ar: creating build/linux/world/libworld.a
+    ranlib build/linux/world/libworld.a
+    Install build/linux/world/libworld.a as export/linux/lib/libworld.a
+    cc -o build/linux/hello/hello build/linux/hello/hello.o -Lexport/linux/lib -lworld
+    Install build/linux/hello/hello as export/linux/bin/hello
+  </literallayout>
+
+  <para>
+
+  The same SConstruct file on Windows would build:
+
+  </para>
+
+    <!--
+    cl /Fohello.obj hello.c
+    link /Fohello.exe hello.obj
+    -->
+  <literallayout>
+    C:\test\><userinput>scons OS=linux</userinput>
+    Install build\linux\world\world.h as export\linux\include\world.h
+    cl /Iexport\linux\include /Fobuild\linux\hello\hello.obj build\linux\hello\hello.c
+    cl /Iexport\linux\include /Fobuild\linux\world\world.obj build\linux\world\world.c
+    XXX
+    ar r build\linux\world\world.lib build\linux\world\world.obj
+    Install build\linux\world\world.lib as export\linux\lib\libworld.a
+    link /Fobuild\linux\hello\hello.exe build\linux\hello\hello.obj -Lexport\linux\lib world.lib
+    Install build\linux\hello\hello.exe as export\linux\bin\hello.exe
+  </literallayout>
+
+  <programlisting>
+    env = Environment(OS = )
+    for os in ['newell', 'post']:
+        SConscript('src/SConscript', build_dir='build/' + os)
+  </programlisting>
+
+  <literallayout>
+    % <userinput>scons</userinput>
+  </literallayout>