diff options
author | Mats Wichmann <mats@linux.com> | 2020-09-15 17:20:27 (GMT) |
---|---|---|
committer | Mats Wichmann <mats@linux.com> | 2020-09-22 03:27:56 (GMT) |
commit | cc4bf014a6ea5d5c4d4ff7c6039f387adcc3d762 (patch) | |
tree | e1d1f63077957d2faccda2fa5d756bf5b43cd78e | |
parent | ea642040eca864aaeac25da013cce9fd875489f0 (diff) | |
download | SCons-cc4bf014a6ea5d5c4d4ff7c6039f387adcc3d762.zip SCons-cc4bf014a6ea5d5c4d4ff7c6039f387adcc3d762.tar.gz SCons-cc4bf014a6ea5d5c4d4ff7c6039f387adcc3d762.tar.bz2 |
Tweaks to variant dir documentation [skip appveyor]
Manpage/shared VariantDir function wording tries to make more
clear that build happens in the variant. Other tweaking.
User guide variant description similarly updated. A (worded) example
of why one might want variants is added.
Formerly separate chapter doc/user/variants.xml is now included
as a section in the previous chapter. An additional example
is enabled (was in the file but commented out), which some
introductiory wording. The introduction to the other sample
in the file is also built up slightly.
Dropped embedded comments that were the old Cons documentation
for these topics.
Signed-off-by: Mats Wichmann <mats@linux.com>
-rw-r--r-- | SCons/Environment.xml | 91 | ||||
-rw-r--r-- | doc/generated/examples/separate_ex1_1.xml | 2 | ||||
-rw-r--r-- | doc/user/main.xml | 1 | ||||
-rw-r--r-- | doc/user/separate.xml | 179 | ||||
-rw-r--r-- | doc/user/variants.xml | 70 |
5 files changed, 132 insertions, 211 deletions
diff --git a/SCons/Environment.xml b/SCons/Environment.xml index ac40f74..13d0754 100644 --- a/SCons/Environment.xml +++ b/SCons/Environment.xml @@ -3171,8 +3171,8 @@ def create(target, source, env): # A function that will write a 'prefix=$SOURCE' # string into the file name specified as the # $TARGET. - f = open(str(target[0]), 'wb') - f.write('prefix=' + source[0].get_contents()) + with open(str(target[0]), 'wb') as f: + f.write('prefix=' + source[0].get_contents()) # Fetch the prefix= argument, if any, from the command # line, and use /usr/local as the default. @@ -3206,90 +3206,75 @@ env.UpdateValue(target = Value(output), source = Value(input)) </arguments> <summary> <para> -Use the -&f-VariantDir; -function to create a copy of your sources in another location: -if a name under -<parameter>variant_dir</parameter> -is not found but exists under -<parameter>src_dir</parameter>, -the file or directory is copied to -<parameter>variant_dir</parameter>. -Target files can be built in a different directory -than the original sources by simply refering to the sources (and targets) -within the variant tree. -</para> - -<para> +Sets up an alternate build location. +When building in the <parameter>variant_dir</parameter>, +&SCons; backfills as needed with files from <parameter>src_dir</parameter> +to create a complete build directory. &f-VariantDir; can be called multiple times with the same <parameter>src_dir</parameter> to set up multiple builds with different options -(<parameter>variants</parameter>). +(<emphasis>variants</emphasis>). +</para> + +<para> The -<parameter>src_dir</parameter> -location must be in or underneath the SConstruct file's directory, and -<parameter>variant_dir</parameter> +<parameter>variant</parameter> +location must be in or underneath the project top directory, +and <parameter>src_dir</parameter> may not be underneath -<parameter>src_dir</parameter>. -<!-- -TODO: Can the above restrictions be clarified or relaxed? -TODO: The latter restriction is clearly not completely right; -TODO: src_dir = '.' works fine with a build dir under it. ---> +<parameter>variant_dir</parameter>. </para> <para> -The default behavior is for -&scons; -to physically duplicate the source files in the variant tree. +By default, &SCons; +physically duplicates the source files and SConscript files +as needed into the variant tree. Thus, a build performed in the variant tree is guaranteed to be identical to a build performed in the source tree even if intermediate source files are generated during the build, -or preprocessors or other scanners search for included files +or if preprocessors or other scanners search for included files relative to the source file, -or individual compilers or other invoked tools are hard-coded +or if individual compilers or other invoked tools are hard-coded to put derived files in the same directory as source files. +Only the files &SCons; calculates are needed for the build are +duplicated into <parameter>variant_dir</parameter>. </para> <para> If possible on the platform, -the duplication is performed by linking rather than copying; -see also the +the duplication is performed by linking rather than copying. +This behavior is affected by the <option>--duplicate</option> command-line option. -Moreover, only the files needed for the build are duplicated; -files and directories that are not used are not present in -<parameter>variant_dir</parameter>. </para> <para> -Duplicating the source tree may be disabled by setting the -<literal>duplicate</literal> +Physically duplicating the source files may be disabled by setting the +<parameter>duplicate</parameter> argument to -<literal>0</literal> -(zero). +<constant>False</constant>. This will cause -&scons; +&SCons; to invoke Builders using the path names of source files in <parameter>src_dir</parameter> and the path names of derived files within <parameter>variant_dir</parameter>. -This is always more efficient than -<literal>duplicate=1</literal>, -and is usually safe for most builds -(but see above for cases that may cause problems). +This is more efficient than +<literal>duplicate=True</literal>, +and is safe for most builds; +revert to <constant>True</constant> +if it causes problems. </para> <para> -Note that &f-VariantDir; -works most naturally with a subsidiary SConscript file. -However, you would then call the subsidiary SConscript file -not in the source directory, but in the +works most naturally with used with a subsidiary SConscript file. +The subsidiary SConscript file is called as if it +were in <parameter>variant_dir</parameter>, regardless of the value of -<literal>duplicate</literal>. +<parameter>duplicate</parameter>. This is how you tell &scons; which variant of a source tree to build: @@ -3319,15 +3304,11 @@ Examples: # use names in the build directory, not the source directory VariantDir('build', 'src', duplicate=0) Program('build/prog', 'build/source.c') -</example_commands> -<example_commands> # this builds both the source and docs in a separate subtree VariantDir('build', '.', duplicate=0) SConscript(dirs=['build/src','build/doc']) -</example_commands> -<example_commands> # same as previous example, but only uses SConscript SConscript(dirs='src', variant_dir='build/src', duplicate=0) SConscript(dirs='doc', variant_dir='build/doc', duplicate=0) diff --git a/doc/generated/examples/separate_ex1_1.xml b/doc/generated/examples/separate_ex1_1.xml index 6efc16f..803bc4f 100644 --- a/doc/generated/examples/separate_ex1_1.xml +++ b/doc/generated/examples/separate_ex1_1.xml @@ -3,6 +3,8 @@ SConscript hello.c % <userinput>scons -Q</userinput> cc -o build/hello.o -c build/hello.c cc -o build/hello build/hello.o +% <userinput>ls src</userinput> +SConscript hello.c % <userinput>ls build</userinput> SConscript hello hello.c hello.o </screen> diff --git a/doc/user/main.xml b/doc/user/main.xml index a19df62..494a208 100644 --- a/doc/user/main.xml +++ b/doc/user/main.xml @@ -105,7 +105,6 @@ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="file-removal.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hierarchy.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="separate.xml"/> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="variants.xml"/> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="gettext.xml"/> <!-- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="builders-built-in.xml"/> --> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="builders-writing.xml"/> diff --git a/doc/user/separate.xml b/doc/user/separate.xml index 748a124..a000260 100644 --- a/doc/user/separate.xml +++ b/doc/user/separate.xml @@ -2,7 +2,7 @@ <!DOCTYPE sconsdoc [ <!ENTITY % scons SYSTEM "../scons.mod"> %scons; - + <!ENTITY % builders-mod SYSTEM "../generated/builders.mod"> %builders-mod; <!ENTITY % functions-mod SYSTEM "../generated/functions.mod"> @@ -17,7 +17,7 @@ xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd"> -<title>Separating Source and Build Directories</title> +<title>Separating Source and Build Trees: Variant Directories</title> <!-- @@ -44,115 +44,49 @@ --> -<!-- + <para> -=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. + It's often useful to keep any built files completely + separate from the source files. Consider if you have a + project to build software for a variety of different + controller hardware. The boards are able to share a + lot of code, so it makes sense to keep them in the same + source tree, but certain build options in the source code + and header files differ. If you build "Controller A" first, + then "Controller B", on the second build everything would + have to be rebuilt, because &SCons; sees that the build + instructions differ, and thus the targets that depend on those + different instructions are not valid for the current build. + Now when you go back and build for "Controller A", + things have to be rebuilt from scratch again for the same reason. + However, if you can separate the places the output files + go, this problem can be avoided. + You can even set up to do both builds in one invocation of &SCons;. ---> + </para> <para> - It's often useful to keep any built files completely - separate from the source files. - In &SCons;, this is usually done by creating one or more separate - <emphasis>variant directory trees</emphasis> + You can enable this separation by creating one or more + <firstterm>variant directory</firstterm> trees that are used to hold the built objects files, libraries, and executable programs, etc. 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 &VariantDir; function. + one through the &f-link-SConscript; function that we've already seen, + and the second through a more flexible &f-link-VariantDir; function. </para> <para> - One historical note: the &VariantDir; function + Historical note: the &VariantDir; function used to be called &BuildDir;, a name which was removed because the &SCons; functionality - differs from the model of a "build directory" - implemented by other build systems like the GNU Autotools. + differs from a familiar model of a "build directory" + implemented by other build systems like GNU Autotools. + You might still find references to the old name on + the Internet in postings about &SCons;, but it no longer works. </para> @@ -162,11 +96,11 @@ program using the F<build/foo.c> path name. <para> The most straightforward way to establish a variant directory tree - uses the fact that the usual way to + relies the fact that the usual way to set up a build hierarchy is to have an - &SConscript; file in the source subdirectory. - If you then pass a &variant_dir; argument to the - &SConscript; function call: + SConscript file in the source subdirectory. + If you pass a &variant_dir; argument to the + &f-link-SConscript; function call: </para> @@ -193,20 +127,25 @@ int main() { printf("Hello, world!\n"); } <scons_output example="separate_ex1" suffix="1"> <scons_output_command>ls src</scons_output_command> <scons_output_command>scons -Q</scons_output_command> + <scons_output_command>ls src</scons_output_command> <scons_output_command>ls build</scons_output_command> </scons_output> <para> - But wait a minute--what's going on here? - &SCons; created the object file + No files were built in &src;, they went to &build;. + The build output might show a bit of a surprise: + the object file <filename>build/hello.o</filename> - in the &build; subdirectory, + and the executable file + <filename>build/hello</filename> + were built 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. + to create the object file, + and that file is now seen in &build;. </para> @@ -215,7 +154,7 @@ int main() { printf("Hello, world!\n"); } 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. + and built the program from there (it also duplicated &SConscript;). The next section explains why &SCons; does this. </para> @@ -227,13 +166,13 @@ int main() { printf("Hello, world!\n"); } <para> - &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, - 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. + The main thing to understand is that when you set up a variant directory, + &SCons; performs the build <emphasis>in that directory</emphasis>. + It turns out it's easiest to ensure where build products end up + by just building in place. + Since the build is happening in a place different from where the + sources are, the most straightforward way to guarantee a correct build + is for &SCons; to copy them there. </para> @@ -312,13 +251,13 @@ int main() { printf("Hello, world!\n"); } duplicating the source files and everything will work just fine. You can disable the default &SCons; behavior - by specifying <literal>duplicate=0</literal> + by specifying <literal>duplicate=False</literal> when you call the &SConscript; function: </para> <sconstruct> -SConscript('src/SConscript', variant_dir='build', duplicate=0) +SConscript('src/SConscript', variant_dir='build', duplicate=False) </sconstruct> <para> @@ -395,14 +334,14 @@ int main() { printf("Hello, world!\n"); } <para> - You can specify the same <literal>duplicate=0</literal> argument + You can specify the same <literal>duplicate=False</literal> argument that you can specify for an &SConscript; call: </para> <scons_example name="separate_duplicate0"> <file name="SConstruct" printme="1"> -VariantDir('build', 'src', duplicate=0) +VariantDir('build', 'src', duplicate=False) env = Environment() env.Program('build/hello.c') </file> @@ -432,8 +371,10 @@ int main() { printf("Hello, world!\n"); } <para> Even when using the &VariantDir; function, - it's much more natural to use it with - a subsidiary &SConscript; file. + it's more natural to use it with + a subsidiary &SConscript; file, + because then you don't have to adjust your individual + build instructions to use the variant directory path. For example, if the <filename>src/SConscript</filename> looks like this: @@ -490,7 +431,7 @@ int main() { printf("Hello, world!\n"); } <para> - The &Glob; file name pattern matching function + The &f-link-Glob; file name pattern matching function works just as usual when using &VariantDir;. For example, if the <filename>src/SConscript</filename> @@ -558,4 +499,6 @@ const char * f2(); --> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="variants.xml"/> + </chapter> diff --git a/doc/user/variants.xml b/doc/user/variants.xml index 0c83b04..6cf8c3d 100644 --- a/doc/user/variants.xml +++ b/doc/user/variants.xml @@ -13,11 +13,11 @@ %variables-mod; ]> -<chapter id="chap-variants" +<section id="sect-variants" xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd"> -<title>Variant Builds</title> +<title>Variant Build Examples</title> <!-- @@ -44,30 +44,6 @@ --> -<!-- - -=head1 Variant builds - -=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> The &variant_dir; keyword argument of @@ -76,9 +52,15 @@ is pretty smart about rebuilding things when you change options. variant builds using &SCons;. Suppose, for example, that we want to build a program for both Windows and Linux platforms, - but that we want to build it in a shared directory + but that we want to build it in directory on a network share with separate side-by-side build directories for the Windows and Linux versions of the program. + We have to do a little bit of work to construct paths, + to make sure unwanted location dependencies don't creep in. + The top-relative path reference can be useful here. + To avoid writing conditional code based on platform, + we can build the <parameter>variant_dir</parameter> + path dynamically: </para> @@ -90,13 +72,15 @@ include = "#export/$PLATFORM/include" lib = "#export/$PLATFORM/lib" bin = "#export/$PLATFORM/bin" -env = Environment(PLATFORM = platform, - BINDIR = bin, - INCDIR = include, - LIBDIR = lib, - CPPPATH = [include], - LIBPATH = [lib], - LIBS = 'world') +env = Environment( + PLATFORM=platform, + BINDIR=bin, + INCDIR=include, + LIBDIR=lib, + CPPPATH=[include], + LIBPATH=[lib], + LIBS='world', +) Export('env') @@ -155,20 +139,32 @@ int world() { printf "world.c\n"; } <scons_output_command>scons -Q OS=windows</scons_output_command> </scons_output> - <!-- + <para> + + In order to build several variants at once when using the + <parameter>variant_dir</parameter> argument to &SConscript;, + you can call the function repeatedely - this example + does so in a loop. Note that the &f-link-SConscript; trick of + passing a list of script files, or a list of source directories, + does not work with <parameter>variant_dir</parameter>, + &SCons; allows only a single &SConscript; to be given if + <parameter>variant_dir</parameter> is used. + + </para> <scons_example name="variants_ex2"> <file name="SConstruct" printme="1"> -env = Environment(OS = ARGUMENTS.get('OS')) +env = Environment(OS=ARGUMENTS.get('OS')) for os in ['newell', 'post']: SConscript('src/SConscript', variant_dir='build/' + os) </file> </scons_example> + <!-- <scons_output example="variants_ex2" suffix="1"> <scons_output_command>scons -Q</scons_output_command> </scons_output> --> -</chapter> +</section> |