Checkin of in-progress work on the User Guide.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 6 Feb 2003 05:17:25 +0000 (05:17 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 6 Feb 2003 05:17:25 +0000 (05:17 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@575 fdb21ef1-2011-0410-befe-b5e4ea1792b1

33 files changed:
doc/scons.mod
doc/user/actions.sgml [new file with mode: 0644]
doc/user/alias.sgml [new file with mode: 0644]
doc/user/builders.sgml
doc/user/caching.sgml
doc/user/command.sgml [new file with mode: 0644]
doc/user/cons.pl [new file with mode: 0644]
doc/user/cons.sgml
doc/user/copyright.sgml
doc/user/default.sgml [new file with mode: 0644]
doc/user/depends.sgml
doc/user/environments.sgml
doc/user/errors.sgml
doc/user/example.sgml
doc/user/help.sgml [new file with mode: 0644]
doc/user/hierarchy.sgml
doc/user/install.sgml [new file with mode: 0644]
doc/user/library.sgml [new file with mode: 0644]
doc/user/main.sgml
doc/user/make.sgml
doc/user/more.sgml
doc/user/object.sgml [new file with mode: 0644]
doc/user/precious.sgml [new file with mode: 0644]
doc/user/preface.sgml
doc/user/program.sgml [new file with mode: 0644]
doc/user/reference.sgml
doc/user/repositories.sgml
doc/user/run.sgml
doc/user/scanners.sgml
doc/user/separate.sgml [new file with mode: 0644]
doc/user/simple.sgml
doc/user/troubleshoot.sgml
doc/user/variants.sgml

index b156e4cedafef5aa44483bd7fbb928395f8e6a3a..642f979a14721871bb924bb1da6ea6d244ffd611 100644 (file)
 <!ENTITY consvars "<literal>construction variables</literal>">
 
 <!ENTITY Dictionary "<literal>Dictionary</literal>">
+
+<!--
+
+  File and program names used in examples.
+
+-->
+
+<!ENTITY hello "<application>hello</application>">
+<!ENTITY hello_c "<filename>hello.c</filename>">
+<!ENTITY hello_h "<filename>hello.h</filename>">
+<!ENTITY stdio_h "<filename>stdio.h</filename>">
diff --git a/doc/user/actions.sgml b/doc/user/actions.sgml
new file mode 100644 (file)
index 0000000..447b331
--- /dev/null
@@ -0,0 +1,240 @@
+<!--
+
+  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.
+
+-->
+
+<!--
+
+=head1 Build actions
+
+Cons supports several types of B<build actions> that can be performed
+to construct one or more target files.  Usually, a build action is
+a construction command, that is, a command-line string that invokes
+an external command.  Cons can also execute Perl code embedded in a
+command-line string, and even supports an experimental ability to build
+a target file by executing a Perl code reference directly.
+
+A build action is usually specified as the value of a construction
+variable:
+
+  $env = new cons(
+       CCCOM         => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
+       LINKCOM       => '[perl] &link_executable("%>", "%<")',
+       ARCOM         => sub { my($env, $target, @sources) = @_;
+                                # code to create an archive
+                               }
+  );
+
+A build action may be associated directly with one or more target files
+via the C<Command> method; see below.
+
+=head2 Construction commands
+
+A construction command goes through expansion of construction variables
+and C<%-> pseudo-variables, as described above, to create the actual
+command line that Cons will execute to generate the target file or
+files.
+
+After substitution occurs, strings of white space are converted into
+single blanks, and leading and trailing white space is eliminated. It
+is therefore currently not possible to introduce variable length white
+space in strings passed into a command.
+
+If a multi-line command string is provided, the commands are executed
+sequentially. If any of the commands fails, then none of the rest are
+executed, and the target is not marked as updated, i.e. a new signature is
+not stored for the target.
+
+Normally, if all the commands succeed, and return a zero status (or whatever
+platform-specific indication of success is required), then a new signature
+is stored for the target. If a command erroneously reports success even
+after a failure, then Cons will assume that the target file created by that
+command is accurate and up-to-date.
+
+The first word of each command string, after expansion, is assumed to be an
+executable command looked up on the C<PATH> environment variable (which is,
+in turn, specified by the C<ENV> construction variable). If this command is
+found on the path, then the target will depend upon it: the command will
+therefore be automatically built, as necessary. It's possible to write
+multi-part commands to some shells, separated by semi-colons. Only the first
+command word will be depended upon, however, so if you write your command
+strings this way, you must either explicitly set up a dependency (with the
+C<Depends> method), or be sure that the command you are using is a system
+command which is expected to be available. If it isn't available, you will,
+of course, get an error.
+
+Cons normally prints a command before executing it.  This behavior is
+suppressed if the first character of the command is C<@>.  Note that
+you may need to separate the C<@> from the command name or escape it to
+prevent C<@cmd> from looking like an array to Perl quote operators that
+perform interpolation:
+
+  # The first command line is incorrect,
+  # because "@cp" looks like an array
+  # to the Perl qq// function.
+  # Use the second form instead.
+  Command $env 'foo', 'foo.in', qq(
+       @cp %< tempfile
+       @ cp tempfile %>
+  );
+
+If there are shell meta characters anywhere in the expanded command line,
+such as C<E<lt>>, C<E<gt>>, quotes, or semi-colon, then the command
+will actually be executed by invoking a shell. This means that a command
+such as:
+
+  cd foo
+
+alone will typically fail, since there is no command C<cd> on the path. But
+the command string:
+
+  cd $<:d; tar cf $>:f $<:f
+
+when expanded will still contain the shell meta character semi-colon, and a
+shell will be invoked to interpret the command. Since C<cd> is interpreted
+by this sub-shell, the command will execute as expected.
+
+=head2 Perl expressions
+
+If any command (even one within a multi-line command) begins with
+C<[perl]>, the remainder of that command line will be evaluated by the
+running Perl instead of being forked by the shell.  If an error occurs
+in parsing the Perl code, or if the Perl expression returns 0 or undef,
+the command will be considered to have failed.  For example, here is a
+simple command which creates a file C<foo> directly from Perl:
+
+  $env = new cons();
+  Command $env 'foo',
+    qq([perl] open(FOO,'>foo');print FOO "hi\\n"; close(FOO); 1);
+
+Note that when the command is executed, you are in the same package as
+when the F<Construct> or F<Conscript> file was read, so you can call
+Perl functions you've defined in the same F<Construct> or F<Conscript>
+file in which the C<Command> appears:
+
+  $env = new cons();
+  sub create_file {
+       my $file = shift;
+       open(FILE, ">$file");
+       print FILE "hi\n";
+       close(FILE);
+       return 1;
+  }
+  Command $env 'foo', "[perl] &create_file('%>')";
+
+The Perl string will be used to generate the signature for the derived
+file, so if you change the string, the file will be rebuilt.  The contents
+of any subroutines you call, however, are not part of the signature,
+so if you modify a called subroutine such as C<create_file> above,
+the target will I<not> be rebuilt.  Caveat user.
+
+=head2 Perl code references [EXPERIMENTAL]
+
+Cons supports the ability to create a derived file by directly executing
+a Perl code reference.  This feature is considered EXPERIMENTAL and
+subject to change in the future.
+
+A code reference may either be a named subroutine referenced by the
+usual C<\&> syntax:
+
+  sub build_output {
+       my($env, $target, @sources) = @_;
+       print "build_output building $target\n";
+       open(OUT, ">$target");
+       foreach $src (@sources) {
+           if (! open(IN, "<$src")) {
+               print STDERR "cannot open '$src': $!\n";
+               return undef;
+           }
+           print OUT, <IN>;
+       }
+       close(OUT);
+       return 1;
+  }
+  Command $env 'output', \&build_output;
+
+or the code reference may be an anonymous subroutine:
+
+  Command $env 'output', sub {
+       my($env, $target, @sources) = @_;
+       print "building $target\n";
+       open(FILE, ">$target");
+       print FILE "hello\n";
+       close(FILE);
+       return 1;
+  };
+
+To build the target file, the referenced subroutine is passed, in order:
+the construction environment used to generate the target; the path
+name of the target itself; and the path names of all the source files
+necessary to build the target file.
+
+The code reference is expected to generate the target file, of course,
+but may manipulate the source and target files in any way it chooses.
+The code reference must return a false value (C<undef> or C<0>) if
+the build of the file failed.  Any true value indicates a successful
+build of the target.
+
+Building target files using code references is considered EXPERIMENTAL
+due to the following current limitations:
+
+=over 4
+
+Cons does I<not> print anything to indicate the code reference is being
+called to build the file.  The only way to give the user any indication
+is to have the code reference explicitly print some sort of "building"
+message, as in the above examples.
+
+Cons does not generate any signatures for code references, so if the
+code in the reference changes, the target will I<not> be rebuilt.
+
+Cons has no public method to allow a code reference to extract
+construction variables.  This would be good to allow generalization of
+code references based on the current construction environment, but would
+also complicate the problem of generating meaningful signatures for code
+references.
+
+=back
+
+Support for building targets via code references has been released in
+this version to encourage experimentation and the seeking of possible
+solutions to the above limitations.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>X</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/user/alias.sgml b/doc/user/alias.sgml
new file mode 100644 (file)
index 0000000..33c236a
--- /dev/null
@@ -0,0 +1,45 @@
+<!--
+
+  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>Alias Targets</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
index 2cba10ed57f246d2994fd26008653c0ac6bc23d9..ac5f19371fb793643f7a5801c2ad7fec50f6f961 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+=head2 Adding new methods
+
+For slightly more demanding changes, you may wish to add new methods to the
+C<cons> package. Here's an example of a very simple extension,
+C<InstallScript>, which installs a tcl script in a requested location, but
+edits the script first to reflect a platform-dependent path that needs to be
+installed in the script:
+
+  # cons::InstallScript - Create a platform dependent version of a shell
+  # script by replacing string ``#!your-path-here'' with platform specific
+  # path $BIN_DIR.
+
+  sub cons::InstallScript {
+       my ($env, $dst, $src) = @_;
+       Command $env $dst, $src, qq(
+               sed s+your-path-here+$BIN_DIR+ %< > %>
+               chmod oug+x %>
+       );
+  }
+
+Notice that this method is defined directly in the C<cons> package (by
+prefixing the name with C<cons::>). A change made in this manner will be
+globally visible to all environments, and could be called as in the
+following example:
+
+  InstallScript $env "$BIN/foo", "foo.tcl";
+
+For a small improvement in generality, the C<BINDIR> variable could be
+passed in as an argument or taken from the construction environment-,-as
+C<%BINDIR>.
+
+
+=head2 Overriding methods
+
+Instead of adding the method to the C<cons> name space, you could define a
+new package which inherits existing methods from the C<cons> package and
+overrides or adds others. This can be done using Perl's inheritance
+mechanisms.
+
+The following example defines a new package C<cons::switch> which
+overrides the standard C<Library> method. The overridden method builds
+linked library modules, rather than library archives. A new
+constructor is provided. Environments created with this constructor
+will have the new library method; others won't.
+
+  package cons::switch;
+  BEGIN {@ISA = 'cons'}
+
+  sub new {
+       shift;
+       bless new cons(@_);
+  }
+
+  sub Library {
+       my($env) = shift;
+       my($lib) = shift;
+       my(@objs) = Objects $env @_;
+       Command $env $lib, @objs, q(
+               %LD -r %LDFLAGS %< -o %>
+       );
+  }
+
+This functionality could be invoked as in the following example:
+
+  $env = new cons::switch(@overrides);
+  ...
+  Library $env 'lib.o', 'foo.c', 'bar.c';
+
+-->
+
  <para>
 
    X
index 3ddfd32bd3c80a5475c7bdac4fd21c32945d5f91..5403c43ed2979747b011e306547954d3bb519e56 100644 (file)
   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<UseCache> method
+
+The C<UseCache> method instructs Cons to maintain a cache of derived
+files, to be shared among separate build trees of the same project.
+
+  UseCache("cache/<buildname>") || warn("cache directory not found");
+
 -->
 
  <para>
diff --git a/doc/user/command.sgml b/doc/user/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/user/cons.pl b/doc/user/cons.pl
new file mode 100644 (file)
index 0000000..8afbfec
--- /dev/null
@@ -0,0 +1,720 @@
+=head1 Introduction
+
+B<Cons> is a system for constructing, primarily, software, but is quite
+different from previous software construction systems. Cons was designed
+from the ground up to deal easily with the construction of software spread
+over multiple source directories. Cons makes it easy to create build scripts
+that are simple, understandable and maintainable. Cons ensures that complex
+software is easily and accurately reproducible.
+
+Cons uses a number of techniques to accomplish all of this. Construction
+scripts are just Perl scripts, making them both easy to comprehend and very
+flexible. Global scoping of variables is replaced with an import/export
+mechanism for sharing information between scripts, significantly improving
+the readability and maintainability of each script. B<Construction
+environments> are introduced: these are Perl objects that capture the
+information required for controlling the build process. Multiple
+environments are used when different semantics are required for generating
+products in the build tree. Cons implements automatic dependency analysis
+and uses this to globally sequence the entire build. Variant builds are
+easily produced from a single source tree. Intelligent build subsetting is
+possible, when working on localized changes. Overrides can be setup to
+easily override build instructions without modifying any scripts. MD5
+cryptographic B<signatures> are associated with derived files, and are used
+to accurately determine whether a given file needs to be rebuilt.
+
+While offering all of the above, and more, Cons remains simple and easy to
+use. This will, hopefully, become clear as you read the remainder of this
+document.
+
+
+
+=head2 Automatic global build sequencing
+
+Because Cons does full and accurate dependency analysis, and does this
+globally, for the entire build, Cons is able to use this information to take
+full control of the B<sequencing> of the build. This sequencing is evident
+in the above examples, and is equivalent to what you would expect for make,
+given a full set of dependencies. With Cons, this extends trivially to
+larger, multi-directory builds. As a result, all of the complexity involved
+in making sure that a build is organized correctly--including multi-pass
+hierarchical builds--is eliminated. We'll discuss this further in the next
+sections.
+
+
+
+=head1 A Model for sharing files
+
+
+=head2 Some simple conventions
+
+In any complex software system, a method for sharing build products needs to
+be established. We propose a simple set of conventions which are trivial to
+implement with Cons, but very effective.
+
+The basic rule is to require that all build products which need to be shared
+between directories are shared via an intermediate directory. We have
+typically called this F<export>, and, in a C environment, provided
+conventional sub-directories of this directory, such as F<include>, F<lib>,
+F<bin>, etc.
+
+These directories are defined by the top-level F<Construct> file. A simple
+F<Construct> file for a B<Hello, World!> application, organized using
+multiple directories, might look like this:
+
+  # Construct file for Hello, World!
+
+  # Where to put all our shared products.
+  $EXPORT = '#export';
+
+  Export qw( CONS INCLUDE LIB BIN );
+
+  # Standard directories for sharing products.
+  $INCLUDE = "$EXPORT/include";
+  $LIB = "$EXPORT/lib";
+  $BIN = "$EXPORT/bin";
+
+  # A standard construction environment.
+  $CONS = new cons (
+       CPPPATH => $INCLUDE,    # Include path for C Compilations
+       LIBPATH => $LIB,        # Library path for linking programs
+       LIBS => '-lworld',      # List of standard libraries
+  );
+
+  Build qw(
+       hello/Conscript
+       world/Conscript
+  );
+
+The F<world> directory's F<Conscript> file looks like this:
+
+  # Conscript file for directory world
+  Import qw( CONS INCLUDE LIB );
+
+  # Install the products of this directory
+  Install $CONS $LIB, 'libworld.a';
+  Install $CONS $INCLUDE, 'world.h';
+
+  # Internal products
+  Library $CONS 'libworld.a', 'world.c';
+
+and the F<hello> directory's F<Conscript> file looks like this:
+
+  # Conscript file for directory hello
+  Import qw( CONS BIN );
+
+  # Exported products
+  Install $CONS $BIN, 'hello';
+
+  # Internal products
+  Program $CONS 'hello', 'hello.c';
+
+To construct a B<Hello, World!> program with this directory structure, go to
+the top-level directory, and invoke C<cons> with the appropriate
+arguments. In the following example, we tell Cons to build the directory
+F<export>. To build a directory, Cons recursively builds all known products
+within that directory (only if they need rebuilding, of course). If any of
+those products depend upon other products in other directories, then those
+will be built, too.
+
+  % cons export
+  Install world/world.h as export/include/world.h
+  cc -Iexport/include -c hello/hello.c -o hello/hello.o
+  cc -Iexport/include -c world/world.c -o world/world.o
+  ar r world/libworld.a world/world.o
+  ar: creating world/libworld.a
+  ranlib world/libworld.a
+  Install world/libworld.a as export/lib/libworld.a
+  cc -o hello/hello hello/hello.o -Lexport/lib -lworld
+  Install hello/hello as export/bin/hello
+
+
+=head2 Clean, understandable, location-independent scripts
+
+You'll note that the two F<Conscript> files are very clean and
+to-the-point. They simply specify products of the directory and how to build
+those products. The build instructions are minimal: they specify which
+construction environment to use, the name of the product, and the name of
+the inputs. Note also that the scripts are location-independent: if you wish
+to reorganize your source tree, you are free to do so: you only have to
+change the F<Construct> file (in this example), to specify the new locations
+of the F<Conscript> files. The use of an export tree makes this goal easy.
+
+Note, too, how Cons takes care of little details for you. All the F<export>
+directories, for example, were made automatically. And the installed files
+were really hard-linked into the respective export directories, to save
+space and time. This attention to detail saves considerable work, and makes
+it even easier to produce simple, maintainable scripts.
+
+
+
+=head1 Signatures
+
+Cons uses file B<signatures> to decide if a derived file is out-of-date
+and needs rebuilding.  In essence, if the contents of a file change,
+or the manner in which the file is built changes, the file's signature
+changes as well.  This allows Cons to decide with certainty when a file
+needs rebuilding, because Cons can detect, quickly and reliably, whether
+any of its dependency files have been changed.
+
+
+=head2 MD5 content and build signatures
+
+Cons uses the B<MD5> (B<Message Digest 5>) algorithm to compute file
+signatures.  The MD5 algorithm computes a strong cryptographic checksum
+for any given input string.  Cons can, based on configuration, use two
+different MD5 signatures for a given file:
+
+The B<content signature> of a file is an MD5 checksum of the file's
+contents.  Consequently, when the contents of a file change, its content
+signature changes as well.
+
+The B<build signature> of a file is a combined MD5 checksum of:
+
+=over 4
+
+the signatures of all the input files used to build the file
+
+the signatures of all dependency files discovered by source scanners
+(for example, C<.h> files)
+
+the signatures of all dependency files specified explicitly via the
+C<Depends> method)
+
+the command-line string used to build the file
+
+=back
+
+The build signature is, in effect, a digest of all the dependency
+information for the specified file.  Consequently, a file's build
+signature changes whenever any part of its dependency information
+changes: a new file is added, the contents of a file on which it depends
+change, there's a change to the command line used to build the file (or
+any of its dependency files), etc.
+
+For example, in the previous section, the build signature of the
+F<world.o> file will include:
+
+=over 4
+
+the signature of the F<world.c> file
+
+the signatures of any header files that Cons detects are included,
+directly or indirectly, by F<world.c>
+
+the text of the actual command line was used to generate F<world.o>
+
+=back
+
+Similarly, the build signature of the F<libworld.a> file will include
+all the signatures of its constituents (and hence, transitively, the
+signatures of B<their> constituents), as well as the command line that
+created the file.
+
+Note that there is no need for a derived file to depend upon any
+particular F<Construct> or F<Conscript> file.  If changes to these files
+affect a file, then this will be automatically reflected in its build
+signature, since relevant parts of the command line are included in the
+signature. Unrelated F<Construct> or F<Conscript> changes will have no
+effect.
+
+
+=head2 Storing signatures in .consign files
+
+Before Cons exits, it stores the calculated signatures for all of the
+files it built or examined in F<.consign> files, one per directory.
+Cons uses this stored information on later invocations to decide if
+derived files need to be rebuilt.
+
+After the previous example was compiled, the F<.consign> file in the
+F<build/peach/world> directory looked like this:
+
+  world.h:985533370 - d181712f2fdc07c1f05d97b16bfad904
+  world.o:985533372 2a0f71e0766927c0532977b0d2158981
+  world.c:985533370 - c712f77189307907f4189b5a7ab62ff3
+  libworld.a:985533374 69e568fc5241d7d25be86d581e1fb6aa
+
+After the file name and colon, the first number is a timestamp of the
+file's modification time (on UNIX systems, this is typically the number
+of seconds since January 1st, 1970).  The second value is the build
+signature of the file (or ``-'' in the case of files with no build
+signature--that is, source files).  The third value, if any, is the
+content signature of the file.
+
+
+=head2 Using build signatures to decide when to rebuild files
+
+When Cons is deciding whether to build or rebuild a derived file, it
+first computes the file's current build signature.  If the file doesn't
+exist, it must obviously be built.
+
+If, however, the file already exists, Cons next compares the
+modification timestamp of the file against the timestamp value in
+the F<.consign> file.  If the timestamps match, Cons compares the
+newly-computed build signature against the build signature in the
+F<.consign> file.  If the timestamps do not match or the build
+signatures do not match, the derived file is rebuilt.
+
+After the file is built or rebuilt, Cons arranges to store the
+newly-computed build signature in the F<.consign> file when it exits.
+
+
+=head2 Signature example
+
+The use of these signatures is an extremely simple, efficient, and
+effective method of improving--dramatically--the reproducibility of a
+system.
+
+We'll demonstrate this with a simple example:
+
+  # Simple "Hello, World!" Construct file
+  $CFLAGS = '-g' if $ARG{DEBUG} eq 'on';
+  $CONS = new cons(CFLAGS => $CFLAGS);
+  Program $CONS 'hello', 'hello.c';
+
+Notice how Cons recompiles at the appropriate times:
+
+  % cons hello
+  cc -c hello.c -o hello.o
+  cc -o hello hello.o
+  % cons hello
+  cons: "hello" is up-to-date.
+  % cons DEBUG=on hello
+  cc -g -c hello.c -o hello.o
+  cc -o hello hello.o
+  % cons DEBUG=on hello
+  cons: "hello" is up-to-date.
+  % cons hello
+  cc -c hello.c -o hello.o
+  cc -o hello hello.o
+
+
+=head2 Source-file signature configuration
+
+Cons provides a C<SourceSignature> method that allows you to configure
+how the signature should be calculated for any source file when its
+signature is being used to decide if a dependent file is up-to-date.
+The arguments to the C<SourceSignature> method consist of one or more
+pairs of strings:
+
+  SourceSignature 'auto/*.c' => 'content',
+                 '*' => 'stored-content';
+
+The first string in each pair is a pattern to match against derived file
+path names. The pattern is a file-globbing pattern, not a Perl regular
+expression; the pattern <*.l> will match all Lex source files.  The C<*>
+wildcard will match across directory separators; the pattern C<foo/*.c>
+would match all C source files in any subdirectory underneath the C<foo>
+subdirectory.
+
+The second string in each pair contains one of the following keywords to
+specify how signatures should be calculated for source files that match
+the pattern.  The available keywords are:
+
+=over 4
+
+=item content
+
+Use the content signature of the source file when calculating signatures
+of files that depend on it.  This guarantees correct calculation of the
+file's signature for all builds, by telling Cons to read the contents of
+a source file to calculate its content signature each time it is run.
+
+=item stored-content
+
+Use the source file's content signature as stored in the F<.consign>
+file, provided the file's timestamp matches the cached timestamp value
+in the F<.consign> file.  This optimizes performance, with the slight
+risk of an incorrect build if a source file's contents have been changed
+so quickly after its previous update that the timestamp still matches
+the stored timestamp in the F<.consign> file even though the contents
+have changed.
+
+=back
+
+The Cons default behavior of always calculating a source file's
+signature from the file's contents is equivalent to specifying:
+
+  SourceSignature '*' => 'content';
+
+The C<*> will match all source files.  The C<content> keyword
+specifies that Cons will read the contents of a source file to calculate
+its signature each time it is run.
+
+A useful global performance optimization is:
+
+  SourceSignature '*' => 'stored-content';
+
+This specifies that Cons will use pre-computed content signatures
+from F<.consign> files, when available, rather than re-calculating a
+signature from the the source file's contents each time Cons is run.  In
+practice, this is safe for most build situations, and only a problem
+when source files are changed automatically (by scripts, for example).
+The Cons default, however, errs on the side of guaranteeing a correct
+build in all situations.
+
+Cons tries to match source file path names against the patterns in the
+order they are specified in the C<SourceSignature> arguments:
+
+  SourceSignature '/usr/repository/objects/*' => 'stored-content',
+                 '/usr/repository/*' => 'content',
+                 '*.y' => 'content',
+                 '*' => 'stored-content';
+
+In this example, all source files under the F</usr/repository/objects>
+directory will use F<.consign> file content signatures, source files
+anywhere else underneath F</usr/repository> will not use F<.consign>
+signature values, all Yacc source files (C<*.y>) anywhere else will not
+use F<.consign> signature values, and any other source file will use
+F<.consign> signature values.
+
+
+=head2 Derived-file signature configuration
+
+Cons provides a C<SIGNATURE> construction variable that allows you to
+configure how signatures are calculated for any derived file when its
+signature is being used to decide if a dependent file is up-to-date.
+The value of the C<SIGNATURE> construction variable is a Perl array
+reference that holds one or more pairs of strings, like the arguments to
+the C<SourceSignature> method.
+
+The first string in each pair is a pattern to match against derived file
+path names. The pattern is a file-globbing pattern, not a Perl regular
+expression; the pattern `*.obj' will match all (Win32) object files.
+The C<*> wildcard will match across directory separators; the pattern
+`foo/*.a' would match all (UNIX) library archives in any subdirectory
+underneath the foo subdirectory.
+
+The second string in each pair contains one of the following keywords
+to specify how signatures should be calculated for derived files that
+match the pattern.  The available keywords are the same as for the
+C<SourceSignature> method, with an additional keyword:
+
+=over 4
+
+=item build
+
+Use the build signature of the derived file when calculating signatures
+of files that depend on it.  This guarantees correct builds by forcing
+Cons to rebuild any and all files that depend on the derived file.
+
+=item content
+
+Use the content signature of the derived file when calculating signatures
+of files that depend on it.  This guarantees correct calculation of the
+file's signature for all builds, by telling Cons to read the contents of
+a derived file to calculate its content signature each time it is run.
+
+=item stored-content
+
+Use the derived file's content signature as stored in the F<.consign>
+file, provided the file's timestamp matches the cached timestamp value
+in the F<.consign> file.  This optimizes performance, with the slight
+risk of an incorrect build if a derived file's contents have been
+changed so quickly after a Cons build that the file's timestamp still
+matches the stored timestamp in the F<.consign> file.
+
+=back
+
+The Cons default behavior (as previously described) for using
+derived-file signatures is equivalent to:
+
+  $env = new cons(SIGNATURE => ['*' => 'build']);
+
+The C<*> will match all derived files.  The C<build> keyword specifies
+that all derived files' build signatures will be used when calculating
+whether a dependent file is up-to-date.
+
+A useful alternative default C<SIGNATURE> configuration for many sites:
+
+  $env = new cons(SIGNATURE => ['*' => 'content']);
+
+In this configuration, derived files have their signatures calculated
+from the file contents.  This adds slightly to Cons' workload, but has
+the useful effect of "stopping" further rebuilds if a derived file is
+rebuilt to exactly the same file contents as before, which usually
+outweighs the additional computation Cons must perform.
+
+For example, changing a comment in a C file and recompiling should
+generate the exact same object file (assuming the compiler doesn't
+insert a timestamp in the object file's header).  In that case,
+specifying C<content> or C<stored-content> for the signature calculation
+will cause Cons to recognize that the object file did not actually
+change as a result of being rebuilt, and libraries or programs that
+include the object file will not be rebuilt.  When C<build> is
+specified, however, Cons will only "know" that the object file was
+rebuilt, and proceed to rebuild any additional files that include the
+object file.
+
+Note that Cons tries to match derived file path names against the
+patterns in the order they are specified in the C<SIGNATURE> array
+reference:
+
+  $env = new cons(SIGNATURE => ['foo/*.o' => 'build',
+                               '*.o' => 'content',
+                               '*.a' => 'stored-content',
+                               '*' => 'content']);
+
+In this example, all object files underneath the F<foo> subdirectory
+will use build signatures, all other object files (including object
+files underneath other subdirectories!) will use F<.consign> file
+content signatures, libraries will use F<.consign> file build
+signatures, and all other derived files will use content signatures.
+
+
+=head2 Debugging signature calculation
+
+Cons provides a C<-S> option that can be used to specify what internal
+Perl package Cons should use to calculate signatures.  The default Cons
+behavior is equivalent to specifying C<-S md5> on the command line.
+
+The only other package (currently) available is an C<md5::debug>
+package that prints out detailed information about the MD5 signature
+calculations performed by Cons:
+
+  % cons -S md5::debug hello
+  sig::md5::srcsig(hello.c)
+          => |52d891204c62fe93ecb95281e1571938|
+  sig::md5::collect(52d891204c62fe93ecb95281e1571938)
+          => |fb0660af4002c40461a2f01fbb5ffd03|
+  sig::md5::collect(52d891204c62fe93ecb95281e1571938,
+                    fb0660af4002c40461a2f01fbb5ffd03,
+                    cc   -c %< -o %>)
+          => |f7128da6c3fe3c377dc22ade70647b39|
+  sig::md5::current(||
+                 eq |f7128da6c3fe3c377dc22ade70647b39|)
+  cc -c hello.c -o hello.o
+  sig::md5::collect()
+          => |d41d8cd98f00b204e9800998ecf8427e|
+  sig::md5::collect(f7128da6c3fe3c377dc22ade70647b39,
+                    d41d8cd98f00b204e9800998ecf8427e,
+                    cc  -o %> %<  )
+          => |a0bdce7fd09e0350e7efbbdb043a00b0|
+  sig::md5::current(||
+                 eq |a0bdce7fd09e0350e7efbbdb043a00b0|)
+  cc -o hello, hello.o
+
+
+
+
+
+
+
+=head1 Temporary overrides
+
+Cons provides a very simple mechanism for overriding aspects of a build. The
+essence is that you write an override file containing one or more
+C<Override> commands, and you specify this on the command line, when you run
+C<cons>:
+
+  % cons -o over export
+
+will build the F<export> directory, with all derived files subject to the
+overrides present in the F<over> file. If you leave out the C<-o> option,
+then everything necessary to remove all overrides will be rebuilt.
+
+
+=head2 Overriding environment variables
+
+The override file can contain two types of overrides. The first is incoming
+environment variables. These are normally accessible by the F<Construct>
+file from the C<%ENV> hash variable. These can trivially be overridden in
+the override file by setting the appropriate elements of C<%ENV> (these
+could also be overridden in the user's environment, of course).
+
+
+=head2 The Override command
+
+The second type of override is accomplished with the C<Override> command,
+which looks like this:
+
+  Override <regexp>, <var1> => <value1>, <var2> => <value2>, ...;
+
+The regular expression I<regexp> is matched against every derived file that
+is a candidate for the build. If the derived file matches, then the
+variable/value pairs are used to override the values in the construction
+environment associated with the derived file.
+
+Let's suppose that we have a construction environment like this:
+
+  $CONS = new cons(
+       COPT => '',
+       CDBG => '-g',
+       CFLAGS => '%COPT %CDBG',
+  );
+
+Then if we have an override file F<over> containing this command:
+
+  Override '\.o$', COPT => '-O', CDBG => '';
+
+then any C<cons> invocation with C<-o over> that creates F<.o> files via
+this environment will cause them to be compiled with C<-O >and no C<-g>. The
+override could, of course, be restricted to a single directory by the
+appropriate selection of a regular expression.
+
+Here's the original version of the Hello, World! program, built with this
+environment. Note that Cons rebuilds the appropriate pieces when the
+override is applied or removed:
+
+  % cons hello
+  cc -g -c hello.c -o hello.o
+  cc -o hello hello.o
+  % cons -o over hello
+  cc -O -c hello.c -o hello.o
+  cc -o hello hello.o
+  % cons -o over hello
+  cons: "hello" is up-to-date.
+  % cons hello
+  cc -g -c hello.c -o hello.o
+  cc -o hello hello.o
+
+It's important that the C<Override> command only be used for temporary,
+on-the-fly overrides necessary for development because the overrides are not
+platform independent and because they rely too much on intimate knowledge of
+the workings of the scripts. For temporary use, however, they are exactly
+what you want.
+
+Note that it is still useful to provide, say, the ability to create a fully
+optimized version of a system for production use--from the F<Construct> and
+F<Conscript> files. This way you can tailor the optimized system to the
+platform. Where optimizer trade-offs need to be made (particular files may
+not be compiled with full optimization, for example), then these can be
+recorded for posterity (and reproducibility) directly in the scripts.
+
+
+
+=head2 The C<Module> method
+
+The C<Module> method is a combination of the C<Program> and C<Command>
+methods. Rather than generating an executable program directly, this command
+allows you to specify your own command to actually generate a module. The
+method is invoked as follows:
+
+  Module $env <module name>, <source or object files>, <construction command>;
+
+This command is useful in instances where you wish to create, for example,
+dynamically loaded modules, or statically linked code libraries.
+
+
+
+
+=head2 The C<RuleSet> method
+
+The C<RuleSet> method returns the construction variables for building
+various components with one of the rule sets supported by Cons.  The
+currently supported rule sets are:
+
+=over 4
+
+=item msvc
+
+Rules for the Microsoft Visual C++ compiler suite.
+
+=item unix
+
+Generic rules for most UNIX-like compiler suites.
+
+=back
+
+On systems with more than one available compiler suite, this allows you
+to easily create side-by-side environments for building software with
+multiple tools:
+
+    $msvcenv = new cons(RuleSet("msvc"));
+    $cygnusenv = new cons(RuleSet("unix"));
+
+In the future, this could also be extended to other platforms that
+have different default rule sets.
+
+
+=head2 The C<DefaultRules> method
+
+The C<DefaultRules> method sets the default construction variables that
+will be returned by the C<new> method to the specified arguments:
+
+  DefaultRules(CC     => 'gcc',
+              CFLAGS => '',
+              CCCOM  => '%CC %CFLAGS %_IFLAGS -c %< -o %>');
+  $env = new cons();
+  # $env now contains *only* the CC, CFLAGS,
+  # and CCCOM construction variables
+
+Combined with the C<RuleSet> method, this also provides an easy way
+to set explicitly the default build environment to use some supported
+toolset other than the Cons defaults:
+
+    # use a UNIX-like tool suite (like cygwin) on Win32
+    DefaultRules(RuleSet('unix'));
+    $env = new cons();
+
+Note that the C<DefaultRules> method completely replaces the default
+construction environment with the specified arguments, it does not
+simply override the existing defaults.  To override one or more
+variables in a supported C<RuleSet>, append the variables and values:
+
+  DefaultRules(RuleSet('unix'), CFLAGS => '-O3');
+  $env1 = new cons();
+  $env2 = new cons();
+  # both $env1 and $env2 have 'unix' defaults
+  # with CFLAGS set to '-O3'
+
+
+
+
+
+
+
+
+=head2 The C<SourcePath> method
+
+The C<SourcePath> mathod returns the real source path name of a file,
+as opposed to the path name within a build directory.  It is invoked
+as follows:
+
+  $path = SourcePath <buildpath>;
+
+
+=head2 The C<ConsPath> method
+
+The C<ConsPath> method returns true if the supplied path is a derivable
+file, and returns undef (false) otherwise.
+It is invoked as follows:
+
+  $result = ConsPath <path>;
+
+
+=head2 The C<SplitPath> method
+
+The C<SplitPath> method looks up multiple path names in a string separated
+by the default path separator for the operating system (':' on UNIX
+systems, ';' on Windows NT), and returns the fully-qualified names.
+It is invoked as follows:
+
+  @paths = SplitPath <pathlist>;
+
+The C<SplitPath> method will convert  names prefixed '#' to the
+appropriate top-level build name (without the '#') and will convert
+relative names to top-level names.
+
+
+=head2 The C<DirPath> method
+
+The C<DirPath> method returns the build path name(s) of a directory or
+list of directories.  It is invoked as follows:
+
+  $cwd = DirPath <paths>;
+
+The most common use for the C<DirPath> method is:
+
+  $cwd = DirPath '.';
+
+to fetch the path to the current directory of a subsidiary F<Conscript>
+file.
+
+
+=head2 The C<FilePath> method
+
+The C<FilePath> method returns the build path name(s) of a file or
+list of files.  It is invoked as follows:
+
+  $file = FilePath <path>;
index 3024c02381bd5f42c21fbbe8c8a845ed7425dccc..448777f1d175d658030520276bbdc59c6bb1b986 100644 (file)
@@ -22,6 +22,7 @@
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
  <para>
 
    X
index 500b81c1f125a9220293d814b1e6ebc833c2c1a5..7f6059ce3a087ad35bb0c1afc8e097f1a71b4f21 100644 (file)
@@ -26,7 +26,7 @@
 <blockquote>
  <para>
 
-  Copyright (c) 2002, 2003 Steven Knight
+  SCons User's Guide Copyright (c) 2003 Steven Knight
 
  </para>
 </blockquote>
diff --git a/doc/user/default.sgml b/doc/user/default.sgml
new file mode 100644 (file)
index 0000000..bb81a3a
--- /dev/null
@@ -0,0 +1,78 @@
+<!--
+
+  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.
+
+-->
+
+<!--
+
+=head1 Default targets
+
+Until now, we've demonstrated invoking Cons with an explicit target
+to build:
+
+  % cons hello
+
+Normally, Cons does not build anything unless a target is specified,
+but specifying '.' (the current directory) will build everything:
+
+  % cons               # does not build anything
+
+  % cons .             # builds everything under the top-level directory
+
+Adding the C<Default> method to any F<Construct> or F<Conscript> file will add
+the specified targets to a list of default targets.  Cons will build
+these defaults if there are no targets specified on the command line.
+So adding the following line to the top-level F<Construct> file will mimic
+Make's typical behavior of building everything by default:
+
+  Default '.';
+
+The following would add the F<hello> and F<goodbye> commands (in the
+same directory as the F<Construct> or F<Conscript> file) to the default list:
+
+  Default qw(
+       hello
+       goodbye
+  );
+
+The C<Default> method may be used more than once to add targets to the
+default list.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Default; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
index d95ae79740d93ca970f3f2e231b33e4e36000c6b..c94ac0d1d18eee0b28b7e8c84237b76f57ced63d 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+
+
+=head2 The C<Salt> method
+
+The C<Salt> method adds a constant value to the signature calculation
+for every derived file.  It is invoked as follows:
+
+  Salt $string;
+
+Changing the Salt value will force a complete rebuild of every derived
+file.  This can be used to force rebuilds in certain desired
+circumstances.  For example,
+
+  Salt `uname -s`;
+
+Would force a complete rebuild of every derived file whenever the
+operating system on which the build is performed (as reported by C<uname
+-s>) changes.
+
+-->
+
  <para>
 
-   X
+ 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>
+
+ (&SCons; only reports "...is up to date"
+ for target files named explicitly on the command line,
+ to avoid cluttering the output.)
 
  </para>
 
 
    <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.
+
+-->
+
  <section>
- <title>Time Stamps</title>
+ <title>Implicit Dependencies</title>
 
    <para>
 
 
    </para>
 
+   <programlisting>
+      #define string    "world"
+   </programlisting>
+
+   <programlisting>
+      #include "hello.h" 
+      int
+      main()
+      {
+          printf("Hello, %s!\n", string);
+      }
+   </programlisting>
+
+   <programlisting>
+      env = Environment(CPPPATH = '.')  XXX IS CPPPATH NECESSARY?
+      hello = env.Program('hello.c')
+   </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>
+      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;
+      for the #include 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.
+-->
+
+   </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>
 
    <para>
 
-   X
+   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 &Ignore; Method</title>
+ <title>The &Salt; Method</title>
 
    <para>
 
 
  </section>
 
+ -->
+
  <section>
- <title>The &Salt; Method</title>
+ <title>Time Stamps</title>
 
    <para>
 
index e0ea8ee8a3d5a32aebc43069acee48f326706653..b06ade113e7d51c5af73ff7a718badea465cbe03 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+=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
+has a set of keyword/value pairs and a set of methods, and which is used
+to tell Cons how target files should be built.  This section describes
+how Cons uses and expands construction environment values to control its
+build behavior.
+
+=head2 Construction variable expansion
+
+Construction variables from a construction environment are expanded
+by preceding the keyword with a C<%> (percent sign):
+
+  Construction variables:
+       XYZZY => 'abracadabra',
+
+  The string:  "The magic word is:  %XYZZY!"
+  expands to:  "The magic word is:  abracadabra!"
+
+A construction variable name may be surrounded by C<{> and C<}> (curly
+braces), which are stripped as part of the expansion.  This can
+sometimes be necessary to separate a variable expansion from trailing
+alphanumeric characters:
+
+  Construction variables:
+       OPT    => 'value1',
+       OPTION => 'value2',
+
+  The string:  "%OPT %{OPT}ION %OPTION %{OPTION}"
+  expands to:  "value1 value1ION value2 value2"
+
+Construction variable expansion is recursive, that is, a string
+containing C<%->expansions after substitution will be re-expanded until
+no further substitutions can be made:
+
+  Construction variables:
+       STRING => 'The result is:  %FOO',
+       FOO    => '%BAR',
+       BAR    => 'final value',
+
+  The string:  "The string says:  %STRING"
+  expands to:  "The string says:  The result is:  final value"
+
+If a construction variable is not defined in an environment, then the
+null string is substituted:
+
+  Construction variables:
+       FOO => 'value1',
+       BAR => 'value2',
+
+  The string:  "%FOO <%NO_VARIABLE> %BAR"
+  expands to:  "value1 <> value2"
+
+A doubled C<%%> will be replaced by a single C<%>:
+
+  The string:  "Here is a percent sign:  %%"
+  expands to:  "Here is a percent sign: %"
+
+=head2 Default construction variables
+
+When you specify no arguments when creating a new construction
+environment:
+
+  $env = new cons();
+
+Cons creates a reference to a new, default construction
+environment. This contains a number of construction variables and some
+methods. At the present writing, the default construction variables on a
+UNIX system are:
+
+  CC            => 'cc',
+  CFLAGS        => '',
+  CCCOM         => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
+  CXX           => '%CC',
+  CXXFLAGS      => '%CFLAGS',
+  CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
+  INCDIRPREFIX  => '-I',
+  INCDIRSUFFIX  => '',
+  LINK          => '%CXX',
+  LINKCOM       => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
+  LINKMODULECOM => '%LD -r -o %> %<',
+  LIBDIRPREFIX  => '-L',
+  LIBDIRSUFFIX  => '',
+  AR           => 'ar',
+  ARFLAGS      => 'r',
+  ARCOM                => ['%AR %ARFLAGS %> %<', '%RANLIB %>'],
+  RANLIB       => 'ranlib',
+  AS           => 'as',
+  ASFLAGS      => '',
+  ASCOM                => '%AS %ASFLAGS %< -o %>',
+  LD           => 'ld',
+  LDFLAGS      => '',
+  PREFLIB      => 'lib',
+  SUFLIB       => '.a',
+  SUFLIBS      => '.so:.a',
+  SUFOBJ       => '.o',
+  SIGNATURE     => [ '*' => 'build' ],
+  ENV          => { 'PATH' => '/bin:/usr/bin' },
+
+
+And on a Win32 system (Windows NT), the default construction variables
+are (unless the default rule style is set using the B<DefaultRules>
+method):
+
+  CC           => 'cl',
+  CFLAGS       => '/nologo',
+  CCCOM                => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
+  CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
+  INCDIRPREFIX  => '/I',
+  INCDIRSUFFIX  => '',
+  LINK          => 'link',
+  LINKCOM       => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
+  LINKMODULECOM => '%LD /r /o %> %<',
+  LIBDIRPREFIX  => '/LIBPATH:',
+  LIBDIRSUFFIX  => '',
+  AR            => 'lib',
+  ARFLAGS       => '/nologo ',
+  ARCOM         => "%AR %ARFLAGS /out:%> %<",
+  RANLIB        => '',
+  LD            => 'link',
+  LDFLAGS       => '/nologo ',
+  PREFLIB       => '',
+  SUFEXE       => '.exe',
+  SUFLIB       => '.lib',
+  SUFLIBS      => '.dll:.lib',
+  SUFOBJ       => '.obj',
+  SIGNATURE     => [ '*' => 'build' ],
+
+These variables are used by the various methods associated with the
+environment. In particular, any method that ultimately invokes an external
+command will substitute these variables into the final command, as
+appropriate. For example, the C<Objects> method takes a number of source
+files and arranges to derive, if necessary, the corresponding object
+files:
+
+  Objects $env 'foo.c', 'bar.c';
+
+This will arrange to produce, if necessary, F<foo.o> and F<bar.o>. The
+command invoked is simply C<%CCCOM>, which expands, through substitution,
+to the appropriate external command required to build each object. The
+substitution rules will be discussed in detail in the next section.
+
+The construction variables are also used for other purposes. For example,
+C<CPPPATH> is used to specify a colon-separated path of include
+directories. These are intended to be passed to the C preprocessor and are
+also used by the C-file scanning machinery to determine the dependencies
+involved in a C Compilation.
+
+Variables beginning with underscore are created by various methods,
+and should normally be considered ``internal'' variables. For example,
+when a method is called which calls for the creation of an object from
+a C source, the variable C<_IFLAGS> is created: this corresponds to the
+C<-I> switches required by the C compiler to represent the directories
+specified by C<CPPPATH>.
+
+Note that, for any particular environment, the value of a variable is set
+once, and then never reset (to change a variable, you must create a new
+environment. Methods are provided for copying existing environments for this
+purpose). Some internal variables, such as C<_IFLAGS> are created on demand,
+but once set, they remain fixed for the life of the environment.
+
+The C<CFLAGS>, C<LDFLAGS>, and C<ARFLAGS> variables all supply a place
+for passing options to the compiler, loader, and archiver, respectively.
+
+The C<INCDIRPREFIX> and C<INCDIRSUFFIX> variables specify option
+strings to be appended to the beginning and end, respectively, of each
+include directory so that the compiler knows where to find F<.h> files.
+Similarly, the C<LIBDIRPREFIX> and C<LIBDIRSUFFIX> variables specify the
+option string to be appended to the beginning of and end, respectively,
+of each directory that the linker should search for libraries.
+
+Another variable, C<ENV>, is used to determine the system environment during
+the execution of an external command. By default, the only environment
+variable that is set is C<PATH>, which is the execution path for a UNIX
+command. For the utmost reproducibility, you should really arrange to set
+your own execution path, in your top-level F<Construct> file (or perhaps by
+importing an appropriate construction package with the Perl C<use>
+command). The default variables are intended to get you off the ground.
+
+=head2 Expanding variables in construction commands
+
+Within a construction command, construction variables will be expanded
+according to the rules described above.  In addition to normal variable
+expansion from the construction environment, construction commands also
+expand the following pseudo-variables to insert the specific input and
+output files in the command line that will be executed:
+
+=over 10
+
+=item %>
+
+The target file name.  In a multi-target command, this expands to the
+first target mentioned.)
+
+=item %0
+
+Same as C<%E<gt>>.
+
+=item %1, %2, ..., %9
+
+These refer to the first through ninth input file, respectively.
+
+=item %E<lt>
+
+The full set of input file names. If any of these have been used
+anywhere else in the current command line (via C<%1>, C<%2>, etc.), then
+those will be deleted from the list provided by C<%E<lt>>. Consider the
+following command found in a F<Conscript> file in the F<test> directory:
+
+  Command $env 'tgt', qw(foo bar baz), qq(
+       echo %< -i %1 > %>
+       echo %< -i %2 >> %>
+       echo %< -i %3 >> %>
+  );
+
+If F<tgt> needed to be updated, then this would result in the execution of
+the following commands, assuming that no remapping has been established for
+the F<test> directory:
+
+  echo test/bar test/baz -i test/foo > test/tgt
+  echo test/foo test/baz -i test/bar >> test/tgt
+  echo test/foo test/bar -i test/baz >> test/tgt
+
+=back
+
+Any of the above pseudo-variables may be followed immediately by one of
+the following suffixes to select a portion of the expanded path name:
+
+  :a    the absolute path to the file name
+  :b    the directory plus the file name stripped of any suffix
+  :d    the directory
+  :f    the file name
+  :s    the file name suffix
+  :F    the file name stripped of any suffix
+  :S    the absolute path path to a Linked source file
+
+Continuing with the above example, C<%E<lt>:f> would expand to C<foo bar baz>,
+and C<%E<gt>:d> would expand to C<test>.
+
+There are additional C<%> elements which affect the command line(s):
+
+=over 10
+
+=item %[ %]
+
+It is possible to programmatically rewrite part of the command by
+enclosing part of it between C<%[> and C<%]>.  This will call the
+construction variable named as the first word enclosed in the brackets
+as a Perl code reference; the results of this call will be used to
+replace the contents of the brackets in the command line.  For example,
+given an existing input file named F<tgt.in>:
+
+  @keywords = qw(foo bar baz);
+  $env = new cons(X_COMMA => sub { join(",", @_) });
+  Command $env 'tgt', 'tgt.in', qq(
+       echo '# Keywords: %[X_COMMA @keywords %]' > %>
+       cat %< >> %>
+  );
+
+This will execute:
+
+  echo '# Keywords: foo,bar,baz' > tgt
+  cat tgt.in >> tgt
+
+=item %( %)
+
+Cons includes the text of the command line in the MD5 signature for a
+build, so that targets get rebuilt if you change the command line (to
+add or remove an option, for example).  Command-line text in between
+C<%(> and C<%)>, however, will be ignored for MD5 signature calculation.
+
+Internally, Cons uses C<%(> and C<%)> around include and library
+directory options (C<-I> and C<-L> on UNIX systems, C</I> and
+C</LIBPATH> on Windows NT) to avoid rebuilds just because the directory
+list changes.  Rebuilds occur only if the changed directory list causes
+any included I<files> to change, and a changed include file is detected
+by the MD5 signature calculation on the actual file contents.
+
+=back
+
+=head2 Expanding construction variables in file names
+
+Cons expands construction variables in the source and target file names
+passed to the various construction methods according to the expansion
+rules described above:
+
+  $env = new cons(
+       DESTDIR =>      'programs',
+       SRCDIR  =>      'src',
+  );
+  Program $env '%DESTDIR/hello', '%SRCDIR/hello.c';
+
+This allows for flexible configuration, through the construction
+environment, of directory names, suffixes, etc.
+
+=head1 Default construction methods
+
+The list of default construction methods includes the following:
+
+
+=head2 The C<new> constructor
+
+The C<new> method is a Perl object constructor. That is, it is not invoked
+via a reference to an existing construction environment B<reference>, but,
+rather statically, using the name of the Perl B<package> where the
+constructor is defined. The method is invoked like this:
+
+  $env = new cons(<overrides>);
+
+The environment you get back is blessed into the package C<cons>, which
+means that it will have associated with it the default methods described
+below. Individual construction variables can be overridden by providing
+name/value pairs in an override list. Note that to override any command
+environment variable (i.e. anything under C<ENV>), you will have to override
+all of them. You can get around this difficulty by using the C<copy> method
+on an existing construction environment.
+
+
+=head2 The C<clone> method
+
+The C<clone> method creates a clone of an existing construction environment,
+and can be called as in the following example:
+
+  $env2 = $env1->clone(<overrides>);
+
+You can provide overrides in the usual manner to create a different
+environment from the original. If you just want a new name for the same
+environment (which may be helpful when exporting environments to existing
+components), you can just use simple assignment.
+
+
+=head2 The C<copy> method
+
+The C<copy> method extracts the externally defined construction variables
+from an environment and returns them as a list of name/value
+pairs. Overrides can also be provided, in which case, the overridden values
+will be returned, as appropriate. The returned list can be assigned to a
+hash, as shown in the prototype, below, but it can also be manipulated in
+other ways:
+
+  %env = $env1->copy(<overrides>);
+
+The value of C<ENV>, which is itself a hash, is also copied to a new hash,
+so this may be changed without fear of affecting the original
+environment. So, for example, if you really want to override just the
+C<PATH> variable in the default environment, you could do the following:
+
+  %cons = new cons()->copy();
+  $cons{ENV}{PATH} = "<your path here>";
+  $cons = new cons(%cons);
+
+This will leave anything else that might be in the default execution
+environment undisturbed.
+
+
+
+=head2 Overriding construction variables
+
+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>
 
    X
 
- </para>
+<!--
 
- <section>
- <title>The &Environment; Constructor</title>
+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:
 
-   <para>
 
-   X
 
-   </para>
+  $env = new cons(
+       CC      =>      'gcc',
+       LIBS    =>      'libworld.a'
+  );
 
- </section>
+  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
+
+-->
+
+ </para>
+
+ <programlisting>
+    optimize = Environment(CCFLAGS = '-O2')
+    debug = Environment(CCFLAGS = '-g')
+
+    o = optimize.Object('foo-opt', 'foo.c')
+    optimize.Program(o)
+
+    d = debug.Object('foo-debug', 'foo.c')
+    debug.Program(d)
+ </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>
 
  <section>
- <title>The &Clone; Method</title>
+ <title>The &Environment; Constructor</title>
 
    <para>
 
index 3024c02381bd5f42c21fbbe8c8a845ed7425dccc..448777f1d175d658030520276bbdc59c6bb1b986 100644 (file)
@@ -22,6 +22,7 @@
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
  <para>
 
    X
index 3024c02381bd5f42c21fbbe8c8a845ed7425dccc..448777f1d175d658030520276bbdc59c6bb1b986 100644 (file)
@@ -22,6 +22,7 @@
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
  <para>
 
    X
diff --git a/doc/user/help.sgml b/doc/user/help.sgml
new file mode 100644 (file)
index 0000000..7c1732e
--- /dev/null
@@ -0,0 +1,88 @@
+<!--
+
+  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>Providing build-specific help instructions</title>
+
+   <para>
+
+   It's often very useful to be able to give
+   users some help that describes the
+   specific targets, build options, etc.,
+   that can be used for the build.
+   &SCons; provides the &Help; function
+   to allow you to specify this help text:
+
+   </para>
+
+   <programlisting>
+      Help("""
+      Type: 'scons program' to build the production program,
+            'scons debug' to build the debug version.
+      """)
+   </programlisting>
+
+   <para>
+
+   (Note the above use of the Python triple-quote syntax,
+   which comes in very handy for
+   specifying multi-line strings like help text.)
+
+   </para>
+
+   <para>
+
+   When the &SConstruct; or &SConscript; files
+   contain such a call to the &Help; function,
+   the specified help text will be displayed in response to
+   the &SCons; <literal>-h</literal> option:
+
+   </para>
+
+   <literallayout>
+      % <userinput>scons -h</userinput>
+      Type: 'scons program' to build the production program,
+            'scons debug' to build the debug version.
+   </literallayout>
+
+   <para>
+
+   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
+   options.
+   This list is also always displayed whenever
+   the <literal>-H</literal> option is used.
+
+   </para>
+
+ </section>
index 3f65aebbaaa56e07fea4506bab63b1194d7c84db..aa56c8d4e34f6f43a7f97bb686688be530c2cff2 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+=head2 A hierarchy of build scripts
+
+A larger build, in Cons, is organized by creating a hierarchy of B<build
+scripts>. At the top of the tree is a script called F<Construct>. The rest
+of the scripts, by convention, are each called F<Conscript>. These scripts
+are connected together, very simply, by the C<Build>, C<Export>, and
+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>
+file:
+
+  Conscript_chdir 1;
+
+When enabled, Cons will change to the subsidiary F<Conscript> file's
+containing directory while reading in that file, and then change back
+to the top-level directory once the file has been processed.
+
+It is expected that this behavior will become the default in some future
+version of Cons.  To prepare for this transition, builds that expect
+Cons to remain at the top of the build while it reads in a subsidiary
+F<Conscript> file should explicitly disable this feature as follows:
+
+  Conscript_chdir 0;
+
+=head2 Relative, top-relative, and absolute file names
+
+You may have noticed that the file names specified to the Build command are
+relative to the location of the script it is invoked from. This is generally
+true for other filename arguments to other commands, too, although we might
+as well mention here that if you begin a file name with a hash mark, ``#'',
+then that file is interpreted relative to the top-level directory (where the
+F<Construct> file resides). And, not surprisingly, if you begin it with ``/'',
+then it is considered to be an absolute pathname. This is true even on
+systems which use a back slash rather than a forward slash to name absolute
+paths.
+
+(There is another file prefix, ``!'', that is interpreted specially by
+Cons.  See discussion of the C<Link> command, below, for details.)
+
+
+=head2 Using modules in build scripts
+
+You may pull modules into each F<Conscript> file using the normal Perl
+C<use> or C<require> statements:
+
+  use English;
+  require My::Module;
+
+Each C<use> or C<require> only affects the one F<Conscript> file in which
+it appears.  To use a module in multiple F<Conscript> files, you must
+put a C<use> or C<require> statement in each one that needs the module.
+
+
+=head2 Scope of variables
+
+The top-level F<Construct> file and all F<Conscript> files begin life in
+a common, separate Perl package.  B<Cons> controls the symbol table for
+the package so that, the symbol table for each script is empty, except
+for the F<Construct> file, which gets some of the command line arguments.
+All of the variables that are set or used, therefore, are set by the
+script itself, not by some external script.
+
+Variables can be explicitly B<imported> by a script from its parent
+script. To import a variable, it must have been B<exported> by the parent
+and initialized (otherwise an error will occur).
+
+
+=head2 The Export command
+
+The C<Export> command is used as in the following example:
+
+  $env = new cons();
+  $INCLUDE = "#export/include";
+  $LIB = "#export/lib";
+  Export qw( env INCLUDE LIB );
+  Build qw( util/Conscript );
+
+The values of the simple variables mentioned in the C<Export> list will be
+squirreled away by any subsequent C<Build> commands. The C<Export> command
+will only export Perl B<scalar> variables, that is, variables whose name
+begins with C<$>. Other variables, objects, etc. can be exported by
+reference, but all scripts will refer to the same object, and this object
+should be considered to be read-only by the subsidiary scripts and by the
+original exporting script. It's acceptable, however, to assign a new value
+to the exported scalar variable, that won't change the underlying variable
+referenced. This sequence, for example, is OK:
+
+  $env = new cons();
+  Export qw( env INCLUDE LIB );
+  Build qw( util/Conscript );
+  $env = new cons(CFLAGS => '-O');
+  Build qw( other/Conscript );
+
+It doesn't matter whether the variable is set before or after the C<Export>
+command. The important thing is the value of the variable at the time the
+C<Build> command is executed. This is what gets squirreled away. Any
+subsequent C<Export> commands, by the way, invalidate the first: you must
+mention all the variables you wish to export on each C<Export> command.
+
+
+=head2 The Import command
+
+Variables exported by the C<Export> command can be imported into subsidiary
+scripts by the C<Import> command. The subsidiary script always imports
+variables directly from the superior script. Consider this example:
+
+  Import qw( env INCLUDE );
+
+This is only legal if the parent script exported both C<$env> and
+C<$INCLUDE>. It also must have given each of these variables values. It is
+OK for the subsidiary script to only import a subset of the exported
+variables (in this example, C<$LIB>, which was exported by the previous
+example, is not imported).
+
+All the imported variables are automatically re-exported, so the sequence:
+
+  Import qw ( env INCLUDE );
+  Build qw ( beneath-me/Conscript );
+
+will supply both C<$env> and C<$INCLUDE> to the subsidiary file. If only
+C<$env> is to be exported, then the following will suffice:
+
+  Import qw ( env INCLUDE );
+  Export qw ( env );
+  Build qw ( beneath-me/Conscript );
+
+Needless to say, the variables may be modified locally before invoking
+C<Build> on the subsidiary script.
+
+
+=head2 Build script evaluation order
+
+The only constraint on the ordering of build scripts is that superior
+scripts are evaluated before their inferior scripts. The top-level
+F<Construct> file, for instance, is evaluated first, followed by any
+inferior scripts. This is all you really need to know about the evaluation
+order, since order is generally irrelevant. Consider the following C<Build>
+command:
+
+  Build qw(
+       drivers/display/Conscript
+       drivers/mouse/Conscript
+       parser/Conscript
+       utilities/Conscript
+  );
+
+We've chosen to put the script names in alphabetical order, simply because
+that's the most convenient for maintenance purposes. Changing the order will
+make no difference to the build.
+
+-->
+
  <para>
 
    X
diff --git a/doc/user/install.sgml b/doc/user/install.sgml
new file mode 100644 (file)
index 0000000..530fa7a
--- /dev/null
@@ -0,0 +1,97 @@
+<!--
+
+  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<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
+
+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:
+
+C<InstallAs> works in two ways:
+
+Single file install:
+
+  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.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Install; Builder</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>The &InstallAs; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/user/library.sgml b/doc/user/library.sgml
new file mode 100644 (file)
index 0000000..0c9292c
--- /dev/null
@@ -0,0 +1,81 @@
+<!--
+
+  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<Library> method
+
+The C<Library> method arranges to create the specified library from the
+specified object files. It is invoked as follows:
+
+  Library $env <library name>, <source or object files>;
+
+The library name will have the value of the C<SUFLIB> construction
+variable appended (by default, C<.lib> on Win32 systems, C<.a> on Unix
+systems) if the suffix is not already present.
+
+Source files may be specified in place of objects files-,-the C<Objects>
+method will be invoked to arrange the conversion of all the files into
+object files, and hence all the observations about the C<Objects> method,
+above, apply to this method also.
+
+The actual creation of the library will be handled by an external
+command which results from expanding the C<ARCOM> construction variable,
+with C<%E<lt>> set to the library members (in the order presented),
+and C<%E<gt>> to the library to be created.  (See the section above
+on construction variable expansion for details.)  The user may set
+variables in the construction environment which will affect the
+operation of the command. These include C<AR>, the archive program
+to use, C<ARFLAGS>, which can be used to modify the flags given to
+the program specified by C<AR>, and C<RANLIB>, the name of a archive
+index generation program, if needed (if the particular need does not
+require the latter functionality, then C<ARCOM> must be redefined to not
+reference C<RANLIB>).
+
+The C<Library> method allows the same library to be specified in multiple
+method invocations. All of the contributing objects from all the invocations
+(which may be from different directories) are combined and generated by a
+single archive command. Note, however, that if you prune a build so that
+only part of a library is specified, then only that part of the library will
+be generated (the rest will disappear!).
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Library; Builder</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
index ca07ce47f899ba6a28c6294d0cff8837f297317c..bb64b7255df550754045e6d71e272d1aacaf934a 100644 (file)
     <!ENTITY % scons SYSTEM "../scons.mod">
     %scons;
 
+    <!ENTITY actions SYSTEM "actions.sgml">
+    <!ENTITY alias SYSTEM "alias.sgml">
     <!ENTITY builders SYSTEM "builders.sgml">
     <!ENTITY caching SYSTEM "caching.sgml">
+    <!ENTITY command SYSTEM "command.sgml">
     <!ENTITY cons SYSTEM "cons.sgml">
     <!ENTITY copyright SYSTEM "copyright.sgml">
+    <!ENTITY default SYSTEM "default.sgml">
     <!ENTITY depends SYSTEM "depends.sgml">
     <!ENTITY environments SYSTEM "environments.sgml">
     <!ENTITY errors SYSTEM "errors.sgml">
     <!ENTITY example SYSTEM "example.sgml">
+    <!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 troubleshoot SYSTEM "troubleshoot.sgml">
     <!ENTITY variants SYSTEM "variants.sgml">
     &depends;
   </chapter>
 
+
+
+  <chapter id="chap-default">
+    <title>Default Targets</title>
+    &default;
+  </chapter>
+
+  <chapter id="chap-help">
+    <title>Providing Build Help</title>
+    &help;
+  </chapter>
+
+  <chapter id="chap-install">
+    <title>Installing Files in Other Directories</title>
+    &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;
+  </chapter>
+
   <chapter id="chap-hierarchical">
-    <title>Hierarchial Builds</title>
+    <title>Hierarchical Builds</title>
     &hierarchy;
   </chapter>
 
-  <chapter id="chap-variant">
+  <chapter id="chap-separate">
+    <title>Separating Source and Build Directories</title>
+    &separate;
+  </chapter>
+
+  <chapter id="chap-variants">
     <title>Variant Builds</title>
     &variants;
   </chapter>
     &builders;
   </chapter>
 
+  <chapter id="chap-actions">
+    <title>SCons Actions</title>
+    &actions;
+  </chapter>
+
   <chapter id="chap-scanners">
     <title>Writing Scanners</title>
     &scanners;
     &run;
   </chapter>
 
+  <chapter id="chap-alias">
+    <title>Alias Targets</title>
+    &alias;
+  </chapter>
+
   <chapter id="chap-troubleshooting">
     <title>Troubleshooting</title>
     &troubleshoot;
index 3024c02381bd5f42c21fbbe8c8a845ed7425dccc..5666ea64e5e9f399292af2a41d8c419cfca8f412 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+=head1 Why Cons? Why not Make?
+
+Cons is a B<make> replacement. In the following paragraphs, we look at a few
+of the undesirable characteristics of make, and typical build environments
+based on make, that motivated the development of Cons.
+
+=head2 Build complexity
+
+Traditional make-based systems of any size tend to become quite complex. The
+original make utility and its derivatives have contributed to this tendency
+in a number of ways. Make is not good at dealing with systems that are
+spread over multiple directories. Various work-arounds are used to overcome
+this difficulty; the usual choice is for make to invoke itself recursively
+for each sub-directory of a build. This leads to complicated code, in which
+it is often unclear how a variable is set, or what effect the setting of a
+variable will have on the build as a whole. The make scripting language has
+gradually been extended to provide more possibilities, but these have
+largely served to clutter an already overextended language. Often, builds
+are done in multiple passes in order to provide appropriate products from
+one directory to another directory. This represents a further increase in
+build complexity.
+
+
+=head2 Build reproducibility
+
+The bane of all makes has always been the correct handling of
+dependencies. Most often, an attempt is made to do a reasonable job of
+dependencies within a single directory, but no serious attempt is made to do
+the job between directories. Even when dependencies are working correctly,
+make's reliance on a simple time stamp comparison to determine whether a
+file is out of date with respect to its dependents is not, in general,
+adequate for determining when a file should be rederived. If an external
+library, for example, is rebuilt and then ``snapped'' into place, the
+timestamps on its newly created files may well be earlier than the last
+local build, since it was built before it became visible.
+
+
+=head2 Variant builds
+
+Make provides only limited facilities for handling variant builds. With the
+proliferation of hardware platforms and the need for debuggable
+vs. optimized code, the ability to easily create these variants is
+essential. More importantly, if variants are created, it is important to
+either be able to separate the variants or to be able to reproduce the
+original or variant at will. With make it is very difficult to separate the
+builds into multiple build directories, separate from the source. And if
+this technique isn't used, it's also virtually impossible to guarantee at
+any given time which variant is present in the tree, without resorting to a
+complete rebuild.
+
+
+=head2 Repositories
+
+Make provides only limited support for building software from code that
+exists in a central repository directory structure.  The VPATH feature of
+GNU make (and some other make implementations) is intended to provide this,
+but doesn't work as expected: it changes the path of target file to the
+VPATH name too early in its analysis, and therefore searches for all
+dependencies in the VPATH directory.  To ensure correct development builds,
+it is important to be able to create a file in a local build directory and
+have any files in a code repository (a VPATH directory, in make terms) that
+depend on the local file get rebuilt properly.  This isn't possible with
+VPATH, without coding a lot of complex repository knowledge directly into
+the makefiles.
+
+-->
+
  <para>
 
    X
index 1c298a80ebfc20f20074c09daf6256b3cc3fe3fc..7defa414254cf726e75085c561504359f210e362 100644 (file)
   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>
-
- <section>
- <title>The &Precious; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
- <section>
- <title>The &Command; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
- <section>
- <title>The &Objects; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
- <section>
- <title>The &Program; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
- <section>
- <title>The &Library; Method</title>
-
-   <para>
-
-   X
-
-   </para>
-
- </section>
-
  <section>
  <title>The &Module; Method</title>
 
diff --git a/doc/user/object.sgml b/doc/user/object.sgml
new file mode 100644 (file)
index 0000000..9e887d8
--- /dev/null
@@ -0,0 +1,71 @@
+<!--
+
+  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<Objects> method
+
+The C<Objects> method arranges to create the object files that correspond to
+the specified source files. It is invoked as shown below:
+
+  @files = Objects $env <source or object files>;
+
+Under Unix, source files ending in F<.s> and F<.c> are currently
+supported, and will be compiled into a name of the same file ending
+in F<.o>. By default, all files are created by invoking the external
+command which results from expanding the C<CCCOM> construction variable,
+with C<%E<lt>> and C<%E<gt>> set to the source and object files,
+respectively. (See the section above on construction variable expansion
+for details).  The variable C<CPPPATH> is also used when scanning source
+files for dependencies. This is a colon separated list of pathnames, and
+is also used to create the construction variable C<_IFLAGS,> which will
+contain the appropriate list of -C<I> options for the compilation. Any
+relative pathnames in C<CPPPATH> is interpreted relative to the
+directory in which the associated construction environment was created
+(absolute and top-relative names may also be used). This variable is
+used by C<CCCOM>. The behavior of this command can be modified by
+changing any of the variables which are interpolated into C<CCCOM>, such
+as C<CC>, C<CFLAGS>, and, indirectly, C<CPPPATH>. It's also possible
+to replace the value of C<CCCOM>, itself. As a convenience, this file
+returns the list of object filenames.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Object; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
diff --git a/doc/user/precious.sgml b/doc/user/precious.sgml
new file mode 100644 (file)
index 0000000..9cd2a43
--- /dev/null
@@ -0,0 +1,69 @@
+<!--
+
+  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<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
+building the given file or files (or finding that they are up to date).
+The eval will happen once per specified file.  C<AfterBuild> is called
+as follows:
+
+  AfterBuild $env 'foo.o', qq(print "foo.o is up to date!\n");
+
+The perl string is evaluated in the C<script> package, and has access
+to all variables and subroutines defined in the F<Conscript> file in
+which the C<AfterBuild> method is called.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Precious; Method</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
index 34217021f23a6de0404c750036d6df1b3f71120f..82ea44a1c3dd1223eb306b0b1b5bbf8794246eec 100644 (file)
@@ -22,6 +22,7 @@
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
  <para>
 
    X
diff --git a/doc/user/program.sgml b/doc/user/program.sgml
new file mode 100644 (file)
index 0000000..30f90d2
--- /dev/null
@@ -0,0 +1,77 @@
+<!--
+
+  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<Program> method
+
+The C<Program> method arranges to link the specified program with the
+specified object files. It is invoked in the following manner:
+
+  Program $env <program name>, <source or object files>;
+
+The program name will have the value of the C<SUFEXE> construction
+variable appended (by default, C<.exe> on Win32 systems, nothing on Unix
+systems) if the suffix is not already present.
+
+Source files may be specified in place of objects files-,-the C<Objects>
+method will be invoked to arrange the conversion of all the files into
+object files, and hence all the observations about the C<Objects> method,
+above, apply to this method also.
+
+The actual linking of the program will be handled by an external command
+which results from expanding the C<LINKCOM> construction variable, with
+C<%E<lt>> set to the object files to be linked (in the order presented),
+and C<%E<gt>> set to the target. (See the section above on construction
+variable expansion for details.)  The user may set additional variables
+in the construction environment, including C<LINK>, to define which
+program to use for linking, C<LIBPATH>, a colon-separated list of
+library search paths, for use with library specifications of the form
+I<-llib>, and C<LIBS>, specifying the list of libraries to link against
+(in either I<-llib> form or just as pathnames. Relative pathnames in
+both C<LIBPATH> and C<LIBS> are interpreted relative to the directory
+in which the associated construction environment is created (absolute
+and top-relative names may also be used). Cons automatically sets up
+dependencies on any libraries mentioned in C<LIBS>: those libraries will
+be built before the command is linked.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>The &Program; Builder</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
index 57f58d8242dfd7a84a22af52fd5b2a5700fb96a2..ef8e5a94dedf5c55a40caa2bb5442103bbd1e6db 100644 (file)
@@ -22,6 +22,7 @@
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
  <para>
 
    X
index 3f0a597c2b6ef9e0cc3df93bef3a909d40b7db8e..4acc943269777b28a641b4a12bf93011ff3f00ea 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+
+=head2 Repository dependency analysis
+
+Due to its built-in scanning, Cons will search the specified repository
+trees for included F<.h> files.  Unless the compiler also knows about the
+repository trees, though, it will be unable to find F<.h> files that only
+exist in a repository.  If, for example, the F<hello.c> file includes the
+F<hello.h> file in its current directory:
+
+  % cons -R /usr/all/repository hello
+  gcc -c /usr/all/repository/hello.c -o hello.o
+  /usr/all/repository/hello.c:1: hello.h: No such file or directory
+
+Solving this problem forces some requirements onto the way construction
+environments are defined and onto the way the C C<#include> preprocessor
+directive is used to include files.
+
+In order to inform the compiler about the repository trees, Cons will add
+appropriate C<-I> flags to the compilation commands.  This means that the
+C<CPPPATH> variable in the construction environment must explicitly specify
+all subdirectories which are to be searched for included files, including the
+current directory.  Consequently, we can fix the above example by changing
+the environment creation in the F<Construct> file as follows:
+
+  $env = new cons(
+       CC      => 'gcc',
+       CPPPATH => '.',
+       LIBS    => 'libworld.a',
+  );
+
+Due to the definition of the C<CPPPATH> variable, this yields, when we
+re-execute the command:
+
+  % cons -R /usr/all/repository hello
+  gcc -c -I. -I/usr/all/repository /usr/all/repository/hello.c -o hello.o
+  gcc -o hello hello.o /usr/all/repository/libworld.a
+
+The order of the C<-I> flags replicates, for the C preprocessor, the same
+repository-directory search path that Cons uses for its own dependency
+analysis.  If there are multiple repositories and multiple C<CPPPATH>
+directories, Cons will append the repository directories to the beginning of
+each C<CPPPATH> directory, rapidly multiplying the number of C<-I> flags.
+As an extreme example, a F<Construct> file containing:
+
+  Repository qw(
+       /u1
+       /u2
+  );
+
+  $env = new cons(
+       CPPPATH => 'a:b:c',
+  );
+
+Would yield a compilation command of:
+
+  cc -Ia -I/u1/a -I/u2/a -Ib -I/u1/b -I/u2/b -Ic -I/u1/c -I/u2/c -c hello.c -o hello.o
+
+In order to shorten the command lines as much as possible, Cons will
+remove C<-I> flags for any directories, locally or in the repositories,
+which do not actually exist.  (Note that the C<-I> flags are not included
+in the MD5 signature calculation for the target file, so the target will
+not be recompiled if the compilation command changes due to a directory
+coming into existence.)
+
+Because Cons relies on the compiler's C<-I> flags to communicate the
+order in which repository directories must be searched, Cons' handling
+of repository directories is fundamentally incompatible with using
+double-quotes on the C<#include> directives in any C source code that
+you plan to modify:
+
+  #include "file.h"    /* DON'T USE DOUBLE-QUOTES LIKE THIS */
+
+This is because most C preprocessors, when faced with such a directive, will
+always first search the directory containing the source file.  This
+undermines the elaborate C<-I> options that Cons constructs to make the
+preprocessor conform to its preferred search path.
+
+Consequently, when using repository trees in Cons, B<always> use
+angle-brackets for included files in any C source (.c or .h) files that
+you plan to modify locally:
+
+  #include <file.h>    /* USE ANGLE-BRACKETS INSTEAD */
+
+Code that will not change can still safely use double quotes on #include
+lines.
+
+
+=head2 Repository_List
+
+Cons provides a C<Repository_List> command to return a list of all
+repository directories in their current search order.  This can be used for
+debugging, or to do more complex Perl stuff:
+
+  @list = Repository_List;
+  print join(' ', @list), "\n";
+
+
+=head2 Repository interaction with other Cons features
+
+Cons' handling of repository trees interacts correctly with other Cons
+features, which is to say, it generally does what you would expect.
+
+Most notably, repository trees interact correctly, and rather powerfully,
+with the 'Link' command.  A repository tree may contain one or more
+subdirectories for version builds established via C<Link> to a source
+subdirectory.  Cons will search for derived files in the appropriate build
+subdirectories under the repository tree.
+
+-->
+
  <para>
 
-   X
+ 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>
+
+   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:
+
+   </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>
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>Finding the &SConstruct; file in repositories</title>
+
+   <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>:
+
+   </para>
+
+   <literallayout>
+     % <userinput>scons -Y /usr/repository1 -Y /usr/repository2 .</userinput>
+   </literallayout>
+
+   <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.
+
+   </para>
+
+ </section>
+
+ <section>
+ <title>Finding derived files in repositories</title>
+
+   <para>
+
+   If a repository contains not only source files,
+   but also derived files (such as object files,
+   libraries, or exectuables), &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>
+
+   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>
+
+   <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>
+
+   <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:
+
+   </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>
+
    <para>
 
-   X
+   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>
 
  </section>
 
  <section>
- <title>X</title>
+ <title>Guaranteeing local copies of files</title>
+
+   <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:
+
+   </para>
+
+   <literallayout>
+     % <userinput>mkdir $HOME/build2</userinput>
+     % <userinput>cd $HOME/build2</userinput>
+     % <userinput>cons -Y /usr/all/repository hello</userinput>
+     cons: "hello" is up-to-date.
+   </literallayout>
+
+   <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.
+
+   </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:
+
+   </para>
+
+   <programlisting>
+      env = Environment()
+      hello = env.Program('hello.c')
+      Local(hello)
+   </programlisting>
+
+   <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:
+
+   </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>
 
    <para>
 
-   X
+   (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>
 
index ba802ff0b1c4449575ad4db6cdb3dac13cefdec5..30b61ca5b6d3637dcff58096da32a97ff13c84cd 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
- <para>
 
-   X
+<!--
 
- </para>
+=head1 Invoking Cons
 
- <section>
- <title>Command-line Target Aliases</title>
+The C<cons> command is usually invoked from the root of the build tree. A
+F<Construct> file must exist in that directory. If the C<-f> argument is
+used, then an alternate F<Construct> file may be used (and, possibly, an
+alternate root, since C<cons> will cd to F<Construct> file's containing
+directory).
 
-   <para>
+If C<cons> is invoked from a child of the root of the build tree with
+the C<-t> argument, it will walk up the directory hierarchy looking for a
+F<Construct> file.  (An alternate name may still be specified with C<-f>.)
+The targets supplied on the command line will be modified to be relative
+to the discovered F<Construct> file.  For example, from a directory
+containing a top-level F<Construct> file, the following invocation:
 
-   X
+  % cd libfoo/subdir
+  % cons -t target
 
-   </para>
+is exactly equivalent to:
 
- </section>
+  % cons libfoo/subdir/target
+
+If there are any C<Default> targets specified in the directory hierarchy's
+F<Construct> or F<Conscript> files, only the default targets at or below
+the directory from which C<cons -t> was invoked will be built.
+
+The command is invoked as follows:
+
+  cons <arguments> ,  <construct-args>
+
+where I<arguments> can be any of the following, in any order:
+
+=over 10
+
+=item I<target>
+
+Build the specified target. If I<target> is a directory, then recursively
+build everything within that directory.
+
+=item I<+pattern>
+
+Limit the F<Conscript> files considered to just those that match I<pattern>,
+which is a Perl regular expression. Multiple C<+> arguments are accepted.
+
+=item I<name>=<val>
+
+Sets I<name> to value I<val> in the C<ARG> hash passed to the top-level
+F<Construct> file.
+
+=item C<-cc>
+
+Show command that would have been executed, when retrieving from cache. No
+indication that the file has been retrieved is given; this is useful for
+generating build logs that can be compared with real build logs.
+
+=item C<-cd>
+
+Disable all caching. Do not retrieve from cache nor flush to cache.
+
+=item C<-cr>
+
+Build dependencies in random order. This is useful when building multiple
+similar trees with caching enabled.
+
+=item C<-cs>
+
+Synchronize existing build targets that are found to be up-to-date with
+cache. This is useful if caching has been disabled with -cc or just recently
+enabled with UseCache.
+
+=item C<-d>
+
+Enable dependency debugging.
+
+=item C<-f> <file>
+
+Use the specified file instead of F<Construct> (but first change to
+containing directory of I<file>).
+
+=item C<-h>
+
+Show a help message local to the current build if one such is defined, and
+exit.
+
+=item C<-k>
+
+Keep going as far as possible after errors.
+
+=item C<-o> <file>
+
+Read override file I<file>.
+
+=item C<-p>
+
+Show construction products in specified trees. No build is attempted.
+
+=item C<-pa>
+
+Show construction products and associated actions. No build is attempted.
+
+=item C<-pw>
+
+Show products and where they are defined. No build is attempted.
+
+=item C<-q>
+
+Make the build quiet.  Multiple C<-q> options may be specified.
+
+A single C<-q> options suppress messages about Installing and Removing
+targets.
+
+Two C<-q> options suppress build command lines and target up-to-date
+messages.
+
+=item C<-r>
+
+Remove construction products associated with <targets>. No build is
+attempted.
+
+=item C<-R> <repos>
+
+Search for files in I<repos>.  Multiple B<-R> I<repos> directories are
+searched in the order specified.
+
+=item C<-S> <pkg>
+
+Use the sig::<pkg> package to calculate.  Supported <pkg> values
+include "md5" for MD5 signature calculation and "md5::debug" for debug
+information about MD5 signature calculation.
+
+If the specified package ends in <::debug>, signature debug information
+will be printed to the file name specified in the C<CONS_SIG_DEBUG>
+environment variable, or to standard output if the environment variable
+is not set.
+
+=item C<-t>
+
+Traverse up the directory hierarchy looking for a F<Construct> file,
+if none exists in the current directory.  Targets will be modified to
+be relative to the F<Construct> file.
+
+Internally, C<cons> will change its working directory to the directory
+which contains the top-level F<Construct> file and report:
+
+  cons: Entering directory `top-level-directory'
+
+This message indicates to an invoking editor (such as emacs) or build
+environment that Cons will now report all file names relative to the
+top-level directory.  This message can not be suppressed with the C<-q>
+option.
+
+=item C<-v>
+
+Show C<cons> version and continue processing.
+
+=item C<-V>
+
+Show C<cons> version and exit.
+
+=item C<-wf> <file>
+
+Write all filenames considered into I<file>.
+
+=item C<-x>
+
+Show a help message similar to this one, and exit.
+
+=back
+
+And I<construct-args> can be any arguments that you wish to process in the
+F<Construct> file. Note that there should be a B<-,-> separating the arguments
+to cons and the arguments that you wish to process in the F<Construct> file.
+
+Processing of I<construct-args> can be done by any standard package like
+B<Getopt> or its variants, or any user defined package. B<cons> will pass in
+the I<construct-args> as B<@ARGV> and will not attempt to interpret anything
+after the B<-,->.
+
+  % cons -R /usr/local/repository -d os=solaris +driver -,- -c test -f DEBUG
+
+would pass the following to cons
+
+  -R /usr/local/repository -d os=solaris +driver
+
+and the following, to the top level F<Construct> file as B<@ARGV>
+
+  -c test -f DEBUG
+
+Note that C<cons -r .> is equivalent to a full recursive C<make clean>,
+but requires no support in the F<Construct> file or any F<Conscript>
+files. This is most useful if you are compiling files into source
+directories (if you separate the F<build> and F<export> directories,
+then you can just remove the directories).
+
+The options C<-p>, C<-pa>, and C<-pw> are extremely useful for use as an aid
+in reading scripts or debugging them. If you want to know what script
+installs F<export/include/foo.h>, for example, just type:
+
+  % cons -pw export/include/foo.h
+
+=head1 Selective builds
+
+Cons provides two methods for reducing the size of given build. The first is
+by specifying targets on the command line, and the second is a method for
+pruning the build tree. We'll consider target specification first.
+
+
+=head2 Selective targeting
+
+Like make, Cons allows the specification of ``targets'' on the command
+line. Cons targets may be either files or directories. When a directory is
+specified, this is simply a short-hand notation for every derivable
+product-,-that Cons knows about-,-in the specified directory and below. For
+example:
+
+  % cons build/hello/hello.o
+
+means build F<hello.o> and everything that F<hello.o> might need. This is
+from a previous version of the B<Hello, World!> program in which F<hello.o>
+depended upon F<export/include/world.h>. If that file is not up-to-date
+(because someone modified F<src/world/world.h)>, then it will be rebuilt,
+even though it is in a directory remote from F<build/hello>.
+
+In this example:
+
+  % cons build
+
+Everything in the F<build> directory is built, if necessary. Again, this may
+cause more files to be built. In particular, both F<export/include/world.h>
+and F<export/lib/libworld.a> are required by the F<build/hello> directory,
+and so they will be built if they are out-of-date.
+
+If we do, instead:
+
+  % cons export
+
+then only the files that should be installed in the export directory will be
+rebuilt, if necessary, and then installed there. Note that C<cons build>
+might build files that C<cons export> doesn't build, and vice-versa.
+
+
+=head2 No ``special'' targets
+
+With Cons, make-style ``special'' targets are not required. The simplest
+analog with Cons is to use special F<export> directories, instead. Let's
+suppose, for example, that you have a whole series of unit tests that are
+associated with your code. The tests live in the source directory near the
+code. Normally, however, you don't want to build these tests. One solution
+is to provide all the build instructions for creating the tests, and then to
+install the tests into a separate part of the tree. If we install the tests
+in a top-level directory called F<tests>, then:
+
+  % cons tests
+
+will build all the tests.
+
+  % cons export
+
+will build the production version of the system (but not the tests), and:
+
+  % cons build
+
+should probably be avoided (since it will compile tests unnecessarily).
+
+If you want to build just a single test, then you could explicitly name the
+test (in either the F<tests> directory or the F<build> directory). You could
+also aggregate the tests into a convenient hierarchy within the tests
+directory. This hierarchy need not necessarily match the source hierarchy,
+in much the same manner that the include hierarchy probably doesn't match
+the source hierarchy (the include hierarchy is unlikely to be more than two
+levels deep, for C programs).
+
+If you want to build absolutely everything in the tree (subject to whatever
+options you select), you can use:
+
+  % cons .
+
+This is not particularly efficient, since it will redundantly walk all the
+trees, including the source tree. The source tree, of course, may have
+buildable objects in it-,-nothing stops you from doing this, even if you
+normally build in a separate build tree.
+
+
+=head1 Build Pruning
+
+In conjunction with target selection, B<build pruning> can be used to reduce
+the scope of the build. In the previous peAcH and baNaNa example, we have
+already seen how script-driven build pruning can be used to make only half
+of the potential build available for any given invocation of C<cons>. Cons
+also provides, as a convenience, a command line convention that allows you
+to specify which F<Conscript> files actually get ``built''-,-that is,
+incorporated into the build tree. For example:
+
+  % cons build +world
+
+The C<+> argument introduces a Perl regular expression. This must, of
+course, be quoted at the shell level if there are any shell meta-characters
+within the expression. The expression is matched against each F<Conscript>
+file which has been mentioned in a C<Build> statement, and only those
+scripts with matching names are actually incorporated into the build
+tree. Multiple such arguments are allowed, in which case a match against any
+of them is sufficient to cause a script to be included.
+
+In the example, above, the F<hello> program will not be built, since Cons
+will have no knowledge of the script F<hello/Conscript>. The F<libworld.a>
+archive will be built, however, if need be.
+
+There are a couple of uses for build pruning via the command line. Perhaps
+the most useful is the ability to make local changes, and then, with
+sufficient knowledge of the consequences of those changes, restrict the size
+of the build tree in order to speed up the rebuild time. A second use for
+build pruning is to actively prevent the recompilation of certain files that
+you know will recompile due to, for example, a modified header file. You may
+know that either the changes to the header file are immaterial, or that the
+changes may be safely ignored for most of the tree, for testing
+purposes.With Cons, the view is that it is pragmatic to admit this type of
+behavior, with the understanding that on the next full build everything that
+needs to be rebuilt will be. There is no equivalent to a ``make touch''
+command, to mark files as permanently up-to-date. So any risk that is
+incurred by build pruning is mitigated. For release quality work, obviously,
+we recommend that you do not use build pruning (it's perfectly OK to use
+during integration, however, for checking compilation, etc. Just be sure to
+do an unconstrained build before committing the integration).
+
+-->
+
+ <para>
+
+   X
+
+ </para>
 
  <section>
  <title>Selective Builds</title>
index 3024c02381bd5f42c21fbbe8c8a845ed7425dccc..8d13b0c1f316329b62b580d58ee89dba209d7740 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+=head1 Using and writing dependency scanners
+
+QuickScan allows simple target-independent scanners to be set up for
+source files. Only one QuickScan scanner may be associated with any given
+source file and environment, although the same scanner may (and should)
+be used for multiple files of a given type.
+
+A QuickScan scanner is only ever invoked once for a given source file,
+and it is only invoked if the file is used by some target in the tree
+(i.e., there is a dependency on the source file).
+
+QuickScan is invoked as follows:
+
+  QuickScan CONSENV CODEREF, FILENAME [, PATH]
+
+The subroutine referenced by CODEREF is expected to return a list of
+filenames included directly by FILE. These filenames will, in turn, be
+scanned. The optional PATH argument supplies a lookup path for finding
+FILENAME and/or files returned by the user-supplied subroutine.  The PATH
+may be a reference to an array of lookup-directory names, or a string of
+names separated by the system's separator character (':' on UNIX systems,
+';' on Windows NT).
+
+The subroutine is called once for each line in the file, with $_ set to the
+current line. If the subroutine needs to look at additional lines, or, for
+that matter, the entire file, then it may read them itself, from the
+filehandle SCAN. It may also terminate the loop, if it knows that no further
+include information is available, by closing the filehandle.
+
+Whether or not a lookup path is provided, QuickScan first tries to lookup
+the file relative to the current directory (for the top-level file
+supplied directly to QuickScan), or from the directory containing the
+file which referenced the file. This is not very general, but seems good
+enough, especially if you have the luxury of writing your own utilities
+and can control the use of the search path in a standard way.
+
+Here's a real example, taken from a F<Construct> file here:
+
+  sub cons::SMFgen {
+      my($env, @tables) = @_;
+      foreach $t (@tables) {
+         $env->QuickScan(sub { /\b\S*?\.smf\b/g }, "$t.smf",
+                         $env->{SMF_INCLUDE_PATH});
+         $env->Command(["$t.smdb.cc","$t.smdb.h","$t.snmp.cc",
+                        "$t.ami.cc", "$t.http.cc"], "$t.smf",
+                       q(smfgen %( %SMF_INCLUDE_OPT %) %<));
+      }
+  }
+
+The subroutine above finds all names of the form <name>.smf in the
+file. It will return the names even if they're found within comments,
+but that's OK (the mechanism is forgiving of extra files; they're just
+ignored on the assumption that the missing file will be noticed when
+the program, in this example, smfgen, is actually invoked).
+
+[NOTE that the form C<$env-E<gt>QuickScan ...>  and C<$env-E<gt>Command
+...> should not be necessary, but, for some reason, is required
+for this particular invocation. This appears to be a bug in Perl or
+a misunderstanding on my part; this invocation style does not always
+appear to be necessary.]
+
+Here is another way to build the same scanner. This one uses an
+explicit code reference, and also (unnecessarily, in this case) reads
+the whole file itself:
+
+  sub myscan {
+      my(@includes);
+      do {
+         push(@includes, /\b\S*?\.smf\b/g);
+      } while <SCAN>;
+      @includes
+  }
+
+Note that the order of the loop is reversed, with the loop test at the
+end. This is because the first line is already read for you. This scanner
+can be attached to a source file by:
+
+  QuickScan $env \&myscan, "$_.smf";
+
+This final example, which scans a different type of input file, takes
+over the file scanning rather than being called for each input line:
+
+  $env->QuickScan(
+      sub { my(@includes) = ();
+         do {
+            push(@includes, $3)
+                if /^(#include|import)\s+(\")(.+)(\")/ && $3
+         } while <SCAN>;
+         @includes
+      },
+      "$idlFileName",
+      "$env->{CPPPATH};$BUILD/ActiveContext/ACSCLientInterfaces"
+  );
+
+-->
+
  <para>
 
    X
diff --git a/doc/user/separate.sgml b/doc/user/separate.sgml
new file mode 100644 (file)
index 0000000..e1c0e49
--- /dev/null
@@ -0,0 +1,128 @@
+<!--
+
+  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.
+
+-->
+
+<!--
+
+=head1 Separating source and build trees
+
+It's often desirable to keep any derived files from the build completely
+separate from the source files. This makes it much easier to keep track of
+just what is a source file, and also makes it simpler to handle B<variant>
+builds, especially if you want the variant builds to co-exist.
+
+=head2 Separating build and source directories using the Link command
+
+Cons provides a simple mechanism that handles all of these requirements. The
+C<Link> command is invoked as in this example:
+
+  Link 'build' => 'src';
+
+The specified directories are ``linked'' to the specified source
+directory. Let's suppose that you setup a source directory, F<src>, with the
+sub-directories F<world> and F<hello> below it, as in the previous
+example. You could then substitute for the original build lines the
+following:
+
+  Build qw(
+       build/world/Conscript
+       build/hello/Conscript
+  );
+
+Notice that you treat the F<Conscript> file as if it existed in the build
+directory. Now if you type the same command as before, you will get the
+following results:
+
+  % cons export
+  Install build/world/world.h as export/include/world.h
+  cc -Iexport/include -c build/hello/hello.c -o build/hello/hello.o
+  cc -Iexport/include -c build/world/world.c -o build/world/world.o
+  ar r build/world/libworld.a build/world/world.o
+  ar: creating build/world/libworld.a
+  ranlib build/world/libworld.a
+  Install build/world/libworld.a as export/lib/libworld.a
+  cc -o build/hello/hello build/hello/hello.o -Lexport/lib -lworld
+  Install build/hello/hello as export/bin/hello
+
+Again, Cons has taken care of the details for you. In particular, you will
+notice that all the builds are done using source files and object files from
+the build directory. For example, F<build/world/world.o> is compiled from
+F<build/world/world.c>, and F<export/include/world.h> is installed from
+F<build/world/world.h>. This is accomplished on most systems by the simple
+expedient of ``hard'' linking the required files from each source directory
+into the appropriate build directory.
+
+The links are maintained correctly by Cons, no matter what you do to the
+source directory. If you modify a source file, your editor may do this ``in
+place'' or it may rename it first and create a new file. In the latter case,
+any hard link will be lost. Cons will detect this condition the next time
+the source file is needed, and will relink it appropriately.
+
+You'll also notice, by the way, that B<no> changes were required to the
+underlying F<Conscript> files. And we can go further, as we shall see in the
+next section.
+
+=head2 Explicit references to the source directory
+
+When using the C<Link> command on some operating systems or with some
+tool chains, it's sometimes useful to have a command actually use
+the path name to the source directory, not the build directory.  For
+example, on systems that must copy, not "hard link," the F<src/> and
+F<build/> copies of C<Linked> files, using the F<src/> path of a file
+name might make an editor aware that a syntax error must be fixed in the
+source directory, not the build directory.
+
+You can tell Cons that you want to use the "source path" for a file by
+preceding the file name with a ``!'' (exclamation point).  For example,
+if we add a ``!'' to the beginning of a source file:
+
+  Program $env "foo", "!foo.c";        # Notice initial ! on foo.c
+
+Cons will compile the target as follows:
+
+  cc -c src/foo.c -o build/foo.o
+  cc -o build/foo build/foo.o
+
+Notice that Cons has compiled the program from the the F<src/foo.c>
+source file.  Without the initial ``!'', Cons would have compiled the
+program using the F<build/foo.c> path name.
+
+-->
+
+ <para>
+
+   X
+
+ </para>
+
+ <section>
+ <title>X</title>
+
+   <para>
+
+   X
+
+   </para>
+
+ </section>
index 5de9d3c64ae37a381d5fa6471f92a5965f029fe7..9071160819b86cfbcedf4769cffa4dc9326a13c2 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+=head2 Perl scripts
+
+Cons is Perl-based. That is, Cons scripts F<Conscript> and F<Construct>
+files, the equivalent to F<Makefile> or F<makefile> are all written in
+Perl. This provides an immediate benefit: the language for writing scripts
+is a familiar one. Even if you don't happen to be a Perl programmer, it
+helps to know that Perl is basically just a simple declarative language,
+with a well-defined flow of control, and familiar semantics. It has
+variables that behave basically the way you would expect them to,
+subroutines, flow of control, and so on. There is no special syntax
+introduced for Cons. The use of Perl as a scripting language simplifies
+the task of expressing the appropriate solution to the often complex
+requirements of a build.
+
+-->
+
  <para>
 
-   X
+ Here's how to build the famous "Hello, World!" example using &SCons;.
+ Enter the following into a file name &SConstruct;:
 
  </para>
 
- <section>
- <title>The &SConstruct; File</title>
+ <programlisting>
+    int
+    main()
+    {
+        printf("Hello, world!\n");
+    }
+ </programlisting>
 
-   <para>
+ <programlisting>
+    env = Environment()
+    env.Program('hello.c')
+ </programlisting>
 
-   X
+ <para>
 
-   </para>
+ That's it.  Now run the &scons; command to build the program.
+ On a POSIX-compliant system like Linux or UNIX,
+ you'll see something like:
 
- </section>
+ </para>
 
- <section>
- <title>The &Program; Builder</title>
+ <literallayout>
+    % <userinput>scons .</userinput>
+    cc -c hello.c -o hello.o
+    cc -o hello hello.o
+ </literallayout>
 
  <para>
+ <para>
 
-   X
+ On a Windows system with the Microsoft Visual C++ compiler,
+ you'll see something like:
 
  </para>
+ </para>
 
- </section>
+ <literallayout>
+    C:\><userinput>scons .</userinput>
+    cl /Fohello.obj hello.c
+    link /Fohello.exe hello.obj
+ </literallayout>
+
+ <para>
+
+ First, notice that you need to supply a '.' on the command line.
+ This tells &SCons; to build everything in the current directory
+ or its subdirectories.
+ We'll tell you later how to avoid having to use the '.'
+
+ </para>
+
+ <para>
+
+ Next, notice that the same input &SConstruct; file
+ without any special input,
+ generates the right output file names on both systems:
+ <filename>hello.o</filename> and <filename>hello</filename>
+ on POSIX systems,
+ <filename>hello.obj</filename> and <filename>hello.exe</filename>
+ on Windows systems.
+ (We won't provide side-by-side examples of POSIX
+ and Windows runs for all future examples;
+ just know that XXX.)
+
+ </para>
 
  <section>
- <title>The &Library; Builder</title>
+ <title>The &SConstruct; File</title>
 
    <para>
 
-   X
+   If you're used to build systems like &Make;
+   you've already figured out that the &SConstruct; file
+   is the &SCons; equivalent of a &Makefile;.
+   That is, the &SConstruct; file is the input file
+   that &SCons; reads to control the build.
 
    </para>
 
</section>
  <para>
 
- <section>
- <title>The &Install; Builder</title>
+   What may not be obvious, though, is that
+   there's an important difference between
+   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;
+   you don't really need to know Python to be able to use
+   &SCons; effectively.
+   But you'll see that being able to use the power of a
+   real scripting language
+   can greatly simplify the solutions
+   to complex requirements of real-world builds.
+
+   </para>
 
    <para>
 
-   X
+   For now, one ramification of using Python as the
+   scripting language means that you can put comments
+   in your &SConstruct; file using Python's commenting convention;
+   that is, everything between a '#' and the end of the line
+   will be ignored:
 
    </para>
 
+   <programlisting>
+      env = Environment()    # Create an environment.
+      # Arrange to build the "hello" program.
+      env.Program('hello.c')
+   </programlisting>
+
  </section>
 
  <section>
- <title>Running &SCons;</title>
+ <title>Compiling Multiple Source Files</title>
 
    <para>
 
-   X
+   If you want
 
    </para>
 
+   <programlisting>
+      env = Environment()
+      env.Program('program', ['main.c', 'file1.c', 'file2.'])
+   </programlisting>
+
+   <programlisting>
+      env = Environment()
+      env.Program('program', Split('main.c file1.c file2.'))
+   </programlisting>
+
+   <literallayout>
+      % <userinput>scons .</userinput>
+      cc -c file1.c -o file1.o
+      cc -c file2.c -o file2.o
+      cc -c main.c -o main.o
+      cc -o program main.o file1.o file2.o
+   </literallayout>
+
  </section>
 
  <section>
- <title>The &Default; Method</title>
+ <title>Compiling Multiple Programs</title>
 
    <para>
 
-   X
+   If you want
 
    </para>
 
+   <programlisting>
+      env = Environment()
+      env.Program('foo.c')
+      env.Program('bar', ['bar1.c', 'bar2.c'])
+   </programlisting>
+
+   <literallayout>
+      % <userinput>scons .</userinput>
+      cc -c bar1.c -o bar1.o
+      cc -c bar2.c -o bar2.o
+      cc -o bar bar1.o bar2.o
+      cc -c foo.c -o foo.o
+      cc -o foo foo.o
+   </literallayout>
+
  </section>
 
  <section>
- <title>The &Help; Method</title>
+ <title>Sharing Files Between Multiple Programs</title>
 
    <para>
 
-   X
+   If you want
 
    </para>
 
+   <programlisting>
+      common = ['common1.c', 'common2.c']
+      env = Environment()
+      env.Program(['foo.c'] + common)
+      env.Program('bar', ['bar1.c', 'bar2.c'] + common)
+   </programlisting>
+
+   <literallayout>
+      % <userinput>scons .</userinput>
+      cc -c bar1.c -o bar1.o
+      cc -c bar2.c -o bar2.o
+      cc -c common1.c -o common1.o
+      cc -c common2.c -o common2.o
+      cc -o bar bar1.o bar2.o common1.o common2.o
+      cc -c foo.c -o foo.o
+      cc -o foo foo.o common1.o common2.o
+   </literallayout>
+
  </section>
index 3024c02381bd5f42c21fbbe8c8a845ed7425dccc..448777f1d175d658030520276bbdc59c6bb1b986 100644 (file)
@@ -22,6 +22,7 @@
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
  <para>
 
    X
index 3024c02381bd5f42c21fbbe8c8a845ed7425dccc..fdd209eec80cf22ec9075a68cb2d2ec5f2cf2f24 100644 (file)
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 -->
+
+<!--
+
+=head1 Variant builds
+
+
+=head2 Hello, World! for baNaNa and peAcH OS's
+
+Variant builds require just another simple extension. Let's take as an
+example a requirement to allow builds for both the baNaNa and peAcH
+operating systems. In this case, we are using a distributed file system,
+such as NFS to access the particular system, and only one or the other of
+the systems has to be compiled for any given invocation of C<cons>. Here's
+one way we could set up the F<Construct> file for our B<Hello, World!>
+application:
+
+  # Construct file for Hello, World!
+
+  die qq(OS must be specified) unless $OS = $ARG{OS};
+  die qq(OS must be "peach" or "banana")
+       if $OS ne "peach" && $OS ne "banana";
+
+  # Where to put all our shared products.
+  $EXPORT = "#export/$OS";
+
+  Export qw( CONS INCLUDE LIB BIN );
+
+  # Standard directories for sharing products.
+  $INCLUDE = "$EXPORT/include";
+  $LIB = "$EXPORT/lib";
+  $BIN = "$EXPORT/bin";
+
+  # A standard construction environment.
+  $CONS = new cons (
+       CPPPATH => $INCLUDE,    # Include path for C Compilations
+       LIBPATH => $LIB,        # Library path for linking programs
+       LIBS => '-lworld',      # List of standard libraries
+  );
+
+  # $BUILD is where we will derive everything.
+  $BUILD = "#build/$OS";
+
+  # Tell cons where the source files for $BUILD are.
+  Link $BUILD => 'src';
+
+  Build (
+       "$BUILD/hello/Conscript",
+       "$BUILD/world/Conscript",
+  );
+
+Now if we login to a peAcH system, we can build our B<Hello, World!>
+application for that platform:
+
+  % cons export OS=peach
+  Install build/peach/world/world.h as export/peach/include/world.h
+  cc -Iexport/peach/include -c build/peach/hello/hello.c -o build/peach/hello/hello.o
+  cc -Iexport/peach/include -c build/peach/world/world.c -o build/peach/world/world.o
+  ar r build/peach/world/libworld.a build/peach/world/world.o
+  ar: creating build/peach/world/libworld.a
+  ranlib build/peach/world/libworld.a
+  Install build/peach/world/libworld.a as export/peach/lib/libworld.a
+  cc -o build/peach/hello/hello build/peach/hello/hello.o -Lexport/peach/lib -lworld
+  Install build/peach/hello/hello as export/peach/bin/hello
+
+
+=head2 Variations on a theme
+
+Other variations of this model are possible. For example, you might decide
+that you want to separate out your include files into platform dependent and
+platform independent files. In this case, you'd have to define an
+alternative to C<$INCLUDE> for platform-dependent files. Most F<Conscript>
+files, generating purely platform-independent include files, would not have
+to change.
+
+You might also want to be able to compile your whole system with debugging
+or profiling, for example, enabled. You could do this with appropriate
+command line options, such as C<DEBUG=on>. This would then be translated
+into the appropriate platform-specific requirements to enable debugging
+(this might include turning off optimization, for example). You could
+optionally vary the name space for these different types of systems, but, as
+we'll see in the next section, it's not B<essential> to do this, since Cons
+is pretty smart about rebuilding things when you change options.
+
+-->
+
  <para>
 
    X