summaryrefslogtreecommitdiffstats
path: root/doc/user/separate.in
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-08-16 04:19:30 (GMT)
committerSteven Knight <knight@baldmt.com>2003-08-16 04:19:30 (GMT)
commit9d21228a092cc048be6e60053d0ed739eec5b629 (patch)
treed2447f2650bf7782e58826ad0c16364496722d1c /doc/user/separate.in
parent601839d06d9563854ce22a615d6670a7651cd858 (diff)
downloadSCons-9d21228a092cc048be6e60053d0ed739eec5b629.zip
SCons-9d21228a092cc048be6e60053d0ed739eec5b629.tar.gz
SCons-9d21228a092cc048be6e60053d0ed739eec5b629.tar.bz2
Branch for User's Guide changes.
Diffstat (limited to 'doc/user/separate.in')
-rw-r--r--doc/user/separate.in429
1 files changed, 429 insertions, 0 deletions
diff --git a/doc/user/separate.in b/doc/user/separate.in
new file mode 100644
index 0000000..c1b3c32
--- /dev/null
+++ b/doc/user/separate.in
@@ -0,0 +1,429 @@
+<!--
+
+ 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>
+
+ It's often useful to keep any built files completely
+ separate from the source files.
+ This is usually done by creating one or more separate
+ <emphasis>build directories</emphasis>
+ that are used to hold the built objects files, libraries,
+ and executable programs, etc.
+ for a specific flavor of build.
+ &SCons; provides two ways to do this,
+ one through the &SConscript; function that we've already seen,
+ and the second through a more flexible &BuildDir; function.
+
+ </para>
+
+ <section>
+ <title>Specifying a Build Directory as Part of an &SConscript; Call</title>
+
+ <para>
+
+ The most straightforward way to establish a build directory
+ uses the fact that the usual way to
+ set up a build hierarcy is to have an
+ &SConscript; file in the source subdirectory.
+ If you then pass a &build_dir; argument to the
+ &SConscript; function call:
+
+ </para>
+
+ <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">
+ env = Environment()
+ env.Program('hello.c')
+ </file>
+ <file name="hello.c">
+ int main() { printf("Hello, world!\n"); }
+ </file>
+ </scons_example>
+
+ <scons_output example="ex1">
+ <command>ls -1 src</command>
+ <command>scons</command>
+ <command>ls -1 build</command>
+ </scons_output>
+
+ <para>
+
+ But wait a minute--what's going on here?
+ &SCons; created the object file
+ <filename>build/hello.o</filename>
+ in the &build; subdirectory,
+ as expected.
+ But even though our &hello_c; file lives in the &src; subdirectory,
+ &SCons; has actually compiled a
+ <filename>build/hello.c</filename> file
+ to create the object file.
+
+ </para>
+
+ <para>
+
+ What's happened is that &SCons; has <emphasis>duplicated</emphasis>
+ the &hello_c; file from the &src; subdirectory
+ to the &build; subdirectory,
+ and built the program from there.
+ The next section explains why &SCons; does this.
+
+ </para>
+
+ </section>
+
+ <section>
+ <title>Why &SCons; Duplicates Source Files in a Build Directory</title>
+
+ <para>
+
+ &SCons; duplicates source files in build directories
+ because it's the most straightforward way to guarantee a correct build
+ <emphasis>regardless of include-file directory paths</emphasis>,
+ and the &SCons; philosophy is to, by default,
+ guarantee a correct build in all cases.
+ Here is an example of an end case where duplicating
+ source files in a build directory
+ is necessary for a correct build:
+
+ </para>
+
+ <para>
+
+ XXX
+
+ </para>
+
+ <sconstruct>
+ env = Environmnet()
+ </sconstruct>
+
+ <para>
+
+ XXX
+
+ </para>
+
+ <literallayout>
+ % <userinput>scons</userinput>
+ cc -c build/hello.c -o build/hello.o
+ cc -o build/hello build/hello.o
+ </literallayout>
+
+ </section>
+
+ <section>
+ <title>Telling &SCons; to Not Duplicate Source Files in the Build Directory</title>
+
+ <para>
+
+ In most cases, however,
+ having &SCons; place its target files in a build subdirectory
+ <emphasis>without</emphasis>
+ duplicating the source files works just fine.
+ You can disable the default &SCons; behavior
+ by specifying <literal>duplicate=0</literal>
+ when you call the &SConscript; function:
+
+ </para>
+
+ <sconstruct>
+ SConscript('src/SConscript', build_dir='build', duplicate=0)
+ </sconstruct>
+
+ <para>
+
+ When this flag is specified,
+ &SCons; uses the build directory
+ like most people expect--that is,
+ the output files are placed in the build directory
+ while the source files stay in the source directory:
+
+ </para>
+
+ <literallayout>
+ % <userinput>ls -1 src</userinput>
+ SConscript
+ hello.c
+ % <userinput>scons</userinput>
+ cc -c src/hello.c -o build/hello.o
+ cc -o build/hello build/hello.o
+ % <userinput>ls -1 build</userinput>
+ hello
+ hello.o
+ </literallayout>
+
+ </section>
+
+ <section>
+ <title>The &BuildDir; Function</title>
+
+ <para>
+
+ Use the &BuildDir; function to establish that target
+ files should be built in a separate directory
+ from the source files:
+
+ </para>
+
+ <scons_example name="ex_builddir">
+ <file name="SConstruct" printme="1">
+ BuildDir('build', 'src')
+ env = Environment()
+ env.Program('build/hello.c')
+ </file>
+ <file name="src/hello.c">
+ int main() { printf("Hello, world!\n"); }
+ </file>
+ </scons_example>
+
+ <para>
+
+ Note that when you're not using
+ an &SConscript; file in the &src; subdirectory,
+ you must actually specify that
+ the program must be built from
+ the <filename>build/hello.c</filename>
+ file that &SCons; will duplicate in the
+ &build; subdirectory.
+
+ </para>
+
+ <para>
+
+ XXX
+
+ </para>
+
+ <para>
+
+ When using the &BuildDir; function directly,
+ &SCons; still duplicates the source files
+ in the build directory by default:
+
+ </para>
+
+ <scons_output example="ex_builddir">
+ <command>ls src</command>
+ <command>scons</command>
+ <command>ls -1 build</command>
+ </scons_output>
+
+ <para>
+
+ You can specify the same <literal>duplicate=0</literal> argument
+ that you can specify for an &SConscript; call:
+
+ </para>
+
+ <scons_example name="ex_duplicate_0">
+ <file name="SConstruct" printme="1">
+ BuildDir('build', 'src', duplicate=0)
+ env = Environment()
+ env.Program('build/hello.c')
+ </file>
+ <file name="src/hello.c">
+ int main() { printf("Hello, world!\n"); }
+ </file>
+ </scons_example>
+
+ <para>
+
+ In which case &SCons;
+ will disable duplication of the source files:
+
+ </para>
+
+ <scons_output example="ex_duplicate_0">
+ <command>ls src</command>
+ <command>scons</command>
+ <command>ls -1 build</command>
+ </scons_output>
+
+ </section>
+
+ <section>
+ <title>Using &BuildDir; With an &SConscript; File</title>
+
+ <para>
+
+ Even when using the &BuildDir; function,
+ it's much more natural to use it with
+ a subsidiary &SConscript; file.
+ For example, if the
+ <filename>src/SConscript</filename>
+ looks like this:
+
+ </para>
+
+ <scons_example name="example_builddir_sconscript">
+ <file name="SConstruct" printme="1">
+ env = Environment()
+ env.Program('hello.c')
+ </file>
+ <file name="SConscript">
+ BuildDir('build', 'src')
+ SConscript('build/SConscript')
+ </scons_example>
+
+ <para>
+
+ Then our &SConscript; file could look like:
+
+ </para>
+
+ <scons_example_file example="example_builddir_sconscript" name="SConscript">
+ </scons_example_file>
+
+ <para>
+
+ Yielding the following output:
+
+ </para>
+
+ <scons_output example="example_builddir_sconscript">
+ <command>ls -1 src</command>
+ <command>scons</command>
+ <command>ls -1 build</command>
+ </scons_output>
+
+ <para>
+
+ Notice that this is completely equivalent
+ to the use of &SConscript; that we
+ learned about in the previous section.
+
+ </para>
+
+ </section>
+
+ <section>
+ <title>Why You'd Want to Call &BuildDir; Instead of &SConscript;</title>
+
+ <para>
+
+ XXX
+
+ </para>
+
+ </section>