Branch for in-progress User's Guide changes.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 25 Mar 2003 05:13:22 +0000 (05:13 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 25 Mar 2003 05:13:22 +0000 (05:13 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@621 fdb21ef1-2011-0410-befe-b5e4ea1792b1

41 files changed:
doc/SConscript
doc/reference/.aeignore [new file with mode: 0644]
doc/reference/Alias.sgml [moved from doc/user/more.sgml with 84% similarity]
doc/reference/CFile.sgml [new file with mode: 0644]
doc/reference/CXXFile.sgml [new file with mode: 0644]
doc/reference/Command.sgml [new file with mode: 0644]
doc/reference/Install.sgml [new file with mode: 0644]
doc/reference/InstallAs.sgml [new file with mode: 0644]
doc/reference/Library.sgml [moved from doc/user/library.sgml with 60% similarity]
doc/reference/Object.sgml [moved from doc/user/object.sgml with 100% similarity]
doc/reference/PCH.sgml [new file with mode: 0644]
doc/reference/PDF.sgml [new file with mode: 0644]
doc/reference/PostScript.sgml [new file with mode: 0644]
doc/reference/Program.sgml [moved from doc/user/program.sgml with 100% similarity]
doc/reference/RES.sgml [new file with mode: 0644]
doc/reference/SharedLibrary.sgml [new file with mode: 0644]
doc/reference/SharedObject.sgml [new file with mode: 0644]
doc/reference/StaticLibrary.sgml [new file with mode: 0644]
doc/reference/StaticObject.sgml [new file with mode: 0644]
doc/reference/copyright.sgml [new file with mode: 0644]
doc/reference/errors.sgml [moved from doc/user/reference.sgml with 87% similarity]
doc/reference/main.sgml [new file with mode: 0644]
doc/reference/preface.sgml [new file with mode: 0644]
doc/scons.mod
doc/user/alias.sgml
doc/user/builders.sgml
doc/user/caching.sgml
doc/user/command.sgml
doc/user/default.sgml
doc/user/depends.sgml
doc/user/environments.sgml
doc/user/help.sgml
doc/user/hierarchy.sgml
doc/user/install.sgml
doc/user/main.sgml
doc/user/precious.sgml
doc/user/repositories.sgml
doc/user/separate.sgml
doc/user/simple.sgml
doc/user/sourcecode.sgml [new file with mode: 0644]
doc/user/variants.sgml

index feb8a7535e99103e8e0bf3f115e486a4f2d0b1a7..d5fe171ba4af4588c6382c3a842e032e8a9a4239 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 #
-# __COPYRIGHT__
+# 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
@@ -141,6 +141,13 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
                 'text'      : 0,
                 'graphics'  : [ 'arch', 'builder', 'job-task', 'node', 'scanner', 'sig' ],
         },
+        'reference' : {
+                'htmlindex' : 'book1.html',
+                'html'      : 1,
+                'ps'        : 1,
+                'pdf'       : 1,
+                'text'      : 0,
+        },
         'user' : {
                 'htmlindex' : 'book1.html',
                 'html'      : 1,
diff --git a/doc/reference/.aeignore b/doc/reference/.aeignore
new file mode 100644 (file)
index 0000000..877ac53
--- /dev/null
@@ -0,0 +1,4 @@
+*,D
+.*.swp
+.consign
+.sconsign
similarity index 84%
rename from doc/user/more.sgml
rename to doc/reference/Alias.sgml
index 7defa414254cf726e75085c561504359f210e362..b87967dd65bc2f14c2004839c2d9f6f9d681270d 100644 (file)
  </para>
 
  <section>
- <title>The &Module; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
- <section>
- <title>The &RuleSet; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
- <section>
- <title>The &DefaultRules; Method</title>
+ <title>The &Alias; Method</title>
 
    <para>
 
diff --git a/doc/reference/CFile.sgml b/doc/reference/CFile.sgml
new file mode 100644 (file)
index 0000000..f76c390
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &CFile; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/CXXFile.sgml b/doc/reference/CXXFile.sgml
new file mode 100644 (file)
index 0000000..c1c038e
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &CXXFile; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/Command.sgml b/doc/reference/Command.sgml
new file mode 100644 (file)
index 0000000..abb3a58
--- /dev/null
@@ -0,0 +1,73 @@
+<!--
+
+  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.
+
+-->
+
+<!--
+
+=head2 The C<Command> method
+
+The C<Command> method is a catchall method which can be used to arrange for
+any build action to be executed to update the target. For this command, a
+target file and list of inputs is provided. In addition, a build action
+is specified as the last argument.  The build action is typically a
+command line or lines, but may also contain Perl code to be executed;
+see the section above on build actions for details.
+
+The C<Command> method is called as follows:
+
+  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.
+
+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
+  );
+
+could be used in a case where the command C<gen> creates two files, both
+F<foo.h> and F<foo.c>.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Command; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/Install.sgml b/doc/reference/Install.sgml
new file mode 100644 (file)
index 0000000..2d06e3b
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Install; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/InstallAs.sgml b/doc/reference/InstallAs.sgml
new file mode 100644 (file)
index 0000000..ed8cb78
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &InstallAs; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
similarity index 60%
rename from doc/user/library.sgml
rename to doc/reference/Library.sgml
index 0c9292ca5c0507d02d1a87fb21581be4a9aaa4d5..19a3e963aec27f27a573f46aa92b71b75af07e74 100644 (file)
@@ -63,11 +63,82 @@ be generated (the rest will disappear!).
 
 -->
 
- <para>
+ <section>
+ <title>Linking With a Library</title>
+
+   <programlisting>
+      env = Environment(CC = 'gcc',
+                        LIBS = 'world')
+      env.Program('hello.c')
+   </programlisting>
+
+   <literallayout>
+      % <userinput>scons</userinput>
+      gcc -c hello.c -o hello.o
+      gcc -c world.c -o world.o
+      gcc -o hello hello.o -lworld
+   </literallayout>
+
+ </section>
+
+ <section>
+ <title>Creating a Library</title>
+
+   <programlisting>
+      env = Environment(CC = 'gcc',
+                        LIBS = 'world')
+      env.Program('hello.c')
+      env.Library('world.c')
+   </programlisting>
+
+   <literallayout>
+      % <userinput>scons</userinput>
+      gcc -c hello.c -o hello.o
+      gcc -c world.c -o world.o
+      ar r libworld.a world.o
+      ar: creating libworld.a
+      ranlib libworld.a
+      gcc -o hello hello.o libworld.a
+   </literallayout>
+
+ </section>
+
+<!--
+
+A key simplification of Cons is the idea of a B<construction environment>. A
+construction environment is an B<object> characterized by a set of key/value
+pairs and a set of B<methods>. In order to tell Cons how to build something,
+you invoke the appropriate method via an appropriate construction
+environment. Consider the following example:
 
-   X
 
- </para>
+
+  $env = new cons(
+       CC      =>      'gcc',
+       LIBS    =>      'libworld.a'
+  );
+
+  Program $env 'hello', 'hello.c';
+
+In this case, rather than using the default construction environment, as is,
+we have overridden the value of C<CC> so that the GNU C Compiler equivalent
+is used, instead. Since this version of B<Hello, World!> requires a library,
+F<libworld.a>, we have specified that any program linked in this environment
+should be linked with that library. If the library exists already, well and
+good, but if not, then we'll also have to include the statement:
+
+
+
+  Library $env 'libworld', 'world.c';
+
+Now if you type C<cons hello>, the library will be built before the program
+is linked, and, of course, C<gcc> will be used to compile both modules:
+
+
+
+  % cons hello
+
+-->
 
  <section>
  <title>The &Library; Builder</title>
diff --git a/doc/reference/PCH.sgml b/doc/reference/PCH.sgml
new file mode 100644 (file)
index 0000000..b2a4d75
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &PCH; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/PDF.sgml b/doc/reference/PDF.sgml
new file mode 100644 (file)
index 0000000..b3a25dc
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &PDF; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/PostScript.sgml b/doc/reference/PostScript.sgml
new file mode 100644 (file)
index 0000000..f5a6579
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &PostScript; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/RES.sgml b/doc/reference/RES.sgml
new file mode 100644 (file)
index 0000000..15c0aea
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &RES; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/SharedLibrary.sgml b/doc/reference/SharedLibrary.sgml
new file mode 100644 (file)
index 0000000..603dab1
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &SharedLibrary; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/SharedObject.sgml b/doc/reference/SharedObject.sgml
new file mode 100644 (file)
index 0000000..0860769
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &SharedObject; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/StaticLibrary.sgml b/doc/reference/StaticLibrary.sgml
new file mode 100644 (file)
index 0000000..ea7ae5b
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &StaticLibrary; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/StaticObject.sgml b/doc/reference/StaticObject.sgml
new file mode 100644 (file)
index 0000000..ff8dae8
--- /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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &StaticObject; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/reference/copyright.sgml b/doc/reference/copyright.sgml
new file mode 100644 (file)
index 0000000..7f6059c
--- /dev/null
@@ -0,0 +1,32 @@
+<!--
+
+  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.
+
+-->
+
+<blockquote>
+ <para>
+
+  SCons User's Guide Copyright (c) 2003 Steven Knight
+
+ </para>
+</blockquote>
similarity index 87%
rename from doc/user/reference.sgml
rename to doc/reference/errors.sgml
index ef8e5a94dedf5c55a40caa2bb5442103bbd1e6db..448777f1d175d658030520276bbdc59c6bb1b986 100644 (file)
 
  </para>
 
- <section>
- <title>Command-Line Options</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
- <section>
- <title>Default Builders</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
  <section>
  <title>X</title>
 
diff --git a/doc/reference/main.sgml b/doc/reference/main.sgml
new file mode 100644 (file)
index 0000000..87b4a84
--- /dev/null
@@ -0,0 +1,204 @@
+<!--
+
+  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.
+
+-->
+
+<!doctype book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"
+[
+
+    <!ENTITY % version SYSTEM "../version.sgml">
+    %version;
+
+    <!ENTITY % scons SYSTEM "../scons.mod">
+    %scons;
+
+    <!-- Builders -->
+    <!ENTITY Alias_file SYSTEM "Alias.sgml">
+    <!ENTITY CFile_file SYSTEM "CFile.sgml">
+    <!ENTITY CXXFile_file SYSTEM "CXXFile.sgml">
+    <!ENTITY Command_file SYSTEM "Command.sgml">
+    <!ENTITY Install_file SYSTEM "Install.sgml">
+    <!ENTITY InstallAs_file SYSTEM "InstallAs.sgml">
+    <!ENTITY Library_file SYSTEM "Library.sgml">
+    <!ENTITY Object_file SYSTEM "Object.sgml">
+    <!ENTITY PCH_file SYSTEM "PCH.sgml">
+    <!ENTITY PDF_file SYSTEM "PDF.sgml">
+    <!ENTITY PostScript_file SYSTEM "PostScript.sgml">
+    <!ENTITY Program_file SYSTEM "Program.sgml">
+    <!ENTITY RES_file SYSTEM "RES.sgml">
+    <!ENTITY SharedLibrary_file SYSTEM "SharedLibrary.sgml">
+    <!ENTITY SharedObject_file SYSTEM "SharedObject.sgml">
+    <!ENTITY StaticLibrary_file SYSTEM "StaticLibrary.sgml">
+    <!ENTITY StaticObject_file SYSTEM "StaticObject.sgml">
+
+    <!-- Construction Variables -->
+
+    <!ENTITY copyright SYSTEM "copyright.sgml">
+    <!ENTITY errors SYSTEM "errors.sgml">
+    <!ENTITY preface SYSTEM "preface.sgml">
+
+]>
+
+<book>
+  <bookinfo>
+    <title>SCons Reference Manual &buildversion;</title>
+
+    <author>
+      <firstname>Steven</firstname>
+      <surname>Knight</surname>
+    </author>
+
+    <edition>Revision &buildrevision; (&builddate;)</edition>
+
+    <pubdate>2003</pubdate>
+
+    <copyright>
+      <year>2003</year>
+      <holder>Steven Knight</holder>
+    </copyright>
+
+    <legalnotice>
+      &copyright;
+    </legalnotice>
+
+    <releaseinfo>version &buildversion;</releaseinfo>
+
+  </bookinfo>
+
+  <chapter id="chap-preface">
+    <title>Preface</title>
+    &preface;
+  </chapter>
+
+  <chapter id="chap-builders">
+    <title>Builder Reference</title>
+
+    <section id="sect-Alias">
+      <title>The Alias Builder</title>
+      &Alias_file;
+    </section>
+
+    <section id="sect-CFile">
+      <title>The CFile Builder</title>
+      &CFile_file;
+    </section>
+
+    <section id="sect-Command">
+      <title>The Command Builder</title>
+      &Command_file;
+    </section>
+
+    <section id="sect-CXXFile">
+      <title>The CXXFile Builder</title>
+      &CXXFile_file;
+    </section>
+
+    <section id="sect-Install">
+      <title>The Install Builder</title>
+      &Install_file;
+    </section>
+
+    <section id="sect-InstallAs">
+      <title>The InstallAs Builder</title>
+      &InstallAs_file;
+    </section>
+
+    <section id="sect-Library">
+      <title>The Library Builder</title>
+      &Library_file;
+    </section>
+
+    <section id="sect-Object">
+      <title>The Object Builder</title>
+      &Object_file;
+    </section>
+
+    <section id="sect-PCH">
+      <title>The PCH Builder</title>
+      &PCH_file;
+    </section>
+
+    <section id="sect-PDF">
+      <title>The PDF Builder</title>
+      &PDF_file;
+    </section>
+
+    <section id="sect-PostScript">
+      <title>The PDF Builder</title>
+      &PostScript_file;
+    </section>
+
+    <section id="sect-Program">
+      <title>The Program Builder</title>
+      &Program_file;
+    </section>
+
+    <section id="sect-RES">
+      <title>The RES Builder</title>
+      &RES_file;
+    </section>
+
+    <section id="sect-SharedLibrary">
+      <title>The SharedLibrary Builder</title>
+      &SharedLibrary_file;
+    </section>
+
+    <section id="sect-SharedObject">
+      <title>The SharedObject Builder</title>
+      &SharedObject_file;
+    </section>
+
+    <section id="sect-StaticLibrary">
+      <title>The StaticLibrary Builder</title>
+      &StaticLibrary_file;
+    </section>
+
+    <section id="sect-StaticObject">
+      <title>The StaticObject Builder</title>
+      &StaticObject_file;
+    </section>
+
+  </chapter>
+
+  <chapter id="chap-variables">
+    <title>&ConsVar; Reference</title>
+
+    <section id="sect-AR">
+      <title>AR</title>
+
+      <para>
+
+      X
+
+      </para>
+
+    </section>
+
+  </chapter>
+
+  <appendix id="chap-errors">
+    <title>Errors Generated by &SCons;</title>
+    &errors;
+  </appendix>
+
+</book>
diff --git a/doc/reference/preface.sgml b/doc/reference/preface.sgml
new file mode 100644 (file)
index 0000000..82ea44a
--- /dev/null
@@ -0,0 +1,85 @@
+<!--
+
+  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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>Why &SCons;?</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>History</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>Conventions</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>Acknowledgements</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>Contact</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
index 9f1832c4f74922402544f02cec6c38062b3faf95..1c2653ef774d39e2ac966548d465ba38d1f0974a 100644 (file)
@@ -16,6 +16,7 @@
 
 <!ENTITY Autoconf "<application>Autoconf</application>">
 <!ENTITY Cons "<application>Cons</application>">
+<!ENTITY gcc "<application>gcc</application>">
 <!ENTITY Make "<application>Make</application>">
 <!ENTITY Makepp "<application>Make++</application>">
 <!ENTITY SCons "<application>SCons</application>">
@@ -79,8 +80,9 @@
 
 <!ENTITY Alias "<function>Alias</function>">
 <!ENTITY Aliases "<function>Aliases</function>">
+<!ENTITY Append "<function>Append</function>">
 <!ENTITY Build "<function>Build</function>">
-<!ENTITY Cache "<function>Cache</function>">
+<!ENTITY CacheDir "<function>CacheDir</function>">
 <!ENTITY Clean "<function>Clean</function>">
 <!ENTITY Clone "<function>Clone</function>">
 <!ENTITY Command "<function>Command</function>">
 <!ENTITY Split "<function>Split</function>">
 <!ENTITY Task "<function>Task</function>">
 
+<!-- Obsolete, but referenced in old documents.  -->
+<!ENTITY Cache "<function>Cache</function>">
+
 
 
 <!--
 
 -->
 
+<!ENTITY CC "<varname>CC</varname>">
 <!ENTITY CCFLAGS "<varname>CCFLAGS</varname>">
 <!ENTITY LIBPATH "<varname>LIBPATH</varname>">
 <!ENTITY PYTHONPATH "<varname>PYTHONPATH</varname>">
 
 -->
 
-<!ENTITY Object "<function>Object</function>">
+<!ENTITY BuildDir "<function>BuildDir</function>">
+<!ENTITY CFile "<function>CFile</function>">
+<!ENTITY CXXFile "<function>CXXFile</function>">
 <!ENTITY Library "<function>Library</function>">
-<!ENTITY SharedLibrary "<function>SharedLibrary</function>">
+<!ENTITY Object "<function>Object</function>">
+<!ENTITY PCH "<function>PCH</function>">
+<!ENTITY PDF "<function>PDF</function>">
+<!ENTITY PostScript "<function>PostScript</function>">
 <!ENTITY Program "<function>Program</function>">
+<!ENTITY RES "<function>RES</function>">
+<!ENTITY SharedLibrary "<function>SharedLibrary</function>">
+<!ENTITY SharedObject "<function>SharedObject</function>">
+<!ENTITY StaticLibrary "<function>StaticLibrary</function>">
+<!ENTITY StaticObject "<function>StaticObject</function>">
+
+<!-- Obsolete, but referenced in old documents.  -->
 <!ENTITY MakeBuilder "<function>Make</function>">
-<!ENTITY BuildDir "<function>BuildDir</function>">
 
 
 
index 33c236ac39b059916ce2bcd3ae9352da414afd2d..3f48ee095f7e80035d06bf7559e40b82a2fd7e42 100644 (file)
 
 -->
 
-<!--
+  <para>
 
--->
+  We've already seen how you can use the &Alias;
+  function to create a target named <literal>install</literal>:
+
+  </para>
+
+  <programlisting>
+     env = Environment()
+     hello = env.Program('hello.c')
+     env.Install('/usr/bin', hello)
+     env.Alias('install', '/usr/bin')
+  </programlisting>
+
+  <para>
+
+  You can then use this alias on the command line
+  to tell &SCons; more naturally that you want to install files:
+
+  </para>
+
+  <literallayout>
+     % <userinput>scons install</userinput>
+     Install file: "hello" as "/usr/bin/hello"
+  </literallayout>
 
- <para>
 <para>
 
-   X
+  Like other &Builder; methods, though,
+  the &Alias; method returns an object
+  representing the alias being built.
+  You can then use this object as input to anothother &Builder;.
+  This is especially useful if you use such an object
+  as input to another call to the &Alias; &Builder;,
+  allowing you to create a hierarchy
+  of nested aliases:
 
- </para>
 </para>
 
- <section>
- <title>Alias Targets</title>
+  <programlisting>
+     env = Environment()
+     p = env.Program('hello.c')
+     l = env.Library('hello.c')
+     env.Install('/usr/bin', p)
+     env.Install('/usr/lib', l)
+     ib = env.Alias('install-bin', '/usr/bin')
+     il = env.Alias('install-lib', '/usr/lib')
+     env.Alias('install', [ib, il])
+  </programlisting>
 
-   <para>
+  <para>
 
-   X
+  This example defines separate <literal>install</literal>,
+  <literal>install-bin</literal>,
+  and <literal>install-lib</literal> aliases,
+  allowing you finer control over what gets installed:
 
-   </para>
+  </para>
 
- </section>
+  <literallayout>
+     % <userinput>scons install-bin</userinput>
+     Install file: "hello" as "/usr/bin/hello"
+     % <userinput>scons install-lib</userinput>
+     Install file: "libhello.a" as "/usr/lib/libhello.a"
+     % <userinput>scons -c /</userinput>
+     % <userinput>scons install</userinput>
+     Install file: "hello" as "/usr/bin/hello"
+     Install file: "libhello.a" as "/usr/lib/libhello.a"
+  </literallayout>
index ac5f19371fb793643f7a5801c2ad7fec50f6f961..c1b426943da5c797fad966e5b341eed39adea650 100644 (file)
@@ -95,30 +95,375 @@ This functionality could be invoked as in the following example:
 
 -->
 
- <para>
+  <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.
+
+  </para>
+
+  <section>
+  <title>Builders That Execute External Commands</title>
+
+    <para>
+
+    The simplest &Builder; to create is
+    one that executes an external command.
+    For example, if we want to build
+    an output file by running the contents
+    of the input file through a command named
+    <literal>foobuild</literal>,
+    creating that &Builder; might look like:
+
+    </para>
+
+    <programlisting>
+       bld = Builder(action = 'foobuild < $TARGET > $SOURCE')
+    </programlisting>
+
+  </section>
+
+  <section>
+  <title>Attaching a Builder to a &ConsEnv;</title>
+
+    <para>
+
+    A &Builder; object by itself, though,
+    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.
+    For example, if we want to call the
+    &Builder; we defined by the name
+    <function>Foo</function>,
+    our &SConstruct; file might look like:
+
+    </para>
+
+    <programlisting>
+       bld = Builder(action = 'foobuild < $TARGET > $SOURCE')
+       env = Environment(BUILDERS = {'Foo' : bld})
+       env.Foo('file.foo', 'file.input')
+    </programlisting>
+
+    <para>
+
+    Then when we run &SCons; it looks like:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      foobuild < file.input > file.foo
+    </literallayout>
+
+    <para>
+
+    Note, however, that the default &BUILDERS;
+    variable in a &consenv;
+    comes with a default set of &Builder; objects
+    already defined:
+    &Program;, &Library;, etc.
+    And when we explicitly set the &BUILDERS; variable
+    when we create the &consenv;,
+    the default &Builder;s are no longer part of
+    the environment:
+
+    </para>
+
+    <programlisting>
+       bld = Builder(action = 'foobuild < $TARGET > $SOURCE')
+       env = Environment(BUILDERS = {'Foo' : bld})
+       env.Foo('file.foo', 'file.input')
+       env.Program('hello.c')
+    </programlisting>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      scons: Reading SConscript files ...
+      other errors
+      Traceback (most recent call last):
+        File "/usr/lib/scons/SCons/Script/__init__.py", line 901, in main
+          _main()
+        File "/usr/lib/scons/SCons/Script/__init__.py", line 762, in _main
+          SCons.Script.SConscript.SConscript(script)
+        File "/usr/lib/scons/SCons/Script/SConscript.py", line 207, in SConscript
+          exec _file_ in stack[-1].globals
+        File "SConstruct", line 4, in ?
+          env.Program('hello.c')
+      scons: Environment instance has no attribute 'Program'
+    </literallayout>
+
+    <para>
+
+    To be able use both our own defined &Builder; objects
+    and the default &Builder; objects in the same &consenv;,
+    you can either add to the &BUILDERS; variable
+    using the &Append; function:
+
+    </para>
+
+    <programlisting>
+       env = Environment()
+       bld = Builder(action = 'foobuild < $TARGET > $SOURCE')
+       env.Append(BUILDERS = {'Foo' : bld})
+       env.Foo('file.foo', 'file.input')
+       env.Program('hello.c')
+    </programlisting>
+
+    <para>
+
+    Or you can explicitly set the appropriately-named
+    key in the &BUILDERS; dictionary:
+
+    </para>
+
+    <programlisting>
+       env = Environment()
+       bld = Builder(action = 'foobuild < $TARGET > $SOURCE')
+       env['BUILDERS']['Foo'] = bld
+       env.Foo('file.foo', 'file.input')
+       env.Program('hello.c')
+    </programlisting>
+
+    <para>
+
+    Either way, the same &consenv;
+    can then use both the newly-defined
+    <function>Foo</function> &Builder;
+    and the default &Program; &Builder;:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      foobuild < file.input > file.foo
+      cc -c hello.c -o hello.o
+      cc -o hello hello.o
+    </literallayout>
+
+  </section>
+
+  <section>
+  <title>Letting &SCons; Handle The File Suffixes</title>
+
+    <para>
+
+    By supplying additional information
+    when you create a &Builder;,
+    you can let &SCons; add appropriate file
+    suffixes to the target and/or the source file.
+    For example, rather than having to specify
+    explicitly that you want the <literal>Foo</literal>
+    &Builder; to build the <literal>file.foo</literal>
+    target file from the <literal>file.input</literal> source file,
+    you can give the <literal>.foo</literal>
+    and <literal>.input</literal> suffixes to the &Builder;,
+    making for more compact and readable calls to
+    the <literal>Foo</literal> &Builder;:
+
+    </para>
+
+    <programlisting>
+       bld = Builder(action = 'foobuild < $TARGET > $SOURCE',
+                     suffix = '.foo',
+                     src_suffix = '.input')
+       env = Environment(BUILDERS = {'Foo' : bld})
+       env.Foo('file1')
+       env.Foo('file2')
+    </programlisting>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      foobuild < file1.input > file1.foo
+      foobuild < file2.input > file2.foo
+    </literallayout>
+
+    <para>
+
+    You can also supply a <literal>prefix</literal> keyword argument
+    if it's appropriate to have &SCons; append a prefix
+    to the beginning of target file names.
+
+    </para>
+
+  </section>
 
-   X
+  <section>
+  <title>Builders That Execute Python Functions</title>
 
</para>
   <para>
 
- <section>
- <title>Builders That Execute External Commands</title>
+    In &SCons;, you don't have to call an external command
+    to build a file.
+    You can, instead, define a Python function
+    that a &Builder; object can invoke
+    to build your target file (or files).
 
-   <para>
+    </para>
 
-   X
+    <programlisting>
+       def build_function(target, source, env):
+           # XXX
+           return None
+    </programlisting>
 
-   </para>
+    <para>
 
- </section>
+    XXX explain the function
+    XXX define the arguments
 
- <section>
- <title>Builders That Execute Python Functions</title>
+    </para>
 
-   <para>
+    <para>
 
-   X
+    Once you've defined the Python function
+    that will build your target file,
+    defining a &Builder; object for it is as
+    simple as specifying the name of the function,
+    instead of an external command,
+    as the &Builder;'s
+    <literal>action</literal>
+    argument:
+
+    </para>
+
+    <programlisting>
+       def build_function(target, source, env):
+           # XXX
+           return None
+       bld = Builder(action = build_function,
+                     suffix = '.foo',
+                     src_suffix = '.input')
+       env = Environment(BUILDERS = {'Foo' : bld})
+       env.Foo('file')
+    </programlisting>
+
+    <para>
+
+    And notice that the output changes slightly,
+    reflecting the fact that a Python function,
+    not an external command,
+    is now called to build the target file:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      build_function("file.foo", "file.input")
+    </literallayout>
+
+  </section>
+
+  <section>
+  <title>Builders That Generate Actions</title>
 
-   </para>
+    <para>
 
- </section>
+    X
+
+    </para>
+
+    <programlisting>
+       def generate_actions(XXX):
+           return XXX
+       bld = Builder(generator = generate_actions,
+                     suffix = '.foo',
+                     src_suffix = '.input')
+       env = Environment(BUILDERS = {'Foo' : bld})
+       env.Foo('file')
+    </programlisting>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      XXX
+    </literallayout>
+
+    <para>
+
+    Note that it's illegal to specify both an
+    <literal>action</literal>
+    and a
+    <literal>generator</literal>
+    for a &Builder;.
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Builders That Modify the Target List</title>
+
+    <para>
+
+    X
+
+    </para>
+
+    <programlisting>
+       def modify_targets(XXX):
+           return XXX
+       bld = Builder(action = 'XXX',
+                     suffix = '.foo',
+                     src_suffix = '.input',
+                     emitter = modify_targets)
+       env = Environment(BUILDERS = {'Foo' : bld})
+       env.Foo('file')
+    </programlisting>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      XXX
+    </literallayout>
+
+    <programlisting>
+       bld = Builder(action = 'XXX',
+                     suffix = '.foo',
+                     src_suffix = '.input',
+                     emitter = 'MY_EMITTER')
+       def modify1(XXX):
+           return XXX
+       def modify2(XXX):
+           return XXX
+       env1 = Environment(BUILDERS = {'Foo' : bld},
+                          MY_EMITTER = modify1)
+       env2 = Environment(BUILDERS = {'Foo' : bld},
+                          MY_EMITTER = modify2)
+       env1.Foo('file1')
+       env2.Foo('file2')
+    </programlisting>
+
+  </section>
+
+  <section>
+  <title>Builders That Use Other Builders</title>
+
+    <para>
+
+    X
+
+    </para>
+
+    <programlisting>
+       env = Environment()
+       env.SourceCode('.', env.BitKeeper('XXX')
+       env.Program('hello.c')
+    </programlisting>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      XXX
+    </literallayout>
+
+  </section>
index 5403c43ed2979747b011e306547954d3bb519e56..ed72c1e000fab038741aca20de07056b59ad2597 100644 (file)
 
 -->
 
-<!--
+  <para>
 
-=head2 The C<UseCache> method
+  On multi-developer software projects,
+  you can sometimes speed up every developer's builds a lot by
+  allowing them to share the derived files that they build.
+  &SCons; makes this easy, as well as reliable.
 
-The C<UseCache> method instructs Cons to maintain a cache of derived
-files, to be shared among separate build trees of the same project.
+  </para>
 
-  UseCache("cache/<buildname>") || warn("cache directory not found");
+  <section>
+  <title>Specifying the Shared Cache Directory</title>
 
--->
+    <para>
+
+    To enable sharing of derived files,
+    use the &CacheDir; function
+    in any &SConscript; file:
+
+    </para>
+
+    <programlisting>
+       CacheDir('/usr/local/build_cache')
+    </programlisting>
+
+    <para>
+
+    Note that the directory you specify must already exist
+    and be readable and writable by all developers
+    who will be sharing derived files.
+    It should also be in some central location
+    that all builds will be able to access.
+    In environments where developers are using separate systems
+    (like individual workstations) for builds,
+    this directory would typically be
+    on a shared or NFS-mounted file system.
+
+    </para>
+
+    <para>
+
+    Here's what happens:
+    When a build has a &CacheDir; specified,
+    every time a file is built,
+    it is stored in the shared cache directory
+    along with its MD5 build signature.
+    On subsequent builds,
+    before an action is invoked to build a file,
+    &SCons; will check the shared cache directory
+    to see if a file with the exact same build
+    signature already exists.
+    If so, the derived file will not be built locally,
+    but will be copied into the local build directory
+    from the shared cache directory,
+    like so:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      cc -c hello.c -o hello.o
+      cc -o hello hello.o
+      % <userinput>scons -c</userinput>
+      % <userinput>scons</userinput>
+      Retrieved `hello.o' from cache
+      Retrieved `hello' from cache
+      %
+    </literallayout>
+
+  </section>
+
+  <section>
+  <title>Keeping Build Output Consistent</title>
+
+    <para>
+
+    One potential drawback to using a shared cache
+    is that your build output can be inconsistent
+    from invocation to invocation,
+    because any given file may be rebuilt one time
+    and retrieved from the shared cache the next time.
+    This can make analyzing build output more difficult,
+    especially for automated scripts that
+    expect consistent output each time.
+
+    </para>
+
+    <para>
+
+    If, however, you use the <literal>--cache-show</literal> option,
+    &SCons; will print the command line that it
+    <emphasis>would</emphasis> have executed
+    to build the file,
+    even when it is retrieving the file from the shared cache.
+    This makes the build output consistent
+    every time the build is run:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      cc -c hello.c -o hello.o
+      cc -o hello hello.o
+      % <userinput>scons -c</userinput>
+      Removed hello.o
+      Removed hello
+      % <userinput>scons --cache-show</userinput>
+      cc -c hello.c -o hello.o
+      cc -o hello hello.o
+      %
+    </literallayout>
+
+    <para>
+
+    The trade-off, of course, is that you no longer
+    know whether or not &SCons;
+    has retrieved a derived file from cache
+    or has rebuilt it locally.
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Not Retrieving Files From a Shared Cache</title>
+
+    <para>
+
+    Retrieving an already-built file
+    from the shared cache
+    is usually a significant time-savings
+    over rebuilding the file,
+    but how much of a savings
+    (or even whether it saves time at all)
+    can depend a great deal on your
+    system or network configuration.
+    For example, retrieving cached files
+    from a busy server over a busy network
+    might end up being slower than
+    rebuilding the files locally.
+
+    </para>
+
+    <para>
+
+    In these cases, you can specify
+    the <literal>--cache-disable</literal>
+    command-line option to tell &SCons;
+    to not retrieve already-built files from the
+    shared cache directory:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      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
+      % <userinput>scons -c</userinput>
+      Removed hello.o
+      Removed hello
+      % <userinput>scons --cache-disable</userinput>
+      cc -c hello.c -o hello.o
+      cc -o hello hello.o
+      %
+    </literallayout>
+
+  </section>
+
+  <section>
+  <title>Populating a Shared Cache With Already-Built Files</title>
+
+    <para>
+
+    Sometimes, you may have one or more derived files
+    already built in your local build tree
+    that you wish to make available to other people doing builds.
+    For example, you may find it more effective to perform
+    integration builds with the cache disabled
+    (per the previous section)
+    and only populate the shared cache directory
+    with the built files after the integration build
+    has completed successfully.
+    This way, the cache will only get filled up
+    with derived files that are part of a complete, successful build
+    not with files that might be later overwritten
+    while you debug integration problems.
+
+    </para>
 
- <para>
   <para>
 
-   X
+    In this case, you can use the
+    the <literal>--cache-force</literal> option
+    to tell &SCons; to put all derived files in the cache,
+    even if the files had already been built
+    by a previous invocation:
 
- </para>
   </para>
 
- <section>
- <title>The &Cache; Method</title>
+    <literallayout>
+      % <userinput>scons --cache-disable</userinput>
+      cc -c hello.c -o hello.o
+      cc -o hello hello.o
+      % <userinput>scons -c</userinput>
+      Removed hello.o
+      Removed hello
+      % <userinput>scons --cache-disable</userinput>
+      cc -c hello.c -o hello.o
+      cc -o hello hello.o
+      % <userinput>scons --cache-force</userinput>
+      % <userinput>scons -c</userinput>
+      Removed hello.o
+      Removed hello
+      % <userinput>scons</userinput>
+      Retrieved `hello.o' from cache
+      Retrieved `hello' from cache
+      %
+    </literallayout>
 
-   <para>
+    <para>
 
-   X
+    Notice how the above sample run
+    demonstrates that the <literal>--cache-disable</literal>
+    option avoids putting the built
+    <filename>hello.o</filename>
+    and 
+    <filename>hello</filename> files in the cache,
+    but after using the <literal>--cache-force</literal> option,
+    the files have been put in the cache
+    for the next invocation to retrieve.
 
-   </para>
+    </para>
 
- </section>
 </section>
index abb3a581df5c6419ad436021eddb6e066523c8a5..945c6565b6a9d8bba107eff41ba758254dc6fd38 100644 (file)
 
 =head2 The C<Command> method
 
-The C<Command> method is a catchall method which can be used to arrange for
-any build action to be executed to update the target. For this command, a
-target file and list of inputs is provided. In addition, a build action
-is specified as the last argument.  The build action is typically a
-command line or lines, but may also contain Perl code to be executed;
-see the section above on build actions for details.
 
 The C<Command> method is called as follows:
 
@@ -55,19 +49,60 @@ F<foo.h> and F<foo.c>.
 
 -->
 
- <para>
-
-   X
-
- </para>
-
- <section>
- <title>The &Command; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
+  <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
+  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).
+  For these situations, &SCons; supports a
+  &Command; &Builder; that arranges
+  for a specific action to be executed
+  to build a specific file or files.
+  This looks a lot like the other builders
+  (like &Program;, &Object;, etc.),
+  but takes as an additional argument
+  the command to be executed to build the file:
+
+  </para>
+
+  <programlisting>
+     env = Environment()
+     env.Command('foo.out', 'foo.in', "sed 's/x/y/' < $TARGET > $SOURCE")
+  </programlisting>
+
+  <literallayout>
+    % <userinput>scons .</userinput>
+    sed 's/x/y' < foo.in > foo.out
+  </literallayout>
+
+  <para>
+
+  This is often more convenient than
+  creating a &Builder; object
+  and adding it to the &BUILDERS; variable
+  of a &consenv;
+
+  </para>
+
+  <para>
+
+  Note that the action you
+
+  </para>
+
+  <programlisting>
+     env = Environment()
+     def build(target, source, env)
+         XXX
+         return None
+     env.Command('foo.out', 'foo.in', build)
+  </programlisting>
+
+  <literallayout>
+    % <userinput>scons .</userinput>
+    build("foo.out", "foo.in")
+  </literallayout>
index eb2bdc1a69e82565096388fa6da8fed2a2b10cad..981ac426dd6de1ac5e6fb461ce06afdde807bf8c 100644 (file)
@@ -69,9 +69,9 @@ default list.
    explicitly specify one or more targets
    on the command line.
    Sometimes, however, you may want
-   to explicitly specify that only
-   certain programs should be built by default,
-   which you do using the &Default; function:
+   to specify explicitly that only
+   certain programs should be built by default.
+   You do this with the &Default; function:
 
    </para>
 
@@ -84,7 +84,7 @@ default list.
 
    <para>
 
-   This &SConstruct; file builds two programs,
+   This &SConstruct; file knows how to build two programs,
    &hello; and &goodbye;,
    but only builds the
    &hello program by default:
@@ -162,7 +162,7 @@ default list.
    <application>prog1</application>
    and
    <application>prog3</application>
-   programs:
+   programs by default:
 
    </para>
 
index e8491e4e2e1b0fd1b219ed47e891f2ad3ec2aa1b..8669c722a52a181e1d3f4fcb6ca1ab6b1b8e70e5 100644 (file)
@@ -46,369 +46,369 @@ operating system on which the build is performed (as reported by C<uname
 
 -->
 
- <para>
-
- So far we've seen how &SCons; handles one-time builds.
- But the real point of a build tool like &SCons;
- is to rebuild the necessary things when source files change.
- The other side of rebuilding all the necessary things
- is that &SCons; should <emphasis>not</emphasis>
- unnecessarily rebuild things that have already
- been built.
- You can see this at work simply be re-invoking &SCons;
- after building our simple &hello; example:
-
- </para>
-
- <literallayout>
-    % <userinput>scons</userinput>
-    cc -c hello.c -o hello.o
-    cc -o hello hello.o
-    % <userinput>scons</userinput>
-    %
- </literallayout>
-
- <para>
-
- &SCons; has remembered that the &hello; program
- is up-to-date with respect to the current &hello_c; source file,
- and avoids rebuilding it.
- You can see this more clearly by naming
- the &hello; program explicitly on the command line:
-
- </para>
-
- <literallayout>
-    % <userinput>scons hello</userinput>
-    cc -c hello.c -o hello.o
-    cc -o hello hello.o
-    % <userinput>scons hello</userinput>
-    scons: `hello' is up to date.
-    %
- </literallayout>
-
- <para>
-
- Note that &SCons; only reports "...is up to date"
- for target files named explicitly on the command line,
- to avoid cluttering the output.
-
- </para>
-
- <section>
- <title>MD5 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:
-
-   </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 saves time by avoiding unnecessary rebuilds when,
-   for example, someone rewrites the
-   contents of a file without making a change.
-   But if the contents of the file 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>
-
-   X
-
-   </para>
-
- </section>
+  <para>
+
+  So far we've seen how &SCons; handles one-time builds.
+  But the real point of a build tool like &SCons;
+  is to rebuild the necessary things,
+  and only the necessary thing, when source files change.
+  Put another way,
+  &SCons; should <emphasis>not</emphasis>
+  waste time rebuilding things that have already been built.
+  You can see this at work simply be re-invoking &SCons;
+  after building our simple &hello; example:
+
+  </para>
+
+  <literallayout>
+     % <userinput>scons</userinput>
+     cc -c hello.c -o hello.o
+     cc -o hello hello.o
+     % <userinput>scons</userinput>
+     %
+  </literallayout>
+
+  <para>
+
+  The second time it is executed,
+  &SCons; realizes that the &hello; program
+  is up-to-date with respect to the current &hello_c; source file,
+  and avoids rebuilding it.
+  You can see this more clearly by naming
+  the &hello; program explicitly on the command line:
+
+  </para>
+
+  <literallayout>
+     % <userinput>scons hello</userinput>
+     cc -c hello.c -o hello.o
+     cc -o hello hello.o
+     % <userinput>scons hello</userinput>
+     scons: `hello' is up to date.
+     %
+  </literallayout>
+
+  <para>
+
+  Note that &SCons; only reports "...is up to date"
+  for target files named explicitly on the command line,
+  to avoid cluttering the output.
+
+  </para>
+
+  <section>
+  <title>MD5 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:
+
+    </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 saves time by avoiding unnecessary rebuilds when,
+    for example, someone rewrites the
+    contents of a file without making a change.
+    But if the contents of the file 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>
+
+    X
+
+    </para>
+
+  </section>
+
+ <!--
+
+ Now it turns out that F<hello.c> also includes the interface definition
+ file, F<world.h>:
+
+ How does Cons know that F<hello.c> includes F<world.h>, and that F<hello.o>
+ must therefore be recompiled? For now, suffice it to say that when
+ considering whether or not F<hello.o> is up-to-date, Cons invokes a scanner
+ for its dependency, F<hello.c>. This scanner enumerates the files included
+ by F<hello.c> to come up with a list of further dependencies, beyond those
+ made explicit by the Cons script. This process is recursive: any files
+ included by included files will also be scanned.
 
-<!--
-
-Now it turns out that F<hello.c> also includes the interface definition
-file, F<world.h>:
-
-How does Cons know that F<hello.c> includes F<world.h>, and that F<hello.o>
-must therefore be recompiled? For now, suffice it to say that when
-considering whether or not F<hello.o> is up-to-date, Cons invokes a scanner
-for its dependency, F<hello.c>. This scanner enumerates the files included
-by F<hello.c> to come up with a list of further dependencies, beyond those
-made explicit by the Cons script. This process is recursive: any files
-included by included files will also be scanned.
-
--->
-
- <section>
- <title>Implicit Dependencies</title>
+ -->
 
-   <para>
+  <section>
+  <title>Implicit Dependencies</title>
+
+    <para>
+
+    Now suppose that our "Hello, World!" program
+    actually has a <literal>#include</literal> line
+    to include &hello_h; file in the compilation:
+
+    </para>
+
+    <programlisting>
+       #include "hello.h" 
+       int
+       main()
+       {
+           printf("Hello, %s!\n", string);
+       }
+    </programlisting>
+
+    <para>
+
+    And, for completeness, the &hello_h; file looks like this:
+
+    </para>
+
+    <programlisting>
+       #define string    "world"
+    </programlisting>
+
+    <para>
+
+    In this case, we want &SCons; to recognize that,
+    if the contents of the &hello_h; file change,
+    the &hello; program must be recompiled.
+    To do this, we need to modify the
+    &SConstruct; file like so:
+
+    </para>
+
+    <programlisting>
+       env = Environment(CPPPATH = '.')  XXX IS CPPPATH NECESSARY?
+       hello = env.Program('hello.c')
+    </programlisting>
+
+    <para>
+
+    The &CPPPATH; assignment in the &Environment; call
+    tells &SCons; to look in the current directory
+    (<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:
+
+    </para>
+
+    <literallayout>
+       % <userinput>scons hello</userinput>
+       cc -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 -o hello hello.o
+       %
+    </literallayout>
+
+    <para>
+
+    &SCons; knows that the &hello;
+    program must be rebuilt
+    because it scans the contents of
+    the &hello_c; file
+    for the <literal>#include</literal> lines that indicate
+    another file is being included in the compilation.
+    &SCons; records these as
+    <emphasis>implicit dependencies</emphasis>
+    of the target file,
+    Consequently,
+    when the &hello_h; file changes,
+    &SCons; realizes that the &hello_c; file includes it,
+    and rebuilds the resulting &hello; program
+    that depends on both the &hello_c; and &hello_h; files.
+
+    </para>
+
+    <para>
+
+    X
+
+ <!--
+ Isn't this expensive? The answer is, it depends. If you do a full build of a
+ large system, the scanning time is insignificant. If you do a rebuild of a
+ large system, then Cons will spend a fair amount of time thinking about it
+ before it decides that nothing has to be done (although not necessarily more
+ time than make!). The good news is that Cons makes it very easy to
+ intelligently subset your build, when you are working on localized changes.
+ -->
 
-   Now suppose that our "Hello, World!" program
-   actually looks like this:
+    </para>
+
+  </section>
+
+  <section>
+  <title>The &Ignore; Method</title>
+
+    <para>
+
+    Sometimes it makes sense 
+    to not rebuild a program,
+    even if a dependency file changes.
+    In this case,
+    you would tell &SCons; specifically
+    to ignore a dependency as follows:
+
+    </para>
+
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       env.Ignore(hello, 'hello.h')
+    </programlisting>
 
-   </para>
+    <!-- XXX mention that you can use arrays for target and source? -->
 
-   <programlisting>
-      #include "hello.h" 
-      int
-      main()
-      {
-          printf("Hello, %s!\n", string);
-      }
-   </programlisting>
+    <literallayout>
+       % <userinput>scons hello</userinput>
+       cc -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>
+       scons: `hello' is up to date.
+    </literallayout>
 
-   <para>
+    <para>
 
-   That is, the first line
-   includes a &hello_h;
-   that looks like this:
+    Now, the above example is a little contrived,
+    because it's hard to imagine a real-world situation
+    where you wouldn't to rebuild &hello;
+    if the &hello_h; file changed.
+    A more realistic example
+    might be if the &hello;
+    program is being built in a
+    directory that is shared between multiple systems
+    that have different copies of the
+    &stdio_h; include file.
+    In that case,
+    &SCons; would notice the differences between
+    the different systems' copies of &stdio_h;
+    and would rebuild &hello;
+    each time you change systems.
+    You could avoid these rebuilds as follows:
 
-   </para>
+    </para>
 
-   <programlisting>
-      #define string    "world"
-   </programlisting>
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       env.Ignore(hello, '/usr/include/stdio.h')
+    </programlisting>
 
-   <para>
+  </section>
 
-   In this case, we want &SCons; to recognize that,
-   if the contents of the &hello_h; file change,
-   the &hello; program must be recompiled.
-   To do this, we need to modify the
-   &SConstruct; file like so:
+  <section>
+  <title>The &Depends; Method</title>
 
-   </para>
+    <para>
 
-   <programlisting>
-      env = Environment(CPPPATH = '.')  XXX IS CPPPATH NECESSARY?
-      hello = env.Program('hello.c')
-   </programlisting>
+    On the other hand,
+    sometimes a file depends on another
+    file that the scanner(s) in &SCons; will not detect.
+    For this situation,
+    &SCons; allows you to specific that one file explicitly
+    depends on another file,
+    and must be rebuilt whenever that file changes,
+    using the &Depends; method:
 
-   <para>
+    </para>
 
-   The &CPPPATH; assignment in the &Environment; call
-   tells &SCons; to look in the current directory
-   (<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:
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       env.Depends(hello, 'other_file')
+    </programlisting>
 
-   </para>
+    <!-- XXX mention that you can use arrays for target and source? -->
 
-   <literallayout>
-      % <userinput>scons hello</userinput>
-      cc -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 -o hello hello.o
-      %
-   </literallayout>
+    <literallayout>
+       % <userinput>scons hello</userinput>
+       cc -c hello.c -o hello.o
+       cc -o hello hello.o
+       % <userinput>scons hello</userinput>
+       scons: `hello' is up to date.
+       % <userinput>edit other_file</userinput>
+           [CHANGE THE CONTENTS OF other_file]
+       % <userinput>scons hello</userinput>
+       cc -c hello.c -o hello.o
+       cc -o hello hello.o
+    </literallayout>
 
-   <para>
+  </section>
 
-   &SCons; knows that the &hello;
-   program must be rebuilt
-   because it scans the contents of
-   the &hello_c; file
-   for the <literal>#include</literal> lines that indicate
-   another file is being included in the compilation.
-   &SCons; records these as
-   <emphasis>implicit dependencies</emphasis>
-   of the target file,
-   Consequently,
-   when the &hello_h; file changes,
-   &SCons; realizes that the &hello_c; file includes it,
-   and rebuilds the resulting &hello; program
-   that depends on both the &hello_c; and &hello_h; files.
+  <!-->
 
-   </para>
+  <section>
+  <title>The &Salt; Method</title>
 
-   <para>
+    <para>
 
-   X
+    X
 
-<!--
-Isn't this expensive? The answer is, it depends. If you do a full build of a
-large system, the scanning time is insignificant. If you do a rebuild of a
-large system, then Cons will spend a fair amount of time thinking about it
-before it decides that nothing has to be done (although not necessarily more
-time than make!). The good news is that Cons makes it very easy to
-intelligently subset your build, when you are working on localized changes.
--->
+    </para>
 
-   </para>
-
- </section>
-
- <section>
- <title>The &Ignore; Method</title>
-
-   <para>
-
-   Sometimes it makes sense 
-   to not rebuild a program,
-   even if a dependency file changes.
-   In this case,
-   you would tell &SCons; specifically
-   to ignore a dependency as follows:
-
-   </para>
-
-   <programlisting>
-      env = Environment()
-      hello = env.Program('hello.c')
-      env.Ignore(hello, 'hello.h')
-   </programlisting>
-
-   <!-- XXX mention that you can use arrays for target and source? -->
-
-   <literallayout>
-      % <userinput>scons hello</userinput>
-      cc -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>
-      scons: `hello' is up to date.
-   </literallayout>
-
-   <para>
-
-   Now, the above example is a little contrived,
-   because it's hard to imagine a real-world situation
-   where you wouldn't to rebuild &hello;
-   if the &hello_h; file changed.
-   A more realistic example
-   might be if the &hello;
-   program is being built in a
-   directory that is shared between multiple systems
-   that have different copies of the
-   &stdio_h; include file.
-   In that case,
-   &SCons; would notice the differences between
-   the different systems' copies of &stdio_h;
-   and would rebuild &hello;
-   each time you change systems.
-   You could avoid these rebuilds as follows:
-
-   </para>
-
-   <programlisting>
-      env = Environment()
-      hello = env.Program('hello.c')
-      env.Ignore(hello, '/usr/include/stdio.h')
-   </programlisting>
-
- </section>
-
- <section>
- <title>The &Depends; Method</title>
-
-   <para>
-
-   On the other hand,
-   sometimes a file depends on another
-   file that the scanner(s) in &SCons; will not detect.
-   For this situation,
-   &SCons; allows you to specific that one file explicitly
-   depends on another file,
-   and must be rebuilt whenever that file changes,
-   using the &Depends; method:
-
-   </para>
-
-   <programlisting>
-      env = Environment()
-      hello = env.Program('hello.c')
-      env.Depends(hello, 'other_file')
-   </programlisting>
-
-   <!-- XXX mention that you can use arrays for target and source? -->
-
-   <literallayout>
-      % <userinput>scons hello</userinput>
-      cc -c hello.c -o hello.o
-      cc -o hello hello.o
-      % <userinput>scons hello</userinput>
-      scons: `hello' is up to date.
-      % <userinput>edit other_file</userinput>
-          [CHANGE THE CONTENTS OF other_file]
-      % <userinput>scons hello</userinput>
-      cc -c hello.c -o hello.o
-      cc -o hello hello.o
-   </literallayout>
-
- </section>
-
- <!-->
-
- <section>
- <title>The &Salt; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
+  </section>
 
- -->
 -->
 
- <section>
- <title>Time Stamps</title>
 <section>
 <title>Time Stamps</title>
 
-   <para>
+    <para>
 
-   X
+    X
 
-   </para>
+    </para>
 
- </section>
 </section>
 
- <section>
- <title>The &SourceSignature; Method</title>
 <section>
 <title>The &SourceSignature; Method</title>
 
-   <para>
+    <para>
 
-   X
+    X
 
-   </para>
+    </para>
 
- </section>
 </section>
index b06ade113e7d51c5af73ff7a718badea465cbe03..8117cf04a652f19a823034195cef7b2f3903c8c3 100644 (file)
 
 <!--
 
-=head2 Construction environments
-
-A key simplification of Cons is the idea of a B<construction environment>. A
-construction environment is an B<object> characterized by a set of key/value
-pairs and a set of B<methods>. In order to tell Cons how to build something,
-you invoke the appropriate method via an appropriate construction
-environment. Consider the following example:
-
-
-
-  $env = new cons(
-       CC      =>      'gcc',
-       LIBS    =>      'libworld.a'
-  );
-
-  Program $env 'hello', 'hello.c';
-
-In this case, rather than using the default construction environment, as is,
-we have overridden the value of C<CC> so that the GNU C Compiler equivalent
-is used, instead. Since this version of B<Hello, World!> requires a library,
-F<libworld.a>, we have specified that any program linked in this environment
-should be linked with that library. If the library exists already, well and
-good, but if not, then we'll also have to include the statement:
-
-
-
-  Library $env 'libworld', 'world.c';
-
-Now if you type C<cons hello>, the library will be built before the program
-is linked, and, of course, C<gcc> will be used to compile both modules:
-
-
-
-  % cons hello
-  gcc -c hello.c -o hello.o
-  gcc -c world.c -o world.o
-  ar r libworld.a world.o
-  ar: creating libworld.a
-  ranlib libworld.a
-  gcc -o hello hello.o libworld.a
-
 =head1 More on construction environments
 
 As previously mentioned, a B<construction environment> is an object that
@@ -346,6 +305,12 @@ by the MD5 signature calculation on the actual file contents.
 
 =back
 
+XXX
+
+DESCRIBE THE Literal() FUNCTION, TOO
+
+XXX
+
 =head2 Expanding construction variables in file names
 
 Cons expands construction variables in the source and target file names
@@ -420,101 +385,261 @@ C<PATH> variable in the default environment, you could do the following:
 This will leave anything else that might be in the default execution
 environment undisturbed.
 
+-->
+
+ <para>
 
+   It is rare that all of the software in a large,
+   complicated system needs to be built the same way.
+   Different source files need different options
+   enabled on the command line;
+   different executable programs need to be linked
+   with different libraries (shared or static);
+   XXX
+   &SCons; accomodates these different build
+   requirements by allowing you to create and
+   configure multiple &consenvs;
+   that control how the software is built.
+   Technically, a &consenv; is an object
+   that has a number of associated
+   &consvars;, each with a name and a value.
+   (A &consenv; also has an attached
+   set of &Builder; methods,
+   about which we'll learn more later.)
 
-=head2 Overriding construction variables
+ </para>
 
-There are several ways of extending Cons, which vary in degree of
-difficulty. The simplest method is to define your own construction
-environment, based on the default environment, but modified to reflect your
-particular needs. This will often suffice for C-based applications. You can
-use the C<new> constructor, and the C<clone> and C<copy> methods to create
-hybrid environments. These changes can be entirely transparent to the
-underlying F<Conscript> files.
+ <para>
 
--->
+   A &consenv; is created by the &Environment;
+   method which you have already seen.
+   What you haven't seen, though,
+   is that when you initialize a &consenv;,
+   you can set the values of the
+   environment's &consvars;
+   to control how a program is built.
+   For example:
+
+ </para>
+
+ <programlisting>
+    env = Environment(CC = 'gcc',
+                      CCFLAGS = '-O2')
+
+    env.Program('foo.c')
+ </programlisting>
 
  <para>
+   
+   This example, rather than using the default,
+   explicitly specifies use of the
+   GNU C compiler &gcc;,
+   and further specifies that the <literal>-O2</literal>
+   (optimization level two)
+   flag should be used when compiling the object file.
+   So a run from this example would look like:
 
-   X
+ </para>
 
-<!--
+ <literallayout>
+    % <userinput>scons</userinput>
+    gcc -c -O2 foo.c -o foo.o
+    gcc -o foo foo.o
+ </literallayout>
 
-A key simplification of Cons is the idea of a B<construction environment>. A
-construction environment is an B<object> characterized by a set of key/value
-pairs and a set of B<methods>. In order to tell Cons how to build something,
-you invoke the appropriate method via an appropriate construction
-environment. Consider the following example:
+ <section>
+ <title>Multiple &ConsEnvs;</title>
 
+   <para>
 
+   So far, we've always created a &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.
+   For example:
 
-  $env = new cons(
-       CC      =>      'gcc',
-       LIBS    =>      'libworld.a'
-  );
+   </para>
+
+   <programlisting>
+      my_env = Environment(CC = 'gcc',
+                        CCFLAGS = '-O2')
 
-  Program $env 'hello', 'hello.c';
+      my_env.Program('foo.c')
+   </programlisting>
 
-In this case, rather than using the default construction environment, as is,
-we have overridden the value of C<CC> so that the GNU C Compiler equivalent
-is used, instead. Since this version of B<Hello, World!> requires a library,
-F<libworld.a>, we have specified that any program linked in this environment
-should be linked with that library. If the library exists already, well and
-good, but if not, then we'll also have to include the statement:
+   <para>
 
+   This opens up the possibility of
+   using multiple &consenvs;,
+   each with a separate variable name.
+   We can then use these separate &consenvs;
+   to build different programs in different ways:
 
+   </para>
 
-  Library $env 'libworld', 'world.c';
+   <programlisting>
+      opt = Environment(CCFLAGS = '-O2')
+      dbg = Environment(CCFLAGS = '-g')
 
-Now if you type C<cons hello>, the library will be built before the program
-is linked, and, of course, C<gcc> will be used to compile both modules:
+      opt.Program('foo', 'foo.c')
 
+      dbg.Program('bar', 'bar.c')
+   </programlisting>
 
+   <literallayout>
+      % <userinput>scons</userinput>
+      cc -c -O2 bar.c -o bar.o
+      cc -o bar bar.o
+      cc -c -g foo.c -o foo.o
+      cc -o foo foo.o
+   </literallayout>
 
-  % cons hello
-  gcc -c hello.c -o hello.o
-  gcc -c world.c -o world.o
-  ar r libworld.a world.o
-  ar: creating libworld.a
-  ranlib libworld.a
-  gcc -o hello hello.o libworld.a
+   <para>
 
--->
+   We can even use multiple &consenvs; to build
+   multiple versions of a single program.
+   If you do this by simply trying to use the
+   &Program; builder with both environments, though,
+   like this:
 
- </para>
  </para>
 
- <programlisting>
-    optimize = Environment(CCFLAGS = '-O2')
-    debug = Environment(CCFLAGS = '-g')
  <programlisting>
+      opt = Environment(CCFLAGS = '-O2')
+      dbg = Environment(CCFLAGS = '-g')
 
-    o = optimize.Object('foo-opt', 'foo.c')
-    optimize.Program(o)
+      opt.Program('foo', 'foo.c')
 
-    d = debug.Object('foo-debug', 'foo.c')
-    debug.Program(d)
- </programlisting>
+      dbg.Program('foo', 'foo.c')
+   </programlisting>
 
- <literallayout>
-    % <userinput>scons .</userinput>
-    cc -c -g foo.c -o foo-debug.o
-    cc -o foo-debug foo-debug.o
-    cc -c -O2 foo.c -o foo-opt.o
-    cc -o foo-opt foo-opt.o
- </literallayout>
+   <para>
+
+   Then &SCons; generates the following error:
+
+   </para>
+
+   <literallayout>
+      % <userinput>scons</userinput>
+      scons: *** Two different environments were specified for the same target:  foo.o
+      File "SConstruct", line 6, in ?
+   </literallayout>
+
+   <para>
+
+   This is because the two &Program; calls have
+   each implicitly told &SCons; to generate an object file named
+   <filename>foo.o</filename>,
+   one with a &CCFLAGS; value of
+   <literal>-O2</literal>
+   and one with a &CCFLAGS; value of
+   <literal>-g</literal>.
+   To work around this,
+   we must explicitly specify
+   that each environment compile
+   <filename>foo.c</filename>
+   to a separately-named object file
+   using the &Object; call, like so:
+
+   </para>
+
+   <programlisting>
+      opt = Environment(CCFLAGS = '-O2')
+      dbg = Environment(CCFLAGS = '-g')
+
+      o = opt.Object('foo-opt', 'foo.c')
+      opt.Program(o)
+
+      d = dbg.Object('foo-dbg', 'foo.c')
+      dbg.Program(d)
+   </programlisting>
+
+   <para>
+
+   Notice that each call to the &Object; builder
+   returns a value,
+   an internal &SCons; object that
+   represents the file that will be built.
+   We then use that object
+   as input to the &Program; builder.
+   This avoids having to specify explicitly
+   the object file name in multiple places,
+   and makes for a compact, readable
+   &SConstruct file.
+   Our &SCons; output then looks like:
+
+   </para>
+
+   <literallayout>
+      % <userinput>scons</userinput>
+      cc -c -g foo.c -o foo-dbg.o
+      cc -o foo-dbg foo-dbg.o
+      cc -c -O2 foo.c -o foo-opt.o
+      cc -o foo-opt foo-opt.o
+   </literallayout>
+
+ </section>
 
  <section>
- <title>The &Environment; Constructor</title>
+ <title>Copying &ConsEnvs;</title>
 
    <para>
 
-   X
+   Sometimes you want to more than one &consenv;
+   to use 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
+   to create a copy of a &consenv;.
+   Like the &Environment; call that creates a &consenv;,
+   the &Copy; method takes &consvar; assignments,
+   which will override the values in the copied &consenv;.
+   For example, suppose we want to use &gcc;
+   to create three versions of a program,
+   one optimized, one debug, and one with neither.
+   We could do this by creating a "base" &consenv;
+   that sets &CC; to &gcc;,
+   and then creating two copies,
+   one which sets &CCFLAGS; for optimization
+   and the other with sets &CCFLAGS; for debugging:
+
+   </para>
+
+   <programlisting>
+      env = Environment(CC = 'gcc')
+      opt = env.Copy(CCFLAGS = '-O2')
+      dbg = env.Copy(CCFLAGS = '-g')
+
+      e = opt.Object('foo', 'foo.c')
+
+      o = opt.Object('foo-opt', 'foo.c')
+      opt.Program(o)
+
+      d = dbg.Object('foo-dbg', 'foo.c')
+      dbg.Program(d)
+   </programlisting>
+
+   <para>
+
+   Then our output would look like:
 
    </para>
 
+   <literallayout>
+      % <userinput>scons</userinput>
+      gcc -c foo.c -o foo.o
+      gcc -o foo foo.o
+      gcc -c -g foo.c -o foo-dbg.o
+      gcc -o foo-dbg foo-dbg.o
+      gcc -c -O2 foo.c -o foo-opt.o
+      gcc -o foo-opt foo-opt.o
+   </literallayout>
+
  </section>
 
  <section>
- <title>The &Copy; Method</title>
+ <title>Fetching Values From a &ConsEnv;</title>
 
    <para>
 
@@ -522,4 +647,74 @@ is linked, and, of course, C<gcc> will be used to compile both modules:
 
    </para>
 
+   <programlisting>
+      env = Environment()
+   </programlisting>
+
+   <literallayout>
+      % <userinput>scons</userinput>
+   </literallayout>
+
+ </section>
+
+ <section>
+ <title>Modifying a &ConsEnv;</title>
+
+   <section>
+   <title>Replacing Values in a &ConsEnv;</title>
+
+     <para>
+
+     X
+
+     </para>
+
+     <programlisting>
+        env = Environment()
+     </programlisting>
+
+     <literallayout>
+        % <userinput>scons</userinput>
+     </literallayout>
+
+   </section>
+
+   <section>
+   <title>Appending to the End of Values in a &ConsEnv;</title>
+
+     <para>
+
+     X
+
+     </para>
+
+     <programlisting>
+        env = Environment()
+     </programlisting>
+
+     <literallayout>
+        % <userinput>scons</userinput>
+     </literallayout>
+
+   </section>
+
+   <section>
+   <title>Appending to the Beginning of Values in a &ConsEnv;</title>
+
+     <para>
+
+     X
+
+     </para>
+
+     <programlisting>
+        env = Environment()
+     </programlisting>
+
+     <literallayout>
+        % <userinput>scons</userinput>
+     </literallayout>
+
+   </section>
+
  </section>
index 5e2ced380d6fb15de3af272f92b38d4bfbecc14d..233809e7a988762df1bf8762b99d444906d583bb 100644 (file)
@@ -69,7 +69,7 @@
    If there is no &Help; text in the &SConstruct; or
    &SConscript; files,
    &SCons; will revert to displaying its
-   standard list and description of available command-line
+   standard list that describes the &SCons; command-line
    options.
    This list is also always displayed whenever
    the <literal>-H</literal> option is used.
index aa56c8d4e34f6f43a7f97bb686688be530c2cff2..617eb5921b28291ebbba2a8ef88b687a10573245 100644 (file)
@@ -36,44 +36,6 @@ C<Import> commands.
 
 =head2 The Build command
 
-The C<Build> command takes a list of F<Conscript> file names, and arranges
-for them to be included in the build. For example:
-
-  Build qw(
-       drivers/display/Conscript
-       drivers/mouse/Conscript
-       parser/Conscript
-       utilities/Conscript
-  );
-
-This is a simple two-level hierarchy of build scripts: all the subsidiary
-F<Conscript> files are mentioned in the top-level F<Construct> file. Notice
-that not all directories in the tree necessarily have build scripts
-associated with them.
-
-This could also be written as a multi-level script. For example, the
-F<Construct> file might contain this command:
-
-  Build qw(
-       parser/Conscript
-       drivers/Conscript
-       utilities/Conscript
-  );
-
-and the F<Conscript> file in the F<drivers> directory might contain this:
-
-  Build qw(
-       display/Conscript
-       mouse/Conscript
-  );
-
-Experience has shown that the former model is a little easier to understand,
-since the whole construction tree is laid out in front of you, at the
-top-level. Hybrid schemes are also possible. A separately maintained
-component that needs to be incorporated into a build tree, for example,
-might hook into the build tree in one place, but define its own construction
-hierarchy.
-
 By default, Cons does not change its working directory to the directory
 containing a subsidiary F<Conscript> file it is including.  This behavior
 can be enabled for a build by specifying, in the top-level F<Construct>
@@ -220,30 +182,169 @@ make no difference to the build.
 
 -->
 
- <para>
+  <para>
+
+  The source code for large software projects
+  rarely stays in a single directory,
+  but is nearly always divided into a
+  hierarchy of directories.
+  Organizing a large software build using &SCons;
+  involves creating a hierarchy of build scripts
+  using the &SConscript; function.
+
+  </para>
+
+  <section>
+  <title>&SConscript; Files</title>
+
+    <para>
+
+    As we've already seen,
+    the build script at the top of the tree is called &SConstruct;.
+    The top-level &SConstruct; file can
+    use the &SConscript; function to
+    include other subsidiary scripts in the build.
+    These subsidiary scripts can, in turn,
+    use the &SConscript; function
+    to include still other scripts in the build.
+    By convention, these subsidiary scripts are usually
+    named &SConscript;.
+    For example, a top-level &SConstruct; file might
+    arrange for four subsidiary scripts to be included
+    in the build as follows:
+
+    </para>
+
+    <programlisting>
+      SConscript(['drivers/display/SConscript',
+                  'drivers/mouse/SConscript',
+                  'parser/SConscript',
+                  'utilities/SConscript'])
+    </programlisting>
+
+    <para>
+
+    In this case, the &SConstruct; file
+    lists all of the &SConscript; files in the build explicitly.
+    (Note, however, that not every directory in the tree
+    necessarily has an &SConscript; file.)
+    Alternatively, the <literal>drivers</literal>
+    subdirectory might contain an intermediate
+    &SConscript; file,
+    in which case the &SConscript; call in
+    the top-level &SConstruct; file
+    would look like:
+
+    </para>
+
+    <programlisting>
+      SConscript(['drivers/SConscript',
+                  'parser/SConscript',
+                  'utilities/SConscript'])
+    </programlisting>
+
+    <para>
+
+    And the subsidiary &SConscript; file in the
+    <literal>drivers</literal> subdirectory
+    would look like:
+
+    </para>
+
+    <programlisting>
+      SConscript(['display/SConscript',
+                  'mouse/SConscript'])
+    </programlisting>
+
+    <para>
+
+    Whether you list all of the &SConscript; files in the
+    top-level &SConstruct; file,
+    or place a subsidiary &SConscript; file in
+    intervening directories,
+    or use some mix of the two schemes,
+    is up to you and the needs of your software.
+
+    </para>
+
+  </section>
+
+  <section>
+  <title>Path Names Are Relative to the &SConscript; Directory</title>
+
+    <para>
+
+    X
+
+    </para>
+
+    <programlisting>
+      SConscript(['display/SConscript',
+                  'mouse/SConscript'])
+    </programlisting>
+
+  </section>
+
+  <section>
+  <title>Sharing Environments (and Other Variables) Between &SConscript; Files</title>
+
+    <para>
+
+    X
+
+    </para>
+
+    <programlisting>
+      SConscript(['display/SConscript',
+                  'mouse/SConscript'])
+    </programlisting>
+
+    <section>
+    <title>Exporting Variables</title>
+
+      <para>
+
+      X
+
+      </para>
+
+      <programlisting>
+        SConscript(['display/SConscript',
+                    'mouse/SConscript'])
+      </programlisting>
+
+    </section>
+
+    <section>
+    <title>Importing Variables</title>
 
-   X
+      <para>
 
- </para>
+      X
 
- <section>
- <title>&SConscript; Files</title>
+      </para>
 
-   <para>
+      <programlisting>
+        SConscript(['display/SConscript',
+                   'mouse/SConscript'])
+      </programlisting>
 
-   X
+    </section>
 
-   </para>
+    <section>
+    <title>Returning Values</title>
 
</section>
     <para>
 
- <section>
- <title>X</title>
+      X
 
-   <para>
+      </para>
 
-   X
+      <programlisting>
+        SConscript(['display/SConscript',
+                    'mouse/SConscript'])
+      </programlisting>
 
-   </para>
+    </section>
 
- </section>
 </section>
index 530fa7ad974dbb34d094037a77a22039c976e6a3..2cebbd4568cbeb157d82af63c87f305975201ea2 100644 (file)
 
 -->
 
-<!--
-
-=head2 The C<Install> method
-
-The C<Install> method arranges for the specified files to be installed in
-the specified directory. The installation is optimized: the file is not
-copied if it can be linked. If this is not the desired behavior, you will
-need to use a different method to install the file. It is called as follows:
-
-  Install $env <directory>, <names>;
-
-Note that, while the files to be installed may be arbitrarily named,
-only the last component of each name is used for the installed target
-name. So, for example, if you arrange to install F<foo/bar> in F<baz>,
-this will create a F<bar> file in the F<baz> directory (not F<foo/bar>).
-
-
-=head2 The C<InstallAs> method
+  <para>
+
+  Once a program is built,
+  it is often appropriate to install it in another
+  directory for public use.
+  You use the &Install; method 
+  to arrange for a program, or any other file,
+  to be copied into a destination directory:
+
+  </para>
+
+  <programlisting>
+     env = Environment()
+     hello = env.Program('hello.c')
+     env.Install('/usr/bin', hello)
+  </programlisting>
+
+  <para>
+
+  Note, however, that installing a file is
+  still considered a type of file "build."
+  This is important when you remember that
+  the default behavior of &SCons; is
+  to build files in or below the current directory.
+  If, as in the example above,
+  you are installing files in a directory
+  outside of the top-level &SConstruct; file's directory tree,
+  you must specify that directory
+  (or a higher directory, such as <literal>/</literal>)
+  for it to install anything there:
+
+  </para>
+
+  <literallayout>
+     % <userinput>scons</userinput>
+     cc -c hello.c -o hello.o
+     cc -o hello hello.o
+     % <userinput>scons /usr/bin</userinput>
+     Install file: "hello" as "/usr/bin/hello"
+  </literallayout>
+
+  <para>
+
+  It can, however, be cumbersome to remember
+  (and type) the specific destination directory
+  in which the program (or any other file)
+  should be installed.
+  This is an area where the &Alias;
+  function comes in handy,
+  allowing you, if you wish,
+  to create a pseudo-target named <literal>install</literal>
+  that can expand to the specified destination directory:
+
+  </para>
+
+  <programlisting>
+     env = Environment()
+     hello = env.Program('hello.c')
+     env.Install('/usr/bin', hello)
+     env.Alias('install', '/usr/bin')
+  </programlisting>
+
+  <para>
+
+  This then yields the more natural
+  ability to install the program
+  in its destination as follows:
+
+  </para>
 
-The C<InstallAs> method arranges for the specified source file(s) to be
-installed as the specified target file(s). Multiple files should be
-specified as a file list. The installation is optimized: the file is not
-copied if it can be linked. If this is not the desired behavior, you will
-need to use a different method to install the file. It is called as follows:
+  <literallayout>
+     % <userinput>scons install</userinput>
+     Install file: "hello" as "/usr/bin/hello"
+  </literallayout>
+
+  <section>
+  <title>Installing Multiple Files in a Directory</title>
+
+    <para>
+
+    You can install multiple files into a directory
+    simploy by calling the &Install; function multiple times:
+
+    </para>
+
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       goodbye = env.Program('goodbye.c')
+       env.Install('/usr/bin', hello)
+       env.Install('/usr/bin', goodbye])
+       env.Alias('install', '/usr/bin')
+    </programlisting>
+
+    <para>
+
+    Or, more succinctly, listing the multiple input
+    files in a list
+    (just like you can do with any other builder):
+
+    </para>
+
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       goodbye = env.Program('goodbye.c')
+       env.Install('/usr/bin', [hello, goodbye])
+       env.Alias('install', '/usr/bin')
+    </programlisting>
+
+    <para>
+
+    Either of these two examples yields:
+
+    </para>
+
+    <literallayout>
+       % <userinput>scons install</userinput>
+       cc -c goodbye.c -o goodbye.o
+       cc -o goodbye goodbye.o
+       cc -c hello.c -o hello.o
+       cc -o hello hello.o
+       Install file: "goodbye" as "/usr/bin/goodbye"
+       Install file: "hello" as "/usr/bin/hello"
+    </literallayout>
+
+  </section>
+
+  <section>
+  <title>Installing a File Under a Different Name</title>
 
-C<InstallAs> works in two ways:
+    <para>
+
+    The &Install; method preserves the name
+    of the file when it is copied into the
+    destination directory.
+    If you need to change the name of the file
+    when you copy it, use the &InstallAs; function:
 
-Single file install:
+    </para>
 
-  InstallAs $env TgtFile, SrcFile;
-
-Multiple file install:
-
-  InstallAs $env ['tgt1', 'tgt2'], ['src1', 'src2'];
-
-Or, even as:
-
-  @srcs = qw(src1 src2 src3);
-  @tgts = qw(tgt1 tgt2 tgt3);
-  InstallAs $env [@tgts], [@srcs];
-
-Both the target and the sources lists should be of the same length.
-
--->
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       env.InstallAs('/usr/bin/hello-new', hello)
+       env.Alias('install', '/usr/bin')
+    </programlisting>
 
- <para>
   <para>
 
-   X
+    This installs the <literal>hello</literal>
+    program with the name <literal>hello-new</literal>
+    as follows:
 
- </para>
   </para>
 
- <section>
- <title>The &Install; Builder</title>
+    <literallayout>
+       % <userinput>scons install</userinput>
+       cc -c hello.c -o hello.o
+       cc -o hello hello.o
+       Install file: "hello" as "/usr/bin/hello-new"
+    </literallayout>
 
-   <para>
+  </section>
 
-   X
+  <section>
+  <title>Installing Multiple Files Under Different Names</title>
 
-   </para>
+    <para>
 
- </section>
+    Lastly, if you have multiple files that all
+    need to be installed with different file names,
+    you can either call the &InstallAs; function
+    multiple times, or as a shorthand,
+    you can supply same-length lists
+    for the both the target and source arguments:
 
- <section>
- <title>The &InstallAs; Method</title>
+    </para>
 
-   <para>
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       goodbye = env.Program('goodbye.c')
+       env.InstallAs(['/usr/bin/hello-new',
+                      '/usr/bin/goodbye-new',
+                     [hello, goodbye])
+    </programlisting>
+
+    <para>
 
-   X
+    In this case, the &InstallAs; function
+    loops through both lists simultaneously,
+    and copies each source file into its corresponding
+    target file name:
 
-   </para>
+    </para>
+
+    <literallayout>
+       % <userinput>scons install</userinput>
+       cc -c goodbye.c -o goodbye.o
+       cc -o goodbye goodbye.o
+       cc -c hello.c -o hello.o
+       cc -o hello hello.o
+       Install file: "goodbye" as "/usr/bin/goodbye-new"
+       Install file: "hello" as "/usr/bin/hello-new"
+    </literallayout>
 
- </section>
 </section>
index b285696d6ec71552af4b5a36d193b17dac2566d5..68bc59c73f4a07ec7e952d1f2e47a684bb0960be 100644 (file)
     <!ENTITY help SYSTEM "help.sgml">
     <!ENTITY hierarchy SYSTEM "hierarchy.sgml">
     <!ENTITY install SYSTEM "install.sgml">
-    <!ENTITY library SYSTEM "library.sgml">
     <!ENTITY make SYSTEM "make.sgml">
-    <!ENTITY more SYSTEM "more.sgml">
-    <!ENTITY object SYSTEM "object.sgml">
     <!ENTITY precious SYSTEM "precious.sgml">
     <!ENTITY preface SYSTEM "preface.sgml">
-    <!ENTITY program SYSTEM "program.sgml">
-    <!ENTITY reference SYSTEM "reference.sgml">
     <!ENTITY repositories SYSTEM "repositories.sgml">
     <!ENTITY run SYSTEM "run.sgml">
     <!ENTITY scanners SYSTEM "scanners.sgml">
     <!ENTITY separate SYSTEM "separate.sgml">
     <!ENTITY simple SYSTEM "simple.sgml">
+    <!ENTITY sourcecode SYSTEM "sourcecode.sgml">
     <!ENTITY troubleshoot SYSTEM "troubleshoot.sgml">
     <!ENTITY variants SYSTEM "variants.sgml">
 
     &depends;
   </chapter>
 
-
-
   <chapter id="chap-default">
     <title>Default Targets</title>
     &default;
     &install;
   </chapter>
 
-  <chapter id="chap-program">
-    <title>The Program Builder</title>
-    &program;
-  </chapter>
-
-  <chapter id="chap-library">
-    <title>The Library Builder</title>
-    &library;
-  </chapter>
-
-  <chapter id="chap-more">
-    <title>More Things to Do With Builds</title>
-    &more;
-  </chapter>
-
-  <chapter id="chap-command">
-    <title>The Command Builder</title>
-    &command;
-  </chapter>
-
-  <chapter id="chap-object">
-    <title>The Object Builder</title>
-    &object;
-  </chapter>
-
   <chapter id="chap-precious">
     <title>Preventing Removal of Targets</title>
     &precious;
     &builders;
   </chapter>
 
+  <chapter id="chap-command">
+    <title>Avoiding Having to Write Builders</title>
+    &command;
+  </chapter>
+
   <chapter id="chap-actions">
     <title>SCons Actions</title>
     &actions;
     &repositories;
   </chapter>
 
+  <chapter id="chap-sourcecode">
+    <title>Fetching Files From Source Code Management Systems</title>
+    &sourcecode;
+  </chapter>
+
   <chapter id="chap-caching">
     <title>Caching Built Files</title>
     &caching;
   </chapter>
 
-  <chapter id="chap-run">
-    <title>How to Run &SCons;</title>
-    &run;
-  </chapter>
-
   <chapter id="chap-alias">
     <title>Alias Targets</title>
     &alias;
   </chapter>
 
+  <chapter id="chap-run">
+    <title>How to Run &SCons;</title>
+    &run;
+  </chapter>
+
   <chapter id="chap-troubleshooting">
     <title>Troubleshooting</title>
     &troubleshoot;
   </chapter>
 
-  <appendix id="app-quick">
-    <title>Quick Reference</title>
-    &reference;
-  </appendix>
-
-  <appendix id="app-errors">
-    <title>Errors Generated by &SCons;</title>
-    &errors;
-  </appendix>
+  <!--
+  AddPostAction()
+  AddPreAction()
+  Clean()
+  Dir()
+  File()
+  FindFile()
+  GetJobs()
+  SetJobs()
+  SideEffect()
+  ParseConfig()
+  Platform()
+  Tools()
+  -->
 
   <appendix id="app-example">
     <title>Complex &SCons; Example</title>
index 9cd2a4313a32378516c57728b88a8e3a4b1132f3..26ad34510c664d1b4827f95cb994417c9b7de04a 100644 (file)
 
 <!--
 
-=head2 The C<Precious> method
-
-The C<Precious> method asks cons not to delete the specified file or
-list of files before building them again.  It is invoked as:
-
-  Precious <files>;
-
-This is especially useful for allowing incremental updates to libraries
-or debug information files which are updated rather than rebuilt anew each
-time.  Cons will still delete the files when the C<-r> flag is specified.
-
 =head2 The C<AfterBuild> method
 
 The C<AfterBuild> method evaluates the specified perl string after
@@ -53,17 +42,38 @@ which the C<AfterBuild> method is called.
 
  <para>
 
-   X
+ By default, &SCons; removes targets before building them.
+ Sometimes, however, this is not what you want.
+ For example, you may want to update a library incrementally,
+ not by having it deleted and then rebuilt from all
+ of the constituent object files.
+ In such cases, you can use the
+ &Precious; method to prevent
+ &SCons; from removing the target before it is built:
 
  </para>
 
- <section>
- <title>The &Precious; Method</title>
+ <programlisting>
+    env = Environment(XXX NEED LIBRARY FLAGS
+                      LIBFLAGS = '-r')
+    lib = env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
+    env.Precious(lib)
+ </programlisting>
 
  <para>
+ <para>
 
-   X
+ XXX:
 
  </para>
+ </para>
 
- </section>
+ <literallayout>
+    % <userinput>scons</userinput>
+    XXX ANY INPUT HERE?
+ </literallayout>
+
+ <para>
+
+ &SCons; will still delete files marked as &Precious;
+ when the <literal>-c</literal> option is used.
+
+ </para>
index 2193a8fdb4cd5417647bd0bbfcbf045499e780d3..616e9031985fc7ac18b5ab65b73c1d34d12fdd0c 100644 (file)
@@ -135,314 +135,326 @@ subdirectories under the repository tree.
 
 -->
 
- <para>
+  <para>
+
+  Often, a software project will have
+  one or more central repositories,
+  directory trees that contain
+  source code, or derived files, or both.
+  You can eliminate additional unnecessary
+  rebuilds of files by having &SCons;
+  use files from one or more code repositories
+  to build files in your local build tree.
+
+  </para>
+
+  <section>
+  <title>The &Repository; Method</title>
+
+ <!--
+
+ The repository directories specified may contain source files, derived files
+ (objects, libraries and executables), or both.  If there is no local file
+ (source or derived) under the directory in which Cons is executed, then the
+ first copy of a same-named file found under a repository directory will be
+ used to build any local derived files.
+
+ -->
+
+    <para>
+
+    It's often useful to allow multiple programmers working
+    on a project to build software from
+    source files and/or derived files that
+    are stored in a centrally-accessible repository,
+    a directory copy of the source code tree.
+    (Note that this is not the sort of repository
+    maintained by a source code management system
+    like BitKeeper, CVS, or Subversion.
+    For information about using &SCons;
+    with these systems, see the section,
+    "Fetching Files From Source Code Management Systems,"
+    below.)
+    You use the &Repository; method
+    to tell &SCons; to search one or more
+    central code repositories (in order)
+    for any source files and derived files
+    that are not present in the local build tree:
 
- Often, a software project will have
- one or more central repositories,
- directory trees that contain
- source code, or derived files, or both.
- You can eliminate additional unnecessary
- rebuilds of files by having &SCons;
- use files from one or more code repositories
- to build files in your local build tree.
+    </para>
+
+    <programlisting>
+       env = Environment()
+       env.Program('hello.c')
+       Repository('/usr/repository1', '/usr/repository2')
+    </programlisting>
+
+    <para>
+
+    Multiple calls to the &Repository; method
+    will simply add repositories to the global list
+    that &SCons; maintains,
+    with the exception that &SCons; will automatically eliminate
+    the current directory and any non-existent
+    directories from the list.
 
- </para>
+    </para>
+
+  </section>
+
+  <section>
+  <title>Finding source files in repositories</title>
+
+    <para>
+
+    The above example
+    specifies that &SCons;
+    will first search for files under
+    the <filename>/usr/repository1</filename> tree
+    and next under the <filename>/usr/repository2</filename> tree.
+    &SCons; expects that any files it searches
+    for will be found in the same position
+    relative to the top-level directory XXX
+    In the above example, if the &hello_c; file is not
+    found in the local build tree,
+    &SCons; will search first for
+    a <filename>/usr/repository1/hello.c</filename> file
+    and then for a <filename>/usr/repository1/hello.c</filename> file
+    to use in its place.
+
+    </para>
+
+    <para>
 
- <section>
- <title>The &Repository; Method</title>
+    So given the &SConstruct; file above,
+    if the &hello_c; file exists in the local
+    build directory,
+    &SCons; will rebuild the &hello; program
+    as normal:
+
+    </para>
 
-<!--
-
-The repository directories specified may contain source files, derived files
-(objects, libraries and executables), or both.  If there is no local file
-(source or derived) under the directory in which Cons is executed, then the
-first copy of a same-named file found under a repository directory will be
-used to build any local derived files.
-
--->
-
-   <para>
-
-   The &Repository; method
-   tells &SCons; to search one or more
-   central code repositories (in order)
-   for any source files and derived files
-   that are not present in the local build tree:
-
-   </para>
-
-   <programlisting>
-      env = Environment()
-      env.Program('hello.c')
-      Repository('/usr/repository1', '/usr/repository2')
-   </programlisting>
-
-   <para>
-
-   (Note that multiple calls to the &Repository; method
-   will simply add repositories to the global list
-   that &SCons; maintains,
-   with the exception that &SCons; will automatically eliminate
-   the current directory and any non-existent
-   directories from the list.)
-
-   </para>
-
- </section>
-
- <section>
- <title>Finding source files in repositories</title>
-
-   <para>
-
-   The above example
-   specifies that &SCons;
-   will first search for files under
-   the <filename>/usr/repository1</filename> tree
-   and next under the <filename>/usr/repository2</filename> tree.
-   &SCons; expects that any files it searches
-   for will be found in the same position
-   relative to the top-level directory XXX
-   In the above example, if the &hello_c; file is not
-   found in the local build tree,
-   &SCons; will search first for
-   a <filename>/usr/repository1/hello.c</filename> file
-   and then for a <filename>/usr/repository1/hello.c</filename> file
-   to use in its place.
-
-   </para>
-
-   <para>
-
-   So given the &SConstruct; file above,
-   if the &hello_c; file exists in the local
-   build directory,
-   &SCons; will rebuild the &hello; program
-   as normal:
-
-   </para>
-
-   <literallayout>
-     % <userinput>scons</userinput>
-     gcc -c hello.c -o hello.o
-     gcc -o hello hello.o
-   </literallayout>
-
-   <para>
-
-   If, however, there is no local &hello_c; file,
-   but one exists in <filename>/usr/repository1</filename>,
-   &SCons; will recompile the &hello; program
-   from the source file it finds in the repository:
-
-   </para>
-
-   <literallayout>
-     % <userinput>scons</userinput>
-     gcc -c /usr/repository1/hello.c -o hello.o
-     gcc -o hello hello.o
-   </literallayout>
-
-   <para>
-
-   And similarly, if there is no local &hello_c; file
-   and no <filename>/usr/repository1/hello.c</filename>,
-   but one exists in <filename>/usr/repository2</filename>:
-
-   </para>
-
-   <literallayout>
-     % <userinput>scons</userinput>
-     gcc -c /usr/repository2/hello.c -o hello.o
-     gcc -o hello hello.o
-   </literallayout>
-
-   <para>
+    <literallayout>
+      % <userinput>scons</userinput>
+      gcc -c hello.c -o hello.o
+      gcc -o hello hello.o
+    </literallayout>
+
+    <para>
 
-   </para>
+    If, however, there is no local &hello_c; file,
+    but one exists in <filename>/usr/repository1</filename>,
+    &SCons; will recompile the &hello; program
+    from the source file it finds in the repository:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      gcc -c /usr/repository1/hello.c -o hello.o
+      gcc -o hello hello.o
+    </literallayout>
+
+    <para>
+
+    And similarly, if there is no local &hello_c; file
+    and no <filename>/usr/repository1/hello.c</filename>,
+    but one exists in <filename>/usr/repository2</filename>:
+
+    </para>
+
+    <literallayout>
+      % <userinput>scons</userinput>
+      gcc -c /usr/repository2/hello.c -o hello.o
+      gcc -o hello hello.o
+    </literallayout>
+
+    <para>
+
+    </para>
 
- </section>
 </section>
 
- <section>
- <title>Finding the &SConstruct; file in repositories</title>
 <section>
 <title>Finding the &SConstruct; file in repositories</title>
 
-   <para>
+    <para>
 
-   &SCons; will also search in repositories
-   for the &SConstruct; file and any specified &SConscript; files.
-   This poses a problem, though:  how can &SCons; search a
-   repository tree for an &SConstruct; file
-   if the &SConstruct; file itself contains the information
-   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>:
+    &SCons; will also search in repositories
+    for the &SConstruct; file and any specified &SConscript; files.
+    This poses a problem, though:  how can &SCons; search a
+    repository tree for an &SConstruct; file
+    if the &SConstruct; file itself contains the information
+    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>:
 
-   </para>
+    </para>
 
-   <literallayout>
-     % <userinput>scons -Y /usr/repository1 -Y /usr/repository2</userinput>
-   </literallayout>
+    <literallayout>
+      % <userinput>scons -Y /usr/repository1 -Y /usr/repository2</userinput>
+    </literallayout>
 
-   <para>
+    <para>
 
-   When looking for source or derived files,
-   &SCons; will first search the repositories
-   specified on the command line,
-   and then search the repositories
-   specified in the &SConstruct; or &SConscript; files.
+    When looking for source or derived files,
+    &SCons; will first search the repositories
+    specified on the command line,
+    and then search the repositories
+    specified in the &SConstruct; or &SConscript; files.
 
-   </para>
+    </para>
 
- </section>
 </section>
 
- <section>
- <title>Finding derived files in repositories</title>
 <section>
 <title>Finding derived files in repositories</title>
 
-   <para>
+    <para>
 
-   If a repository contains not only source files,
-   but also derived files (such as object files,
-   libraries, or executables), &SCons; will perform
-   its normal MD5 signature calculation to
-   decide if a derived file in a repository is up-to-date,
-   or the derived file must be rebuilt in the local build directory.
-   For the &SCons; signature calculation to work correctly,
-   a repository tree must contain the &sconsign; files
-   that &SCons; uses to keep track of signature information.
+    If a repository contains not only source files,
+    but also derived files (such as object files,
+    libraries, or executables), &SCons; will perform
+    its normal MD5 signature calculation to
+    decide if a derived file in a repository is up-to-date,
+    or the derived file must be rebuilt in the local build directory.
+    For the &SCons; signature calculation to work correctly,
+    a repository tree must contain the &sconsign; files
+    that &SCons; uses to keep track of signature information.
 
-   </para>
+    </para>
 
-   <para>
+    <para>
 
-   Usually, this would be done by a build integrator
-   who would run &SCons; in the repository
-   to create all of its derived files and &sconsign; files,
-   or who would &SCons; in a separate build directory
-   and copying the resulting tree to the desired repository:
+    Usually, this would be done by a build integrator
+    who would run &SCons; in the repository
+    to create all of its derived files and &sconsign; files,
+    or who would &SCons; in a separate build directory
+    and copying the resulting tree to the desired repository:
 
-   </para>
+    </para>
 
-   <literallayout>
-     % <userinput>cd /usr/repository1</userinput>
-     % <userinput>scons</userinput>
-     gcc -c hello.c -o hello.o
-     gcc -o hello hello.o
-   </literallayout>
+    <literallayout>
+      % <userinput>cd /usr/repository1</userinput>
+      % <userinput>scons</userinput>
+      gcc -c hello.c -o hello.o
+      gcc -o hello hello.o
+    </literallayout>
 
-   <para>
-   
-   (Note that this is safe even if the &SConstruct; file
-   lists <filename>/usr/repository1</filename> as a repository,
-   because &SCons; will remove the current build directory
-   from its repository list for that invocation.)
+    <para>
+    
+    (Note that this is safe even if the &SConstruct; file
+    lists <filename>/usr/repository1</filename> as a repository,
+    because &SCons; will remove the current build directory
+    from its repository list for that invocation.)
 
-   </para>
+    </para>
 
-   <para>
+    <para>
 
-   Now, with the repository populated,
-   we only need to create the one local source file
-   we're interested in working with at the moment,
-   and use the <literal>-Y</literal> option to
-   tell &SCons; to fetch any other files it needs
-   from the repository:
+    Now, with the repository populated,
+    we only need to create the one local source file
+    we're interested in working with at the moment,
+    and use the <literal>-Y</literal> option to
+    tell &SCons; to fetch any other files it needs
+    from the repository:
 
-   </para>
+    </para>
 
-   <literallayout>
-     % <userinput>cd $HOME/build</userinput>
-     % <userinput>edit hello.c</userinput>
-     % <userinput>scons -Y /usr/repository1</userinput>
-     gcc -c hello.c -o hello.o
-     gcc -o hello hello.o
-     XXXXXXX
-   </literallayout>
+    <literallayout>
+      % <userinput>cd $HOME/build</userinput>
+      % <userinput>edit hello.c</userinput>
+      % <userinput>scons -Y /usr/repository1</userinput>
+      gcc -c hello.c -o hello.o
+      gcc -o hello hello.o
+      XXXXXXX
+    </literallayout>
 
-   <para>
+    <para>
 
-   Notice that &SCons; realizes that it does not need to
-   rebuild a local XXX.o file,
-   but instead uses the already-compiled XXX.o file
-   from the repository.
+    Notice that &SCons; realizes that it does not need to
+    rebuild a local XXX.o file,
+    but instead uses the already-compiled XXX.o file
+    from the repository.
 
-   </para>
+    </para>
 
- </section>
 </section>
 
- <section>
- <title>Guaranteeing local copies of files</title>
 <section>
 <title>Guaranteeing local copies of files</title>
 
-   <para>
+    <para>
 
-   If the repository tree contains the complete results of a build,
-   and we try to build from the repository
-   without any files in our local tree,
-   something moderately surprising happens:
+    If the repository tree contains the complete results of a build,
+    and we try to build from the repository
+    without any files in our local tree,
+    something moderately surprising happens:
 
-   </para>
+    </para>
 
-   <literallayout>
-     % <userinput>mkdir $HOME/build2</userinput>
-     % <userinput>cd $HOME/build2</userinput>
-     % <userinput>scons -Y /usr/all/repository hello</userinput>
-     scons: `hello' is up-to-date.
-   </literallayout>
+    <literallayout>
+      % <userinput>mkdir $HOME/build2</userinput>
+      % <userinput>cd $HOME/build2</userinput>
+      % <userinput>scons -Y /usr/all/repository hello</userinput>
+      scons: `hello' is up-to-date.
+    </literallayout>
 
-   <para>
+    <para>
 
-   Why does &SCons; say that the &hello; program
-   is up-to-date when there is no &hello; program
-   in the local build directory?
-   Because the repository (not the local directory)
-   contains the up-to-date &hello; program,
-   and &SCons; correctly determines that nothing
-   needs to be done to rebuild that
-   up-to-date copy of the file.
+    Why does &SCons; say that the &hello; program
+    is up-to-date when there is no &hello; program
+    in the local build directory?
+    Because the repository (not the local directory)
+    contains the up-to-date &hello; program,
+    and &SCons; correctly determines that nothing
+    needs to be done to rebuild that
+    up-to-date copy of the file.
 
-   </para>
-
-   <para>
+    </para>
+
+    <para>
 
-   There are, however, many times when you want to ensure that a
-   local copy of a file always exists.
-   A packaging or testing script, for example,
-   may assume that certain generated files exist locally.
-   To tell &SCons; to make a copy of any up-to-date repository
-   file in the local build directory,
-   use the &Local; function:
+    There are, however, many times when you want to ensure that a
+    local copy of a file always exists.
+    A packaging or testing script, for example,
+    may assume that certain generated files exist locally.
+    To tell &SCons; to make a copy of any up-to-date repository
+    file in the local build directory,
+    use the &Local; function:
 
-   </para>
+    </para>
 
-   <programlisting>
-      env = Environment()
-      hello = env.Program('hello.c')
-      Local(hello)
-   </programlisting>
+    <programlisting>
+       env = Environment()
+       hello = env.Program('hello.c')
+       Local(hello)
+    </programlisting>
 
-   <para>
+    <para>
 
-   If we then run the same command,
-   &SCons; will make a local copy of the program
-   from the repository copy,
-   and tell you that it is doing so:
+    If we then run the same command,
+    &SCons; will make a local copy of the program
+    from the repository copy,
+    and tell you that it is doing so:
 
-   </para>
+    </para>
 
-   <literallayout>
-     % cons -R /usr/all/repository hello
-     Local copy of hello from /usr/all/repository/hello
-     scons: `hello' is up-to-date.
-     XXXXXX DO WE REALLY REPORT up-to-date, TOO?
-   </literallayout>
+    <literallayout>
+      % scons -Y /usr/all/repository hello
+      Local copy of hello from /usr/all/repository/hello
+      scons: `hello' is up-to-date.
+      XXXXXX DO WE REALLY REPORT up-to-date, TOO?
+    </literallayout>
 
-   <para>
+    <para>
 
-   (Notice that, because the act of making the local copy
-   is not considered a "build" of the &hello; file,
-   &SCons; still reports that it is up-to-date.)
-   XXXXXX DO WE REALLY REPORT up-to-date, TOO?
+    (Notice that, because the act of making the local copy
+    is not considered a "build" of the &hello; file,
+    &SCons; still reports that it is up-to-date.)
+    XXXXXX DO WE REALLY REPORT up-to-date, TOO?
 
-   </para>
+    </para>
 
- </section>
 </section>
index e1c0e49bb42e96fd45386813bcb468dcc9f45636..9050eb7f43e73faaf34f490e79fe66e1732d3792 100644 (file)
@@ -112,12 +112,178 @@ program using the F<build/foo.c> path name.
 
  <para>
 
-   X
+ 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.
 
  </para>
 
  <section>
- <title>X</title>
+ <title>The &BuildDir; Function</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+     BuildDir('build', 'src')
+     env = Environment()
+     env.Program('build/hello.c')
+   </programlisting>
+
+   <para>
+
+   X
+
+   </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>
+
+ </section>
+
+ <section>
+ <title>Avoiding Duplicate Source Files in the Build Directory</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+     BuildDir('build', 'src', duplicate=0)
+     env = Environment()
+     env.Program('build/hello.c')
+   </programlisting>
+
+   <para>
+
+   X
+
+   </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>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>Why &SCons; Duplicates Source Files by Default</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+     env = Environmnet()
+   </programlisting>
+
+   <para>
+
+   X
+
+   </para>
+
+   <literallayout>
+     % <userinput>scons</userinput>
+     cc -c build/hello.c -o build/hello.o
+     cc -o build/hello build/hello.o
+   </literallayout>
+
+ </section>
+
+ <section>
+ <title>Using &BuildDir; With an &SConscript; File</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+     env = Environment()
+     env.Program('hello.c')
+   </programlisting>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+     BuildDir('build', 'src')
+     SConscript('build/SConscript')
+   </programlisting>
+
+   <para>
+
+   X
+
+   </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>
+
+ </section>
+
+ <section>
+ <title>Specifying a Build Directory as Part of an &SConscript; Call</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+     SConscript('src/SConscript', build_dir='build')
+   </programlisting>
 
    <para>
 
@@ -125,4 +291,45 @@ program using the F<build/foo.c> path name.
 
    </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>
+
+   X
+
+   </para>
+
+   <programlisting>
+     SConscript('src/SConscript', build_dir='build', duplicate=0)
+   </programlisting>
+
+   <para>
+
+   X
+
+   </para>
+
+   <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>
index 8cafe2d87760f0622c10bb852b7555c99185299f..a86fd344023c0a15fa6648b780b3be0193bb1b4c 100644 (file)
@@ -147,10 +147,10 @@ requirements of a build.
    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 extremely easy to learn,
+   Python is very easy to learn,
    and this User's Guide will introduce you step-by-step
    to the relatively small amount of Python you'll
-   neede to know to be able to use &SCons; effectively.
+   need to know to be able to use &SCons; effectively.
 
    </para>
 
@@ -254,7 +254,7 @@ requirements of a build.
 
    <para>
 
-   One minor drawback to the use of a Python list
+   One drawback to the use of a Python list
    for source files is that 
    each file name must be enclosed in quotes
    (either single quotes or double quotes).
diff --git a/doc/user/sourcecode.sgml b/doc/user/sourcecode.sgml
new file mode 100644 (file)
index 0000000..4ee49d4
--- /dev/null
@@ -0,0 +1,144 @@
+<!--
+
+  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>
+
+   X
+
+ </para>
+
+ <section>
+ <title>Fetching Source Code From BitKeeper</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+      env = Environment()
+      env.SourceCode('.', env.BitKeeper('XXX')
+      env.Program('hello.c')
+   </programlisting>
+
+   <literallayout>
+     % <userinput>scons</userinput>
+     XXX
+   </literallayout>
+
+ </section>
+
+ <section>
+ <title>Fetching Source Code From CVS</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+      env = Environment()
+      env.SourceCode('.', env.CVS('XXX')
+      env.Program('hello.c')
+   </programlisting>
+
+   <literallayout>
+     % <userinput>scons</userinput>
+     XXX
+   </literallayout>
+
+ </section>
+
+ <section>
+ <title>Fetching Source Code From RCS</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+      env = Environment()
+      env.SourceCode('.', env.RCS()
+      env.Program('hello.c')
+   </programlisting>
+
+   <literallayout>
+     % <userinput>scons</userinput>
+     XXX
+   </literallayout>
+
+ </section>
+
+ <section>
+ <title>Fetching Source Code From SCCS</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+      env = Environment()
+      env.SourceCode('.', env.SCCS()
+      env.Program('hello.c')
+   </programlisting>
+
+   <literallayout>
+     % <userinput>scons</userinput>
+     XXX
+   </literallayout>
+
+ </section>
+
+ <section>
+ <title>Fetching Source Code From Subversion</title>
+
+   <para>
+
+   X
+
+   </para>
+
+   <programlisting>
+      env = Environment()
+      env.SourceCode('.', env.Subversion('XXX')
+      env.Program('hello.c')
+   </programlisting>
+
+   <literallayout>
+     % <userinput>scons</userinput>
+     XXX
+   </literallayout>
+
+ </section>
index fdd209eec80cf22ec9075a68cb2d2ec5f2cf2f24..6ad936094639728170ea5646de94ee64706e3559 100644 (file)
@@ -122,4 +122,25 @@ is pretty smart about rebuilding things when you change options.
 
    </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>