Eliminate / replace remaining cPickle references in test scripts.
[scons.git] / doc / user / separate.in
index c1b3c32eb6caf04091f02c8e3900f9578089c3fc..75605fe5bb46b6c5df6041c210d8a0e2409c78b8 100644 (file)
@@ -1,6 +1,6 @@
 <!--
 
-  Copyright (c) 2001, 2002, 2003 Steven Knight
+  __COPYRIGHT__
 
   Permission is hereby granted, free of charge, to any person obtaining
   a copy of this software and associated documentation files (the
@@ -114,56 +114,67 @@ program using the F<build/foo.c> path name.
 
   It's often useful to keep any built files completely
   separate from the source files.
-  This is usually done by creating one or more separate
-  <emphasis>build directories</emphasis>
+  In &SCons;, this is usually done by creating one or more separate
+  <emphasis>variant directory trees</emphasis>
   that are used to hold the built objects files, libraries,
   and executable programs, etc.
-  for a specific flavor of build.
+  for a specific flavor, or variant, of build.
   &SCons; provides two ways to do this,
   one through the &SConscript; function that we've already seen,
-  and the second through a more flexible &BuildDir; function.
+  and the second through a more flexible &VariantDir; function.
+
+  </para>
+
+  <para>
+
+  One historical note:  the &VariantDir; function
+  used to be called &BuildDir;.
+  That name is still supported
+  but has been deprecated
+  because the &SCons; functionality
+  differs from the model of a "build directory"
+  implemented by other build systems like the GNU Autotools.
 
   </para>
 
   <section>
-  <title>Specifying a Build Directory as Part of an &SConscript; Call</title>
+  <title>Specifying a Variant Directory Tree as Part of an &SConscript; Call</title>
 
     <para>
 
-    The most straightforward way to establish a build directory
+    The most straightforward way to establish a variant directory tree
     uses the fact that the usual way to
-    set up a build hierarcy is to have an
+    set up a build hierarchy is to have an
     &SConscript; file in the source subdirectory.
-    If you then pass a &build_dir; argument to the
+    If you then pass a &variant_dir; argument to the
     &SConscript; function call:
 
     </para>
 
-    <sconstruct>
-      SConscript('src/SConscript', build_dir='build')
-    </sconstruct>
-
-    <para>
-
-    &SCons; will then build all of the files in
-    the &build; subdirectory:
-
-    </para>
-
     <scons_example name="ex1">
       <file name="SConstruct" printme="1">
+      SConscript('src/SConscript', variant_dir='build')
+      </file>
+      <file name="src/SConscript">
       env = Environment()
       env.Program('hello.c')
       </file>
-      <file name="hello.c">
+      <file name="src/hello.c">
       int main() { printf("Hello, world!\n"); }
       </file>
     </scons_example>
 
+    <para>
+
+    &SCons; will then build all of the files in
+    the &build; subdirectory:
+
+    </para>
+
     <scons_output example="ex1">
-      <command>ls -1 src</command>
-      <command>scons</command>
-      <command>ls -1 build</command>
+      <scons_output_command>ls src</scons_output_command>
+      <scons_output_command>scons -Q</scons_output_command>
+      <scons_output_command>ls build</scons_output_command>
     </scons_output>
 
     <para>
@@ -193,54 +204,94 @@ program using the F<build/foo.c> path name.
   </section>
 
   <section>
-  <title>Why &SCons; Duplicates Source Files in a Build Directory</title>
+  <title>Why &SCons; Duplicates Source Files in a Variant Directory Tree</title>
 
     <para>
 
-    &SCons; duplicates source files in build directories
+    &SCons; duplicates source files in variant directory trees
     because it's the most straightforward way to guarantee a correct build
-     <emphasis>regardless of include-file directory paths</emphasis>,
+    <emphasis>regardless of include-file directory paths,
+    relative references between files,
+    or tool support for putting files in different locations</emphasis>,
     and the &SCons; philosophy is to, by default,
     guarantee a correct build in all cases.
-    Here is an example of an end case where duplicating
-    source files in a build directory
-    is necessary for a correct build:
 
     </para>
 
     <para>
 
-    XXX
+    The most direct reason to duplicate source files
+    in variant directories
+    is simply that some tools (mostly older versions)
+    are written to only build their output files
+    in the same directory as the source files.
+    In this case, the choices are either
+    to build the output file in the source directory
+    and move it to the variant directory,
+    or to duplicate the source files in the variant directory.
+
+    </para>
+
+    <para>
+
+    Additionally,
+    relative references between files
+    can cause problems if we don't
+    just duplicate the hierarchy of source files
+    in the variant directory.
+    You can see this at work in
+    use of the C preprocessor <literal>#include</literal>
+    mechanism with double quotes, not angle brackets:
 
     </para>
 
     <sconstruct>
-      env = Environmnet()
+      #include "file.h"
     </sconstruct>
 
     <para>
 
-    XXX
+    The <emphasis>de facto</emphasis> standard behavior
+    for most C compilers in this case
+    is to first look in the same directory
+    as the source file that contains the <literal>#include</literal> line,
+    then to look in the directories in the preprocessor search path.
+    Add to this that the &SCons; implementation of
+    support for code repositories
+    (described below)
+    means not all of the files
+    will be found in the same directory hierarchy,
+    and the simplest way to make sure
+    that the right include file is found
+    is to duplicate the source files into the variant directory,
+    which provides a correct build
+    regardless of the original location(s) of the source files.
 
     </para>
 
-    <literallayout>
-      % <userinput>scons</userinput>
-      cc -c build/hello.c -o build/hello.o
-      cc -o build/hello build/hello.o
-    </literallayout>
+    <para>
+
+    Although source-file duplication guarantees a correct build
+    even in these end-cases,
+    it <emphasis>can</emphasis> usually be safely disabled.
+    The next section describes
+    how you can disable the duplication of source files
+    in the variant directory.
+
+    </para>
 
   </section>
 
   <section>
-  <title>Telling &SCons; to Not Duplicate Source Files in the Build Directory</title>
+  <title>Telling &SCons; to Not Duplicate Source Files in the Variant Directory Tree</title>
 
     <para>
 
-    In most cases, however,
-    having &SCons; place its target files in a build subdirectory
+    In most cases and with most tool sets,
+    &SCons; can place its target files in a build subdirectory
     <emphasis>without</emphasis>
-    duplicating the source files works just fine.
+    duplicating the source files
+    and everything will work just fine.
     You can disable the default &SCons; behavior
     by specifying <literal>duplicate=0</literal>
     when you call the &SConscript; function:
@@ -248,39 +299,39 @@ program using the F<build/foo.c> path name.
     </para>
 
     <sconstruct>
-      SConscript('src/SConscript', build_dir='build', duplicate=0)
+      SConscript('src/SConscript', variant_dir='build', duplicate=0)
     </sconstruct>
 
     <para>
 
     When this flag is specified,
-    &SCons; uses the build directory
+    &SCons; uses the variant directory
     like most people expect--that is,
-    the output files are placed in the build directory
+    the output files are placed in the variant directory
     while the source files stay in the source directory:
 
     </para>
 
-    <literallayout>
-      % <userinput>ls -1 src</userinput>
+    <screen>
+      % <userinput>ls src</userinput>
       SConscript
       hello.c
-      % <userinput>scons</userinput>
+      % <userinput>scons -Q</userinput>
       cc -c src/hello.c -o build/hello.o
       cc -o build/hello build/hello.o
-      % <userinput>ls -1 build</userinput>
+      % <userinput>ls build</userinput>
       hello
       hello.o
-    </literallayout>
+    </screen>
 
   </section>
 
   <section>
-  <title>The &BuildDir; Function</title>
+  <title>The &VariantDir; Function</title>
 
     <para>
 
-    Use the &BuildDir; function to establish that target
+    Use the &VariantDir; function to establish that target
     files should be built in a separate directory
     from the source files:
 
@@ -288,7 +339,7 @@ program using the F<build/foo.c> path name.
 
     <scons_example name="ex_builddir">
       <file name="SConstruct" printme="1">
-      BuildDir('build', 'src')
+      VariantDir('build', 'src')
       env = Environment()
       env.Program('build/hello.c')
       </file>
@@ -311,22 +362,16 @@ program using the F<build/foo.c> path name.
 
     <para>
 
-    XXX
-
-    </para>
-
-    <para>
-
-    When using the &BuildDir; function directly,
+    When using the &VariantDir; function directly,
     &SCons; still duplicates the source files
-    in the build directory by default:
+    in the variant directory by default:
 
     </para>
 
     <scons_output example="ex_builddir">
-      <command>ls src</command>
-      <command>scons</command>
-      <command>ls -1 build</command>
+      <scons_output_command>ls src</scons_output_command>
+      <scons_output_command>scons -Q</scons_output_command>
+      <scons_output_command>ls build</scons_output_command>
     </scons_output>
 
     <para>
@@ -338,7 +383,7 @@ program using the F<build/foo.c> path name.
 
     <scons_example name="ex_duplicate_0">
       <file name="SConstruct" printme="1">
-      BuildDir('build', 'src', duplicate=0)
+      VariantDir('build', 'src', duplicate=0)
       env = Environment()
       env.Program('build/hello.c')
       </file>
@@ -355,19 +400,19 @@ program using the F<build/foo.c> path name.
     </para>
 
     <scons_output example="ex_duplicate_0">
-      <command>ls src</command>
-      <command>scons</command>
-      <command>ls -1 build</command>
+      <scons_output_command>ls src</scons_output_command>
+      <scons_output_command>scons -Q</scons_output_command>
+      <scons_output_command>ls build</scons_output_command>
     </scons_output>
 
   </section>
 
   <section>
-  <title>Using &BuildDir; With an &SConscript; File</title>
+  <title>Using &VariantDir; With an &SConscript; File</title>
 
     <para>
 
-    Even when using the &BuildDir; function,
+    Even when using the &VariantDir; function,
     it's much more natural to use it with
     a subsidiary &SConscript; file.
     For example, if the
@@ -377,22 +422,26 @@ program using the F<build/foo.c> path name.
     </para>
 
     <scons_example name="example_builddir_sconscript">
-      <file name="SConstruct" printme="1">
+      <file name="SConstruct">
+      VariantDir('build', 'src')
+      SConscript('build/SConscript')
+      </file>
+      <file name="src/SConscript" printme="1">
       env = Environment()
       env.Program('hello.c')
       </file>
-      <file name="SConscript">
-      BuildDir('build', 'src')
-      SConscript('build/SConscript')
+      <file name="src/hello.c">
+      int main() { printf("Hello, world!\n"); }
+      </file>
     </scons_example>
 
     <para>
 
-    Then our &SConscript; file could look like:
+    Then our &SConstruct; file could look like:
 
     </para>
 
-    <scons_example_file example="example_builddir_sconscript" name="SConscript">
+    <scons_example_file example="example_builddir_sconscript" name="SConstruct">
     </scons_example_file>
 
     <para>
@@ -402,9 +451,9 @@ program using the F<build/foo.c> path name.
     </para>
 
     <scons_output example="example_builddir_sconscript">
-      <command>ls -1 src</command>
-      <command>scons</command>
-      <command>ls -1 build</command>
+      <scons_output_command>ls src</scons_output_command>
+      <scons_output_command>scons -Q</scons_output_command>
+      <scons_output_command>ls build</scons_output_command>
     </scons_output>
 
     <para>
@@ -418,12 +467,74 @@ program using the F<build/foo.c> path name.
   </section>
 
   <section>
-  <title>Why You'd Want to Call &BuildDir; Instead of &SConscript;</title>
+  <title>Using &Glob; with &VariantDir;</title>
 
     <para>
-    
-    XXX
+
+    The &Glob; file name pattern matching function
+    works just as usual when using &VariantDir;.
+    For example, if the
+    <filename>src/SConscript</filename>
+    looks like this:
+
+    </para>
+
+    <scons_example name="example_glob_builddir_sconscript">
+      <file name="SConstruct">
+      VariantDir('build', 'src')
+      SConscript('build/SConscript')
+      </file>
+      <file name="src/SConscript" printme="1">
+      env = Environment()
+      env.Program('hello', Glob('*.c'))
+      </file>
+      <file name="src/f1.c">
+      #include "f2.h"
+      int main() { printf(f2()); }
+      </file>
+      <file name="src/f2.c">
+      const char * f2() { return("Hello, world!\n"); }
+      </file>
+      <file name="src/f2.h">
+      const char * f2();
+      </file>
+    </scons_example>
+
+    <para>
+
+    Then with the same &SConstruct; file as in the previous section,
+    and source files <filename>f1.c</filename>
+    and <filename>f2.c</filename> in src,
+    we would see the following output:
+
+    </para>
+
+    <scons_output example="example_glob_builddir_sconscript">
+      <scons_output_command>ls src</scons_output_command>
+      <scons_output_command>scons -Q</scons_output_command>
+      <scons_output_command>ls build</scons_output_command>
+    </scons_output>
+
+    <para>
+
+    The &Glob; function returns Nodes in the
+    <filename>build/</filename> tree, as you'd expect.
+
+    </para>
+
+  </section>
+
+  <!--
+
+  <section>
+  <title>Why You'd Want to Call &VariantDir; Instead of &SConscript;</title>
+
+    <para>
+
+    XXX why call VariantDir() instead of SConscript(variant_dir=)
 
     </para>
 
   </section>
+
+  -->