From: stevenknight Date: Wed, 21 May 2003 13:01:13 +0000 (+0000) Subject: Branch for User's Guide updates. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=13c76c7ff121a39bf58f28f7c520923c8f809834;p=scons.git Branch for User's Guide updates. git-svn-id: http://scons.tigris.org/svn/scons/trunk@692 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/SConstruct b/SConstruct index 87eafb04..b1af6918 100644 --- a/SConstruct +++ b/SConstruct @@ -865,7 +865,10 @@ if change: for f in pf + cf: u[f] = 1 for f in df: - del u[f] + try: + del u[f] + except KeyError: + pass sfiles = filter(lambda x: x[-9:] != '.aeignore' and x[-9:] != '.sconsign', u.keys()) diff --git a/doc/scons.mod b/doc/scons.mod index 32283c31..f9deaa1e 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -14,14 +14,20 @@ --> +Aegis"> Autoconf"> Cons"> gcc"> +Jam"> Make"> Make++"> +ranlib"> SCons"> scons"> ScCons"> +tar"> +touch"> +zip"> +build"> Makefile"> Makefiles"> SConscript"> @@ -68,6 +75,7 @@ Sconstruct"> sconstruct"> .sconsign"> +src"> @@ -106,10 +114,17 @@ Repository"> RuleSet"> Salt"> +SetBuildSignatureType"> +SetContentSignatureType"> SourceSignature"> +SourceSignatures"> Split"> +TargetSignatures"> Task"> +str"> +zipfile"> + Cache"> @@ -125,6 +140,8 @@ BUILDERS"> SCANNERMAP"> SCANNERS"> +TARFLAGS"> +TARSUFFIX"> @@ -137,11 +154,24 @@ CC"> CCFLAGS"> LIBPATH"> +LIBS"> PYTHONPATH"> SCONSFLAGS"> + + +build_dir"> +source"> +target"> + + + Make"> @@ -175,6 +212,8 @@ --> +builder function"> + Construction Environment"> Construction Environments"> Construction environment"> @@ -193,14 +232,29 @@ Dictionary"> +Emitter"> +emitter"> +Generator"> +generator"> + +signature"> +build signature"> + +common1.c"> +common2.c"> goodbye"> hello"> hello.c"> +hello.exe"> hello.h"> +hello.o"> +prog"> +prog.c"> +prog.exe"> stdio.h"> diff --git a/doc/user/actions.sgml b/doc/user/actions.sgml index 447b331e..c35ccdda 100644 --- a/doc/user/actions.sgml +++ b/doc/user/actions.sgml @@ -224,16 +224,16 @@ solutions to the above limitations. - X + XXX
- X + XXX - X + XXX diff --git a/doc/user/ant.sgml b/doc/user/ant.sgml new file mode 100644 index 00000000..f83ab639 --- /dev/null +++ b/doc/user/ant.sgml @@ -0,0 +1,41 @@ + + + + + XXX + + + +
+ XXX + + + + XXX + + + +
diff --git a/doc/user/builders-built-in.sgml b/doc/user/builders-built-in.sgml new file mode 100644 index 00000000..bb29cc41 --- /dev/null +++ b/doc/user/builders-built-in.sgml @@ -0,0 +1,628 @@ + + + + + &SCons; provides the ability to build a lot of different + types of files right "out of the box." + So far, we've been using &SCons;' ability to build + programs, objects and libraries to + illustrate much of the underlying functionality of &SCons; + This section will describe all of the different + types of files that you can build with &SCons;, + and the built-in &Builder; objects used to build them. + + + +
+ Programs: the &Program; Builder + + + + As we've seen, the &Program; Builder + is used to build an executable program. + The &source; argument is one or more + source-code files or object files, + and the ⌖ argument is the + name of the executable program name to be created. + For example: + + + + + env = Environment() + env.Program('prog', 'file1.o') + + + + + Will create the &prog; + executable on a POSIX system, + the &prog_exe; executable on a Windows system. + + + + + + The target file's prefix and suffix may be omitted, + and the values from the + $PROGPREFIX + and + $PROGSUFFIX + construction variables + will be appended appropriately. + For example: + + + + + env = Environment(PROGPREFIX='my', PROGSUFFIX='.xxx') + env.Program('prog', ['file1.o', 'file2.o']) + + + + + Will create a program named + myprog.xxx + regardless of the system on which it is run. + + + + + + If you omit the ⌖, + the base of the first input + file name specified + because the base of the target + program created. + For example: + + + + + env = Environment() + env.Program(['hello.c', 'goodbye.c']) + + + + + Will create the &hello; + executable on a POSIX system, + the &hello_exe; executable on a Windows system. + + + +
+ +
+ Object-File Builders + + + + &SCons; provides separate Builder objects + to create both static and shared object files. + + + +
+ The &StaticObject; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ The &SharedObject; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ The &Object; Builder + + + + XXX + + + + + XXX + + + + + Creates a static object file. + + + +
+ +
+ +
+ Library Builders + + + + &SCons; provides separate Builder objects + to create both static and shared libraries. + + + +
+ The &StaticLibrary; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ The &SharedLibrary; Builder + + + + XXX + + + +
+ +
+ The &Library; Builder + + + + XXX + + + + + XXX + + + + XXX + + + + + Creates a static library file. + + + +
+ +
+ +
+ Pre-Compiled Headers: the &PCH; Builder + + + + XXX + + + +
+ +
+ Microsoft Visual C++ Resource Files: the &RES; Builder + + + + XXX + + + +
+ +
+ Source Files + + + + By default + &SCons; supports two Builder objects + that know how to build source files + from other input files. + + + +
+ The &CFile; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ The &CXXFile; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ +
+ Documents + + + + &SCons; provides a number of Builder objects + for creating different types of documents. + + + +
+ The &DVI; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ The &PDF; Builder + + + + XXX + + + +
+ +
+ The &PostScript; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ +
+ Archives + + + + &SCons; provides Builder objects + for creating two different types of archive files. + + + +
+ The &Tar; Builder + + + + The &Tar; Builder object uses the &tar; + utility to create archives of files + and/or directory trees: + + + + + env = Environment() + env.Tar('out1.tar', ['file1', 'file2']) + env.Tar('out2', 'directory') + + + + % scons . + tar -c -f out1.tar file1 file2 + tar -c -f out2.tar directory + + + + + One common requirement when creating a &tar; archive + is to create a compressed archive using the + option. + This is easily handled by specifying + the value of the &TARFLAGS; variable + when you create the construction environment. + Note, however, that the used to + to instruct &tar; to create the archive + is part of the default value of &TARFLAGS;, + so you need to set it both options: + + + + + env = Environment(TARFLAGS = '-c -z') + env.Tar('out.tar.gz', 'directory') + + + + % scons . + tar -c -z -f out.tar.gz directory + + + + + you may also wish to set the value of the + &TARSUFFIX; construction variable + to your desired suffix for compress &tar; archives, + so that &SCons; can append it to the target file name + without your having to specify it explicitly: + + + + + env = Environment(TARFLAGS = '-c -z', + TARSUFFIX = '.tgz') + env.Tar('out', 'directory') + + + + % scons . + tar -c -z -f out.tgz directory + + +
+ +
+ The &Zip; Builder + + + + The &Zip; Builder object creates archives of files + and/or directory trees in the ZIP file format. + Python versions 1.6 or later + contain an internal &zipfile; module + that &SCons; will use. + In this case, given the following + &SConstruct; file: + + + + + env = Environment() + env.Zip('out', ['file1', 'file2']) + + + + + Your output will reflect the fact + that an internal Python function + is being used to create the output ZIP archive: + + + + + % scons . + zip("out.zip", ["file1", "file2"]) + + + + + If you're using Python version 1.5.2 to run &SCons;, + then &SCons; will try to use an external + &zip; program as follows: + + + + + % scons . + zip /home/my/project/zip.out file1 file2 + + +
+ +
+ +
+ Java + + + + &SCons; provides Builder objects + for creating various types of Java output files. + + + +
+ Building Class Files: the &Java; Builder + + + + The &Java; builder takes one or more input + .java files + and turns them into one or more + .class files + Unlike most builders, however, + the &Java; builder takes + target and source directories, + not files, as input. + + + + + env = Environment() + env.Java(target = 'classes', source = 'src') + + + + + The &Java; builder will then + search the specified source directory + tree for all .java files, + and pass any out-of-date + + + + + XXX + + +
+ +
+ The &Jar; Builder + + + + The &Jar; builder object XXX + + + + + env = Environment() + env.Java(target = 'classes', source = 'src') + env.Jar(target = '', source = 'classes') + + + + XXX + + +
+ +
+ Building C header and stub files: the &JavaH; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
+ Building RMI stub and skeleton class files: the &RMIC; Builder + + + + XXX + + + + + XXX + + + + XXX + + +
+ +
diff --git a/doc/user/command.sgml b/doc/user/builders-commands.sgml similarity index 75% rename from doc/user/command.sgml rename to doc/user/builders-commands.sgml index 945c6565..e21f6d01 100644 --- a/doc/user/command.sgml +++ b/doc/user/builders-commands.sgml @@ -23,41 +23,41 @@ --> - + --> Creating a &Builder; and attaching it to a &consenv; allows for a lot of flexibility when you - want to re-use the same actions + want to re-use actions to build multiple files of the same type. This can, however, be cumbersome if you only need to execute one specific command - to build a single file (or single group of files). + to build a single file (or group of files). For these situations, &SCons; supports a &Command; &Builder; that arranges for a specific action to be executed @@ -90,7 +90,7 @@ F and F. - Note that the action you + Note that the action you diff --git a/doc/user/builders.sgml b/doc/user/builders-writing.sgml similarity index 69% rename from doc/user/builders.sgml rename to doc/user/builders-writing.sgml index c1b42694..27a48b97 100644 --- a/doc/user/builders.sgml +++ b/doc/user/builders-writing.sgml @@ -97,20 +97,24 @@ This functionality could be invoked as in the following example: - &SCons; provides many useful methods - for building common software products: - programs, libraries, documents. - Frequently, however, you want to be - able to build some other type of file - not supported directly by &SCons; - Fortunately, &SCons; makes it very easy - to define your own &Builder; objects - for any custom file types you want to build. + Although &SCons; provides many useful methods + for building common software products: + programs, libraries, documents. + you frequently want to be + able to build some other type of file + not supported directly by &SCons; + Fortunately, &SCons; makes it very easy + to define your own &Builder; objects + for any custom file types you want to build. + (In fact, the &SCons; interfaces for creating + &Builder; objects are flexible enough and easy enough to use + that all of the the &SCons; built-in &Builder; objects + are created the mechanisms described in this section.)
- Builders That Execute External Commands + Writing Builders That Execute External Commands @@ -128,6 +132,14 @@ This functionality could be invoked as in the following example: bld = Builder(action = 'foobuild < $TARGET > $SOURCE') + + + All the above line does is create a free-standing + &Builder; object. + The next section will show us how to actually use it. + + +
@@ -135,17 +147,17 @@ This functionality could be invoked as in the following example: - A &Builder; object by itself, though, - isn't useful until it's attached to a &consenv; + A &Builder; object isn't useful + until it's attached to a &consenv; so that we can call it to arrange for files to be built. This is done through the &BUILDERS; &consvar; in an environment. The &BUILDERS; variable is a Python dictionary - that maps the names by which you want to call various &Builder; - to the &Builder; objects themselves. + that maps the names by which you want to call + various &Builder; objects to the objects themselves. For example, if we want to call the - &Builder; we defined by the name + &Builder; we just defined by the name Foo, our &SConstruct; file might look like: @@ -154,6 +166,16 @@ This functionality could be invoked as in the following example: bld = Builder(action = 'foobuild < $TARGET > $SOURCE') env = Environment(BUILDERS = {'Foo' : bld}) + + + + + With the &Builder; so attached to our &consenv; + we can now actually call it like so: + + + + env.Foo('file.foo', 'file.input') @@ -310,6 +332,7 @@ This functionality could be invoked as in the following example: You can, instead, define a Python function that a &Builder; object can invoke to build your target file (or files). + Such a &buildfunc; definition looks like: @@ -321,8 +344,70 @@ This functionality could be invoked as in the following example: - XXX explain the function - XXX define the arguments + The arguments of a &buildfunc; are: + + + + + + + target + + + + + A list of Node objects representing + the target or targets to be + built by this builder function. + The file names of these target(s) + may be extracted using the Python &str; funcion. + + + + + + + source + + + + + A list of Node objects representing + the sources to be + used by this builder function to build the targets. + The file names of these source(s) + may be extracted using the Python &str; funcion. + + + + + + + env + + + + + The &consenv; used for building the target(s). + The builder function may use any of the + environment's construction variables + in any way to affect how it builds the targets. + + + + + + + + + + The builder function must + return a 0 or None value + if the target(s) are built successfully. + The builder function + may raise an exception + or return any non-zero value + to indicate that the build is unsuccessful, @@ -367,17 +452,120 @@ This functionality could be invoked as in the following example:
- Builders That Generate Actions + Builders That Create Actions Using a &Generator; - X + &SCons; Builder objects can create an action "on the fly" + by using a function called a &generator;. + This provides a great deal of flexibility XXX + A &generator; looks like: - def generate_actions(XXX): + def generate_actions(source, target, env, for_signature): return XXX + + + + + The arguments of a &generator; are: + + + + + + + source + + + + + A list of Node objects representing + the sources to be built + by the command or other action + generated by this function. + The file names of these source(s) + may be extracted using the Python &str; funcion. + + + + + + + + target + + + + + A list of Node objects representing + the target or targets to be built + by the command or other action + generated by this function. + The file names of these target(s) + may be extracted using the Python &str; funcion. + + + + + + + + env + + + + + The &consenv; used for building the target(s). + The generator may use any of the + environment's construction variables + in any way to determine what command + or other action to return. + + + + + + + + for_signature + + + + + A flag that specifies whether the + generator is being called to contribute to a build signature, + as opposed to actually executing the command. + + XXX + + + + + + + + + + + The &generator; must return a + command string or other action that will be used to + build the specified target(s) from the specified source(s). + + + + + + Once you've defined a &generator;, + you create a &Builder; to use it + by specifying the generator keyword argument + instead of action. + + + + bld = Builder(generator = generate_actions, suffix = '.foo', src_suffix = '.input') @@ -403,11 +591,12 @@ This functionality could be invoked as in the following example:
- Builders That Modify the Target List + Builders That Modify the Target or Source Lists Using an &Emitter; - X + &SCons; supports the ability for a Builder to modify the + lists of target(s) from the specified source(s). @@ -451,7 +640,7 @@ This functionality could be invoked as in the following example: - X + XXX diff --git a/doc/user/caching.sgml b/doc/user/caching.sgml index ed72c1e0..3d9158ef 100644 --- a/doc/user/caching.sgml +++ b/doc/user/caching.sgml @@ -85,6 +85,8 @@ cc -c hello.c -o hello.o cc -o hello hello.o % scons -c + Removed hello.o + Removed hello % scons Retrieved `hello.o' from cache Retrieved `hello' from cache diff --git a/doc/user/cons.sgml b/doc/user/cons.sgml index 448777f1..f83ab639 100644 --- a/doc/user/cons.sgml +++ b/doc/user/cons.sgml @@ -25,16 +25,16 @@ - X + XXX
- X + XXX - X + XXX diff --git a/doc/user/default.sgml b/doc/user/default.sgml index 981ac426..f44719f9 100644 --- a/doc/user/default.sgml +++ b/doc/user/default.sgml @@ -87,7 +87,7 @@ default list. This &SConstruct; file knows how to build two programs, &hello; and &goodbye;, but only builds the - &hello program by default: + &hello; program by default: diff --git a/doc/user/depends.sgml b/doc/user/depends.sgml index bc466181..fbbb54ae 100644 --- a/doc/user/depends.sgml +++ b/doc/user/depends.sgml @@ -25,8 +25,6 @@ - -
- Time Stamps - - - - X - - - -
- -
- The &SourceSignature; Method - - - - X - - - -
diff --git a/doc/user/environments.sgml b/doc/user/environments.sgml index 77d9c6b9..d3c3b0cd 100644 --- a/doc/user/environments.sgml +++ b/doc/user/environments.sgml @@ -452,18 +452,20 @@ environment undisturbed. - So far, we've always created a &consenv; named + So far, + all of our examples have + created a single &consenv; named env. env, however, is simply a Python variable name, - and you can use any other variable name that we like. + and you can use any other variable name that you like. For example: my_env = Environment(CC = 'gcc', - CCFLAGS = '-O2') + CCFLAGS = '-O2') my_env.Program('foo.c') @@ -535,7 +537,7 @@ environment undisturbed. -O2 and one with a &CCFLAGS; value of -g. - To work around this, + To avoid this problem, we must explicitly specify that each environment compile foo.c @@ -566,7 +568,7 @@ environment undisturbed. This avoids having to specify explicitly the object file name in multiple places, and makes for a compact, readable - &SConstruct file. + &SConstruct; file. Our &SCons; output then looks like: @@ -586,8 +588,8 @@ environment undisturbed. - Sometimes you want to more than one &consenv; - to use the same values for one or more variables. + Sometimes you want more than one &consenv; + to share the same values for one or more variables. Rather than always having to repeat all of the common variables when you create each &consenv;, you can use the &Copy; method diff --git a/doc/user/errors.sgml b/doc/user/errors.sgml index 448777f1..f83ab639 100644 --- a/doc/user/errors.sgml +++ b/doc/user/errors.sgml @@ -25,16 +25,16 @@ - X + XXX
- X + XXX - X + XXX diff --git a/doc/user/example.sgml b/doc/user/example.sgml index 448777f1..f83ab639 100644 --- a/doc/user/example.sgml +++ b/doc/user/example.sgml @@ -25,16 +25,16 @@ - X + XXX
- X + XXX - X + XXX diff --git a/doc/user/hierarchy.sgml b/doc/user/hierarchy.sgml index 617eb592..e39da8f2 100644 --- a/doc/user/hierarchy.sgml +++ b/doc/user/hierarchy.sgml @@ -274,7 +274,7 @@ make no difference to the build. - X + XXX @@ -290,7 +290,7 @@ make no difference to the build. - X + XXX @@ -304,7 +304,7 @@ make no difference to the build. - X + XXX @@ -320,7 +320,7 @@ make no difference to the build. - X + XXX @@ -336,7 +336,7 @@ make no difference to the build. - X + XXX diff --git a/doc/user/install.sgml b/doc/user/install.sgml index 2cebbd45..7f522e56 100644 --- a/doc/user/install.sgml +++ b/doc/user/install.sgml @@ -72,7 +72,7 @@ should be installed. This is an area where the &Alias; function comes in handy, - allowing you, if you wish, + allowing you, for example, to create a pseudo-target named install that can expand to the specified destination directory: @@ -104,7 +104,7 @@ You can install multiple files into a directory - simploy by calling the &Install; function multiple times: + simply by calling the &Install; function multiple times: diff --git a/doc/user/libraries.sgml b/doc/user/libraries.sgml new file mode 100644 index 00000000..ea41f5d6 --- /dev/null +++ b/doc/user/libraries.sgml @@ -0,0 +1,250 @@ + + + + + One of the more useful ways in which you can use multiple + construction environments is to link programs + with different sets of libraries. + + + +
+ Building Libraries + + + + You build your own libraries by specifying &Library; + instead of &Program;: + + + + + env = Environment() + env.Library('foo', ['f1.c', 'f2.c', 'f3.c']) + + + + + &SCons; uses the appropriate library prefix and suffix for your system. + So on POSIX or Linux systems, + the above example would build as follows + (although &ranlib may not be called on all systems): + + + + + % scons + cc -c f1.c -o f1.o + cc -c f2.c -o f2.o + cc -c f3.c -o f3.o + ar r libfoo.a f1.o f2.o f3.o + ranlib libfoo.a + + + + + On a Windows system, + a build of the above example would look like: + + + + + C:\>scons + cl /Fof1.obj f1.c + cl /Fof2.obj f2.c + cl /Fof3.obj f3.c + lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj + + + + + The rules for the target name of the library + are similar to those for programs: + if you don't explicitly specify a target library name, + &SCons; will deduce one from the + name of the first source file specified, + and &SCons; will add an appropriate + file prefix and suffix if you leave them off. + + + +
+ +
+ Linking with Libraries + + + + Usually, the goal of building a library + is to link it with one or more programs. + You link libraries with a program by specifying + the libraries in the &LIBS; construction variable, + and by specifying the directory in which + the library will be found in the + &LIBPATH; construction variable: + + + + + env = Environment(LIBS = 'foo', LIBPATH = '.') + env.Library('foo', ['f1.c', 'f2.c', 'f3.c']) + env.Program('prog.c') + + + + + Notice, of course, that you don't need to specify a library + prefix (like lib) + or suffix (like .a or .lib). + &SCons; uses the correct prefix or suffix for the current system. + + + + + + On a POSIX or Linux system, + a build of the above example would look like: + + + + + % scons + cc -c f1.c -o f1.o + cc -c f2.c -o f2.o + cc -c f3.c -o f3.o + ar r libfoo.a f1.o f2.o f3.o + ranlib libfoo.a + cc -c prog.c -o prog.o + cc -o prog -L. -lfoo prog.o + + + + + On a Windows system, + a build of the above example would look like: + + + + + C:\>scons + cl /Fof1.obj f1.c + cl /Fof2.obj f2.c + cl /Fof3.obj f3.c + lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj + cl /Foprog.obj prog.c + link /OUT:prog.exe /LIBPATH:. foo.lib prog.obj + + + + + As usual, notice that &SCons; has taken care + of constructing the correct command lines + to link with the specified library on each system. + + + +
+ +
+ Finding Libraries: the &LIBPATH; Construction Variable + + + + By default, the linker will only look in + certain system-defined directories for libraries. + &SCons; knows how to look for libraries + in directories that you specify with the + &LIBPATH; construction variable. + &LIBPATH; consists of a list of + directory names, like so: + + + + + env = Environment(LIBS = 'm', + LIBPATH = ['/usr/lib', '/usr/local/lib']) + env.Program('prog.c') + + + + + Using a Python list is preferred because it's portable + across systems. Alternatively, you could put all of + the directory names in a single string, separated by the + system-specific path separator character: + a colon on POSIX systems: + + + + + LIBPATH = '/usr/lib:/usr/local/lib' + + + + + or a semi-colon on Windows systems: + + + + + LIBPATH = 'C:\lib;D:\lib' + + + + + On a POSIX or Linux system, + a build of the above example would look like: + + + + + % scons + cc -c prog.c -o prog.o + cc -o prog -L/usr/lib -L/usr/local/lib -lm prog.o + + + + + On a Windows system, + a build of the above example would look like: + + + + + C:\>scons + cl /Foprog.obj prog.c + link /nologo /OUT:program.exe /LIBPATH:\usr\lib;\usr\local\lib m.lib prog.obj + + + + + Note again that &SCons; has taken care of + the system-specific details of creating + the right command-line options. + + + +
diff --git a/doc/user/main.sgml b/doc/user/main.sgml index 9ea4dd5a..12b0480b 100644 --- a/doc/user/main.sgml +++ b/doc/user/main.sgml @@ -34,9 +34,11 @@ - + + + + - @@ -47,6 +49,7 @@ + @@ -102,6 +105,11 @@ &environments; + + Building and Linking with Libraries + &libraries; + + Dependencies &depends; @@ -142,14 +150,19 @@ &variants; - - Writing Builders - &builders; + + Built-In Builders + &builders-built-in; + + + + Writing Your Own Builders + &builders-writing; - - Not Writing a Builder (for One-Time Builds) - &command; + + Not Writing a Builder: The &Command; Builder + &builders-commands; @@ -222,4 +235,9 @@ &cons; + + Converting From Ant + &ant; + + diff --git a/doc/user/make.sgml b/doc/user/make.sgml index 5666ea64..c7ecc630 100644 --- a/doc/user/make.sgml +++ b/doc/user/make.sgml @@ -94,16 +94,16 @@ the makefiles. - X + XXX
- X + XXX - X + XXX diff --git a/doc/user/preface.sgml b/doc/user/preface.sgml index 82ea44a1..bba7f49d 100644 --- a/doc/user/preface.sgml +++ b/doc/user/preface.sgml @@ -23,63 +23,182 @@ --> - + - X + XXX - + -
- Why &SCons;? +
+ Why &SCons;? - + - X + XXX - + -
+
-
- History +
+ &SCons; Principles - + - X + By default, &SCons; guarantees a correct build + regardless of what end case you may have. - + -
+ -
- Conventions + &SCons; makes it easy to speed up the build through + optimization options that trade off + guaranteed correctness for speed. - + - X + - + &SCons; tries to do as much for you out of the box as reasonable. -
+
-
- Acknowledgements +
- +
+ History - X + - + &SCons; originated with a design + that was submitted to the Software Carpentry + design competition in 2000. -
+
-
- Contact + - + &SCons; is the direct descendant + of a Perl utility called &Cons;. + &Cons; in turn based some of its ideas on &Jam;, + a build tool from Perforce Systems. - X + - +
-
+
+ Conventions + + + + XXX + + + +
+ +
+ Acknowledgements + + + + &SCons; would not exist without a lot of help + from a lot of people, + many of whom may not even be aware + that they helped or served as inspiration. + So in no particular order, + and at the risk of leaving out someone: + + + + + + First and foremost, + &SCons; owes a tremendous debt to Bob Sidebotham, + the original author of the classic Perl-based &Cons; tool + which Bob first released to the world back around 1996. + Bob's work on Cons classic provided the underlying architecture + and model of specifying a build configuration + using a real scripting language. + My real-world experience working on Cons + informed many of the design decisions in SCons, + including the improved parallel build support, + making Builder objects easily definable by users, + and separating the build engine from the wrapping interface. + + + + + + Greg Wilson was instrumental in getting + &SCons; started as a real project + when he initiated the Software Carpentry design + competition in February 2000. + Without that nudge, + marrying the advantages of the Cons classic + architecture with the readability of Python + might have just stayed no more than a nice idea. + + + + + + The entire &SCons; team have been + absolutely wonderful to work with, + and &SCons; would be nowhere near as useful a + tool without the energy, enthusiasm + and time people have contributed over the past few years. + The "core team" + of Chad Austin, Anthony Roach, Charles Crain, and Steve Leblanc + have been great about reviewing my (and other) changes + and catching problems before they get in the code base. + Technically, + Anthony's outstanding and innovative work on the tasking engine + has given &SCons; a vastly superior parallel build model, + and Charles has been the master of the crucial Node infrastructure. + &SCons; has received contributions + from many other people, of course: + Matt Balvin (extending long command-line support on Win32), + Michael Cook (avoiding losing signal bits from executed commands), + Derrick 'dman' Hudson (), + Alex Jacques (work on the Win32 scons.bat file), + Stephen Kennedy (performance enhancements), + Lachlan O'Dea (SharedObject() support for masm + and normalized paths for the WhereIs() function), + Jeff Petkau (fixes for CacheDir and other areas), + Zed Shaw (Append() and Replace() environment methods), + Terrel Shumway (build and test fixes, as well as the SCons Wiki), + sam th (dynamic checks for utilities) + and Moshe Zadke (Debian packaging). + + + + + + Thanks to Peter Miller + for his splendid change management system, &Aegis;, + which has provided the &SCons; project + with a robust development methodology from day one, + and which showed me how you could + integrate incremental regression tests into + a practical development cycle + (years before eXtreme Programming arrived on the scene). + + + +
+ +
+ Contact + + + + The best way to contact people involved with SCons, + including the author, + is through the SCons mailing lists. + + + +
diff --git a/doc/user/repositories.sgml b/doc/user/repositories.sgml index 616e9031..07af1156 100644 --- a/doc/user/repositories.sgml +++ b/doc/user/repositories.sgml @@ -288,7 +288,7 @@ subdirectories under the repository tree. about the pathname of the repository? To solve this problem, &SCons; allows you to specify repository directories - on the command line using the -Y: + on the command line using the -Y option: diff --git a/doc/user/run.sgml b/doc/user/run.sgml index 30b61ca5..83ca3d2d 100644 --- a/doc/user/run.sgml +++ b/doc/user/run.sgml @@ -266,48 +266,6 @@ rebuilt, if necessary, and then installed there. Note that C might build files that C 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 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, 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 directory or the F 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 can be used to reduce @@ -351,52 +309,56 @@ do an unconstrained build before committing the integration). --> - + + + XXX + + - X +
+ Selective Builds - + -
- Selective Builds + XXX - + - X +
-
+ -
- Overriding Construction Variables +
+ Overriding Construction Variables - + - X + XXX - + -
+
-
- The &SCONSFLAGS; Environment Variable +
+ The &SCONSFLAGS; Environment Variable - + - X + XXX - + -
+
diff --git a/doc/user/scanners.sgml b/doc/user/scanners.sgml index 8d13b0c1..76b2a1af 100644 --- a/doc/user/scanners.sgml +++ b/doc/user/scanners.sgml @@ -123,16 +123,16 @@ over the file scanning rather than being called for each input line: - X + XXX
- X + XXX - X + XXX diff --git a/doc/user/separate.sgml b/doc/user/separate.sgml index 21fcabc3..ac3c0f33 100644 --- a/doc/user/separate.sgml +++ b/doc/user/separate.sgml @@ -110,228 +110,322 @@ program using the F 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 - build directories - that are used to hold the built objects files, libraries, - and executable programs, etc. - for a specific flavor of build. - &SCons; provides two ways of doing this, - one with a little more flexibility. + 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 + build directories + 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. - + -
- The &BuildDir; Function +
+ Specifying a Build Directory as Part of an &SConscript; Call - + - Use the &BuildDir; function to establish that target - files should be built in a separate directory - from the source files: + 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: - + - - BuildDir('build', 'src') - env = Environment() - env.Program('build/hello.c') - + + SConscript('src/SConscript', build_dir='build') + - + - Note that XXX + &SCons; will then build all of the files in + the &build; subdirectory: - + - - % ls src - hello.c - % scons - cc -c build/hello.c -o build/hello.o - cc -o build/hello build/hello.o - % ls -1 build - hello - hello.c - hello.o - + + % ls -1 src + SConscript + hello.c + % scons + cc -c build/hello.c -o build/hello.o + cc -o build/hello build/hello.o + % ls -1 build + hello + hello.c + hello.o + -
+ -
- Avoiding Duplicate Source Files in the Build Directory + But wait a minute--what's going on here? + &SCons; created the object file + build/hello.o + in the &build; subdirectory, + as expected. + But even though our &hello_c; file lives in the &src; subdirectory, + &SCons; has actually compiled a + build/hello.c file + to create the object file. - + - X + - + What's happened is that &SCons; has duplicated + 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. - - BuildDir('build', 'src', duplicate=0) - env = Environment() - env.Program('build/hello.c') - + - +
- X +
+ Why &SCons; Duplicates Source Files in a Build Directory - + - - % ls -1 src - hello.c - % scons - cc -c src/hello.c -o build/hello.o - cc -o build/hello build/hello.o - % ls -1 build - hello - hello.o - + &SCons; duplicates source files in build directories + because it's the most straightforward way to guarantee a correct build + regardless of include-file directory paths, + 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: - + - X + - + XXX -
+
-
- Why &SCons; Duplicates Source Files by Default + + env = Environmnet() + - + - X + XXX - + - - env = Environmnet() - + + % scons + cc -c build/hello.c -o build/hello.o + cc -o build/hello build/hello.o + - +
- X +
+ Telling &SCons; to Not Duplicate Source Files in the Build Directory - + - - % scons - cc -c build/hello.c -o build/hello.o - cc -o build/hello build/hello.o - + In most cases, however, + having &SCons; place its target files in a build subdirectory + without + duplicating the source files works just fine. + You can disable the default &SCons; behavior + by specifying duplicate=0 + when you call the &SConscript; function: -
+ -
- Using &BuildDir; With an &SConscript; File + + SConscript('src/SConscript', build_dir='build', duplicate=0) + - + - X + 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: - + - - env = Environment() - env.Program('hello.c') - + + % ls -1 src + SConscript + hello.c + % scons + cc -c src/hello.c -o build/hello.o + cc -o build/hello build/hello.o + % ls -1 build + hello + hello.o + - +
- X +
+ The &BuildDir; Function - + - - BuildDir('build', 'src') - SConscript('build/SConscript') - + Use the &BuildDir; function to establish that target + files should be built in a separate directory + from the source files: - + - X + + BuildDir('build', 'src') + env = Environment() + env.Program('build/hello.c') + - + - - % ls -1 src - SConscript - hello.c - % scons - cc -c build/hello.c -o build/hello.o - cc -o build/hello build/hello.o - % ls -1 build - hello - hello.c - hello.o - + 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 build/hello.c + file that &SCons; will duplicate in the + &build; subdirectory. -
+ -
- Specifying a Build Directory as Part of an &SConscript; Call + - + XXX - X + - + - - SConscript('src/SConscript', build_dir='build') - + When using the &BuildDir; function directly, + &SCons; still duplicates the source files + in the build directory by default: - + - X + + % ls src + hello.c + % scons + cc -c build/hello.c -o build/hello.o + cc -o build/hello build/hello.o + % ls -1 build + hello + hello.c + hello.o + - + - - % ls -1 src - SConscript - hello.c - % scons - cc -c build/hello.c -o build/hello.o - cc -o build/hello build/hello.o - % ls -1 build - hello - hello.c - hello.o - + You can specify the same duplicate=0 argument + that you can specify for an &SConscript; call: - + - X + + BuildDir('build', 'src', duplicate=0) + env = Environment() + env.Program('build/hello.c') + - + - - SConscript('src/SConscript', build_dir='build', duplicate=0) - + In which case &SCons; + will disable duplication of the source files: - + - X + + % ls src + hello.c + % scons + cc -c src/hello.c -o build/hello.o + cc -o build/hello build/hello.o + % ls -1 build + hello + hello.o + - +
- - % ls -1 src - SConscript - hello.c - % scons - cc -c src/hello.c -o build/hello.o - cc -o build/hello build/hello.o - % ls -1 build - hello - hello.o - +
+ Using &BuildDir; With an &SConscript; File -
+ + + Even when using the &BuildDir; function, + it's much more natural to use it with + a subsidiary &SConscript; file. + For example, if the + src/SConscript + looks like this: + + + + + env = Environment() + env.Program('hello.c') + + + + + Then our &SConscript; file could look like: + + + + + BuildDir('build', 'src') + SConscript('build/SConscript') + + + + + Yielding the following output: + + + + + % ls -1 src + SConscript + hello.c + % scons + cc -c build/hello.c -o build/hello.o + cc -o build/hello build/hello.o + % ls -1 build + hello + hello.c + hello.o + + + + + Notice that this is completely equivalent + to the use of &SConscript; that we + learned about in the previous section. + + + +
+ +
+ Why You'd Want to Call &BuildDir; Instead of &SConscript; + + + + XXX + + + +
diff --git a/doc/user/simple.sgml b/doc/user/simple.sgml index 2acd669e..8f76f2aa 100644 --- a/doc/user/simple.sgml +++ b/doc/user/simple.sgml @@ -43,7 +43,7 @@ requirements of a build. - Here's how to build the famous "Hello, World!" example using &SCons;. + Here's the famous "Hello, World!" program in C: @@ -57,7 +57,8 @@ requirements of a build. - Enter the following into a file name &SConstruct;: + And here's how to build it using &SCons;. + Enter the following into a file named &SConstruct;: @@ -144,7 +145,7 @@ requirements of a build. What may not be obvious, though, is that there's an important difference between - an &SConstruct; file and a &Makefile: + an &SConstruct; file and a &Makefile;: the &SConstruct; file is actually a Python script. If you're not already familiar with Python, don't worry; Python is very easy to learn, @@ -193,29 +194,58 @@ requirements of a build. To do this, you need to put the source files in a Python list (enclosed in square brackets), - and slide that list over to to the right - to make room for the output program file name. - For example: + like so: env = Environment() - env.Program('program', ['main.c', 'file1.c', 'file2.']) + env.Program(['prog.c', 'file1.c', 'file2.']) + A build of the above example would look like: + + + + + % scons + cc -c file1.c -o file1.o + cc -c file2.c -o file2.o + cc -c prog.c -o prog.o + cc -o prog prog.o file1.o file2.o + + + + + Notice that &SCons; + deduces the output program name + from the first source file specified + in the list--that is, + because the first source file was &prog_c;, + &SCons; will name the resulting program &prog; + (or &prog_exe; on a Windows system). + If you want to specify a different program name, + then you slide the list of source files + over to the right + to make room for the output program file name. (&SCons; puts the output file name to the left of the source file names so that the order mimics that of an assignment statement: "program = source files".) + This makes our example: + + env = Environment() + env.Program('program', ['main.c', 'file1.c', 'file2.']) + + - A build of the above example would look: + On Linux, a build of this example would look like: @@ -227,11 +257,7 @@ requirements of a build. cc -o program main.o file1.o file2.o - -
@@ -260,8 +284,8 @@ requirements of a build. (either single quotes or double quotes). This can get cumbersome and difficult to read when the list of file names is long. - Fortunately, there are a number of things - we can do to make sure that + Fortunately, &SCons; and Python provide a number of ways + to make sure that the &SConstruct; file stays easy to read. @@ -363,7 +387,7 @@ requirements of a build. In order to compile multiple programs within the same &SConstruct; file, - simply call env.Program + simply call the env.Program method multiple times, once for each program you need to build: @@ -390,6 +414,19 @@ requirements of a build. cc -o foo foo.o + + + Notice that &SCons; does not necessarily build the + programs in the same order in which you specify + them in the &SConstruct; file. + &SCons; does, however, recognize that + the individual object files must be built + before the resulting program can be built. + We'll discuss this in greater detail in + the "Dependencies" section, below. + + +
@@ -397,17 +434,40 @@ requirements of a build. - XXX + It's common to re-use code by sharing source files + between multiple programs. + One way to do this is to create a library + from the common source files, + which can then be linked into resulting programs. + (Creating libraries is discussed in + section XXX, below.) + + + + + + A more straightforward, but perhaps less convenient, + way to share source files between multiple programs + is to simply include the common source files + when listing the source files for each program: - common = ['common1.c', 'common2.c'] env = Environment() - env.Program(['foo.c'] + common) - env.Program('bar', ['bar1.c', 'bar2.c'] + common) + env.Program(Split('foo.c common1.c common2.c')) + env.Program('bar', Split('bar1.c bar2.c common1.c common2.c')) + + + &SCons; recognizes that the object files for + the &common1_c; and &common2_c; source files + each only need to be built once, + even though the files are listed multiple times: + + + % scons cc -c bar1.c -o bar1.o @@ -419,4 +479,33 @@ requirements of a build. cc -o foo foo.o common1.o common2.o + + + If two or more programs + share a lot of common source files, + repeating the common files in the list for each program + a maintenance problem if you need to change the + list of common files. + You can simplify this by creating a separate Python list + to hold the common file names, + and concatenating it with other lists + using the Python &+; operator: + + + + + common = ['common1.c', 'common2.c'] + foo_files = ['foo.c'] + common + bar_files = ['bar1.c', 'bar2.c'] + common + env = Environment() + env.Program('foo', foo_files) + env.Program('bar', bar_files) + + + + + This is functionally equivalent to the previous example. + + +
diff --git a/doc/user/sourcecode.sgml b/doc/user/sourcecode.sgml index 4ee49d44..6bbcceed 100644 --- a/doc/user/sourcecode.sgml +++ b/doc/user/sourcecode.sgml @@ -44,7 +44,7 @@ env = Environment() - env.SourceCode('.', env.BitKeeper('XXX') + env.SourceCode('.', env.BitKeeper('XXX')) env.Program('hello.c') @@ -66,7 +66,7 @@ env = Environment() - env.SourceCode('.', env.CVS('XXX') + env.SourceCode('.', env.CVS('XXX')) env.Program('hello.c') @@ -88,7 +88,7 @@ env = Environment() - env.SourceCode('.', env.RCS() + env.SourceCode('.', env.RCS()) env.Program('hello.c') @@ -110,7 +110,7 @@ env = Environment() - env.SourceCode('.', env.SCCS() + env.SourceCode('.', env.SCCS()) env.Program('hello.c') @@ -132,7 +132,7 @@ env = Environment() - env.SourceCode('.', env.Subversion('XXX') + env.SourceCode('.', env.Subversion('XXX')) env.Program('hello.c') diff --git a/doc/user/troubleshoot.sgml b/doc/user/troubleshoot.sgml index 448777f1..f83ab639 100644 --- a/doc/user/troubleshoot.sgml +++ b/doc/user/troubleshoot.sgml @@ -25,16 +25,16 @@ - X + XXX
- X + XXX - X + XXX diff --git a/doc/user/variants.sgml b/doc/user/variants.sgml index 6ad93609..09dd16d1 100644 --- a/doc/user/variants.sgml +++ b/doc/user/variants.sgml @@ -107,40 +107,89 @@ is pretty smart about rebuilding things when you change options. --> - - - X - - - -
- X - - - - X - - - - - env = Environment(OS = ARGUMENT['os']) - SConscript('src/SConscript', build_dir='build/$OS') - - - - - X - - - - - env = Environment(OS = ) - for os in ['newell', 'post']: - SConscript('src/SConscript', build_dir='build/' + os) - - - - % scons - - -
+ + + The &BuildDir; function now gives us everything + we need to show how easy it is to create + 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 + with separate side-by-side build directories + for the Windows and Linux versions of the program. + + + + + platform = ARGUMENT.get('OS', Platform()) + + include = "#export/$PLATFORM/include" + lib = "#export/$PLATFORM/lib" + bin = "#export/$PLATFORM/bin" + + env = Environment(PLATFORM = platform, + CPPPATH = [include], + LIB = lib, + LIBS = '-lworld') + + Export('env') + + SConscript('src/SConscript', build_dir='build/$PLATFORM') + + # + #BuildDir("#build/$PLATFORM", 'src') + #SConscript("build/$PLATFORM/hello/SConscript") + #SConscript("build/$PLATFORM/world/SConscript") + + + + + This SConstruct file, + when run on a Linux system, yields: + + + + + $ scons OS=linux + Install build/linux/world/world.h as export/linux/include/world.h + cc -Iexport/linux/include -c build/linux/hello/hello.c -o build/linux/hello/hello.o + cc -Iexport/linux/include -c build/linux/world/world.c -o build/linux/world/world.o + ar r build/linux/world/libworld.a build/linux/world/world.o + ar: creating build/linux/world/libworld.a + ranlib build/linux/world/libworld.a + Install build/linux/world/libworld.a as export/linux/lib/libworld.a + cc -o build/linux/hello/hello build/linux/hello/hello.o -Lexport/linux/lib -lworld + Install build/linux/hello/hello as export/linux/bin/hello + + + + + The same SConstruct file on Windows would build: + + + + + + C:\test\>scons OS=linux + Install build\linux\world\world.h as export\linux\include\world.h + cl /Iexport\linux\include /Fobuild\linux\hello\hello.obj build\linux\hello\hello.c + cl /Iexport\linux\include /Fobuild\linux\world\world.obj build\linux\world\world.c + XXX + ar r build\linux\world\world.lib build\linux\world\world.obj + Install build\linux\world\world.lib as export\linux\lib\libworld.a + link /Fobuild\linux\hello\hello.exe build\linux\hello\hello.obj -Lexport\linux\lib world.lib + Install build\linux\hello\hello.exe as export\linux\bin\hello.exe + + + + env = Environment(OS = ) + for os in ['newell', 'post']: + SConscript('src/SConscript', build_dir='build/' + os) + + + + % scons +