diff options
| author | Steven Knight <knight@baldmt.com> | 2007-08-17 03:17:04 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2007-08-17 03:17:04 (GMT) |
| commit | 8cb34cccc26935bce5d07ed3f51cc29fbbd1ab03 (patch) | |
| tree | 7bc281e44fe45cae35656e0e457fef8f308fbb7b /doc/user/command-line.xml | |
| parent | 5b4b4c6e5384712ab1835bdcf8beea09611b6e62 (diff) | |
| download | SCons-8cb34cccc26935bce5d07ed3f51cc29fbbd1ab03.zip SCons-8cb34cccc26935bce5d07ed3f51cc29fbbd1ab03.tar.gz SCons-8cb34cccc26935bce5d07ed3f51cc29fbbd1ab03.tar.bz2 | |
Merged revisions 2136-2200,2202-2290,2292-2301 via svnmerge from
http://scons.tigris.org/svn/scons/branches/core
........
r2145 | stevenknight | 2007-07-17 09:15:12 -0500 (Tue, 17 Jul 2007) | 3 lines
Don't put null strings (from variable expansion) in a path list.
(They get turned into the current directory on later expansion.)
........
r2146 | stevenknight | 2007-07-17 10:47:39 -0500 (Tue, 17 Jul 2007) | 3 lines
Add support for optional arguments on command-line long options
by specifying nargs='?'.
........
r2149 | stevenknight | 2007-07-17 15:22:24 -0500 (Tue, 17 Jul 2007) | 2 lines
Remove left-over Optik mentions.
........
r2150 | stevenknight | 2007-07-17 15:39:34 -0500 (Tue, 17 Jul 2007) | 4 lines
Add a $SWIGPATH variable for finding SWIG dependencies, with
$SWIGINC{PREFIX,SUFFIX} for adding them to the command line.
........
r2154 | stevenknight | 2007-07-18 20:05:31 -0500 (Wed, 18 Jul 2007) | 2 lines
Fix variable misspellings in the doc added for $SWIGOUTPUT.
........
r2155 | stevenknight | 2007-07-18 20:07:28 -0500 (Wed, 18 Jul 2007) | 2 lines
Add the Python eggs info file to the RPM packaging build.
........
r2156 | stevenknight | 2007-07-18 20:15:08 -0500 (Wed, 18 Jul 2007) | 2 lines
Convert documentation from DocBook SGML to XML.
........
r2158 | stevenknight | 2007-07-19 17:16:19 -0500 (Thu, 19 Jul 2007) | 3 lines
Conditionally add the .egg-info the RPM file list only if the distutils
in the version of Python that rpmbuild will execute knows about them.
........
r2161 | stevenknight | 2007-07-19 19:12:29 -0500 (Thu, 19 Jul 2007) | 5 lines
Capture a test case (contributed by Tilo Prutz) where instantiation of
a private class causes javac to generate an additional anonymous inner
class file. (No solution yet, but there's no sense throwing away the
preparatory work.)
........
r2162 | stevenknight | 2007-07-20 11:29:56 -0500 (Fri, 20 Jul 2007) | 3 lines
Support passing a list of .java files as source to the Java() builder.
(Leanid Nazdrynau)
........
r2163 | garyo | 2007-07-20 12:00:35 -0500 (Fri, 20 Jul 2007) | 1 line
Fixed cut-n-paste error in Touch factory method doc in users guide.
........
r2167 | stevenknight | 2007-07-21 22:59:40 -0500 (Sat, 21 Jul 2007) | 2 lines
Don't execute the SWIGOUTDIR test if swig isn't installed.
........
r2168 | stevenknight | 2007-07-21 23:14:17 -0500 (Sat, 21 Jul 2007) | 2 lines
Fix the test's ability to run under a path name containing spaces.
........
r2171 | stevenknight | 2007-07-24 15:54:41 -0500 (Tue, 24 Jul 2007) | 2 lines
Handle white space in key file names in the packaging build.
........
r2172 | stevenknight | 2007-07-24 21:41:15 -0500 (Tue, 24 Jul 2007) | 2 lines
More efficient copying of construction environments.
........
r2173 | stevenknight | 2007-07-25 10:56:02 -0500 (Wed, 25 Jul 2007) | 2 lines
Update the SCons build for Subversion and general clean-up.
........
r2174 | stevenknight | 2007-07-25 11:35:16 -0500 (Wed, 25 Jul 2007) | 3 lines
Suppress the [brackets] around a node in the --tree=prune output if
the node is a source.
........
r2175 | stevenknight | 2007-07-25 12:52:18 -0500 (Wed, 25 Jul 2007) | 3 lines
Commonize the skip_test() method and make its behavior configurable
via a TESTCOMMON_PASS_SKIPS environment variable.
........
r2178 | stevenknight | 2007-07-25 21:43:47 -0500 (Wed, 25 Jul 2007) | 3 lines
Add $JAVACLASSPATH and $JAVASOURCEPATH construction variables. (Leanid
Nazdrynau)
........
r2182 | stevenknight | 2007-07-30 12:10:20 -0500 (Mon, 30 Jul 2007) | 3 lines
Refactor Builder suffix-adjusting into its own method, so we can
(potentially) re-use it for Builders with attached source Builders.
........
r2183 | stevenknight | 2007-07-30 14:51:53 -0500 (Mon, 30 Jul 2007) | 2 lines
More efficient source-builder suffix matching.
........
r2184 | stevenknight | 2007-07-30 16:01:42 -0500 (Mon, 30 Jul 2007) | 4 lines
Encapsulate initialization of the default FS object by an accessor
function in SCons.Node.FS. (This also gets rid of an unnecessary
reference to SCons.Node.FS.default_fs in the LaTeX scanner.)
........
r2193 | stevenknight | 2007-07-30 18:24:07 -0500 (Mon, 30 Jul 2007) | 3 lines
Fix interpretation of source arguments that have no suffix when the
called Builder has both a src_suffix and a src_builder.
........
r2194 | stevenknight | 2007-07-31 10:25:31 -0500 (Tue, 31 Jul 2007) | 2 lines
Increase the number of tries for random output from three to ten.
........
r2195 | stevenknight | 2007-07-31 10:52:28 -0500 (Tue, 31 Jul 2007) | 3 lines
Skip the test gracefully if the zipfile module can't read the file it
just wrote (which is the case for Python 2.1 on 64-bit systems).
........
r2196 | stevenknight | 2007-07-31 13:06:21 -0500 (Tue, 31 Jul 2007) | 2 lines
Move the "import zipfile" so it doesn't fail on Python <= 2.0.
........
r2197 | stevenknight | 2007-07-31 14:51:50 -0500 (Tue, 31 Jul 2007) | 3 lines
Commonize initialization of the various Java builders so they can be
hooked up into a multi-stage Builder chain. (Leanid Nazdrynau)
........
r2198 | stevenknight | 2007-07-31 16:15:18 -0500 (Tue, 31 Jul 2007) | 3 lines
Fix use of ${TARGET.dir} and ${SOURCE.dir} expansions in $FORTRANMODDIR
$JARCHDIR, $JARFLAGS, $LEXFLAGS, $SWIGFLAGS, $SWIGOUTDIR and $YACCFLAGS.
........
r2199 | stevenknight | 2007-07-31 16:25:48 -0500 (Tue, 31 Jul 2007) | 2 lines
Remove left-over Trace() call.
........
r2202 | stevenknight | 2007-08-01 12:31:48 -0500 (Wed, 01 Aug 2007) | 3 lines
Bail out via test.skip_test() if wix ("candle") isn't found.
Put the main body of code flush left instead of under an if: block.
........
r2203 | stevenknight | 2007-08-01 15:35:55 -0500 (Wed, 01 Aug 2007) | 5 lines
Fix Tool.packaging.rpm.package() so it doesn't always overwrite
$RPMFLAGS with -ta.
Set --buildroot in RPM packaging tests so they don't overwrite
each other when run simultaneously.
........
r2204 | stevenknight | 2007-08-01 15:37:36 -0500 (Wed, 01 Aug 2007) | 2 lines
Fix a nested scope issue with the internal build_sources() function.
........
r2205 | stevenknight | 2007-08-01 15:46:08 -0500 (Wed, 01 Aug 2007) | 5 lines
Normalize (X out) the CreationDate field inside embedded, compressed
PostScript streams within the generated PDF files. Also normalize
preceding Length field, since compression length is affected by different
patterns of input, including the variable CreationDate value.
........
r2211 | stevenknight | 2007-08-02 08:52:06 -0500 (Thu, 02 Aug 2007) | 2 lines
Add the new modules from branches/packaging to the SCons packaging build.
........
r2212 | stevenknight | 2007-08-02 19:59:01 -0500 (Thu, 02 Aug 2007) | 2 lines
Fix the JAVACLASSPATH test when javah isn't on the default $PATH.
........
r2214 | stevenknight | 2007-08-03 15:05:21 -0500 (Fri, 03 Aug 2007) | 4 lines
Hook up the Java builders into a multi-step chain underneath a Java()
pseudo-builder (wrapper) that examines its arguments and calls the
appropriate underlying file-or-dir builder.
........
r2215 | stevenknight | 2007-08-03 15:49:58 -0500 (Fri, 03 Aug 2007) | 2 lines
Fix for old Python versions: use apply() instead of *args, **kw.
........
r2216 | stevenknight | 2007-08-03 16:49:31 -0500 (Fri, 03 Aug 2007) | 2 lines
Hook up the SWIG builder as a source builder for .java files.
........
r2217 | stevenknight | 2007-08-03 17:28:19 -0500 (Fri, 03 Aug 2007) | 2 lines
Don't use .endswith(), which didn't appear until later Python versions.
........
r2218 | stevenknight | 2007-08-03 17:29:38 -0500 (Fri, 03 Aug 2007) | 2 lines
Replace tabs with spaces.
........
r2219 | stevenknight | 2007-08-04 08:06:23 -0500 (Sat, 04 Aug 2007) | 3 lines
Initialize a loop-invariant lambda for matching .java suffixes outside
the loop.
........
r2220 | stevenknight | 2007-08-07 15:06:13 -0500 (Tue, 07 Aug 2007) | 2 lines
Refactor parallel class-generation loops into one.
........
r2221 | stevenknight | 2007-08-07 16:04:06 -0500 (Tue, 07 Aug 2007) | 5 lines
Have the Java multi-step builder test actually check for generated files,
and fix the generation of .java and .class file names, and interaction
with the SWIG builder, so that the files are generated in the correct
place.
........
r2222 | stevenknight | 2007-08-07 16:45:05 -0500 (Tue, 07 Aug 2007) | 3 lines
Fix dependencies on SWIG-generated .java files so they don't have to
be built in multiple passes.
........
r2226 | stevenknight | 2007-08-07 18:00:22 -0500 (Tue, 07 Aug 2007) | 2 lines
Fix SWIG when used with BuildDir().
........
r2227 | stevenknight | 2007-08-07 22:15:55 -0500 (Tue, 07 Aug 2007) | 5 lines
User's guide updates:
- Make the multiple files example match its text.
- Expand a truncated sentence about being able to use Python function actions
in the Command() Builder.
........
r2228 | stevenknight | 2007-08-07 23:25:18 -0500 (Tue, 07 Aug 2007) | 3 lines
Don't generate an error if a #include file matches a same-named
directory in $CPPPATH (or $FORTRANPATH, etc.).
........
r2229 | stevenknight | 2007-08-07 23:40:00 -0500 (Tue, 07 Aug 2007) | 2 lines
Fix a code example. (Gary Oberbrunner)
........
r2230 | stevenknight | 2007-08-08 00:05:43 -0500 (Wed, 08 Aug 2007) | 3 lines
Capture a test case to make sure AddPostAction() doesn't interfere
with normal linking. (Matt Doar, Gary Oberbrunner)
........
r2233 | stevenknight | 2007-08-08 14:15:44 -0500 (Wed, 08 Aug 2007) | 2 lines
Fix documentation typo in a construction variable cross-reference.
........
r2234 | stevenknight | 2007-08-08 17:03:25 -0500 (Wed, 08 Aug 2007) | 2 lines
Changes to SCons packaging to support checkpoint releases.
........
r2235 | stevenknight | 2007-08-09 10:10:01 -0500 (Thu, 09 Aug 2007) | 2 lines
Sidestep false negatives on heavily loaded systems.
........
r2236 | garyo | 2007-08-09 11:16:26 -0500 (Thu, 09 Aug 2007) | 1 line
Allow unpackaged files (e.g. *.pyo) to exist in the build dir without being packaged in the RPM. Without this, on some systems the rpmbuild may error out.
........
r2237 | stevenknight | 2007-08-09 11:27:56 -0500 (Thu, 09 Aug 2007) | 5 lines
Fix test/SWIG/build-dir.py so it works on old Python versions without
distutils.sysconfig.
Instead of just cutting-and-pasting initialization code from other
SWIG tests, centralize it in some new TestSCons methods.
........
r2238 | garyo | 2007-08-09 11:30:58 -0500 (Thu, 09 Aug 2007) | 1 line
Use docbook 4.3 instead of 4.4 for the XML doctype since some older(?) jade parsers can't handle new 4-byte Unicode chars in the 4.4 version of isogrk4.ent.
........
r2240 | stevenknight | 2007-08-09 16:35:06 -0500 (Thu, 09 Aug 2007) | 2 lines
User's Guide updates (post packaging changes).
........
r2243 | stevenknight | 2007-08-10 10:31:51 -0500 (Fri, 10 Aug 2007) | 3 lines
Fix the User's Guide build to use openjade, and to accomodate a change
in the name of the main generated file (book1.html => index.html).
........
r2245 | stevenknight | 2007-08-10 11:09:16 -0500 (Fri, 10 Aug 2007) | 2 lines
Update the {CHANGES,RELEASE}.txt datestamp lines.
........
r2253 | stevenknight | 2007-08-10 16:21:54 -0500 (Fri, 10 Aug 2007) | 2 lines
Fix the wix Tool module's ability to handle null entries in $PATH.
........
r2261 | stevenknight | 2007-08-11 23:08:12 -0500 (Sat, 11 Aug 2007) | 3 lines
Remove unnecessary files (.svnt/*, .{ae,cvs}ignore, www/*) from the
scons-src packages.
........
r2262 | stevenknight | 2007-08-11 23:24:49 -0500 (Sat, 11 Aug 2007) | 2 lines
Add missing __revision__ lines.
........
r2263 | stevenknight | 2007-08-11 23:33:42 -0500 (Sat, 11 Aug 2007) | 2 lines
Skip the test if the MANIFEST file hasn't been built.
........
r2264 | stevenknight | 2007-08-11 23:36:30 -0500 (Sat, 11 Aug 2007) | 2 lines
Add recent compatibility modules to the relevant exceptions lists.
........
r2265 | stevenknight | 2007-08-11 23:39:00 -0500 (Sat, 11 Aug 2007) | 3 lines
Update __VERSION__ strings in the QMTest/*.py modules, so that packaging
tests (src/test_*.py) will pass after builds of checkpoint releases.
........
r2266 | stevenknight | 2007-08-12 07:36:19 -0500 (Sun, 12 Aug 2007) | 2 lines
Add a comment about why we construct the __VERSION__ string at run time.
........
r2267 | stevenknight | 2007-08-12 07:42:30 -0500 (Sun, 12 Aug 2007) | 2 lines
Avoid reading the MANIFEST file twice. (Courtesy review by Greg Noel.)
........
r2268 | stevenknight | 2007-08-12 08:14:53 -0500 (Sun, 12 Aug 2007) | 3 lines
Shift Install() and InstallAs() from being documented as functions
to being documented as Builders.
........
r2269 | garyo | 2007-08-13 08:49:52 -0500 (Mon, 13 Aug 2007) | 1 line
Tests: Skip some more Java tests if javac is not installed on the test machine so they don't get marked as failing.
........
r2270 | garyo | 2007-08-13 11:09:39 -0500 (Mon, 13 Aug 2007) | 1 line
Fixed typo in test (shows up on non-Linux platforms).
........
r2271 | garyo | 2007-08-13 14:09:05 -0500 (Mon, 13 Aug 2007) | 4 lines
Test portability fixes for Darwin/OSX and IRIX.
This does not make all the tests pass on those OSes,
but it takes care of some of the more obvious errors that
I have time for right now. More to come.
........
r2272 | stevenknight | 2007-08-13 15:33:29 -0500 (Mon, 13 Aug 2007) | 2 lines
Tab => space fix.
........
r2273 | stevenknight | 2007-08-13 15:33:52 -0500 (Mon, 13 Aug 2007) | 2 lines
Test for swig, too, which is used to build from the .i file.
........
r2277 | garyo | 2007-08-14 10:40:00 -0500 (Tue, 14 Aug 2007) | 8 lines
Test portability on IRIX: test/Actions/pre-post creates target file
before building target, then IRIX CC does not chmod +x afterwards.
I think this change is safe on all OSes.
test/AS/ml.py: I think this is only supposed to be run on win32
(not skipped only on win32); the sense of the skip test was backwards.
........
r2278 | stevenknight | 2007-08-14 11:04:40 -0500 (Tue, 14 Aug 2007) | 2 lines
Add -tt when running tests, to catch inconsistent tab usage.
........
r2279 | stevenknight | 2007-08-14 14:00:43 -0500 (Tue, 14 Aug 2007) | 2 lines
Minor refactor of logic in File.retrieve_from_cache().
........
r2280 | stevenknight | 2007-08-15 01:11:40 -0500 (Wed, 15 Aug 2007) | 2 lines
Refactor CacheDir support into its own module.
........
r2281 | stevenknight | 2007-08-15 07:24:51 -0500 (Wed, 15 Aug 2007) | 2 lines
Move the cachepath() method from FS.File to the CacheDir class.
........
r2282 | stevenknight | 2007-08-15 08:31:34 -0500 (Wed, 15 Aug 2007) | 2 lines
Python 1.5.2 fix in the new Null class.
........
r2283 | stevenknight | 2007-08-15 10:45:53 -0500 (Wed, 15 Aug 2007) | 5 lines
Refactor CacheDir unit tests to:
- restore functionality that was dropped in the transition;
- commonize creation of test Nodes and other (mock) objects
- separate CacheDir tests from tests of CacheDir through Node.FS.File.
........
r2284 | stevenknight | 2007-08-15 11:46:38 -0500 (Wed, 15 Aug 2007) | 3 lines
Replace the Executor.Null.NullEnvironment object with a real Null object,
so it will absorb the CacheDir method calls as well.
........
r2285 | stevenknight | 2007-08-15 11:52:57 -0500 (Wed, 15 Aug 2007) | 5 lines
Add a get_CacheDir() method to a construction environment, which will
be used to fetch per-environment CacheDir specifications. (Right now
all calls to it still just return the one attached to underlying default
FS object.)
........
r2286 | stevenknight | 2007-08-15 15:15:46 -0500 (Wed, 15 Aug 2007) | 2 lines
Support per-construction-environment configuration of CacheDir().
........
r2287 | stevenknight | 2007-08-15 15:33:04 -0500 (Wed, 15 Aug 2007) | 2 lines
Move the tests of CacheDir()-related command-line options into test/CacheDir.
........
r2293 | stevenknight | 2007-08-16 11:14:49 -0500 (Thu, 16 Aug 2007) | 3 lines
Add the Package() builder description to the documentation build,
fixing the XML so that it will build.
........
r2294 | stevenknight | 2007-08-16 12:51:19 -0500 (Thu, 16 Aug 2007) | 3 lines
Reorganize packaging documentation: alphabetize the variable definitions
(and function names), document Tag() as a function, not a builder.
........
r2296 | stevenknight | 2007-08-16 12:55:01 -0500 (Thu, 16 Aug 2007) | 2 lines
Add a build command.
........
r2300 | stevenknight | 2007-08-16 16:49:13 -0500 (Thu, 16 Aug 2007) | 2 lines
First cut at documenting packaging variables.
........
r2301 | stevenknight | 2007-08-16 16:51:21 -0500 (Thu, 16 Aug 2007) | 3 lines
Construct the .src.rpm and .arch.rpm file names independnetly, not
by trying to massage one into the other.
........
Diffstat (limited to 'doc/user/command-line.xml')
| -rw-r--r-- | doc/user/command-line.xml | 1486 |
1 files changed, 1486 insertions, 0 deletions
diff --git a/doc/user/command-line.xml b/doc/user/command-line.xml new file mode 100644 index 0000000..d7f3d7b --- /dev/null +++ b/doc/user/command-line.xml @@ -0,0 +1,1486 @@ +<!-- + + __COPYRIGHT__ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--> + + <para> + + &SCons; provides a number of ways that + allow the writer of the &SConscript; files + to give users a great deal of control over how to run the builds. + + </para> + + <section> + <title>Not Having to Specify Command-Line Options Each Time: the &SCONSFLAGS; Environment Variable</title> + + <para> + + Users may find themselves supplying + the same command-line options every time + they run &SCons;. + For example, a user might find that it saves time + to specify a value of <literal>-j 2</literal> + to run the builds in parallel. + To avoid having to type <literal>-j 2</literal> by hand + every time, + you can set the external environment variable + &SCONSFLAGS; to a string containing + command-line options that you want &SCons; to use. + + </para> + + <para> + + If, for example, + and you're using a POSIX shell that's + compatible with the Bourne shell, + and you always want &SCons; to use the + <literal>-Q</literal> option, + you can set the &SCONSFLAGS; + environment as follows: + + </para> + + + + <screen> + % <userinput>scons</userinput> + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + ... [build output] ... + scons: done building targets. + % <userinput>export SCONSFLAGS="-Q"</userinput> + % <userinput>scons</userinput> + ... [build output] ... + </screen> + + <para> + + Users of &csh;-style shells on POSIX systems + can set the &SCONSFLAGS; environment as follows: + + </para> + + <screen> + $ <userinput>setenv SCONSFLAGS "-Q"</userinput> + </screen> + + <para> + + Windows users may typically want to set this + &SCONSFLAGS; in the appropriate tab of the + <literal>System Properties</literal> window. + + </para> + + </section> + + <section> + <title>Getting at Command-Line Targets</title> + + <para> + + &SCons; supports a &COMMAND_LINE_TARGETS; variable + that lets you get at the list of targets that the + user specified on the command line. + You can use the targets to manipulate the + build in any way you wish. + As a simple example, + suppose that you want to print a reminder + to the user whenever a specific program is built. + You can do this by checking for the + target in the &COMMAND_LINE_TARGETS; list: + + </para> + + <programlisting> + if 'bar' in COMMAND_LINE_TARGETS: + print "Don't forget to copy `bar' to the archive!" + Default(Program('foo.c')) + Program('bar.c') + </programlisting> + + <para> + + Then, running &SCons; with the default target + works as it always does, + but explicity specifying the &bar; target + on the command line generates the warning message: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + cc -o foo.o -c foo.c + cc -o foo foo.o + % <userinput>scons -Q bar</userinput> + Don't forget to copy `bar' to the archive! + cc -o bar.o -c bar.c + cc -o bar bar.o + </screen> + + <para> + + Another practical use for the &COMMAND_LINE_TARGETS; variable + might be to speed up a build + by only reading certain subsidiary &SConscript; + files if a specific target is requested. + + </para> + + </section> + + <section> + <title>Controlling the Default Targets</title> + + <para> + + One of the most basic things you can control + is which targets &SCons; will build by default--that is, + when there are no targets specified on the command line. + As mentioned previously, + &SCons; will normally build every target + in or below the current directory + by default--that is, when you don't + explicitly specify one or more targets + on the command line. + Sometimes, however, you may want + to specify explicitly that only + certain programs, or programs in certain directories, + should be built by default. + You do this with the &Default; function: + + </para> + + <programlisting> + env = Environment() + hello = env.Program('hello.c') + env.Program('goodbye.c') + Default(hello) + </programlisting> + + <para> + + This &SConstruct; file knows how to build two programs, + &hello; and &goodbye;, + but only builds the + &hello; program by default: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + cc -o hello.o -c hello.c + cc -o hello hello.o + % <userinput>scons -Q</userinput> + scons: `hello' is up to date. + % <userinput>scons -Q goodbye</userinput> + cc -o goodbye.o -c goodbye.c + cc -o goodbye goodbye.o + </screen> + + <para> + + Note that, even when you use the &Default; + function in your &SConstruct; file, + you can still explicitly specify the current directory + (<literal>.</literal>) on the command line + to tell &SCons; to build + everything in (or below) the current directory: + + </para> + + <screen> + % <userinput>scons -Q .</userinput> + cc -o goodbye.o -c goodbye.c + cc -o goodbye goodbye.o + cc -o hello.o -c hello.c + cc -o hello hello.o + </screen> + + <para> + + You can also call the &Default; + function more than once, + in which case each call + adds to the list of targets to be built by default: + + </para> + + <programlisting> + env = Environment() + prog1 = env.Program('prog1.c') + Default(prog1) + prog2 = env.Program('prog2.c') + prog3 = env.Program('prog3.c') + Default(prog3) + </programlisting> + + <para> + + Or you can specify more than one target + in a single call to the &Default; function: + + </para> + + <programlisting> + env = Environment() + prog1 = env.Program('prog1.c') + prog2 = env.Program('prog2.c') + prog3 = env.Program('prog3.c') + Default(prog1, prog3) + </programlisting> + + <para> + + Either of these last two examples + will build only the + <application>prog1</application> + and + <application>prog3</application> + programs by default: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + cc -o prog1.o -c prog1.c + cc -o prog1 prog1.o + cc -o prog3.o -c prog3.c + cc -o prog3 prog3.o + % <userinput>scons -Q .</userinput> + cc -o prog2.o -c prog2.c + cc -o prog2 prog2.o + </screen> + + <para> + + You can list a directory as + an argument to &Default;: + + </para> + + <programlisting> + env = Environment() + env.Program(['prog1/main.c', 'prog1/foo.c']) + env.Program(['prog2/main.c', 'prog2/bar.c']) + Default('prog1') + </programlisting> + + <para> + + In which case only the target(s) in that + directory will be built by default: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + cc -o prog1/foo.o -c prog1/foo.c + cc -o prog1/main.o -c prog1/main.c + cc -o prog1/main prog1/main.o prog1/foo.o + % <userinput>scons -Q</userinput> + scons: `prog1' is up to date. + % <userinput>scons -Q .</userinput> + cc -o prog2/bar.o -c prog2/bar.c + cc -o prog2/main.o -c prog2/main.c + cc -o prog2/main prog2/main.o prog2/bar.o + </screen> + + <para> + + Lastly, if for some reason you don't want + any targets built by default, + you can use the Python <literal>None</literal> + variable: + + </para> + + <programlisting> + env = Environment() + prog1 = env.Program('prog1.c') + prog2 = env.Program('prog2.c') + Default(None) + </programlisting> + + <para> + + Which would produce build output like: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + scons: *** No targets specified and no Default() targets found. Stop. + % <userinput>scons -Q .</userinput> + cc -o prog1.o -c prog1.c + cc -o prog1 prog1.o + cc -o prog2.o -c prog2.c + cc -o prog2 prog2.o + </screen> + + <section> + <title>Getting at the List of Default Targets</title> + + <para> + + &SCons; supports a &DEFAULT_TARGETS; variable + that lets you get at the current list of default targets. + The &DEFAULT_TARGETS variable has + two important differences from the &COMMAND_LINE_TARGETS; variable. + First, the &DEFAULT_TARGETS; variable is a list of + internal &SCons; nodes, + so you need to convert the list elements to strings + if you want to print them or look for a specific target name. + Fortunately, you can do this easily + by using the Python <function>map</function> function + to run the list through <function>str</function>: + + </para> + + <programlisting> + prog1 = Program('prog1.c') + Default(prog1) + print "DEFAULT_TARGETS is", map(str, DEFAULT_TARGETS) + </programlisting> + + <para> + + (Keep in mind that all of the manipulation of the + &DEFAULT_TARGETS; list takes place during the + first phase when &SCons; is reading up the &SConscript; files, + which is obvious if + we leave off the <literal>-Q</literal> flag when we run &SCons;:) + + </para> + + <screen> + % <userinput>scons</userinput> + scons: Reading SConscript files ... + DEFAULT_TARGETS is ['prog1'] + scons: done reading SConscript files. + scons: Building targets ... + cc -o prog1.o -c prog1.c + cc -o prog1 prog1.o + scons: done building targets. + </screen> + + <para> + + Second, + the contents of the &DEFAULT_TARGETS; list change + in response to calls to the &Default;: function, + as you can see from the following &SConstruct; file: + + </para> + + <programlisting> + prog1 = Program('prog1.c') + Default(prog1) + print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS) + prog2 = Program('prog2.c') + Default(prog2) + print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS) + </programlisting> + + <para> + + Which yields the output: + + </para> + + <screen> + % <userinput>scons</userinput> + scons: Reading SConscript files ... + DEFAULT_TARGETS is now ['prog1'] + DEFAULT_TARGETS is now ['prog1', 'prog2'] + scons: done reading SConscript files. + scons: Building targets ... + cc -o prog1.o -c prog1.c + cc -o prog1 prog1.o + cc -o prog2.o -c prog2.c + cc -o prog2 prog2.o + scons: done building targets. + </screen> + + <para> + + In practice, this simply means that you + need to pay attention to the order in + which you call the &Default; function + and refer to the &DEFAULT_TARGETS; list, + to make sure that you don't examine the + list before you've added the default targets + you expect to find in it. + + </para> + + </section> + + </section> + + <section> + <title>Getting at the List of Build Targets, Regardless of Origin</title> + + <para> + + We've already been introduced to the + &COMMAND_LINE_TARGETS; variable, + which contains a list of targets specified on the command line, + and the &DEFAULT_TARGETS; variable, + which contains a list of targets specified + via calls to the &Default; method or function. + Sometimes, however, + you want a list of whatever targets + &SCons; will try to build, + regardless of whether the targets came from the + command line or a &Default; call. + You could code this up by hand, as follows: + + </para> + + <programlisting> + if COMMAND_LINE_TARGETS: + targets = COMMAND_LINE_TARGETS + else: + targets = DEFAULT_TARGETS + </programlisting> + + <para> + + &SCons;, however, provides a convenient + &BUILD_TARGETS; variable + that eliminates the need for this by-hand manipulation. + Essentially, the &BUILD_TARGETS; variable + contains a list of the command-line targets, + if any were specified, + and if no command-line targets were specified, + it contains a list of the targets specified + via the &Default; method or function. + + </para> + + <para> + + Because &BUILD_TARGETS; may contain a list of &SCons; nodes, + you must convert the list elements to strings + if you want to print them or look for a specific target name, + just like the &DEFAULT_TARGETS; list: + + </para> + + <programlisting> + prog1 = Program('prog1.c') + Program('prog2.c') + Default(prog1) + print "BUILD_TARGETS is", map(str, BUILD_TARGETS) + </programlisting> + + <para> + + Notice how the value of &BUILD_TARGETS; + changes depending on whether a target is + specified on the command line: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + BUILD_TARGETS is ['prog1'] + cc -o prog1.o -c prog1.c + cc -o prog1 prog1.o + % <userinput>scons -Q prog2</userinput> + BUILD_TARGETS is ['prog2'] + cc -o prog2.o -c prog2.c + cc -o prog2 prog2.o + % <userinput>scons -Q -c .</userinput> + BUILD_TARGETS is ['.'] + Removed prog1.o + Removed prog1 + Removed prog2.o + Removed prog2 + </screen> + + </section> + + <section> + <title>Command-Line <varname>variable</varname>=<varname>value</varname> Build Options</title> + + <para> + + You may want to control various aspects + of your build by allowing the user + to specify <varname>variable</varname>=<varname>value</varname> + values on the command line. + For example, suppose you + want users to be able to + build a debug version of a program + by running &SCons; as follows: + + </para> + + <screen> + % <userinput>scons -Q debug=1</userinput> + </screen> + + <para> + + &SCons; provides an &ARGUMENTS; dictionary + that stores all of the + <varname>variable</varname>=<varname>value</varname> + assignments from the command line. + This allows you to modify + aspects of your build in response + to specifications on the command line. + (Note that unless you want to require + that users <emphasis>always</emphasis> + specify an option, + you probably want to use + the Python + <literal>ARGUMENTS.get()</literal> function, + which allows you to specify a default value + to be used if there is no specification + on the command line.) + + </para> + + <para> + + The following code sets the &cv-link-CCFLAGS; construction + variable in response to the <varname>debug</varname> + flag being set in the &ARGUMENTS; dictionary: + + </para> + + <programlisting> + env = Environment() + debug = ARGUMENTS.get('debug', 0) + if int(debug): + env.Append(CCFLAGS = '-g') + env.Program('prog.c') + </programlisting> + + <para> + + This results in the <varname>-g</varname> + compiler option being used when + <literal>debug=1</literal> + is used on the command line: + + </para> + + <screen> + % <userinput>scons -Q debug=0</userinput> + cc -o prog.o -c prog.c + cc -o prog prog.o + % <userinput>scons -Q debug=0</userinput> + scons: `.' is up to date. + % <userinput>scons -Q debug=1</userinput> + cc -o prog.o -c -g prog.c + cc -o prog prog.o + % <userinput>scons -Q debug=1</userinput> + scons: `.' is up to date. + </screen> + + <para> + + Notice that &SCons; keeps track of + the last values used to build the object files, + and as a result correctly rebuilds + the object and executable files + only when the value of the <literal>debug</literal> + argument has changed. + + </para> + + </section> + + <section> + <title>Controlling Command-Line Build Options</title> + + <para> + + Being able to use a command-line build option like + <literal>debug=1</literal> is handy, + but it can be a chore to write specific Python code + to recognize each such option + and apply the values to a construction variable. + To help with this, + &SCons; supports a class to + define such build options easily, + and a mechanism to apply the + build options to a construction environment. + This allows you to control how the build options affect + construction environments. + + </para> + + <para> + + For example, suppose that you want users to set + a &RELEASE; construction variable on the + command line whenever the time comes to build + a program for release, + and that the value of this variable + should be added to the command line + with the appropriate <literal>-D</literal> option + (or other command line option) + to pass the value to the C compiler. + Here's how you might do that by setting + the appropriate value in a dictionary for the + &cv-link-CPPDEFINES; construction variable: + + </para> + + <programlisting> + opts = Options() + opts.Add('RELEASE', 'Set to 1 to build for release', 0) + env = Environment(options = opts, + CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'}) + env.Program(['foo.c', 'bar.c']) + </programlisting> + + <para> + + This &SConstruct; file first creates an + &Options; object + (the <literal>opts = Options()</literal> call), + and then uses the object's &Add; + method to indicate that the &RELEASE; + option can be set on the command line, + and that it's default value will be <literal>0</literal> + (the third argument to the &Add; method). + The second argument is a line of help text; + we'll learn how to use it in the next section. + + </para> + + <para> + + We then pass the created &Options; + object as an &options; keyword argument + to the &Environment; call + used to create the construction environment. + This then allows a user to set the + &RELEASE; build option on the command line + and have the variable show up in + the command line used to build each object from + a C source file: + + </para> + + <screen> + % <userinput>scons -Q RELEASE=1</userinput> + cc -o bar.o -c -DRELEASE_BUILD=1 bar.c + cc -o foo.o -c -DRELEASE_BUILD=1 foo.c + cc -o foo foo.o bar.o + </screen> + + </section> + + <section> + <title>Providing Help for Command-Line Build Options</title> + + <para> + + To make command-line build options most useful, + you ideally want to provide + some help text that will describe + the available options + when the user runs <literal>scons -h</literal>. + You could write this text by hand, + but &SCons; provides an easier way. + &Options; objects support a + &GenerateHelpText; method + that will, as its name indicates, + generate text that describes + the various options that + have been added to it. + You then pass the output from this method to + the &Help; function: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add('RELEASE', 'Set to 1 to build for release', 0) + env = Environment(options = opts) + Help(opts.GenerateHelpText(env)) + </programlisting> + + <para> + + &SCons; will now display some useful text + when the <literal>-h</literal> option is used: + + </para> + + <screen> + % <userinput>scons -Q -h</userinput> + + RELEASE: Set to 1 to build for release + default: 0 + actual: 0 + + Use scons -H for help about command-line options. + </screen> + + <para> + + Notice that the help output shows the default value, + and the current actual value of the build option. + + </para> + + </section> + + <section> + <title>Reading Build Options From a File</title> + + <para> + + Being able to use a command-line build option like + <literal>debug=1</literal> is handy, + but it can be a chore to write specific Python code + to recognize each such option + and apply the values to a construction variable. + To help with this, + &SCons; supports a class to + define such build options easily + and to read build option values from a file. + This allows you to control how the build options affect + construction environments. + The way you do this is by specifying + a file name when you call &Options;, + like &custom_py; in the following example: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add('RELEASE', 'Set to 1 to build for release', 0) + env = Environment(options = opts, + CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'}) + env.Program(['foo.c', 'bar.c']) + Help(opts.GenerateHelpText(env)) + </programlisting> + + <para> + + This then allows us to control the &RELEASE; + variable by setting it in the &custom_py; file: + + </para> + + <programlisting> + RELEASE = 1 + </programlisting> + + <para> + + Note that this file is actually executed + like a Python script. + Now when we run &SCons;: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + cc -o bar.o -c -DRELEASE_BUILD=1 bar.c + cc -o foo.o -c -DRELEASE_BUILD=1 foo.c + cc -o foo foo.o bar.o + </screen> + + <para> + + And if we change the contents of &custom_py; to: + + </para> + + <programlisting> + RELEASE = 0 + </programlisting> + + <para> + + The object files are rebuilt appropriately + with the new option: + + </para> + + <screen> + % <userinput>scons -Q</userinput> + cc -o bar.o -c -DRELEASE_BUILD=0 bar.c + cc -o foo.o -c -DRELEASE_BUILD=0 foo.c + cc -o foo foo.o bar.o + </screen> + + </section> + + <section> + <title>Canned Build Options</title> + + <para> + + &SCons; provides a number of functions + that provide ready-made behaviors + for various types of command-line build options. + + </para> + + <section> + <title>True/False Values: the &BoolOption; Build Option</title> + + <para> + + It's often handy to be able to specify an + option that controls a simple Boolean variable + with a &true; or &false; value. + It would be even more handy to accomodate + users who have different preferences for how to represent + &true; or &false; values. + The &BoolOption; function + makes it easy to accomodate a variety of + common values that represent + &true; or &false;. + + </para> + + <para> + + The &BoolOption; function takes three arguments: + the name of the build option, + the default value of the build option, + and the help string for the option. + It then returns appropriate information for + passing to the &Add; method of an &Options; object, like so: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(BoolOption('RELEASE', 'Set to build for release', 0)) + env = Environment(options = opts, + CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'}) + env.Program('foo.c') + </programlisting> + + <para> + + With this build option, + the &RELEASE; variable can now be enabled by + setting it to the value <literal>yes</literal> + or <literal>t</literal>: + + </para> + + <screen> + % <userinput>scons -Q RELEASE=yes foo.o</userinput> + cc -o foo.o -c -DRELEASE_BUILD=True foo.c + </screen> + + <screen> + % <userinput>scons -Q RELEASE=t foo.o</userinput> + cc -o foo.o -c -DRELEASE_BUILD=True foo.c + </screen> + + <para> + + Other values that equate to &true; include + <literal>y</literal>, + <literal>1</literal>, + <literal>on</literal> + and + <literal>all</literal>. + + </para> + + <para> + + Conversely, &RELEASE; may now be given a &false; + value by setting it to + <literal>no</literal> + or + <literal>f</literal>: + + </para> + + <screen> + % <userinput>scons -Q RELEASE=no foo.o</userinput> + cc -o foo.o -c -DRELEASE_BUILD=False foo.c + </screen> + + <screen> + % <userinput>scons -Q RELEASE=f foo.o</userinput> + cc -o foo.o -c -DRELEASE_BUILD=False foo.c + </screen> + + <para> + + Other values that equate to &false; include + <literal>n</literal>, + <literal>0</literal>, + <literal>off</literal> + and + <literal>none</literal>. + + </para> + + <para> + + Lastly, if a user tries to specify + any other value, + &SCons; supplies an appropriate error message: + + </para> + + <screen> + % <userinput>scons -Q RELEASE=bad_value foo.o</userinput> + + scons: *** Error converting option: RELEASE + Invalid value for boolean option: bad_value + File "/home/my/project/SConstruct", line 4, in <module> + </screen> + + </section> + + <section> + <title>Single Value From a List: the &EnumOption; Build Option</title> + + <para> + + Suppose that we want a user to be able to + set a &COLOR; option + that selects a background color to be + displayed by an application, + but that we want to restrict the + choices to a specific set of allowed colors. + This can be set up quite easily + using the &EnumOption;, + which takes a list of &allowed_values + in addition to the variable name, + default value, + and help text arguments: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(EnumOption('COLOR', 'Set background color', 'red', + allowed_values=('red', 'green', 'blue'))) + env = Environment(options = opts, + CPPDEFINES={'COLOR' : '"${COLOR}"'}) + env.Program('foo.c') + </programlisting> + + <para> + + The user can now explicity set the &COLOR; build option + to any of the specified allowed values: + + </para> + + <screen> + % <userinput>scons -Q COLOR=red foo.o</userinput> + cc -o foo.o -c -DCOLOR="red" foo.c + % <userinput>scons -Q COLOR=blue foo.o</userinput> + cc -o foo.o -c -DCOLOR="blue" foo.c + % <userinput>scons -Q COLOR=green foo.o</userinput> + cc -o foo.o -c -DCOLOR="green" foo.c + </screen> + + <para> + + But, almost more importantly, + an attempt to set &COLOR; + to a value that's not in the list + generates an error message: + + </para> + + <screen> + % <userinput>scons -Q COLOR=magenta foo.o</userinput> + + scons: *** Invalid value for option COLOR: magenta + File "/home/my/project/SConstruct", line 5, in <module> + </screen> + + <para> + + The &EnumOption; function also supports a way + to map alternate names to allowed values. + Suppose, for example, + that we want to allow the user + to use the word <literal>navy</literal> as a synonym for + <literal>blue</literal>. + We do this by adding a ↦ dictionary + that will map its key values + to the desired legal value: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(EnumOption('COLOR', 'Set background color', 'red', + allowed_values=('red', 'green', 'blue'), + map={'navy':'blue'})) + env = Environment(options = opts, + CPPDEFINES={'COLOR' : '"${COLOR}"'}) + env.Program('foo.c') + </programlisting> + + <para> + + As desired, the user can then use + <literal>navy</literal> on the command line, + and &SCons; will translate it into <literal>blue</literal> + when it comes time to use the &COLOR; + option to build a target: + + </para> + + <screen> + % <userinput>scons -Q COLOR=navy foo.o</userinput> + cc -o foo.o -c -DCOLOR="blue" foo.c + </screen> + + <para> + + By default, when using the &EnumOption; function, + arguments that differ + from the legal values + only in case + are treated as illegal values: + + </para> + + <screen> + % <userinput>scons -Q COLOR=Red foo.o</userinput> + + scons: *** Invalid value for option COLOR: Red + File "/home/my/project/SConstruct", line 5, in <module> + % <userinput>scons -Q COLOR=BLUE foo.o</userinput> + + scons: *** Invalid value for option COLOR: BLUE + File "/home/my/project/SConstruct", line 5, in <module> + % <userinput>scons -Q COLOR=nAvY foo.o</userinput> + + scons: *** Invalid value for option COLOR: nAvY + File "/home/my/project/SConstruct", line 5, in <module> + </screen> + + <para> + + The &EnumOption; function can take an additional + &ignorecase; keyword argument that, + when set to <literal>1</literal>, + tells &SCons; to allow case differences + when the values are specified: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(EnumOption('COLOR', 'Set background color', 'red', + allowed_values=('red', 'green', 'blue'), + map={'navy':'blue'}, + ignorecase=1)) + env = Environment(options = opts, + CPPDEFINES={'COLOR' : '"${COLOR}"'}) + env.Program('foo.c') + </programlisting> + + <para> + + Which yields the output: + + </para> + + <screen> + % <userinput>scons -Q COLOR=Red foo.o</userinput> + cc -o foo.o -c -DCOLOR="Red" foo.c + % <userinput>scons -Q COLOR=BLUE foo.o</userinput> + cc -o foo.o -c -DCOLOR="BLUE" foo.c + % <userinput>scons -Q COLOR=nAvY foo.o</userinput> + cc -o foo.o -c -DCOLOR="blue" foo.c + % <userinput>scons -Q COLOR=green foo.o</userinput> + cc -o foo.o -c -DCOLOR="green" foo.c + </screen> + + <para> + + Notice that an &ignorecase; value of <literal>1</literal> + preserves the case-spelling that the user supplied. + If you want &SCons; to translate the names + into lower-case, + regardless of the case used by the user, + specify an &ignorecase; value of <literal>2</literal>: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(EnumOption('COLOR', 'Set background color', 'red', + allowed_values=('red', 'green', 'blue'), + map={'navy':'blue'}, + ignorecase=2)) + env = Environment(options = opts, + CPPDEFINES={'COLOR' : '"${COLOR}"'}) + env.Program('foo.c') + </programlisting> + + <para> + + Now &SCons; will use values of + <literal>red</literal>, + <literal>green</literal> or + <literal>blue</literal> + regardless of how the user spells + those values on the command line: + + </para> + + <screen> + % <userinput>scons -Q COLOR=Red foo.o</userinput> + cc -o foo.o -c -DCOLOR="red" foo.c + % <userinput>scons -Q COLOR=nAvY foo.o</userinput> + cc -o foo.o -c -DCOLOR="blue" foo.c + % <userinput>scons -Q COLOR=GREEN foo.o</userinput> + cc -o foo.o -c -DCOLOR="green" foo.c + </screen> + + </section> + + <section> + <title>Multiple Values From a List: the &ListOption; Build Option</title> + + <para> + + Another way in which you might want to allow users + to control build option is to + specify a list of one or more legal values. + &SCons; supports this through the &ListOption; function. + If, for example, we want a user to be able to set a + &COLORS; option to one or more of the legal list of values: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(ListOption('COLORS', 'List of colors', 0, + ['red', 'green', 'blue'])) + env = Environment(options = opts, + CPPDEFINES={'COLORS' : '"${COLORS}"'}) + env.Program('foo.c') + </programlisting> + + <para> + + A user can now specify a comma-separated list + of legal values, + which will get translated into a space-separated + list for passing to the any build commands: + + </para> + + <screen> + % <userinput>scons -Q COLORS=red,blue foo.o</userinput> + cc -o foo.o -c -DCOLORS="red blue" foo.c + % <userinput>scons -Q COLORS=blue,green,red foo.o</userinput> + cc -o foo.o -c -DCOLORS="blue green red" foo.c + </screen> + + <para> + + In addition, the &ListOption; function + allows the user to specify explicit keywords of + &all; or &none; + to select all of the legal values, + or none of them, respectively: + + </para> + + <screen> + % <userinput>scons -Q COLORS=all foo.o</userinput> + cc -o foo.o -c -DCOLORS="red green blue" foo.c + % <userinput>scons -Q COLORS=none foo.o</userinput> + cc -o foo.o -c -DCOLORS="" foo.c + </screen> + + <para> + + And, of course, an illegal value + still generates an error message: + + </para> + + <screen> + % <userinput>scons -Q COLORS=magenta foo.o</userinput> + + scons: *** Error converting option: COLORS + Invalid value(s) for option: magenta + File "/home/my/project/SConstruct", line 5, in <module> + </screen> + + </section> + + <section> + <title>Path Names: the &PathOption; Build Option</title> + + <para> + + &SCons; supports a &PathOption; function + to make it easy to create a build option + to control an expected path name. + If, for example, you need to + define a variable in the preprocessor + that control the location of a + configuration file: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(PathOption('CONFIG', + 'Path to configuration file', + '/etc/my_config')) + env = Environment(options = opts, + CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'}) + env.Program('foo.c') + </programlisting> + + <para> + + This then allows the user to + override the &CONFIG; build option + on the command line as necessary: + + </para> + + <screen> + % <userinput>scons -Q foo.o</userinput> + cc -o foo.o -c -DCONFIG_FILE="/etc/my_config" foo.c + % <userinput>scons -Q CONFIG=/usr/local/etc/other_config foo.o</userinput> + scons: `foo.o' is up to date. + </screen> + + <para> + + By default, &PathOption; checks to make sure + that the specified path exists and generates an error if it + doesn't: + + </para> + + <screen> + % <userinput>scons -Q CONFIG=/does/not/exist foo.o</userinput> + + scons: *** Path for option CONFIG does not exist: /does/not/exist + File "/home/my/project/SConstruct", line 6, in <module> + </screen> + + <para> + + &PathOption; provides a number of methods + that you can use to change this behavior. + If you want to ensure that any specified paths are, + in fact, files and not directories, + use the &PathOption_PathIsFile; method: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(PathOption('CONFIG', + 'Path to configuration file', + '/etc/my_config', + PathOption.PathIsFile)) + env = Environment(options = opts, + CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'}) + env.Program('foo.c') + </programlisting> + + <para> + + Conversely, to ensure that any specified paths are + directories and not files, + use the &PathOption_PathIsDir; method: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(PathOption('DBDIR', + 'Path to database directory', + '/var/my_dbdir', + PathOption.PathIsDir)) + env = Environment(options = opts, + CPPDEFINES={'DBDIR' : '"$DBDIR"'}) + env.Program('foo.c') + </programlisting> + + <para> + + If you want to make sure that any specified paths + are directories, + and you would like the directory created + if it doesn't already exist, + use the &PathOption_PathIsDirCreate; method: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(PathOption('DBDIR', + 'Path to database directory', + '/var/my_dbdir', + PathOption.PathIsDirCreate)) + env = Environment(options = opts, + CPPDEFINES={'DBDIR' : '"$DBDIR"'}) + env.Program('foo.c') + </programlisting> + + <para> + + Lastly, if you don't care whether the path exists, + is a file, or a directory, + use the &PathOption_PathAccept; method + to accept any path that the user supplies: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(PathOption('OUTPUT', + 'Path to output file or directory', + None, + PathOption.PathAccept)) + env = Environment(options = opts, + CPPDEFINES={'OUTPUT' : '"$OUTPUT"'}) + env.Program('foo.c') + </programlisting> + + </section> + + <section> + <title>Enabled/Disabled Path Names: the &PackageOption; Build Option</title> + + <para> + + Sometimes you want to give users + even more control over a path name variable, + allowing them to explicitly enable or + disable the path name + by using <literal>yes</literal> or <literal>no</literal> keywords, + in addition to allow them + to supply an explicit path name. + &SCons; supports the &PackageOption; + function to support this: + + </para> + + <programlisting> + opts = Options('custom.py') + opts.Add(PackageOption('PACKAGE', + 'Location package', + '/opt/location')) + env = Environment(options = opts, + CPPDEFINES={'PACKAGE' : '"$PACKAGE"'}) + env.Program('foo.c') + </programlisting> + + <para> + + When the &SConscript; file uses the &PackageOption; funciton, + user can now still use the default + or supply an overriding path name, + but can now explicitly set the + specified variable to a value + that indicates the package should be enabled + (in which case the default should be used) + or disabled: + + </para> + + <screen> + % <userinput>scons -Q foo.o</userinput> + cc -o foo.o -c -DPACKAGE="/opt/location" foo.c + % <userinput>scons -Q PACKAGE=/usr/local/location foo.o</userinput> + cc -o foo.o -c -DPACKAGE="/usr/local/location" foo.c + % <userinput>scons -Q PACKAGE=yes foo.o</userinput> + cc -o foo.o -c -DPACKAGE="True" foo.c + % <userinput>scons -Q PACKAGE=no foo.o</userinput> + cc -o foo.o -c -DPACKAGE="False" foo.c + </screen> + + </section> + + </section> + + <section> + <title>Adding Multiple Command-Line Build Options at Once</title> + + <para> + + Lastly, &SCons; provides a way to add + multiple build options to an &Options; object at once. + Instead of having to call the &Add; method + multiple times, + you can call the &AddOptions; + method with a list of build options + to be added to the object. + Each build option is specified + as either a tuple of arguments, + just like you'd pass to the &Add; method itself, + or as a call to one of the canned + functions for pre-packaged command-line build options. + in any order: + + </para> + + <programlisting> + opts = Options() + opts.AddOptions( + ('RELEASE', 'Set to 1 to build for release', 0), + ('CONFIG', 'Configuration file', '/etc/my_config'), + BoolOption('warnings', 'compilation with -Wall and similiar', 1), + EnumOption('debug', 'debug output and symbols', 'no', + allowed_values=('yes', 'no', 'full'), + map={}, ignorecase=0), # case sensitive + ListOption('shared', + 'libraries to build as shared libraries', + 'all', + names = list_of_libs), + PackageOption('x11', + 'use X11 installed here (yes = search some places)', + 'yes'), + PathOption('qtdir', 'where the root of Qt is installed', qtdir), + ) + </programlisting> + + <para> + </para> + + </section> |
