summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-05-21 13:01:13 (GMT)
committerSteven Knight <knight@baldmt.com>2003-05-21 13:01:13 (GMT)
commit15da9cb4667872d0da09e5c0bb684d92197c5e34 (patch)
treeb8237f5c5923475e53eb069fd6aa80fec40517e5
parent52255add2e794c695db690519e96fc5def8664e3 (diff)
downloadSCons-15da9cb4667872d0da09e5c0bb684d92197c5e34.zip
SCons-15da9cb4667872d0da09e5c0bb684d92197c5e34.tar.gz
SCons-15da9cb4667872d0da09e5c0bb684d92197c5e34.tar.bz2
Branch for User's Guide updates.
-rw-r--r--SConstruct5
-rw-r--r--doc/scons.mod56
-rw-r--r--doc/user/actions.sgml6
-rw-r--r--doc/user/ant.sgml41
-rw-r--r--doc/user/builders-built-in.sgml628
-rw-r--r--doc/user/builders-commands.sgml (renamed from doc/user/command.sgml)38
-rw-r--r--doc/user/builders-writing.sgml (renamed from doc/user/builders.sgml)235
-rw-r--r--doc/user/caching.sgml2
-rw-r--r--doc/user/cons.sgml6
-rw-r--r--doc/user/default.sgml2
-rw-r--r--doc/user/depends.sgml393
-rw-r--r--doc/user/environments.sgml16
-rw-r--r--doc/user/errors.sgml6
-rw-r--r--doc/user/example.sgml6
-rw-r--r--doc/user/hierarchy.sgml10
-rw-r--r--doc/user/install.sgml4
-rw-r--r--doc/user/libraries.sgml250
-rw-r--r--doc/user/main.sgml34
-rw-r--r--doc/user/make.sgml6
-rw-r--r--doc/user/preface.sgml185
-rw-r--r--doc/user/repositories.sgml2
-rw-r--r--doc/user/run.sgml100
-rw-r--r--doc/user/scanners.sgml6
-rw-r--r--doc/user/separate.sgml410
-rw-r--r--doc/user/simple.sgml133
-rw-r--r--doc/user/sourcecode.sgml10
-rw-r--r--doc/user/troubleshoot.sgml6
-rw-r--r--doc/user/variants.sgml123
28 files changed, 2236 insertions, 483 deletions
diff --git a/SConstruct b/SConstruct
index 87eafb0..b1af691 100644
--- a/SConstruct
+++ b/SConstruct
@@ -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())
diff --git a/doc/scons.mod b/doc/scons.mod
index 32283c3..f9deaa1 100644
--- a/doc/scons.mod
+++ b/doc/scons.mod
@@ -14,14 +14,20 @@
-->
+<!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>">
<!--
@@ -57,10 +63,11 @@
<!--
- 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>">
@@ -106,10 +114,17 @@
<!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>">
@@ -125,6 +140,8 @@
<!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>">
@@ -137,6 +154,7 @@
<!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>">
@@ -144,6 +162,18 @@
<!--
+ 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.
-->
@@ -151,6 +181,10 @@
<!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>">
@@ -158,10 +192,13 @@
<!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>">
@@ -175,6 +212,8 @@
-->
+<!ENTITY buildfunc "<literal>builder function</literal>">
+
<!ENTITY ConsEnv "<literal>Construction Environment</literal>">
<!ENTITY ConsEnvs "<literal>Construction Environments</literal>">
<!ENTITY Consenv "<literal>Construction environment</literal>">
@@ -193,14 +232,29 @@
<!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>">
diff --git a/doc/user/actions.sgml b/doc/user/actions.sgml
index 447b331..c35ccdd 100644
--- a/doc/user/actions.sgml
+++ b/doc/user/actions.sgml
@@ -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
index 0000000..f83ab63
--- /dev/null
+++ b/doc/user/ant.sgml
@@ -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
index 0000000..bb29cc4
--- /dev/null
+++ b/doc/user/builders-built-in.sgml
@@ -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>
diff --git a/doc/user/command.sgml b/doc/user/builders-commands.sgml
index 945c656..e21f6d0 100644
--- a/doc/user/command.sgml
+++ b/doc/user/builders-commands.sgml
@@ -23,41 +23,41 @@
-->
-<!--
+ <!--
-=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>
diff --git a/doc/user/builders.sgml b/doc/user/builders-writing.sgml
index c1b4269..27a48b9 100644
--- a/doc/user/builders.sgml
+++ b/doc/user/builders-writing.sgml
@@ -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>
diff --git a/doc/user/caching.sgml b/doc/user/caching.sgml
index ed72c1e..3d9158e 100644
--- a/doc/user/caching.sgml
+++ b/doc/user/caching.sgml
@@ -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
diff --git a/doc/user/cons.sgml b/doc/user/cons.sgml
index 448777f..f83ab63 100644
--- a/doc/user/cons.sgml
+++ b/doc/user/cons.sgml
@@ -25,16 +25,16 @@
<para>
- X
+ XXX
</para>
<section>
- <title>X</title>
+ <title>XXX</title>
<para>
- X
+ XXX
</para>
diff --git a/doc/user/default.sgml b/doc/user/default.sgml
index 981ac42..f44719f 100644
--- a/doc/user/default.sgml
+++ b/doc/user/default.sgml
@@ -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>
diff --git a/doc/user/depends.sgml b/doc/user/depends.sgml
index bc46618..fbbb54a 100644
--- a/doc/user/depends.sgml
+++ b/doc/user/depends.sgml
@@ -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>
diff --git a/doc/user/environments.sgml b/doc/user/environments.sgml
index 77d9c6b..d3c3b0c 100644
--- a/doc/user/environments.sgml
+++ b/doc/user/environments.sgml
@@ -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
diff --git a/doc/user/errors.sgml b/doc/user/errors.sgml
index 448777f..f83ab63 100644
--- a/doc/user/errors.sgml
+++ b/doc/user/errors.sgml
@@ -25,16 +25,16 @@
<para>
- X
+ XXX
</para>
<section>
- <title>X</title>
+ <title>XXX</title>
<para>
- X
+ XXX
</para>
diff --git a/doc/user/example.sgml b/doc/user/example.sgml
index 448777f..f83ab63 100644
--- a/doc/user/example.sgml
+++ b/doc/user/example.sgml
@@ -25,16 +25,16 @@
<para>
- X
+ XXX
</para>
<section>
- <title>X</title>
+ <title>XXX</title>
<para>
- X
+ XXX
</para>
diff --git a/doc/user/hierarchy.sgml b/doc/user/hierarchy.sgml
index 617eb59..e39da8f 100644
--- a/doc/user/hierarchy.sgml
+++ b/doc/user/hierarchy.sgml
@@ -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>
diff --git a/doc/user/install.sgml b/doc/user/install.sgml
index 2cebbd4..7f522e5 100644
--- a/doc/user/install.sgml
+++ b/doc/user/install.sgml
@@ -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:
@@ -104,7 +104,7 @@
<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
index 0000000..ea41f5d
--- /dev/null
+++ b/doc/user/libraries.sgml
@@ -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>
diff --git a/doc/user/main.sgml b/doc/user/main.sgml
index 9ea4dd5..12b0480 100644
--- a/doc/user/main.sgml
+++ b/doc/user/main.sgml
@@ -34,9 +34,11 @@
<!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">
@@ -102,6 +105,11 @@
&environments;
</chapter>
+ <chapter id="chap-libraries">
+ <title>Building and Linking with Libraries</title>
+ &libraries;
+ </chapter>
+
<chapter id="chap-depends">
<title>Dependencies</title>
&depends;
@@ -142,14 +150,19 @@
&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">
@@ -222,4 +235,9 @@
&cons;
</appendix>
+ <appendix id="app-ant">
+ <title>Converting From Ant</title>
+ &ant;
+ </appendix>
+
</book>
diff --git a/doc/user/make.sgml b/doc/user/make.sgml
index 5666ea6..c7ecc63 100644
--- a/doc/user/make.sgml
+++ b/doc/user/make.sgml
@@ -94,16 +94,16 @@ the makefiles.
<para>
- X
+ XXX
</para>
<section>
- <title>X</title>
+ <title>XXX</title>
<para>
- X
+ XXX
</para>
diff --git a/doc/user/preface.sgml b/doc/user/preface.sgml
index 82ea44a..bba7f49 100644
--- a/doc/user/preface.sgml
+++ b/doc/user/preface.sgml
@@ -23,63 +23,182 @@
-->
- <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>
diff --git a/doc/user/repositories.sgml b/doc/user/repositories.sgml
index 616e903..07af115 100644
--- a/doc/user/repositories.sgml
+++ b/doc/user/repositories.sgml
@@ -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>
diff --git a/doc/user/run.sgml b/doc/user/run.sgml
index 30b61ca..83ca3d2 100644
--- a/doc/user/run.sgml
+++ b/doc/user/run.sgml
@@ -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>
diff --git a/doc/user/scanners.sgml b/doc/user/scanners.sgml
index 8d13b0c..76b2a1a 100644
--- a/doc/user/scanners.sgml
+++ b/doc/user/scanners.sgml
@@ -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>
diff --git a/doc/user/separate.sgml b/doc/user/separate.sgml
index 21fcabc..ac3c0f3 100644
--- a/doc/user/separate.sgml
+++ b/doc/user/separate.sgml
@@ -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>
diff --git a/doc/user/simple.sgml b/doc/user/simple.sgml
index 2acd669..8f76f2a 100644
--- a/doc/user/simple.sgml
+++ b/doc/user/simple.sgml
@@ -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>
diff --git a/doc/user/sourcecode.sgml b/doc/user/sourcecode.sgml
index 4ee49d4..6bbccee 100644
--- a/doc/user/sourcecode.sgml
+++ b/doc/user/sourcecode.sgml
@@ -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>
@@ -110,7 +110,7 @@
<programlisting>
env = Environment()
- env.SourceCode('.', env.SCCS()
+ env.SourceCode('.', env.SCCS())
env.Program('hello.c')
</programlisting>
@@ -132,7 +132,7 @@
<programlisting>
env = Environment()
- env.SourceCode('.', env.Subversion('XXX')
+ env.SourceCode('.', env.Subversion('XXX'))
env.Program('hello.c')
</programlisting>
diff --git a/doc/user/troubleshoot.sgml b/doc/user/troubleshoot.sgml
index 448777f..f83ab63 100644
--- a/doc/user/troubleshoot.sgml
+++ b/doc/user/troubleshoot.sgml
@@ -25,16 +25,16 @@
<para>
- X
+ XXX
</para>
<section>
- <title>X</title>
+ <title>XXX</title>
<para>
- X
+ XXX
</para>
diff --git a/doc/user/variants.sgml b/doc/user/variants.sgml
index 6ad9360..09dd16d 100644
--- a/doc/user/variants.sgml
+++ b/doc/user/variants.sgml
@@ -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>