File scons-user.html of Package scons

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>SCons User Guide 1.0.1</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"></HEAD
><BODY
CLASS="book"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="BOOK"
><A
NAME="AEN1"
></A
><DIV
CLASS="TITLEPAGE"
><H1
CLASS="title"
><A
NAME="AEN2"
>SCons User Guide 1.0.1</A
></H1
><H3
CLASS="author"
><A
NAME="AEN4"
></A
>Steven Knight</H3
><P
CLASS="copyright"
>Copyright &copy; 2004, 2005, 2006, 2007, 2008 Steven Knight</P
><DIV
CLASS="legalnotice"
><P
></P
><A
NAME="AEN12"
></A
><A
NAME="AEN13"
></A
><BLOCKQUOTE
CLASS="BLOCKQUOTE"
><P
>&#13;
  SCons User's Guide Copyright (c) 2004, 2005, 2006, 2007 Steven Knight

 </P
></BLOCKQUOTE
><P
></P
></DIV
><HR></DIV
><DIV
CLASS="TOC"
><DL
><DT
><B
>Table of Contents</B
></DT
><DT
><A
HREF="#chap-preface"
>Preface</A
></DT
><DD
><DL
><DT
>1. <A
HREF="#AEN29"
><SPAN
CLASS="application"
>SCons</SPAN
> Principles</A
></DT
><DT
>2. <A
HREF="#AEN54"
>A Caveat About This Guide's Completeness</A
></DT
><DT
>3. <A
HREF="#AEN62"
>Acknowledgements</A
></DT
><DT
>4. <A
HREF="#AEN83"
>Contact</A
></DT
></DL
></DD
><DT
>1. <A
HREF="#chap-build-install"
>Building and Installing <SPAN
CLASS="application"
>SCons</SPAN
></A
></DT
><DD
><DL
><DT
>1.1. <A
HREF="#AEN102"
>Installing Python</A
></DT
><DT
>1.2. <A
HREF="#AEN124"
>Installing <SPAN
CLASS="application"
>SCons</SPAN
> From Pre-Built Packages</A
></DT
><DD
><DL
><DT
>1.2.1. <A
HREF="#AEN129"
>Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Red Hat (and Other RPM-based) Linux Systems</A
></DT
><DT
>1.2.2. <A
HREF="#AEN149"
>Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Debian Linux Systems</A
></DT
><DT
>1.2.3. <A
HREF="#AEN157"
>Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Windows Systems</A
></DT
></DL
></DD
><DT
>1.3. <A
HREF="#AEN166"
>Building and Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Any System</A
></DT
><DD
><DL
><DT
>1.3.1. <A
HREF="#AEN194"
>Building and Installing Multiple Versions of <SPAN
CLASS="application"
>SCons</SPAN
> Side-by-Side</A
></DT
><DT
>1.3.2. <A
HREF="#AEN218"
>Installing <SPAN
CLASS="application"
>SCons</SPAN
> in Other Locations</A
></DT
><DT
>1.3.3. <A
HREF="#AEN236"
>Building and Installing <SPAN
CLASS="application"
>SCons</SPAN
> Without Administrative Privileges</A
></DT
></DL
></DD
></DL
></DD
><DT
>2. <A
HREF="#chap-simple"
>Simple Builds</A
></DT
><DD
><DL
><DT
>2.1. <A
HREF="#AEN256"
>Building Simple C / C++ Programs</A
></DT
><DT
>2.2. <A
HREF="#AEN288"
>Building Object Files</A
></DT
><DT
>2.3. <A
HREF="#AEN307"
>Simple Java Builds</A
></DT
><DT
>2.4. <A
HREF="#AEN328"
>Cleaning Up After a Build</A
></DT
><DT
>2.5. <A
HREF="#AEN348"
>The <TT
CLASS="filename"
>SConstruct</TT
> File</A
></DT
><DD
><DL
><DT
>2.5.1. <A
HREF="#AEN358"
><TT
CLASS="filename"
>SConstruct</TT
> Files Are Python Scripts</A
></DT
><DT
>2.5.2. <A
HREF="#AEN370"
><SPAN
CLASS="application"
>SCons</SPAN
> Functions Are Order-Independent</A
></DT
></DL
></DD
><DT
>2.6. <A
HREF="#AEN420"
>Making the <SPAN
CLASS="application"
>SCons</SPAN
> Output Less Verbose</A
></DT
></DL
></DD
><DT
>3. <A
HREF="#chap-less-simple"
>Less Simple Things to Do With Builds</A
></DT
><DD
><DL
><DT
>3.1. <A
HREF="#AEN443"
>Specifying the Name of the Target (Output) File</A
></DT
><DT
>3.2. <A
HREF="#AEN467"
>Compiling Multiple Source Files</A
></DT
><DT
>3.3. <A
HREF="#AEN489"
>Making a list of files with <CODE
CLASS="function"
>Glob</CODE
></A
></DT
><DT
>3.4. <A
HREF="#AEN508"
>Specifying Single Files Vs. Lists of Files</A
></DT
><DT
>3.5. <A
HREF="#AEN526"
>Making Lists of Files Easier to Read</A
></DT
><DT
>3.6. <A
HREF="#AEN552"
>Keyword Arguments</A
></DT
><DT
>3.7. <A
HREF="#AEN563"
>Compiling Multiple Programs</A
></DT
><DT
>3.8. <A
HREF="#AEN577"
>Sharing Source Files Between Multiple Programs</A
></DT
></DL
></DD
><DT
>4. <A
HREF="#chap-libraries"
>Building and Linking with Libraries</A
></DT
><DD
><DL
><DT
>4.1. <A
HREF="#AEN597"
>Building Libraries</A
></DT
><DD
><DL
><DT
>4.1.1. <A
HREF="#AEN616"
>Building Libraries From Source Code or Object Files</A
></DT
><DT
>4.1.2. <A
HREF="#AEN627"
>Building Static Libraries Explicitly:  the <CODE
CLASS="function"
>StaticLibrary</CODE
> Builder</A
></DT
><DT
>4.1.3. <A
HREF="#AEN641"
>Building Shared (DLL) Libraries:  the <CODE
CLASS="function"
>SharedLibrary</CODE
> Builder</A
></DT
></DL
></DD
><DT
>4.2. <A
HREF="#AEN658"
>Linking with Libraries</A
></DT
><DT
>4.3. <A
HREF="#AEN685"
>Finding Libraries:  the <CODE
CLASS="envar"
>$LIBPATH</CODE
> Construction Variable</A
></DT
></DL
></DD
><DT
>5. <A
HREF="#chap-nodes"
>Node Objects</A
></DT
><DD
><DL
><DT
>5.1. <A
HREF="#AEN716"
>Builder Methods Return Lists of Target Nodes</A
></DT
><DT
>5.2. <A
HREF="#AEN747"
>Explicitly Creating File and Directory Nodes</A
></DT
><DT
>5.3. <A
HREF="#AEN767"
>Printing <CODE
CLASS="classname"
>Node</CODE
> File Names</A
></DT
><DT
>5.4. <A
HREF="#AEN779"
>Using a <CODE
CLASS="classname"
>Node</CODE
>'s File Name as a String</A
></DT
></DL
></DD
><DT
>6. <A
HREF="#chap-depends"
>Dependencies</A
></DT
><DD
><DL
><DT
>6.1. <A
HREF="#AEN815"
>Deciding When an Input File Has Changed:  the <CODE
CLASS="function"
>Decider</CODE
> Function</A
></DT
><DD
><DL
><DT
>6.1.1. <A
HREF="#AEN823"
>Using MD5 Signatures to Decide if a File Has Changed</A
></DT
><DT
>6.1.2. <A
HREF="#AEN866"
>Using Time Stamps to Decide If a File Has Changed</A
></DT
><DT
>6.1.3. <A
HREF="#AEN912"
>Deciding If a File Has Changed Using Both MD Signatures and Time Stamps</A
></DT
><DT
>6.1.4. <A
HREF="#AEN937"
>Writing Your Own Custom <CODE
CLASS="function"
>Decider</CODE
> Function</A
></DT
><DT
>6.1.5. <A
HREF="#AEN977"
>Mixing Different Ways of Deciding If a File Has Changed</A
></DT
></DL
></DD
><DT
>6.2. <A
HREF="#AEN994"
>Older Functions for Deciding When an Input File Has Changed</A
></DT
><DD
><DL
><DT
>6.2.1. <A
HREF="#AEN999"
>The <CODE
CLASS="function"
>SourceSignatures</CODE
> Function</A
></DT
><DT
>6.2.2. <A
HREF="#AEN1011"
>The <CODE
CLASS="function"
>TargetSignatures</CODE
> Function</A
></DT
></DL
></DD
><DT
>6.3. <A
HREF="#AEN1056"
>Implicit Dependencies:  The <CODE
CLASS="envar"
>$CPPPATH</CODE
> Construction Variable</A
></DT
><DT
>6.4. <A
HREF="#AEN1115"
>Caching Implicit Dependencies</A
></DT
><DD
><DL
><DT
>6.4.1. <A
HREF="#AEN1154"
>The <TT
CLASS="literal"
>--implicit-deps-changed</TT
> Option</A
></DT
><DT
>6.4.2. <A
HREF="#AEN1166"
>The <TT
CLASS="literal"
>--implicit-deps-unchanged</TT
> Option</A
></DT
></DL
></DD
><DT
>6.5. <A
HREF="#AEN1179"
>Explicit Dependencies:  the <CODE
CLASS="function"
>Depends</CODE
> Function</A
></DT
><DT
>6.6. <A
HREF="#AEN1198"
>Dependencies From External Files:  the <CODE
CLASS="function"
>ParseDepends</CODE
>
  Function</A
></DT
><DT
>6.7. <A
HREF="#AEN1234"
>Ignoring Dependencies:  the <CODE
CLASS="function"
>Ignore</CODE
> Function</A
></DT
><DT
>6.8. <A
HREF="#AEN1261"
>Order-Only Dependencies:  the <CODE
CLASS="function"
>Requires</CODE
> Function</A
></DT
><DT
>6.9. <A
HREF="#AEN1312"
>The <CODE
CLASS="function"
>AlwaysBuild</CODE
> Function</A
></DT
></DL
></DD
><DT
>7. <A
HREF="#chap-environments"
>Environments</A
></DT
><DD
><DL
><DT
>7.1. <A
HREF="#sect-external-environments"
>Using Values From the External Environment</A
></DT
><DT
>7.2. <A
HREF="#sect-construction-environments"
>Construction Environments</A
></DT
><DD
><DL
><DT
>7.2.1. <A
HREF="#AEN1400"
>Creating a <TT
CLASS="literal"
>Construction Environment</TT
>:  the <CODE
CLASS="function"
>Environment</CODE
> Function</A
></DT
><DT
>7.2.2. <A
HREF="#AEN1423"
>Fetching Values From a <TT
CLASS="literal"
>Construction Environment</TT
></A
></DT
><DT
>7.2.3. <A
HREF="#AEN1446"
>Expanding Values From a <TT
CLASS="literal"
>Construction Environment</TT
>:  the <CODE
CLASS="function"
>subst</CODE
> Method</A
></DT
><DT
>7.2.4. <A
HREF="#AEN1479"
>Controlling the Default <TT
CLASS="literal"
>Construction Environment</TT
>:  the <CODE
CLASS="function"
>DefaultEnvironment</CODE
> Function</A
></DT
><DT
>7.2.5. <A
HREF="#AEN1510"
>Multiple <TT
CLASS="literal"
>Construction Environments</TT
></A
></DT
><DT
>7.2.6. <A
HREF="#AEN1550"
>Making Copies of <TT
CLASS="literal"
>Construction Environments</TT
>:  the <CODE
CLASS="function"
>Clone</CODE
> Method</A
></DT
><DT
>7.2.7. <A
HREF="#AEN1571"
>Replacing Values:  the <CODE
CLASS="function"
>Replace</CODE
> Method</A
></DT
><DT
>7.2.8. <A
HREF="#AEN1603"
>Setting Values Only If They're Not Already Defined:  the <CODE
CLASS="function"
>SetDefault</CODE
> Method</A
></DT
><DT
>7.2.9. <A
HREF="#AEN1612"
>Appending to the End of Values:  the <CODE
CLASS="function"
>Append</CODE
> Method</A
></DT
><DT
>7.2.10. <A
HREF="#AEN1632"
>Appending Unique Values:  the <CODE
CLASS="function"
>AppendUnique</CODE
> Method</A
></DT
><DT
>7.2.11. <A
HREF="#AEN1642"
>Appending to the Beginning of Values:  the <CODE
CLASS="function"
>Prepend</CODE
> Method</A
></DT
><DT
>7.2.12. <A
HREF="#AEN1663"
>Prepending Unique Values:  the <CODE
CLASS="function"
>PrependUnique</CODE
> Method</A
></DT
></DL
></DD
><DT
>7.3. <A
HREF="#sect-execution-environments"
>Controlling the Execution Environment for Issued Commands</A
></DT
><DD
><DL
><DT
>7.3.1. <A
HREF="#AEN1704"
>Propagating <CODE
CLASS="varname"
>PATH</CODE
> From the External Environment</A
></DT
><DT
>7.3.2. <A
HREF="#AEN1723"
>Adding to <CODE
CLASS="varname"
>PATH</CODE
> Values in the Execution Environment</A
></DT
></DL
></DD
></DL
></DD
><DT
>8. <A
HREF="#chap-mergeflags"
>Merging Options into the Environment: the <CODE
CLASS="function"
>MergeFlags</CODE
> Function</A
></DT
><DT
>9. <A
HREF="#chap-parseflags"
>Separating Compile Arguments into their Variables:  the <CODE
CLASS="function"
>ParseFlags</CODE
> Function</A
></DT
><DT
>10. <A
HREF="#chap-parseconfig"
>Finding Installed Library Information:  the <CODE
CLASS="function"
>ParseConfig</CODE
> Function</A
></DT
><DT
>11. <A
HREF="#chap-output"
>Controlling Build Output</A
></DT
><DD
><DL
><DT
>11.1. <A
HREF="#AEN1846"
>Providing Build Help:  the <CODE
CLASS="function"
>Help</CODE
> Function</A
></DT
><DT
>11.2. <A
HREF="#AEN1884"
>Controlling How <SPAN
CLASS="application"
>SCons</SPAN
> Prints Build Commands:  the <CODE
CLASS="envar"
>$*COMSTR</CODE
> Variables</A
></DT
><DT
>11.3. <A
HREF="#AEN1921"
>Providing Build Progress Output:  the <CODE
CLASS="function"
>Progress</CODE
> Function</A
></DT
><DT
>11.4. <A
HREF="#AEN1977"
>Printing Detailed Build Status:  the <CODE
CLASS="function"
>GetBuildFailures</CODE
> Function</A
></DT
></DL
></DD
><DT
>12. <A
HREF="#chap-command-line"
>Controlling a Build From the Command Line</A
></DT
><DD
><DL
><DT
>12.1. <A
HREF="#sect-command-line-options"
>Command-Line Options</A
></DT
><DD
><DL
><DT
>12.1.1. <A
HREF="#AEN2048"
>Not Having to Specify Command-Line Options Each Time:  the <CODE
CLASS="varname"
>SCONSFLAGS</CODE
> Environment Variable</A
></DT
><DT
>12.1.2. <A
HREF="#AEN2074"
>Getting Values Set by Command-Line Options:  the <CODE
CLASS="function"
>GetOption</CODE
> Function</A
></DT
><DT
>12.1.3. <A
HREF="#AEN2099"
>Setting Values of Command-Line Options:  the <CODE
CLASS="function"
>SetOption</CODE
> Function</A
></DT
><DT
>12.1.4. <A
HREF="#sect-command-line-option-strings"
>Strings for Getting or Setting Values of <SPAN
CLASS="application"
>SCons</SPAN
> Command-Line Options</A
></DT
><DT
>12.1.5. <A
HREF="#AEN2327"
>Adding Custom Command-Line Options:  the <CODE
CLASS="function"
>AddOption</CODE
> Function</A
></DT
></DL
></DD
><DT
>12.2. <A
HREF="#sect-command-line-variables"
>Command-Line <CODE
CLASS="varname"
>variable</CODE
>=<CODE
CLASS="varname"
>value</CODE
> Build Variables</A
></DT
><DD
><DL
><DT
>12.2.1. <A
HREF="#AEN2420"
>Controlling Command-Line Build Variables</A
></DT
><DT
>12.2.2. <A
HREF="#AEN2456"
>Providing Help for Command-Line Build Variables</A
></DT
><DT
>12.2.3. <A
HREF="#AEN2471"
>Reading Build Variables From a File</A
></DT
><DT
>12.2.4. <A
HREF="#AEN2491"
>Pre-Defined Build Variable Functions</A
></DT
><DT
>12.2.5. <A
HREF="#AEN2677"
>Adding Multiple Command-Line Build Variables at Once</A
></DT
><DT
>12.2.6. <A
HREF="#AEN2687"
>Handling Unknown Command-Line Build Variables:  the <CODE
CLASS="function"
>UnknownVariables</CODE
> Function</A
></DT
></DL
></DD
><DT
>12.3. <A
HREF="#sect-command-line-targets"
>Command-Line Targets</A
></DT
><DD
><DL
><DT
>12.3.1. <A
HREF="#AEN2722"
>Fetching Command-Line Targets: the <CODE
CLASS="varname"
>COMMAND_LINE_TARGETS</CODE
> Variable</A
></DT
><DT
>12.3.2. <A
HREF="#AEN2739"
>Controlling the Default Targets:  the <CODE
CLASS="function"
>Default</CODE
> Function</A
></DT
><DT
>12.3.3. <A
HREF="#AEN2822"
>Fetching the List of Build Targets, Regardless of Origin: the <CODE
CLASS="varname"
>BUILD_TARGETS</CODE
> Variable</A
></DT
></DL
></DD
></DL
></DD
><DT
>13. <A
HREF="#chap-install"
>Installing Files in Other Directories:  the <CODE
CLASS="function"
>Install</CODE
> Builder</A
></DT
><DD
><DL
><DT
>13.1. <A
HREF="#AEN2869"
>Installing Multiple Files in a Directory</A
></DT
><DT
>13.2. <A
HREF="#AEN2879"
>Installing a File Under a Different Name</A
></DT
><DT
>13.3. <A
HREF="#AEN2890"
>Installing Multiple Files Under Different Names</A
></DT
></DL
></DD
><DT
>14. <A
HREF="#chap-factories"
>Platform-Independent File System Manipulation</A
></DT
><DD
><DL
><DT
>14.1. <A
HREF="#AEN2906"
>Copying Files or Directories:  The <CODE
CLASS="function"
>Copy</CODE
> Factory</A
></DT
><DT
>14.2. <A
HREF="#AEN2940"
>Deleting Files or Directories:  The <CODE
CLASS="function"
>Delete</CODE
> Factory</A
></DT
><DT
>14.3. <A
HREF="#AEN2969"
>Moving (Renaming) Files or Directories:  The <CODE
CLASS="function"
>Move</CODE
> Factory</A
></DT
><DT
>14.4. <A
HREF="#AEN2978"
>Updating the Modification Time of a File:  The <CODE
CLASS="function"
>Touch</CODE
> Factory</A
></DT
><DT
>14.5. <A
HREF="#AEN2987"
>Creating a Directory:  The <CODE
CLASS="function"
>Mkdir</CODE
> Factory</A
></DT
><DT
>14.6. <A
HREF="#AEN2996"
>Changing File or Directory Permissions:  The <CODE
CLASS="function"
>Chmod</CODE
> Factory</A
></DT
><DT
>14.7. <A
HREF="#AEN3005"
>Executing an action immediately:  the <CODE
CLASS="function"
>Execute</CODE
> Function</A
></DT
></DL
></DD
><DT
>15. <A
HREF="#chap-file-removal"
>Controlling Removal of Targets</A
></DT
><DD
><DL
><DT
>15.1. <A
HREF="#AEN3044"
>Preventing target removal during build: the <CODE
CLASS="function"
>Precious</CODE
> Function</A
></DT
><DT
>15.2. <A
HREF="#AEN3060"
>Preventing target removal during clean: the <CODE
CLASS="function"
>NoClean</CODE
> Function</A
></DT
><DT
>15.3. <A
HREF="#AEN3074"
>Removing additional files during clean: the <CODE
CLASS="function"
>Clean</CODE
> Function</A
></DT
></DL
></DD
><DT
>16. <A
HREF="#chap-hierarchical"
>Hierarchical Builds</A
></DT
><DD
><DL
><DT
>16.1. <A
HREF="#AEN3101"
><TT
CLASS="filename"
>SConscript</TT
> Files</A
></DT
><DT
>16.2. <A
HREF="#AEN3129"
>Path Names Are Relative to the <TT
CLASS="filename"
>SConscript</TT
> Directory</A
></DT
><DT
>16.3. <A
HREF="#AEN3155"
>Top-Level Path Names in Subsidiary <TT
CLASS="filename"
>SConscript</TT
> Files</A
></DT
><DT
>16.4. <A
HREF="#AEN3176"
>Absolute Path Names</A
></DT
><DT
>16.5. <A
HREF="#AEN3186"
>Sharing Environments (and Other Variables) Between <TT
CLASS="filename"
>SConscript</TT
> Files</A
></DT
><DD
><DL
><DT
>16.5.1. <A
HREF="#AEN3198"
>Exporting Variables</A
></DT
><DT
>16.5.2. <A
HREF="#AEN3226"
>Importing Variables</A
></DT
><DT
>16.5.3. <A
HREF="#AEN3249"
>Returning Values From an <TT
CLASS="filename"
>SConscript</TT
> File</A
></DT
></DL
></DD
></DL
></DD
><DT
>17. <A
HREF="#chap-separate"
>Separating Source and Build Directories</A
></DT
><DD
><DL
><DT
>17.1. <A
HREF="#AEN3283"
>Specifying a Variant Directory Tree as Part of an <TT
CLASS="filename"
>SConscript</TT
> Call</A
></DT
><DT
>17.2. <A
HREF="#AEN3313"
>Why <SPAN
CLASS="application"
>SCons</SPAN
> Duplicates Source Files in a Variant Directory Tree</A
></DT
><DT
>17.3. <A
HREF="#AEN3330"
>Telling <SPAN
CLASS="application"
>SCons</SPAN
> to Not Duplicate Source Files in the Variant Directory Tree</A
></DT
><DT
>17.4. <A
HREF="#AEN3346"
>The <CODE
CLASS="function"
>VariantDir</CODE
> Function</A
></DT
><DT
>17.5. <A
HREF="#AEN3375"
>Using <CODE
CLASS="function"
>VariantDir</CODE
> With an <TT
CLASS="filename"
>SConscript</TT
> File</A
></DT
><DT
>17.6. <A
HREF="#AEN3394"
>Using <CODE
CLASS="function"
>Glob</CODE
> with <CODE
CLASS="function"
>VariantDir</CODE
></A
></DT
></DL
></DD
><DT
>18. <A
HREF="#chap-variants"
>Variant Builds</A
></DT
><DT
>19. <A
HREF="#chap-builders-writing"
>Writing Your Own Builders</A
></DT
><DD
><DL
><DT
>19.1. <A
HREF="#AEN3438"
>Writing Builders That Execute External Commands</A
></DT
><DT
>19.2. <A
HREF="#AEN3447"
>Attaching a Builder to a <TT
CLASS="literal"
>Construction Environment</TT
></A
></DT
><DT
>19.3. <A
HREF="#AEN3503"
>Letting <SPAN
CLASS="application"
>SCons</SPAN
> Handle The File Suffixes</A
></DT
><DT
>19.4. <A
HREF="#AEN3524"
>Builders That Execute Python Functions</A
></DT
><DT
>19.5. <A
HREF="#AEN3560"
>Builders That Create Actions Using a <TT
CLASS="literal"
>Generator</TT
></A
></DT
><DT
>19.6. <A
HREF="#AEN3603"
>Builders That Modify the Target or Source Lists Using an <TT
CLASS="literal"
>Emitter</TT
></A
></DT
><DT
>19.7. <A
HREF="#AEN3627"
>Where To Put Your Custom Builders and Tools</A
></DT
></DL
></DD
><DT
>20. <A
HREF="#chap-builders-commands"
>Not Writing a Builder:  the <CODE
CLASS="function"
>Command</CODE
> Builder</A
></DT
><DT
>21. <A
HREF="#chap-add-method"
>Pseudo-Builders:  the AddMethod function</A
></DT
><DT
>22. <A
HREF="#chap-scanners"
>Writing Scanners</A
></DT
><DD
><DL
><DT
>22.1. <A
HREF="#AEN3743"
>A Simple Scanner Example</A
></DT
></DL
></DD
><DT
>23. <A
HREF="#chap-repositories"
>Building From Code Repositories</A
></DT
><DD
><DL
><DT
>23.1. <A
HREF="#AEN3794"
>The <CODE
CLASS="function"
>Repository</CODE
> Method</A
></DT
><DT
>23.2. <A
HREF="#AEN3805"
>Finding source files in repositories</A
></DT
><DT
>23.3. <A
HREF="#AEN3837"
>Finding <TT
CLASS="literal"
>#include</TT
> files in repositories</A
></DT
><DD
><DL
><DT
>23.3.1. <A
HREF="#AEN3878"
>Limitations on <TT
CLASS="literal"
>#include</TT
> files in repositories</A
></DT
></DL
></DD
><DT
>23.4. <A
HREF="#AEN3919"
>Finding the <TT
CLASS="filename"
>SConstruct</TT
> file in repositories</A
></DT
><DT
>23.5. <A
HREF="#AEN3937"
>Finding derived files in repositories</A
></DT
><DT
>23.6. <A
HREF="#AEN3966"
>Guaranteeing local copies of files</A
></DT
></DL
></DD
><DT
>24. <A
HREF="#chap-sconf"
>Multi-Platform Configuration (<SPAN
CLASS="application"
>Autoconf</SPAN
> Functionality)</A
></DT
><DD
><DL
><DT
>24.1. <A
HREF="#AEN4000"
><TT
CLASS="literal"
>Configure Contexts</TT
></A
></DT
><DT
>24.2. <A
HREF="#AEN4016"
>Checking for the Existence of Header Files</A
></DT
><DT
>24.3. <A
HREF="#AEN4025"
>Checking for the Availability of a Function</A
></DT
><DT
>24.4. <A
HREF="#AEN4030"
>Checking for the Availability of a Library</A
></DT
><DT
>24.5. <A
HREF="#AEN4045"
>Checking for the Availability of a <TT
CLASS="literal"
>typedef</TT
></A
></DT
><DT
>24.6. <A
HREF="#AEN4056"
>Adding Your Own Custom Checks</A
></DT
><DT
>24.7. <A
HREF="#AEN4085"
>Not Configuring When Cleaning Targets</A
></DT
></DL
></DD
><DT
>25. <A
HREF="#chap-caching"
>Caching Built Files</A
></DT
><DD
><DL
><DT
>25.1. <A
HREF="#AEN4101"
>Specifying the Shared Cache Directory</A
></DT
><DT
>25.2. <A
HREF="#AEN4123"
>Keeping Build Output Consistent</A
></DT
><DT
>25.3. <A
HREF="#AEN4137"
>Not Using the Shared Cache for Specific Files</A
></DT
><DT
>25.4. <A
HREF="#AEN4148"
>Disabling the Shared Cache</A
></DT
><DT
>25.5. <A
HREF="#AEN4160"
>Populating a Shared Cache With Already-Built Files</A
></DT
><DT
>25.6. <A
HREF="#AEN4177"
>Minimizing Cache Contention:  the <TT
CLASS="literal"
>--random</TT
> Option</A
></DT
></DL
></DD
><DT
>26. <A
HREF="#chap-alias"
>Alias Targets</A
></DT
><DT
>27. <A
HREF="#chap-java"
>Java Builds</A
></DT
><DD
><DL
><DT
>27.1. <A
HREF="#AEN4237"
>Building Java Class Files:  the <CODE
CLASS="function"
>Java</CODE
> Builder</A
></DT
><DT
>27.2. <A
HREF="#AEN4261"
>How <SPAN
CLASS="application"
>SCons</SPAN
> Handles Java Dependencies</A
></DT
><DT
>27.3. <A
HREF="#AEN4288"
>Building Java Archive (<TT
CLASS="filename"
>.jar</TT
>) Files:  the <CODE
CLASS="function"
>Jar</CODE
> Builder</A
></DT
><DT
>27.4. <A
HREF="#AEN4319"
>Building C Header and Stub Files:  the <CODE
CLASS="function"
>JavaH</CODE
> Builder</A
></DT
><DT
>27.5. <A
HREF="#AEN4373"
>Building RMI Stub and Skeleton Class Files:  the <CODE
CLASS="function"
>RMIC</CODE
> Builder</A
></DT
></DL
></DD
><DT
>28. <A
HREF="#chap-misc"
>Miscellaneous Functionality</A
></DT
><DD
><DL
><DT
>28.1. <A
HREF="#AEN4401"
>Verifying the Python Version:  the <CODE
CLASS="function"
>EnsurePythonVersion</CODE
> Function</A
></DT
><DT
>28.2. <A
HREF="#AEN4417"
>Verifying the SCons Version:  the <CODE
CLASS="function"
>EnsureSConsVersion</CODE
> Function</A
></DT
><DT
>28.3. <A
HREF="#AEN4437"
>Explicitly Terminating <SPAN
CLASS="application"
>SCons</SPAN
> While Reading <TT
CLASS="filename"
>SConscript</TT
> Files:  the <CODE
CLASS="function"
>Exit</CODE
> Function</A
></DT
><DT
>28.4. <A
HREF="#AEN4461"
>Searching for Files:  the <CODE
CLASS="function"
>FindFile</CODE
> Function</A
></DT
><DT
>28.5. <A
HREF="#AEN4490"
>Handling Nested Lists:  the <CODE
CLASS="function"
>Flatten</CODE
> Function</A
></DT
><DT
>28.6. <A
HREF="#AEN4517"
>Finding the Invocation Directory:  the <CODE
CLASS="function"
>GetLaunchDir</CODE
> Function</A
></DT
></DL
></DD
><DT
>29. <A
HREF="#chap-troubleshooting"
>Troubleshooting</A
></DT
><DD
><DL
><DT
>29.1. <A
HREF="#AEN4543"
>Why is That Target Being Rebuilt?  the <TT
CLASS="literal"
>--debug=explain</TT
> Option</A
></DT
><DT
>29.2. <A
HREF="#AEN4593"
>What's in That Construction Environment?  the <CODE
CLASS="function"
>Dump</CODE
> Method</A
></DT
><DT
>29.3. <A
HREF="#AEN4619"
>What Dependencies Does <SPAN
CLASS="application"
>SCons</SPAN
> Know About?  the <TT
CLASS="literal"
>--tree</TT
> Option</A
></DT
><DT
>29.4. <A
HREF="#AEN4689"
>How is <SPAN
CLASS="application"
>SCons</SPAN
> Constructing the Command Lines It Executes?  the <TT
CLASS="literal"
>--debug=presub</TT
> Option</A
></DT
><DT
>29.5. <A
HREF="#AEN4698"
>Where is <SPAN
CLASS="application"
>SCons</SPAN
> Searching for Libraries?  the <TT
CLASS="literal"
>--debug=findlibs</TT
> Option</A
></DT
><DT
>29.6. <A
HREF="#AEN4715"
>Where is <SPAN
CLASS="application"
>SCons</SPAN
> Blowing Up?  the <TT
CLASS="literal"
>--debug=stacktrace</TT
> Option</A
></DT
><DT
>29.7. <A
HREF="#AEN4736"
>How is <SPAN
CLASS="application"
>SCons</SPAN
> Making Its Decisions?  the <TT
CLASS="literal"
>--taskmastertrace</TT
> Option</A
></DT
></DL
></DD
><DT
>A. <A
HREF="#app-variables"
>Construction Variables</A
></DT
><DT
>B. <A
HREF="#app-builders"
>Builders</A
></DT
><DT
>C. <A
HREF="#app-tools"
>Tools</A
></DT
><DT
>D. <A
HREF="#app-tasks"
>Handling Common Tasks</A
></DT
></DL
></DIV
><DIV
CLASS="LOT"
><DL
CLASS="LOT"
><DT
><B
>List of Examples</B
></DT
><DT
>D-1. <A
HREF="#AEN10745"
>Wildcard globbing to create a list of filenames</A
></DT
><DT
>D-2. <A
HREF="#AEN10748"
>Filename extension substitution</A
></DT
><DT
>D-3. <A
HREF="#AEN10751"
>Appending a path prefix to a list of filenames</A
></DT
><DT
>D-4. <A
HREF="#AEN10756"
>Substituting a path prefix with another one</A
></DT
><DT
>D-5. <A
HREF="#AEN10761"
>Filtering a filename list to exclude/retain only a specific set
of extensions</A
></DT
><DT
>D-6. <A
HREF="#AEN10766"
>The "backtick function": run a shell command and capture the
output</A
></DT
></DL
></DIV
><DIV
CLASS="preface"
><HR><H1
><A
NAME="chap-preface"
></A
>Preface</H1
><P
>&#13;
  Thank you for taking the time to read about <SPAN
CLASS="application"
>SCons</SPAN
>.
  <SPAN
CLASS="application"
>SCons</SPAN
> is a next-generation
  software construction tool,
  or make tool--that is, a software utility
  for building software (or other files)
  and keeping built software up-to-date
  whenever the underlying input files change.

  </P
><P
>&#13;
  The most distinctive thing about <SPAN
CLASS="application"
>SCons</SPAN
>
  is that its configuration files are
  actually <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>scripts</I
></SPAN
>,
  written in the <SPAN
CLASS="application"
>Python</SPAN
> programming language.
  This is in contrast to most alternative build tools,
  which typically invent a new language to
  configure the build.
  <SPAN
CLASS="application"
>SCons</SPAN
> still has a learning curve, of course,
  because you have to know what functions to call
  to set up your build properly,
  but the underlying syntax used should be familiar
  to anyone who has ever looked at a Python script.

  </P
><P
>&#13;
  Paradoxically,
  using Python as the configuration file format
  makes <SPAN
CLASS="application"
>SCons</SPAN
>
  <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>easier</I
></SPAN
>
  for non-programmers to learn
  than the cryptic languages of other build tools,
  which are usually invented by programmers for other programmers.
  This is in no small part due to the
  consistency and readability that are built in to Python.
  It just so happens that making a real, live
  scripting language the basis for the
  configuration files
  makes it a snap for more accomplished programmers
  to do more complicated things with builds,
  as necessary.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN29"
>1. <SPAN
CLASS="application"
>SCons</SPAN
> Principles</A
></H2
><P
>&#13;
    There are a few overriding principles
    we try to live up to in designing and implementing <SPAN
CLASS="application"
>SCons</SPAN
>:

    </P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
>Correctness</DT
><DD
><P
>&#13;
      First and foremost,
      by default, <SPAN
CLASS="application"
>SCons</SPAN
> guarantees a correct build
      even if it means sacrificing performance a little.
      We strive to guarantee the build is correct
      regardless of how the software being built is structured,
      how it may have been written,
      or how unusual the tools are that build it.

      </P
></DD
><DT
>Performance</DT
><DD
><P
>&#13;
      Given that the build is correct,
      we try to make <SPAN
CLASS="application"
>SCons</SPAN
> build software
      as quickly as possible.
      In particular, wherever we may have needed to slow
      down the default <SPAN
CLASS="application"
>SCons</SPAN
> behavior to guarantee a correct build,
      we also try to make it easy to speed up <SPAN
CLASS="application"
>SCons</SPAN
>
      through optimization options that let you trade off
      guaranteed correctness in all end cases for
      a speedier build in the usual cases.

      </P
></DD
><DT
>Convenience</DT
><DD
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> tries to do as much for you out of the box as reasonable,
      including detecting the right tools on your system
      and using them correctly to build the software.

      </P
></DD
></DL
></DIV
><P
>&#13;
    In a nutshell, we try hard to make <SPAN
CLASS="application"
>SCons</SPAN
> just
    "do the right thing" and build software correctly,
    with a minimum of hassles.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN54"
>2. A Caveat About This Guide's Completeness</A
></H2
><P
>&#13;
  One word of warning as you read through this Guide:
  Like too much Open Source software out there,
  the <SPAN
CLASS="application"
>SCons</SPAN
> documentation isn't always
  kept up-to-date with the available features.
  In other words,
  there's a lot that <SPAN
CLASS="application"
>SCons</SPAN
> can do that
  isn't yet covered in this User's Guide.
  (Come to think of it,
  that also describes a lot of proprietary software, doesn't it?)

  </P
><P
>&#13;
  Although this User's Guide isn't as complete as we'd like it to be,
  our development process does emphasize
  making sure that the <SPAN
CLASS="application"
>SCons</SPAN
> man page is kept up-to-date
  with new features.
  So if you're trying to figure out how to do something
  that <SPAN
CLASS="application"
>SCons</SPAN
> supports
  but can't find enough (or any) information here,
  it would be worth your while to look
  at the man page to see if the information is covered there.
  And if you do,
  maybe you'd even consider contributing
  a section to the User's Guide
  so the next person looking for
  that information won't have to
  go through the same thing...?

  </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN62"
>3. Acknowledgements</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> 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:

    </P
><P
>&#13;
    First and foremost,
    <SPAN
CLASS="application"
>SCons</SPAN
> owes a tremendous debt to Bob Sidebotham,
    the original author of the classic Perl-based <SPAN
CLASS="application"
>Cons</SPAN
> 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.

    </P
><P
>&#13;
    Greg Wilson was instrumental in getting
    <SPAN
CLASS="application"
>SCons</SPAN
> 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.

    </P
><P
>&#13;
    The entire <SPAN
CLASS="application"
>SCons</SPAN
> team have been
    absolutely wonderful to work with,
    and <SPAN
CLASS="application"
>SCons</SPAN
> 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,
    Bill Deegan, Charles Crain, Steve Leblanc, Greg Noel,
    Gary Oberbrunner, Greg Spencer and Christoph Wiedemann
    have been great about reviewing my (and other) changes
    and catching problems before they get in the code base.
    Of particular technical note:
    Anthony's outstanding and innovative work on the tasking engine
    has given <SPAN
CLASS="application"
>SCons</SPAN
> a vastly superior parallel build model;
    Charles has been the master of the crucial Node infrastructure;
    Christoph's work on the Configure infrastructure
    has added crucial Autoconf-like functionality;
    and Greg has provided excellent support
    for Microsoft Visual Studio.

    </P
><P
>&#13;
    Special thanks to David Snopek for contributing
    his underlying "Autoscons" code that formed
    the basis of Christoph's work with the Configure functionality.
    David was extremely generous in making
    this code available to <SPAN
CLASS="application"
>SCons</SPAN
>,
    given that he initially released it under the GPL
    and <SPAN
CLASS="application"
>SCons</SPAN
> is released under a less-restrictive MIT-style license.

    </P
><P
>&#13;
    Thanks to Peter Miller
    for his splendid change management system, <SPAN
CLASS="application"
>Aegis</SPAN
>,
    which has provided the <SPAN
CLASS="application"
>SCons</SPAN
> 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).

    </P
><P
>&#13;
    And last, thanks to Guido van Rossum
    for his elegant scripting language,
    which is the basis not only for the <SPAN
CLASS="application"
>SCons</SPAN
> implementation,
    but for the interface itself.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN83"
>4. Contact</A
></H2
><P
>&#13;
    The best way to contact people involved with SCons,
    including the author,
    is through the SCons mailing lists.

    </P
><P
>&#13;
    If you want to ask general questions about how to use <SPAN
CLASS="application"
>SCons</SPAN
>
    send email to <TT
CLASS="literal"
>users@scons.tigris.org</TT
>.

    </P
><P
>&#13;
    If you want to contact the <SPAN
CLASS="application"
>SCons</SPAN
> development community directly,
    send email to <TT
CLASS="literal"
>dev@scons.tigris.org</TT
>.

    </P
><P
>&#13;
    If you want to receive announcements about <SPAN
CLASS="application"
>SCons</SPAN
>,
    join the low-volume <TT
CLASS="literal"
>announce@scons.tigris.org</TT
> mailing list.

    </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-build-install"
></A
>Chapter 1. Building and Installing <SPAN
CLASS="application"
>SCons</SPAN
></H1
><P
>&#13;
  This chapter will take you through the basic steps
  of installing <SPAN
CLASS="application"
>SCons</SPAN
> on your system,
  and building <SPAN
CLASS="application"
>SCons</SPAN
> if you don't have a
  pre-built package available
  (or simply prefer the flexibility of building it yourself).
  Before that, however, this chapter will also describe the basic steps
  involved in installing Python on your system,
  in case that is necessary.
  Fortunately, both <SPAN
CLASS="application"
>SCons</SPAN
> and Python
  are very easy to install on almost any system,
  and Python already comes installed on many systems.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN102"
>1.1. Installing Python</A
></H2
><P
>&#13;
    Because <SPAN
CLASS="application"
>SCons</SPAN
> is written in Python,
    you must obviously have Python installed on your system
    to use <SPAN
CLASS="application"
>SCons</SPAN
>.
    Before you try to install Python,
    you should check to see if Python is already
    available on your system  by typing
    <KBD
CLASS="userinput"
>python -V</KBD
>
    (capital 'V')
    or
    <KBD
CLASS="userinput"
>python --version</KBD
>
    at your system's command-line prompt.

    </P
><PRE
CLASS="screen"
>&#13;       $ <KBD
CLASS="userinput"
>python -V</KBD
>
       Python 2.5.1
    </PRE
><P
>&#13;
    And on a Windows system with Python installed:

    </P
><PRE
CLASS="screen"
>&#13;       C:\&#62;<KBD
CLASS="userinput"
>python -V</KBD
>
       Python 2.5.1
    </PRE
><P
>&#13;
    If Python is not installed on your system,
    you will see an error message
    stating something like "command not found"
    (on UNIX or Linux)
    or "'python' is not recognized
    as an internal or external command, operable progam or batch file"
    (on Windows).
    In that case, you need to install Python
    before you can install <SPAN
CLASS="application"
>SCons</SPAN
>.

    </P
><P
>&#13;
    (Note that the <CODE
CLASS="option"
>-V</CODE
> option
    was added to Python version 2.0,
    so if your system only has an earlier version available
    you may see an
    <TT
CLASS="literal"
>"Unknown option: -V"</TT
>
    error message.)

    </P
><P
>&#13;
    The standard location for information
    about downloading and installing Python is
    <A
HREF="http://www.python.org/download/"
TARGET="_top"
>http://www.python.org/download/</A
>.
    See that page for information about
    how to download and install Python on your system.

    </P
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> will work with any version of Python from 1.5.2 or later.
    If you need to install Python and have a choice,
    we recommend using the most recent Python 2.5 version available.
    Python 2.5 has significant improvements
    the help speed up the performance of <SPAN
CLASS="application"
>SCons</SPAN
>'.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN124"
>1.2. Installing <SPAN
CLASS="application"
>SCons</SPAN
> From Pre-Built Packages</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> comes pre-packaged for installation on a number of systems,
    including Linux and Windows systems.
    You do not need to read this entire section,
    you should only need to read the section
    appropriate to the type of system you're running on.

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN129"
>1.2.1. Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Red Hat (and Other RPM-based) Linux Systems</A
></H3
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> comes in RPM (Red Hat Package Manager) format,
      pre-built and ready to install on Red Hat Linux,
      Fedora Core,
      or any other Linux distribution that uses RPM.
      Your distribution may
      already have an <SPAN
CLASS="application"
>SCons</SPAN
> RPM built specifically for it;
      many do, including SuSe, Mandrake and Fedora.
      You can check for the availability of an <SPAN
CLASS="application"
>SCons</SPAN
> RPM
      on your distribution's download servers,
      or by consulting an RPM search site like
      <A
HREF="http://www.rpmfind.net/"
TARGET="_top"
>http://www.rpmfind.net/</A
> or
      <A
HREF="http://rpm.pbone.net/"
TARGET="_top"
>http://rpm.pbone.net/</A
>.

      </P
><P
>&#13;
      If your Linux distribution does not already have
      a specific <SPAN
CLASS="application"
>SCons</SPAN
> RPM file,
      you can download and install from the
      generic RPM provided by the <SPAN
CLASS="application"
>SCons</SPAN
> project.
      This will install the 
      SCons script(s) in <TT
CLASS="filename"
>/usr/bin</TT
>,
      and the SCons library modules in
      <TT
CLASS="filename"
>/usr/lib/scons</TT
>.

      </P
><P
>&#13;
      To install from the command line, simply download the
      appropriate <TT
CLASS="filename"
>.rpm</TT
> file,
      and then run:

      </P
><PRE
CLASS="screen"
>&#13;        # <KBD
CLASS="userinput"
>rpm -Uvh scons-0.96-1.noarch.rpm</KBD
>
      </PRE
><P
>&#13;
      Or, you can use a graphical RPM package manager
      like <SPAN
CLASS="application"
>gnorpm</SPAN
>.
      See your package manager application's documention
      for specific instructions about
      how to use it to install a downloaded RPM.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN149"
>1.2.2. Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Debian Linux Systems</A
></H3
><P
>&#13;
      Debian Linux systems use a different package management
      format that also makes it very easy to install <SPAN
CLASS="application"
>SCons</SPAN
>.

      </P
><P
>&#13;
      If your system is connected to the Internet,
      you can install the latest official Debian package
      by running:

      </P
><PRE
CLASS="screen"
>&#13;        # <KBD
CLASS="userinput"
>apt-get install scons</KBD
>
      </PRE
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN157"
>1.2.3. Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Windows Systems</A
></H3
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> provides a Windows installer
      that makes installation extremely easy.
      Download the <TT
CLASS="filename"
>scons-0.95.win32.exe</TT
>
      file from the <SPAN
CLASS="application"
>SCons</SPAN
> download page at
      <A
HREF="http://www.scons.org/download.html"
TARGET="_top"
>http://www.scons.org/download.html</A
>.
      Then all you need to do is execute the file
      (usually by clicking on its icon in Windows Explorer).
      These will take you through a small
      sequence of windows that will install
      <SPAN
CLASS="application"
>SCons</SPAN
> on your system.

      

      </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN166"
>1.3. Building and Installing <SPAN
CLASS="application"
>SCons</SPAN
> on Any System</A
></H2
><P
>&#13;
    If a pre-built <SPAN
CLASS="application"
>SCons</SPAN
> package is not available for your system,
    then you can still easily build and install <SPAN
CLASS="application"
>SCons</SPAN
> using the native
    Python <TT
CLASS="filename"
>distutils</TT
> package.

    </P
><P
>&#13;
    The first step is to download either the
    <TT
CLASS="filename"
>scons-1.0.1.tar.gz</TT
>
    or <TT
CLASS="filename"
>scons-1.0.1.zip</TT
>,
    which are available from the SCons download page at
    <A
HREF="http://www.scons.org/download.html"
TARGET="_top"
>http://www.scons.org/download.html</A
>.

    </P
><P
>&#13;
    Unpack the archive you downloaded,
    using a utility like <SPAN
CLASS="application"
>tar</SPAN
>
    on Linux or UNIX,
    or <SPAN
CLASS="application"
>WinZip</SPAN
> on Windows.
    This will create a directory called
    <TT
CLASS="filename"
>scons-1.0.1</TT
>,
    usually in your local directory.
    Then change your working directory to that directory
    and install <SPAN
CLASS="application"
>SCons</SPAN
> by executing the following commands:

    </P
><PRE
CLASS="screen"
>&#13;      # <KBD
CLASS="userinput"
>cd scons-1.0.1</KBD
>
      # <KBD
CLASS="userinput"
>python setup.py install</KBD
>
    </PRE
><P
>&#13;
    This will build <SPAN
CLASS="application"
>SCons</SPAN
>,
    install the <SPAN
CLASS="application"
>scons</SPAN
> script
    in the default system scripts directory
    (<TT
CLASS="filename"
>/usr/local/bin</TT
> or
    <TT
CLASS="filename"
>C:\Python25\Scripts</TT
>),
    and will install the <SPAN
CLASS="application"
>SCons</SPAN
> build engine
    in an appropriate stand-alone library directory
    (<TT
CLASS="filename"
>/usr/local/lib/scons</TT
> or
    <TT
CLASS="filename"
>C:\Python25\scons</TT
>).
    Because these are system directories,
    you may need root (on Linux or UNIX) or Administrator (on Windows)
    privileges to install <SPAN
CLASS="application"
>SCons</SPAN
> like this.

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN194"
>1.3.1. Building and Installing Multiple Versions of <SPAN
CLASS="application"
>SCons</SPAN
> Side-by-Side</A
></H3
><P
>&#13;
      The <SPAN
CLASS="application"
>SCons</SPAN
> <TT
CLASS="filename"
>setup.py</TT
> script
      has some extensions that support
      easy installation of multiple versions of <SPAN
CLASS="application"
>SCons</SPAN
>
      in side-by-side locations.
      This makes it easier to download and
      experiment with different versions of <SPAN
CLASS="application"
>SCons</SPAN
>
      before moving your official build process to a new version,
      for example.

      </P
><P
>&#13;
      To install <SPAN
CLASS="application"
>SCons</SPAN
> in a version-specific location,
      add the <CODE
CLASS="option"
>--version-lib</CODE
> option
      when you call <TT
CLASS="filename"
>setup.py</TT
>:

      </P
><PRE
CLASS="screen"
>&#13;        # <KBD
CLASS="userinput"
>python setup.py install --version-lib</KBD
>
      </PRE
><P
>&#13;
      This will install the <SPAN
CLASS="application"
>SCons</SPAN
> build engine
      in the
      <TT
CLASS="filename"
>/usr/lib/scons-1.0.1</TT
>
      or
      <TT
CLASS="filename"
>C:\Python25\scons-1.0.1</TT
>
      directory, for example.

      </P
><P
>&#13;
      If you use the <CODE
CLASS="option"
>--version-lib</CODE
> option
      the first time you install <SPAN
CLASS="application"
>SCons</SPAN
>,
      you do not need to specify it each time you install
      a new version.
      The <SPAN
CLASS="application"
>SCons</SPAN
> <TT
CLASS="filename"
>setup.py</TT
> script
      will detect the version-specific directory name(s)
      and assume you want to install all versions
      in version-specific directories.
      You can override that assumption in the future
      by explicitly specifying the <CODE
CLASS="option"
>--standalone-lib</CODE
> option.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN218"
>1.3.2. Installing <SPAN
CLASS="application"
>SCons</SPAN
> in Other Locations</A
></H3
><P
>&#13;
      You can install <SPAN
CLASS="application"
>SCons</SPAN
> in locations other than
      the default by specifying the <CODE
CLASS="option"
>--prefix=</CODE
> option:

      </P
><PRE
CLASS="screen"
>&#13;        # <KBD
CLASS="userinput"
>python setup.py install --prefix=/opt/scons</KBD
>
      </PRE
><P
>&#13;
      This would
      install the <SPAN
CLASS="application"
>scons</SPAN
> script in
      <TT
CLASS="filename"
>/opt/scons/bin</TT
>
      and the build engine in 
      <TT
CLASS="filename"
>/opt/scons/lib/scons</TT
>,

      </P
><P
>&#13;
      Note that you can specify both the <CODE
CLASS="option"
>--prefix=</CODE
>
      and the <CODE
CLASS="option"
>--version-lib</CODE
> options
      at the same type,
      in which case <TT
CLASS="filename"
>setup.py</TT
>
      will install the build engine
      in a version-specific directory
      relative to the specified prefix.
      Adding <CODE
CLASS="option"
>--version-lib</CODE
> to the
      above example would install the build engine in
      <TT
CLASS="filename"
>/opt/scons/lib/scons-1.0.1</TT
>.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN236"
>1.3.3. Building and Installing <SPAN
CLASS="application"
>SCons</SPAN
> Without Administrative Privileges</A
></H3
><P
>&#13;
      If you don't have the right privileges to install <SPAN
CLASS="application"
>SCons</SPAN
>
      in a system location,
      simply use the <TT
CLASS="literal"
>--prefix=</TT
> option
      to install it in a location of your choosing.
      For example,
      to install <SPAN
CLASS="application"
>SCons</SPAN
> in appropriate locations
      relative to the user's <TT
CLASS="literal"
>$HOME</TT
> directory,
      the <SPAN
CLASS="application"
>scons</SPAN
> script in
      <TT
CLASS="filename"
>$HOME/bin</TT
>
      and the build engine in 
      <TT
CLASS="filename"
>$HOME/lib/scons</TT
>,
      simply type:

      </P
><PRE
CLASS="screen"
>&#13;        $ <KBD
CLASS="userinput"
>python setup.py install --prefix=$HOME</KBD
>
      </PRE
><P
>&#13;
      You may, of course, specify any other location you prefer,
      and may use the <CODE
CLASS="option"
>--version-lib</CODE
> option
      if you would like to install version-specific directories
      relative to the specified prefix.

      </P
></DIV
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-simple"
></A
>Chapter 2. Simple Builds</H1
><P
>&#13;
 In this chapter,
 you will see several examples of
 very simple build configurations using <SPAN
CLASS="application"
>SCons</SPAN
>,
 which will demonstrate how easy
 it is to use <SPAN
CLASS="application"
>SCons</SPAN
> to
 build programs from several different programming languages
 on different types of systems.

 </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN256"
>2.1. Building Simple C / C++ Programs</A
></H2
><P
>&#13;
   Here's the famous "Hello, World!" program in C:

   </P
><PRE
CLASS="programlisting"
>&#13;      int
      main()
      {
          printf("Hello, world!\n");
      }
   </PRE
><P
>&#13;
   And here's how to build it using <SPAN
CLASS="application"
>SCons</SPAN
>.
   Enter the following into a file named <TT
CLASS="filename"
>SConstruct</TT
>:

   </P
><PRE
CLASS="programlisting"
>&#13;      Program('hello.c')
   </PRE
><P
>&#13;
   This minimal configuration file gives
   <SPAN
CLASS="application"
>SCons</SPAN
> two pieces of information:
   what you want to build
   (an executable program),
   and the input file from
   which you want it built
   (the <TT
CLASS="filename"
>hello.c</TT
> file).
   <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
> is a <I
CLASS="firstterm"
>builder_method</I
>,
   a Python call that tells <SPAN
CLASS="application"
>SCons</SPAN
> that you want to build an
   executable program.

   </P
><P
>&#13;
   That's it.  Now run the <SPAN
CLASS="application"
>scons</SPAN
> command to build the program.
   On a POSIX-compliant system like Linux or UNIX,
   you'll see something like:

   </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      scons: done building targets.
   </PRE
><P
>&#13;
   On a Windows system with the Microsoft Visual C++ compiler,
   you'll see something like:

   </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      cl /nologo /c hello.c /Fohello.obj
      link /nologo /OUT:hello.exe hello.obj
      scons: done building targets.
   </PRE
><P
>&#13;
   First, notice that you only need
   to specify the name of the source file,
   and that <SPAN
CLASS="application"
>SCons</SPAN
> correctly deduces the names of
   the object and executable files to be built
   from the base of the source file name.

   </P
><P
>&#13;
   Second, notice that the same input <TT
CLASS="filename"
>SConstruct</TT
> file,
   without any changes,
   generates the correct output file names on both systems:
   <TT
CLASS="filename"
>hello.o</TT
> and <TT
CLASS="filename"
>hello</TT
>
   on POSIX systems,
   <TT
CLASS="filename"
>hello.obj</TT
> and <TT
CLASS="filename"
>hello.exe</TT
>
   on Windows systems.
   This is a simple example of how <SPAN
CLASS="application"
>SCons</SPAN
>
   makes it extremely easy to
   write portable software builds.

   </P
><P
>&#13;
   (Note that we won't provide duplicate side-by-side
   POSIX and Windows output for all of the examples in this guide;
   just keep in mind that, unless otherwise specified,
   any of the examples should work equally well on both types of systems.)

   </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN288"
>2.2. Building Object Files</A
></H2
><P
>&#13;
   The <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
> builder method is only one of
   many builder methods that <SPAN
CLASS="application"
>SCons</SPAN
> provides
   to build different types of files.
   Another is the <A
HREF="#b-Object"
><CODE
CLASS="function"
>Object</CODE
></A
> builder method,
   which tells <SPAN
CLASS="application"
>SCons</SPAN
> to build an object file
   from the specified source file:

   </P
><PRE
CLASS="programlisting"
>&#13;      Object('hello.c')
   </PRE
><P
>&#13;
   Now when you run the <SPAN
CLASS="application"
>scons</SPAN
> command to build the program,
   it will build just the <TT
CLASS="filename"
>hello.o</TT
> object file on a POSIX system:

   </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      cc -o hello.o -c hello.c
      scons: done building targets.
   </PRE
><P
>&#13;
   And just the <TT
CLASS="filename"
>hello.obj</TT
> object file
   on a Windows system (with the Microsoft Visual C++ compiler):

   </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      cl /nologo /c hello.c /Fohello.obj
      scons: done building targets.
   </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN307"
>2.3. Simple Java Builds</A
></H2
><P
>&#13;
   <SPAN
CLASS="application"
>SCons</SPAN
> also makes building with Java extremely easy.
   Unlike the <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
> and <A
HREF="#b-Object"
><CODE
CLASS="function"
>Object</CODE
></A
> builder methods,
   however, the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> builder method
   requires that you specify
   the name of a destination directory in which
   you want the class files placed,
   followed by the source directory
   in which the <TT
CLASS="filename"
>.java</TT
> files live:

   </P
><PRE
CLASS="programlisting"
>&#13;     Java('classes', 'src')
   </PRE
><P
>&#13;
   If the <TT
CLASS="filename"
>src</TT
> directory
   contains a single <TT
CLASS="filename"
>hello.java</TT
> file,
   then the output from running the <SPAN
CLASS="application"
>scons</SPAN
> command
   would look something like this
   (on a POSIX system):

   </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      javac -d classes -sourcepath src src/hello.java
      scons: done building targets.
   </PRE
><P
>&#13;
   We'll cover Java builds in more detail,
   including building Java archive (<TT
CLASS="filename"
>.jar</TT
>)
   and other types of file,
   in <A
HREF="#chap-java"
>Chapter 27</A
>.

   </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN328"
>2.4. Cleaning Up After a Build</A
></H2
><P
>&#13;
   When using <SPAN
CLASS="application"
>SCons</SPAN
>, it is unnecessary to add special
   commands or target names to clean up after a build.
   Instead, you simply use the
   <TT
CLASS="literal"
>-c</TT
> or <TT
CLASS="literal"
>--clean</TT
>
   option when you invoke <SPAN
CLASS="application"
>SCons</SPAN
>,
   and <SPAN
CLASS="application"
>SCons</SPAN
> removes the appropriate built files.
   So if we build our example above
   and then invoke <TT
CLASS="literal"
>scons -c</TT
>
   afterwards, the output on POSIX looks like:

   </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      scons: done building targets.
      % <KBD
CLASS="userinput"
>scons -c</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Cleaning targets ...
      Removed hello.o
      Removed hello
      scons: done cleaning targets.
   </PRE
><P
>&#13;
   And the output on Windows looks like:

   </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      cl /nologo /c hello.c /Fohello.obj
      link /nologo /OUT:hello.exe hello.obj
      scons: done building targets.
      C:\&#62;<KBD
CLASS="userinput"
>scons -c</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Cleaning targets ...
      Removed hello.obj
      Removed hello.exe
      scons: done cleaning targets.
   </PRE
><P
>&#13;
   Notice that <SPAN
CLASS="application"
>SCons</SPAN
> changes its output to tell you that it
   is <TT
CLASS="literal"
>Cleaning targets ...</TT
> and
   <TT
CLASS="literal"
>done cleaning targets.</TT
>

   </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN348"
>2.5. The <TT
CLASS="filename"
>SConstruct</TT
> File</A
></H2
><P
>&#13;
   If you're used to build systems like <SPAN
CLASS="application"
>Make</SPAN
>
   you've already figured out that the <TT
CLASS="filename"
>SConstruct</TT
> file
   is the <SPAN
CLASS="application"
>SCons</SPAN
> equivalent of a <TT
CLASS="filename"
>Makefile</TT
>.
   That is, the <TT
CLASS="filename"
>SConstruct</TT
> file is the input file
   that <SPAN
CLASS="application"
>SCons</SPAN
> reads to control the build.

   </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN358"
>2.5.1. <TT
CLASS="filename"
>SConstruct</TT
> Files Are Python Scripts</A
></H3
><P
>&#13;
     There is, however, an important difference between
     an <TT
CLASS="filename"
>SConstruct</TT
> file and a <TT
CLASS="filename"
>Makefile</TT
>:
     the <TT
CLASS="filename"
>SConstruct</TT
> file is actually a Python script.
     If you're not already familiar with Python, don't worry.
     This User's Guide will introduce you step-by-step
     to the relatively small amount of Python you'll
     need to know to be able to use <SPAN
CLASS="application"
>SCons</SPAN
> effectively.
     And Python is very easy to learn.

     </P
><P
>&#13;
     One aspect of using Python as the
     scripting language is that you can put comments
     in your <TT
CLASS="filename"
>SConstruct</TT
> file using Python's commenting convention;
     that is, everything between a '#' and the end of the line
     will be ignored:

     </P
><PRE
CLASS="programlisting"
>&#13;        # Arrange to build the "hello" program.
        Program('hello.c')    # "hello.c" is the source file.
     </PRE
><P
>&#13;
     You'll see throughout the remainder of this Guide
     that being able to use the power of a
     real scripting language
     can greatly simplify the solutions
     to complex requirements of real-world builds.

     </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN370"
>2.5.2. <SPAN
CLASS="application"
>SCons</SPAN
> Functions Are Order-Independent</A
></H3
><P
>&#13;
     One important way in which the <TT
CLASS="filename"
>SConstruct</TT
>
     file is not exactly like a normal Python script,
     and is more like a <TT
CLASS="filename"
>Makefile</TT
>,
     is that the order in which
     the <SPAN
CLASS="application"
>SCons</SPAN
> functions are called in
     the <TT
CLASS="filename"
>SConstruct</TT
> file
     does <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
     affect the order in which <SPAN
CLASS="application"
>SCons</SPAN
>
     actually builds the programs and object files
     you want it to build.<A
NAME="AEN380"
HREF="#FTN.AEN380"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
>
     In other words, when you call the <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
> builder
     (or any other builder method),
     you're not telling <SPAN
CLASS="application"
>SCons</SPAN
> to build
     the program at the instant the builder method is called.
     Instead, you're telling <SPAN
CLASS="application"
>SCons</SPAN
> to build the program
     that you want, for example,
     a program built from a file named <TT
CLASS="filename"
>hello.c</TT
>,
     and it's up to <SPAN
CLASS="application"
>SCons</SPAN
> to build that program
     (and any other files) whenever it's necessary.
     (We'll learn more about how
     <SPAN
CLASS="application"
>SCons</SPAN
> decides when building or rebuilding a file
     is necessary in <A
HREF="#chap-depends"
>Chapter 6</A
>, below.)
 
     </P
><P
>&#13;
     <SPAN
CLASS="application"
>SCons</SPAN
> reflects this distinction between
     <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>calling a builder method like</I
></SPAN
> <CODE
CLASS="function"
>Program</CODE
>&#62;
     and <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>actually building the program</I
></SPAN
>
     by printing the status messages that indicate
     when it's "just reading" the <TT
CLASS="filename"
>SConstruct</TT
> file,
     and when it's actually building the target files.
     This is to make it clear when <SPAN
CLASS="application"
>SCons</SPAN
> is
     executing the Python statements that make up the <TT
CLASS="filename"
>SConstruct</TT
> file,
     and when <SPAN
CLASS="application"
>SCons</SPAN
> is actually executing the
     commands or other actions to
     build the necessary files.

     </P
><P
>&#13;
     Let's clarify this with an example.
     Python has a <TT
CLASS="literal"
>print</TT
> statement that
     prints a string of characters to the screen.
     If we put <TT
CLASS="literal"
>print</TT
> statements around
     our calls to the <CODE
CLASS="function"
>Program</CODE
> builder method:

     </P
><PRE
CLASS="programlisting"
>&#13;       print "Calling Program('hello.c')"
       Program('hello.c')
       print "Calling Program('goodbye.c')"
       Program('goodbye.c')
       print "Finished calling Program()"
     </PRE
><P
>&#13;
     Then when we execute <SPAN
CLASS="application"
>SCons</SPAN
>,
     we see the output from the <TT
CLASS="literal"
>print</TT
>
     statements in between the messages about
     reading the <TT
CLASS="filename"
>SConscript</TT
> files,
     indicating that that is when the
     Python statements are being executed:

     </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons</KBD
>
       scons: Reading SConscript files ...
       Calling Program('hello.c')
       Calling Program('goodbye.c')
       Finished calling Program()
       scons: done reading SConscript files.
       scons: Building targets ...
       cc -o goodbye.o -c goodbye.c
       cc -o goodbye goodbye.o
       cc -o hello.o -c hello.c
       cc -o hello hello.o
       scons: done building targets.
     </PRE
><P
>&#13;
     Notice also that <SPAN
CLASS="application"
>SCons</SPAN
> built the <SPAN
CLASS="application"
>goodbye</SPAN
> program first,
     even though the "reading <TT
CLASS="filename"
>SConscript</TT
>" output
     shows that we called <TT
CLASS="literal"
>Program('hello.c')</TT
>
     first in the <TT
CLASS="filename"
>SConstruct</TT
> file.

     </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN420"
>2.6. Making the <SPAN
CLASS="application"
>SCons</SPAN
> Output Less Verbose</A
></H2
><P
>&#13;
   You've already seen how <SPAN
CLASS="application"
>SCons</SPAN
> prints
   some messages about what it's doing,
   surrounding the actual commands used to build the software:

   </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      scons: done reading SConscript files.
      scons: Building targets ...
      cl /nologo /c hello.c /Fohello.obj
      link /nologo /OUT:hello.exe hello.obj
      scons: done building targets.
   </PRE
><P
>&#13;
   These messages emphasize the
   order in which <SPAN
CLASS="application"
>SCons</SPAN
> does its work:
   all of the configuration files
   (generically referred to as <TT
CLASS="filename"
>SConscript</TT
> files)
   are read and executed first,
   and only then are the target files built.
   Among other benefits, these messages help to distinguish between
   errors that occur while the configuration files are read,
   and errors that occur while targets are being built.

   </P
><P
>&#13;
   One drawback, of course, is that these messages clutter the output.
   Fortunately, they're easily disabled by using
   the <TT
CLASS="literal"
>-Q</TT
> option when invoking <SPAN
CLASS="application"
>SCons</SPAN
>:

   </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
      cl /nologo /c hello.c /Fohello.obj
      link /nologo /OUT:hello.exe hello.obj
   </PRE
><P
>&#13;
   Because we want this User's Guide to focus
   on what <SPAN
CLASS="application"
>SCons</SPAN
> is actually doing,
   we're going to use the <TT
CLASS="literal"
>-Q</TT
> option
   to remove these messages from the
   output of all the remaining examples in this Guide.

   </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-less-simple"
></A
>Chapter 3. Less Simple Things to Do With Builds</H1
><P
>&#13;
  In this chapter,
  you will see several examples of
  very simple build configurations using <SPAN
CLASS="application"
>SCons</SPAN
>,
  which will demonstrate how easy
  it is to use <SPAN
CLASS="application"
>SCons</SPAN
> to
  build programs from several different programming languages
  on different types of systems.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN443"
>3.1. Specifying the Name of the Target (Output) File</A
></H2
><P
>&#13;
    You've seen that when you call the <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
> builder method,
    it builds the resulting program with the same
    base name as the source file.
    That is, the following call to build an
    executable program from the <TT
CLASS="filename"
>hello.c</TT
> source file
    will build an executable program named <SPAN
CLASS="application"
>hello</SPAN
> on POSIX systems,
    and an executable program named <TT
CLASS="filename"
>hello.exe</TT
> on Windows systems:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('hello.c')
    </PRE
><P
>&#13;
    If you want to build a program with
    a different name than the base of the source file name,
    you simply put the target file name
    to the left of the source file name:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('new_hello', 'hello.c')
    </PRE
><P
>&#13;
    (<SPAN
CLASS="application"
>SCons</SPAN
> requires the target file name first,
    followed by the source file name,
    so that the order mimics that of an
    assignment statement in most programming languages,
    including Python:
    <TT
CLASS="literal"
>"program = source files"</TT
>.)

    </P
><P
>&#13;
    Now <SPAN
CLASS="application"
>SCons</SPAN
> will build an executable program
    named <SPAN
CLASS="application"
>new_hello</SPAN
> when run on a POSIX system:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o hello.o -c hello.c
       cc -o new_hello hello.o
    </PRE
><P
>&#13;
    And <SPAN
CLASS="application"
>SCons</SPAN
> will build an executable program
    named <SPAN
CLASS="application"
>new_hello.exe</SPAN
> when run on a Windows system:

    </P
><PRE
CLASS="screen"
>&#13;       C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
       cl /nologo /c hello.c /Fohello.obj
       link /nologo /OUT:new_hello.exe hello.obj
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN467"
>3.2. Compiling Multiple Source Files</A
></H2
><P
>&#13;
    You've just seen how to configure <SPAN
CLASS="application"
>SCons</SPAN
>
    to compile a program from a single source file.
    It's more common, of course,
    that you'll need to build a program from
    many input source files, not just one.
    To do this, you need to put the
    source files in a Python list
    (enclosed in square brackets),
    like so:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program(['prog.c', 'file1.c', 'file2.c'])
    </PRE
><P
>&#13;
    A build of the above example would look like:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o file1.o -c file1.c
       cc -o file2.o -c file2.c
       cc -o prog.o -c prog.c
       cc -o prog prog.o file1.o file2.o
    </PRE
><P
>&#13;
    Notice that <SPAN
CLASS="application"
>SCons</SPAN
>
    deduces the output program name
    from the first source file specified
    in the list--that is,
    because the first source file was <TT
CLASS="filename"
>prog.c</TT
>,
    <SPAN
CLASS="application"
>SCons</SPAN
> will name the resulting program <TT
CLASS="filename"
>prog</TT
>
    (or <TT
CLASS="filename"
>prog.exe</TT
> on a Windows system).
    If you want to specify a different program name,
    then (as we've seen in the previous section)
    you slide the list of source files
    over to the right
    to make room for the output program file name.
    (<SPAN
CLASS="application"
>SCons</SPAN
> 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:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('program', ['prog.c', 'file1.c', 'file2.c'])
    </PRE
><P
>&#13;
    On Linux, a build of this example would look like:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o file1.o -c file1.c
       cc -o file2.o -c file2.c
       cc -o prog.o -c prog.c
       cc -o program prog.o file1.o file2.o
    </PRE
><P
>&#13;
    Or on Windows:

    </P
><PRE
CLASS="screen"
>&#13;       C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
       cl /nologo /c file1.c /Fofile1.obj
       cl /nologo /c file2.c /Fofile2.obj
       cl /nologo /c prog.c /Foprog.obj
       link /nologo /OUT:program.exe prog.obj file1.obj file2.obj
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN489"
>3.3. Making a list of files with <CODE
CLASS="function"
>Glob</CODE
></A
></H2
><P
>&#13;
    You can also use the <CODE
CLASS="function"
>Glob</CODE
> function to find all files matching a
    certain template, using the standard shell pattern matching
    characters <TT
CLASS="literal"
>*</TT
>, <TT
CLASS="literal"
>?</TT
>
    and <TT
CLASS="literal"
>[abc]</TT
> to match any of
    <TT
CLASS="literal"
>a</TT
>, <TT
CLASS="literal"
>b</TT
> or <TT
CLASS="literal"
>c</TT
>.
    <TT
CLASS="literal"
>[!abc]</TT
> is also supported,
    to match any character <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>except</I
></SPAN
>
    <TT
CLASS="literal"
>a</TT
>, <TT
CLASS="literal"
>b</TT
> or <TT
CLASS="literal"
>c</TT
>.
    This makes many multi-source-file builds quite easy:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('program', Glob('*.c'))
    </PRE
><P
>&#13;
    The SCons man page has more details on using <CODE
CLASS="function"
>Glob</CODE
> with Variant
    directories and Repositories, and returning strings rather than Nodes.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN508"
>3.4. Specifying Single Files Vs. Lists of Files</A
></H2
><P
>&#13;
    We've now shown you two ways to specify
    the source for a program,
    one with a list of files:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('hello', ['file1.c', 'file2.c'])
    </PRE
><P
>&#13;
    And one with a single file:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('hello', 'hello.c')
    </PRE
><P
>&#13;
    You could actually put a single file name in a list, too,
    which you might prefer just for the sake of consistency:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('hello', ['hello.c'])
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> functions will accept a single file name in either form.
    In fact, internally, <SPAN
CLASS="application"
>SCons</SPAN
> treats all input as lists of files,
    but allows you to omit the square brackets
    to cut down a little on the typing
    when there's only a single file name.

    </P
><DIV
CLASS="important"
><P
></P
><TABLE
CLASS="important"
WIDTH="100%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/important.gif"
HSPACE="5"
ALT="Important"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>&#13;
    Although <SPAN
CLASS="application"
>SCons</SPAN
> functions
    are forgiving about whether or not you
    use a string vs. a list for a single file name,
    Python itself is more strict about
    treating lists and strings differently.
    So where <SPAN
CLASS="application"
>SCons</SPAN
> allows either
    a string or list:

    </P
><PRE
CLASS="programlisting"
>&#13;       # The following two calls both work correctly:
       Program('program1', 'program1.c')
       Program('program2', ['program2.c'])
    </PRE
><P
>&#13;
    Trying to do "Python things" that mix strings and
    lists will cause errors or lead to incorrect results:

    </P
><PRE
CLASS="programlisting"
>&#13;       common_sources = ['file1.c', 'file2.c']

       # THE FOLLOWING IS INCORRECT AND GENERATES A PYTHON ERROR
       # BECAUSE IT TRIES TO ADD A STRING TO A LIST:
       Program('program1', common_sources + 'program1.c')

       # The following works correctly, because it's adding two
       # lists together to make another list.
       Program('program2', common_sources + ['program2.c'])
    </PRE
></TD
></TR
></TABLE
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN526"
>3.5. Making Lists of Files Easier to Read</A
></H2
><P
>&#13;
    One drawback to the use of a Python list
    for source files is that 
    each file name must be enclosed in quotes
    (either single quotes or double quotes).
    This can get cumbersome and difficult to read
    when the list of file names is long.
    Fortunately, <SPAN
CLASS="application"
>SCons</SPAN
> and Python provide a number of ways
    to make sure that
    the <TT
CLASS="filename"
>SConstruct</TT
> file stays easy to read.

    </P
><P
>&#13;
    To make long lists of file names
    easier to deal with, <SPAN
CLASS="application"
>SCons</SPAN
> provides a
    <CODE
CLASS="function"
>Split</CODE
> function
    that takes a quoted list of file names,
    with the names separated by spaces or other white-space characters,
    and turns it into a list of separate file names.
    Using the <CODE
CLASS="function"
>Split</CODE
> function turns the
    previous example into:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('program', Split('main.c file1.c file2.c'))
    </PRE
><P
>&#13;
    (If you're already familiar with Python,
    you'll have realized that this is similar to the
    <CODE
CLASS="function"
>split()</CODE
> method
    in the Python standard <CODE
CLASS="function"
>string</CODE
> module.
    Unlike the <CODE
CLASS="function"
>string.split()</CODE
> method,
    however, the <CODE
CLASS="function"
>Split</CODE
> function
    does not require a string as input
    and will wrap up a single non-string object in a list,
    or return its argument untouched if it's already a list.
    This comes in handy as a way to make sure
    arbitrary values can be passed to <SPAN
CLASS="application"
>SCons</SPAN
> functions
    without having to check the type of the variable by hand.)

    </P
><P
>&#13;
    Putting the call to the <CODE
CLASS="function"
>Split</CODE
> function
    inside the <CODE
CLASS="function"
>Program</CODE
> call
    can also be a little unwieldy.
    A more readable alternative is to
    assign the output from the <CODE
CLASS="function"
>Split</CODE
> call
    to a variable name,
    and then use the variable when calling the
    <CODE
CLASS="function"
>Program</CODE
> function:

    </P
><PRE
CLASS="programlisting"
>&#13;       src_files = Split('main.c file1.c file2.c')
       Program('program', src_files)
    </PRE
><P
>&#13;
    Lastly, the <CODE
CLASS="function"
>Split</CODE
> function
    doesn't care how much white space separates
    the file names in the quoted string.
    This allows you to create lists of file
    names that span multiple lines,
    which often makes for easier editing:

    </P
><PRE
CLASS="programlisting"
>&#13;       src_files = Split("""main.c
                            file1.c
                            file2.c""")
       Program('program', src_files)
    </PRE
><P
>&#13;
    (Note in this example that we used
    the Python "triple-quote" syntax,
    which allows a string to contain
    multiple lines.
    The three quotes can be either
    single or double quotes.)

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN552"
>3.6. Keyword Arguments</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> also allows you to identify
    the output file and input source files
    using Python keyword arguments.
    The output file is known as the
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>target</I
></SPAN
>,
    and the source file(s) are known (logically enough) as the
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>source</I
></SPAN
>.
    The Python syntax for this is:

    </P
><PRE
CLASS="programlisting"
>&#13;       src_files = Split('main.c file1.c file2.c')
       Program(target = 'program', source = src_files)
    </PRE
><P
>&#13;
    Because the keywords explicitly identify
    what each argument is,
    you can actually reverse the order if you prefer:

    </P
><PRE
CLASS="programlisting"
>&#13;       src_files = Split('main.c file1.c file2.c')
       Program(source = src_files, target = 'program')
    </PRE
><P
>&#13;
    Whether or not you choose to use keyword arguments
    to identify the target and source files,
    and the order in which you specify them
    when using keywords,
    are purely personal choices;
    <SPAN
CLASS="application"
>SCons</SPAN
> functions the same regardless.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN563"
>3.7. Compiling Multiple Programs</A
></H2
><P
>&#13;
    In order to compile multiple programs
    within the same <TT
CLASS="filename"
>SConstruct</TT
> file,
    simply call the <CODE
CLASS="function"
>Program</CODE
> method
    multiple times,
    once for each program you need to build:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('foo.c')
       Program('bar', ['bar1.c', 'bar2.c'])
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> would then build the programs as follows:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o bar1.o -c bar1.c
       cc -o bar2.o -c bar2.c
       cc -o bar bar1.o bar2.o
       cc -o foo.o -c foo.c
       cc -o foo foo.o
    </PRE
><P
>&#13;
    Notice that <SPAN
CLASS="application"
>SCons</SPAN
> does not necessarily build the
    programs in the same order in which you specify
    them in the <TT
CLASS="filename"
>SConstruct</TT
> file.
    <SPAN
CLASS="application"
>SCons</SPAN
> 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.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN577"
>3.8. Sharing Source Files Between Multiple Programs</A
></H2
><P
>&#13;
    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
    <A
HREF="#chap-libraries"
>Chapter 4</A
>, below.)

    </P
><P
>&#13;
    A more straightforward, but perhaps less convenient,
    way to share source files between multiple programs
    is simply to include the common files
    in the lists of source files for each program:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program(Split('foo.c common1.c common2.c'))
       Program('bar', Split('bar1.c bar2.c common1.c common2.c'))
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> recognizes that the object files for
    the <TT
CLASS="filename"
>common1.c</TT
> and <TT
CLASS="filename"
>common2.c</TT
> source files
    each only need to be built once,
    even though the resulting object files are
    each linked in to both of the resulting executable programs:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o bar1.o -c bar1.c
       cc -o bar2.o -c bar2.c
       cc -o common1.o -c common1.c
       cc -o common2.o -c common2.c
       cc -o bar bar1.o bar2.o common1.o common2.o
       cc -o foo.o -c foo.c
       cc -o foo foo.o common1.o common2.o
    </PRE
><P
>&#13;
    If two or more programs
    share a lot of common source files,
    repeating the common files in the list for each program
    can be a maintenance problem when 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 <TT
CLASS="literal"
>+</TT
> operator:

    </P
><PRE
CLASS="programlisting"
>&#13;       common = ['common1.c', 'common2.c']
       foo_files = ['foo.c'] + common
       bar_files = ['bar1.c', 'bar2.c'] + common
       Program('foo', foo_files)
       Program('bar', bar_files)
    </PRE
><P
>&#13;
    This is functionally equivalent to the previous example.

    </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-libraries"
></A
>Chapter 4. Building and Linking with Libraries</H1
><P
>&#13;
  It's often useful to organize large software projects
  by collecting parts of the software into one or more libraries.
  <SPAN
CLASS="application"
>SCons</SPAN
> makes it easy to create libraries
  and to use them in the programs.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN597"
>4.1. Building Libraries</A
></H2
><P
>&#13;
    You build your own libraries by specifying <A
HREF="#b-Library"
><CODE
CLASS="function"
>Library</CODE
></A
>
    instead of <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
>:

    </P
><PRE
CLASS="programlisting"
>&#13;      Library('foo', ['f1.c', 'f2.c', 'f3.c'])
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> uses the appropriate library prefix and suffix for your system.
    So on POSIX or Linux systems,
    the above example would build as follows
    (although <SPAN
CLASS="application"
>ranlib</SPAN
> may not be called on all systems):

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o f1.o -c f1.c
      cc -o f2.o -c f2.c
      cc -o f3.o -c f3.c
      ar rc libfoo.a f1.o f2.o f3.o
      ranlib libfoo.a
    </PRE
><P
>&#13;
    On a Windows system,
    a build of the above example would look like:

    </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
      cl /nologo /c f1.c /Fof1.obj
      cl /nologo /c f2.c /Fof2.obj
      cl /nologo /c f3.c /Fof3.obj
      lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj
    </PRE
><P
>&#13;
    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,
    <SPAN
CLASS="application"
>SCons</SPAN
> will deduce one from the
    name of the first source file specified,
    and <SPAN
CLASS="application"
>SCons</SPAN
> will add an appropriate
    file prefix and suffix if you leave them off.

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN616"
>4.1.1. Building Libraries From Source Code or Object Files</A
></H3
><P
>&#13;
      The previous example shows building a library from a
      list of source files.
      You can, however, also give the <A
HREF="#b-Library"
><CODE
CLASS="function"
>Library</CODE
></A
> call
      object files,
      and it will correctly realize
      In fact, you can arbitrarily mix source code files
      and object files in the source list:

      </P
><PRE
CLASS="programlisting"
>&#13;        Library('foo', ['f1.c', 'f2.o', 'f3.c', 'f4.o'])
      </PRE
><P
>&#13;
      And SCons realizes that only the source code files
      must be compiled into object files
      before creating the final library:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        cc -o f1.o -c f1.c
        cc -o f3.o -c f3.c
        ar rc libfoo.a f1.o f2.o f3.o f4.o
        ranlib libfoo.a
      </PRE
><P
>&#13;
      Of course, in this example, the object files
      must already exist for the build to succeed.
      See <A
HREF="#chap-nodes"
>Chapter 5</A
>, below,
      for information about how you can
      build object files explicitly
      and include the built files in a library.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN627"
>4.1.2. Building Static Libraries Explicitly:  the <CODE
CLASS="function"
>StaticLibrary</CODE
> Builder</A
></H3
><P
>&#13;
      The <A
HREF="#b-Library"
><CODE
CLASS="function"
>Library</CODE
></A
> function builds a traditional static library.
      If you want to be explicit about the type of library being built,
      you can use the synonym <A
HREF="#b-StaticLibrary"
><CODE
CLASS="function"
>StaticLibrary</CODE
></A
> function
      instead of <CODE
CLASS="function"
>Library</CODE
>:

      </P
><PRE
CLASS="programlisting"
>&#13;        StaticLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])
      </PRE
><P
>&#13;
      There is no functional difference between the
      <A
HREF="#b-StaticLibrary"
><CODE
CLASS="function"
>StaticLibrary</CODE
></A
> and <CODE
CLASS="function"
>Library</CODE
> functions.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN641"
>4.1.3. Building Shared (DLL) Libraries:  the <CODE
CLASS="function"
>SharedLibrary</CODE
> Builder</A
></H3
><P
>&#13;
      If you want to build a shared library (on POSIX systems)
      or a DLL file (on Windows systems),
      you use the <A
HREF="#b-SharedLibrary"
><CODE
CLASS="function"
>SharedLibrary</CODE
></A
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;        SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])
      </PRE
><P
>&#13;
      The output on POSIX:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        cc -o f1.os -c f1.c
        cc -o f2.os -c f2.c
        cc -o f3.os -c f3.c
        cc -o libfoo.so -shared f1.os f2.os f3.os
      </PRE
><P
>&#13;
      And the output on Windows:

      </P
><PRE
CLASS="screen"
>&#13;        C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
        cl /nologo /c f1.c /Fof1.obj
        cl /nologo /c f2.c /Fof2.obj
        cl /nologo /c f3.c /Fof3.obj
        link /nologo /dll /out:foo.dll /implib:foo.lib f1.obj f2.obj f3.obj
        RegServerFunc(target, source, env)
      </PRE
><P
>&#13;
      Notice again that <SPAN
CLASS="application"
>SCons</SPAN
> takes care of
      building the output file correctly,
      adding the <TT
CLASS="literal"
>-shared</TT
> option
      for a POSIX compilation,
      and the <TT
CLASS="literal"
>/dll</TT
> option on Windows.

      </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN658"
>4.2. Linking with Libraries</A
></H2
><P
>&#13;
    Usually, you build a library
    because you want to link it with one or more programs.
    You link libraries with a program by specifying
    the libraries in the <A
HREF="#cv-LIBS"
><CODE
CLASS="envar"
>$LIBS</CODE
></A
> construction variable,
    and by specifying the directory in which
    the library will be found in the 
    <A
HREF="#cv-LIBPATH"
><CODE
CLASS="envar"
>$LIBPATH</CODE
></A
> construction variable:

    

    </P
><PRE
CLASS="programlisting"
>&#13;      Library('foo', ['f1.c', 'f2.c', 'f3.c'])
      Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.')
    </PRE
><P
>&#13;
    Notice, of course, that you don't need to specify a library
    prefix (like <TT
CLASS="literal"
>lib</TT
>)
    or suffix (like <TT
CLASS="literal"
>.a</TT
> or <TT
CLASS="literal"
>.lib</TT
>).
    <SPAN
CLASS="application"
>SCons</SPAN
> uses the correct prefix or suffix for the current system.

    </P
><P
>&#13;
    On a POSIX or Linux system,
    a build of the above example would look like:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o f1.o -c f1.c
      cc -o f2.o -c f2.c
      cc -o f3.o -c f3.c
      ar rc libfoo.a f1.o f2.o f3.o
      ranlib libfoo.a
      cc -o prog.o -c prog.c
      cc -o prog prog.o -L. -lfoo -lbar
    </PRE
><P
>&#13;
    On a Windows system,
    a build of the above example would look like:

    </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
      cl /nologo /c f1.c /Fof1.obj
      cl /nologo /c f2.c /Fof2.obj
      cl /nologo /c f3.c /Fof3.obj
      lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj
      cl /nologo /c prog.c /Foprog.obj
      link /nologo /OUT:prog.exe /LIBPATH:. foo.lib bar.lib prog.obj
    </PRE
><P
>&#13;
    As usual, notice that <SPAN
CLASS="application"
>SCons</SPAN
> has taken care
    of constructing the correct command lines
    to link with the specified library on each system.

    </P
><P
>&#13;
    Note also that,
    if you only have a single library to link with,
    you can specify the library name in single string,
    instead of a Python list,
    so that:

    </P
><PRE
CLASS="programlisting"
>&#13;      Program('prog.c', LIBS='foo', LIBPATH='.')
    </PRE
><P
>&#13;
    is equivalent to:

    </P
><PRE
CLASS="programlisting"
>&#13;      Program('prog.c', LIBS=['foo'], LIBPATH='.')
    </PRE
><P
>&#13;
    This is similar to the way that <SPAN
CLASS="application"
>SCons</SPAN
>
    handles either a string or a list to
    specify a single source file.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN685"
>4.3. Finding Libraries:  the <CODE
CLASS="envar"
>$LIBPATH</CODE
> Construction Variable</A
></H2
><P
>&#13;
    By default, the linker will only look in
    certain system-defined directories for libraries.
    <SPAN
CLASS="application"
>SCons</SPAN
> knows how to look for libraries
    in directories that you specify with the
    <A
HREF="#cv-LIBPATH"
><CODE
CLASS="envar"
>$LIBPATH</CODE
></A
> construction variable.
    <CODE
CLASS="envar"
>$LIBPATH</CODE
> consists of a list of
    directory names, like so:

    </P
><PRE
CLASS="programlisting"
>&#13;      Program('prog.c', LIBS = 'm',
                        LIBPATH = ['/usr/lib', '/usr/local/lib'])
    </PRE
><P
>&#13;
    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:

    </P
><PRE
CLASS="programlisting"
>&#13;      LIBPATH = '/usr/lib:/usr/local/lib'
    </PRE
><P
>&#13;
    or a semi-colon on Windows systems:

    </P
><PRE
CLASS="programlisting"
>&#13;      LIBPATH = 'C:\\lib;D:\\lib'
    </PRE
><P
>&#13;
    (Note that Python requires that the backslash
    separators in a Windows path name
    be escaped within strings.)

    </P
><P
>&#13;
    When the linker is executed,
    <SPAN
CLASS="application"
>SCons</SPAN
> will create appropriate flags
    so that the linker will look for
    libraries in the same directories as <SPAN
CLASS="application"
>SCons</SPAN
>.
    So on a POSIX or Linux system,
    a build of the above example would look like:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o prog.o -c prog.c
      cc -o prog prog.o -L/usr/lib -L/usr/local/lib -lm
    </PRE
><P
>&#13;
    On a Windows system,
    a build of the above example would look like:

    </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
      cl /nologo /c prog.c /Foprog.obj
      link /nologo /OUT:prog.exe /LIBPATH:\usr\lib /LIBPATH:\usr\local\lib m.lib prog.obj
    </PRE
><P
>&#13;
    Note again that <SPAN
CLASS="application"
>SCons</SPAN
> has taken care of
    the system-specific details of creating
    the right command-line options.

    </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-nodes"
></A
>Chapter 5. Node Objects</H1
><P
>&#13;
  Internally, <SPAN
CLASS="application"
>SCons</SPAN
> represents all of the files
  and directories it knows about as <TT
CLASS="literal"
>Nodes</TT
>.
  These internal objects
  (not object <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>files</I
></SPAN
>)
  can be used in a variety of ways
  to make your <TT
CLASS="filename"
>SConscript</TT
>
  files portable and easy to read.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN716"
>5.1. Builder Methods Return Lists of Target Nodes</A
></H2
><P
>&#13;
    All builder methods return a list of
    <CODE
CLASS="classname"
>Node</CODE
> objects that identify the
    target file or files that will be built.
    These returned <TT
CLASS="literal"
>Nodes</TT
> can be passed
    as source files to other builder methods,

    </P
><P
>&#13;
    For example, suppose that we want to build
    the two object files that make up a program with different options.
    This would mean calling the <A
HREF="#b-Object"
><CODE
CLASS="function"
>Object</CODE
></A
>
    builder once for each object file,
    specifying the desired options:

    </P
><PRE
CLASS="programlisting"
>&#13;    Object('hello.c', CCFLAGS='-DHELLO')
    Object('goodbye.c', CCFLAGS='-DGOODBYE')
    </PRE
><P
>&#13;
    One way to combine these object files
    into the resulting program
    would be to call the <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
>
    builder with the names of the object files
    listed as sources:

    </P
><PRE
CLASS="programlisting"
>&#13;    Object('hello.c', CCFLAGS='-DHELLO')
    Object('goodbye.c', CCFLAGS='-DGOODBYE')
    Program(['hello.o', 'goodbye.o'])
    </PRE
><P
>&#13;
    The problem with listing the names as strings
    is that our <TT
CLASS="filename"
>SConstruct</TT
> file is no longer portable
    across operating systems.
    It won't, for example, work on Windows
    because the object files there would be
    named <TT
CLASS="filename"
>hello.obj</TT
> and <TT
CLASS="filename"
>goodbye.obj</TT
>,
    not <TT
CLASS="filename"
>hello.o</TT
> and <TT
CLASS="filename"
>goodbye.o</TT
>.

    </P
><P
>&#13;
    A better solution is to assign the lists of targets
    returned by the calls to the <CODE
CLASS="function"
>Object</CODE
> builder to variables,
    which we can then concatenate in our
    call to the <CODE
CLASS="function"
>Program</CODE
> builder:

    </P
><PRE
CLASS="programlisting"
>&#13;      hello_list = Object('hello.c', CCFLAGS='-DHELLO')
      goodbye_list = Object('goodbye.c', CCFLAGS='-DGOODBYE')
      Program(hello_list + goodbye_list)
    </PRE
><P
>&#13;
    This makes our <TT
CLASS="filename"
>SConstruct</TT
> file portable again,
    the build output on Linux looking like:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o goodbye.o -c -DGOODBYE goodbye.c
       cc -o hello.o -c -DHELLO hello.c
       cc -o hello hello.o goodbye.o
    </PRE
><P
>&#13;
    And on Windows:

    </P
><PRE
CLASS="screen"
>&#13;       C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
       cl -DGOODBYE /c goodbye.c /Fogoodbye.obj
       cl -DHELLO /c hello.c /Fohello.obj
       link /nologo /OUT:hello.exe hello.obj goodbye.obj
    </PRE
><P
>&#13;
    We'll see examples of using the list of nodes
    returned by builder methods throughout
    the rest of this guide.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN747"
>5.2. Explicitly Creating File and Directory Nodes</A
></H2
><P
>&#13;
    It's worth mentioning here that
    <SPAN
CLASS="application"
>SCons</SPAN
> maintains a clear distinction
    between Nodes that represent files
    and Nodes that represent directories.
    <SPAN
CLASS="application"
>SCons</SPAN
> supports <CODE
CLASS="function"
>File</CODE
> and <CODE
CLASS="function"
>Dir</CODE
>
    functions that, repectively,
    return a file or directory Node:

    </P
><PRE
CLASS="programlisting"
>&#13;      hello_c = File('hello.c')
      Program(hello_c)

      classes = Dir('classes')
      Java(classes, 'src')
    </PRE
><P
>&#13;
    Normally, you don't need to call
    <CODE
CLASS="function"
>File</CODE
> or <CODE
CLASS="function"
>Dir</CODE
> directly,
    because calling a builder method automatically
    treats strings as the names of files or directories,
    and translates them into
    the Node objects for you.
    The <CODE
CLASS="function"
>File</CODE
> and <CODE
CLASS="function"
>Dir</CODE
> functions can come in handy
    in situations where you need to explicitly
    instruct <SPAN
CLASS="application"
>SCons</SPAN
> about the type of Node being
    passed to a builder or other function,
    or unambiguously refer to a specific
    file in a directory tree.
    

    </P
><P
>&#13;
    There are also times when you may need to
    refer to an entry in a file system
    without knowing in advance
    whether it's a file or a directory.
    For those situations,
    <SPAN
CLASS="application"
>SCons</SPAN
> also supports an <CODE
CLASS="function"
>Entry</CODE
> function,
    which returns a Node
    that can represent either a file or a directory.

    </P
><PRE
CLASS="programlisting"
>&#13;    xyzzy = Entry('xyzzy')
    </PRE
><P
>&#13;
    The returned <TT
CLASS="literal"
>xyzzy</TT
> Node
    will be turned into a file or directory Node
    the first time it is used by a builder method
    or other function that
    requires one vs. the other.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN767"
>5.3. Printing <CODE
CLASS="classname"
>Node</CODE
> File Names</A
></H2
><P
>&#13;
    One of the most common things you can do
    with a Node is use it to print the
    file name that the node represents.
    For example, the following <TT
CLASS="filename"
>SConstruct</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;      hello_c = File('hello.c')
      Program(hello_c)

      classes = Dir('classes')
      Java(classes, 'src')

      object_list = Object('hello.c')
      program_list = Program(object_list)
      print "The object file is:", object_list[0]
      print "The program file is:", program_list[0]
    </PRE
><P
>&#13;
    Would print the following file names on a POSIX system:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      The object file is: hello.o
      The program file is: hello
      cc -o hello.o -c hello.c
      cc -o hello hello.o
    </PRE
><P
>&#13;
    And the following file names on a Windows system:

    </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
      The object file is: hello.obj
      The program file is: hello.exe
      cl /nologo /c hello.c /Fohello.obj
      link /nologo /OUT:hello.exe hello.obj
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN779"
>5.4. Using a <CODE
CLASS="classname"
>Node</CODE
>'s File Name as a String</A
></H2
><P
>&#13;
    Printing a <CODE
CLASS="classname"
>Node</CODE
>'s name
    as described in the previous section
    works because the string representation of a <CODE
CLASS="classname"
>Node</CODE
>
    is the name of the file.
    If you want to do something other than
    print the name of the file,
    you can fetch it by using the builtin Python
    <CODE
CLASS="function"
>str</CODE
> function.
    For example, if you want to use the Python
    <CODE
CLASS="function"
>os.path.exists</CODE
>
    to figure out whether a file
    exists while the <TT
CLASS="filename"
>SConstruct</TT
> file
    is being read and executed,
    you can fetch the string as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;      import os.path
      program_list = Program('hello.c')
      program_name = str(program_list[0])
      if not os.path.exists(program_name):
          print program_name, "does not exist!"
    </PRE
><P
>&#13;
    Which executes as follows on a POSIX system:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      hello does not exist!
      cc -o hello.o -c hello.c
      cc -o hello hello.o
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-depends"
></A
>Chapter 6. Dependencies</H1
><P
>&#13;
  So far we've seen how <SPAN
CLASS="application"
>SCons</SPAN
> handles one-time builds.
  But one of the main functions of a build tool like <SPAN
CLASS="application"
>SCons</SPAN
>
  is to rebuild only the necessary things
  when source files change--or, put another way,
  <SPAN
CLASS="application"
>SCons</SPAN
> should <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
  waste time rebuilding things that have already been built.
  You can see this at work simply by re-invoking <SPAN
CLASS="application"
>SCons</SPAN
>
  after building our simple <SPAN
CLASS="application"
>hello</SPAN
> example:

  </P
><PRE
CLASS="screen"
>&#13;     % <KBD
CLASS="userinput"
>scons -Q</KBD
>
     cc -o hello.o -c hello.c
     cc -o hello hello.o
     % <KBD
CLASS="userinput"
>scons -Q</KBD
>
     scons: `.' is up to date.
  </PRE
><P
>&#13;
  The second time it is executed,
  <SPAN
CLASS="application"
>SCons</SPAN
> realizes that the <SPAN
CLASS="application"
>hello</SPAN
> program
  is up-to-date with respect to the current <TT
CLASS="filename"
>hello.c</TT
> source file,
  and avoids rebuilding it.
  You can see this more clearly by naming
  the <SPAN
CLASS="application"
>hello</SPAN
> program explicitly on the command line:

  </P
><PRE
CLASS="screen"
>&#13;     % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
     cc -o hello.o -c hello.c
     cc -o hello hello.o
     % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
     scons: `hello' is up to date.
  </PRE
><P
>&#13;
  Note that <SPAN
CLASS="application"
>SCons</SPAN
> reports <TT
CLASS="literal"
>"...is up to date"</TT
>
  only for target files named explicitly on the command line,
  to avoid cluttering the output.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN815"
>6.1. Deciding When an Input File Has Changed:  the <CODE
CLASS="function"
>Decider</CODE
> Function</A
></H2
><P
>&#13;
    Another aspect of avoiding unnecessary rebuilds
    is the fundamental build tool behavior
    of <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>rebuilding</I
></SPAN
>
    things when an input file changes,
    so that the built software is up to date.
    By default,
    <SPAN
CLASS="application"
>SCons</SPAN
> keeps track of this through an
    MD5 <TT
CLASS="literal"
>signature</TT
>, or checksum, of the contents of each file,
    although you can easily configure
    <SPAN
CLASS="application"
>SCons</SPAN
> to use the
    modification times (or time stamps)
    instead.
    You can even specify your own Python function
    for deciding if an input file has changed.

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN823"
>6.1.1. Using MD5 Signatures to Decide if a File Has Changed</A
></H3
><P
>&#13;
      By default,
      <SPAN
CLASS="application"
>SCons</SPAN
> keeps track of whether a file has changed
      based on an MD5 checksum of the file's contents,
      not the file's modification time.
      This means that you may be surprised by the
      default <SPAN
CLASS="application"
>SCons</SPAN
> behavior if you are used to the
      <SPAN
CLASS="application"
>Make</SPAN
> convention of forcing
      a rebuild by updating the file's modification time
      (using the <SPAN
CLASS="application"
>touch</SPAN
> command, for example):

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>touch hello.c</KBD
>
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         scons: `hello' is up to date.
      </PRE
><P
>&#13;
      Even though the file's modification time has changed,
      <SPAN
CLASS="application"
>SCons</SPAN
> realizes that the contents of the
      <TT
CLASS="filename"
>hello.c</TT
> file have <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
> changed,
      and therefore that the <SPAN
CLASS="application"
>hello</SPAN
> program
      need not be rebuilt.
      This avoids unnecessary rebuilds when,
      for example, someone rewrites the
      contents of a file without making a change.
      But if the contents of the file really do change,
      then <SPAN
CLASS="application"
>SCons</SPAN
> detects the change
      and rebuilds the program as required:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>edit hello.c</KBD
>
             [CHANGE THE CONTENTS OF hello.c]
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
      </PRE
><P
>&#13;
      Note that you can, if you wish,
      specify this default behavior
      (MD5 signatures) explicitly
      using the <CODE
CLASS="function"
>Decider</CODE
> function as follows:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        Decider('MD5')
      </PRE
><P
>&#13;
      You can also use the string <TT
CLASS="literal"
>'content'</TT
>
      as a synonym for <TT
CLASS="literal"
>'MD5'</TT
>
      when calling the <CODE
CLASS="function"
>Decider</CODE
> function.

      </P
><DIV
CLASS="section"
><HR><H4
CLASS="section"
><A
NAME="AEN851"
>6.1.1.1. Ramifications of Using MD5 Signatures</A
></H4
><P
>&#13;
        Using MD5 Signatures to decide if an input file has changed
        has one surprising benefit:
        if a source file has been changed
        in such a way that the contents of the
        rebuilt target file(s)
        will be exactly the same as the last time
        the file was built,
        then any "downstream" target files
        that depend on the rebuilt-but-not-changed target
        file actually need not be rebuilt.

        </P
><P
>&#13;
        So if, for example,
        a user were to only change a comment in a <TT
CLASS="filename"
>hello.c</TT
> file,
        then the rebuilt <TT
CLASS="filename"
>hello.o</TT
> file
        would be exactly the same as the one previously built
        (assuming the compiler doesn't put any build-specific
        information in the object file).
        <SPAN
CLASS="application"
>SCons</SPAN
> would then realize that it would not
        need to rebuild the <SPAN
CLASS="application"
>hello</SPAN
> program as follows:

        </P
><PRE
CLASS="screen"
>&#13;           % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
           cc -o hello.o -c hello.c
           cc -o hello hello.o
           % <KBD
CLASS="userinput"
>edit hello.c</KBD
>
             [CHANGE A COMMENT IN hello.c]
           % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
           cc -o hello.o -c hello.c
           scons: `hello' is up to date.
        </PRE
><P
>&#13;
        In essence, <SPAN
CLASS="application"
>SCons</SPAN
>
        "short-circuits" any dependent builds
        when it realizes that a target file
        has been rebuilt to exactly the same file as the last build.
        This does take some extra processing time
        to read the contents of the target (<TT
CLASS="filename"
>hello.o</TT
>) file,
        but often saves time when the rebuild that was avoided
        would have been time-consuming and expensive.

        </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN866"
>6.1.2. Using Time Stamps to Decide If a File Has Changed</A
></H3
><P
>&#13;
      If you prefer, you can
      configure <SPAN
CLASS="application"
>SCons</SPAN
> to use the modification time
      of a file, not the file contents,
      when deciding if a target needs to be rebuilt.
      <SPAN
CLASS="application"
>SCons</SPAN
> gives you two ways to use time stamps
      to decide if an input file has changed
      since the last time a target has been built.

      </P
><P
>&#13;
      The most familiar way to use time stamps
      is the way <SPAN
CLASS="application"
>Make</SPAN
> does:
      that is, have <SPAN
CLASS="application"
>SCons</SPAN
> decide
      and target must be rebuilt if
      if a source file's modification time is
      <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>newer</I
></SPAN
>
      than the target file.
      To do this, call the <CODE
CLASS="function"
>Decider</CODE
>
      function as follows:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        Decider('timestamp-newer')
      </PRE
><P
>&#13;
      This makes <SPAN
CLASS="application"
>SCons</SPAN
> act like <SPAN
CLASS="application"
>Make</SPAN
>
      when a file's modification time is updated
      (using the <SPAN
CLASS="application"
>touch</SPAN
> command, for example):

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>touch hello.c</KBD
>
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
      </PRE
><P
>&#13;
      And, in fact, because this behavior is the same
      as the behavior of <SPAN
CLASS="application"
>Make</SPAN
>,
      you can also use the string <TT
CLASS="literal"
>'make'</TT
>
      as a synonym for <TT
CLASS="literal"
>'timestamp-newer'</TT
>
      when calling the <CODE
CLASS="function"
>Decider</CODE
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        Decider('make')
      </PRE
><P
>&#13;
      One drawback to using times stamps exactly like <SPAN
CLASS="application"
>Make</SPAN
>
      is that if an input file's modification time suddenly
      becomes <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>older</I
></SPAN
> than a target file,
      the target file will not be rebuilt.
      This can happen if an old copy of a source file is restored
      from a backup archive, for example.
      The contents of the restored file will likely be different
      than they were the last time a dependent target was built,
      but the target won't be rebuilt
      because the modification time of the source file
      is not newer than the target.

      </P
><P
>&#13;
      Because <SPAN
CLASS="application"
>SCons</SPAN
> actually stores information
      about the source files' time stamps whenever a target is built,
      it can handle this situation by checking for
      an exact match of the source file time stamp,
      instead of just whether or not the source file
      is newer than the target file.
      To do this, specify the argument
      <TT
CLASS="literal"
>'timestamp-match'</TT
>
      when calling the <CODE
CLASS="function"
>Decider</CODE
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        Decider('timestamp-match')
      </PRE
><P
>&#13;
      When configured this way,
      <SPAN
CLASS="application"
>SCons</SPAN
> will rebuild a target whenever
      a source file's modification time has changed.
      So if we use the <TT
CLASS="literal"
>touch -t</TT
>
      option to change the modification time of
      <TT
CLASS="filename"
>hello.c</TT
> to an old date (January 1, 1989),
      <SPAN
CLASS="application"
>SCons</SPAN
> will still rebuild the target file:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>touch -t 198901010000 hello.c</KBD
>
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         scons: `hello' is up to date.
      </PRE
><P
>&#13;
      In general, the only reason to prefer
      <TT
CLASS="literal"
>timestamp-newer</TT
>
      instead of
      <TT
CLASS="literal"
>timestamp-match</TT
>,
      would be if you have some specific reason
      to require this <SPAN
CLASS="application"
>Make</SPAN
>-like behavior of 
      not rebuilding a target when an otherwise-modified
      source file is older.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN912"
>6.1.3. Deciding If a File Has Changed Using Both MD Signatures and Time Stamps</A
></H3
><P
>&#13;
      As a performance enhancement,
      <SPAN
CLASS="application"
>SCons</SPAN
> provides a way to use
      MD5 checksums of file contents
      but to only read the contents
      whenever the file's timestamp has changed.
      To do this, call the <CODE
CLASS="function"
>Decider</CODE
>
      function with <TT
CLASS="literal"
>'MD5-timestamp'</TT
>
      argument as follows:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        Decider('MD5-timestamp')
      </PRE
><P
>&#13;
      So configured, <SPAN
CLASS="application"
>SCons</SPAN
> will still behave like
      it does when using <TT
CLASS="literal"
>Decider('MD5')</TT
>:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>touch hello.c</KBD
>
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         scons: `hello' is up to date.
         % <KBD
CLASS="userinput"
>edit hello.c</KBD
>
             [CHANGE THE CONTENTS OF hello.c]
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
      </PRE
><P
>&#13;
      However, the second call to <SPAN
CLASS="application"
>SCons</SPAN
> in the above output,
      when the build is up-to-date,
      will have been performed by simply looking at the
      modification time of the <TT
CLASS="filename"
>hello.c</TT
> file,
      not by opening it and performing
      an MD5 checksum calcuation on its contents.
      This can significantly speed up many up-to-date builds.

      </P
><P
>&#13;
      The only drawback to using
      <TT
CLASS="literal"
>Decider('MD5-timestamp')</TT
>
      is that <SPAN
CLASS="application"
>SCons</SPAN
> will <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
      rebuild a target file if a source file was modified
      within one second of the last time <SPAN
CLASS="application"
>SCons</SPAN
> built the file.
      While most developers are programming,
      this isn't a problem in practice,
      since it's unlikely that someone will have built
      and then thought quickly enought to make a substantive
      change to a source file within one second.
      Certain build scripts or
      continuous integration tools may, however,
      rely on the ability to applying changes to files
      automatically and then rebuild as quickly as possible,
      in which case use of
      <TT
CLASS="literal"
>Decider('MD5-timestamp')</TT
>
      may not be appropriate.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN937"
>6.1.4. Writing Your Own Custom <CODE
CLASS="function"
>Decider</CODE
> Function</A
></H3
><P
>&#13;
      The different string values that we've passed to
      the <CODE
CLASS="function"
>Decider</CODE
> function are essentially used by <SPAN
CLASS="application"
>SCons</SPAN
>
      to pick one of several specific internal functions
      that implement various ways of deciding if a dependency
      (usually a source file)
      has changed since a target file has been built.
      As it turns out,
      you can also supply your own function
      to decide if a dependency has changed.

      </P
><P
>&#13;
      For example, suppose we have an input file
      that contains a lot of data,
      in some specific regular format,
      that is used to rebuild a lot of different target files,
      but each target file really only depends on
      one particular section of the input file.
      We'd like to have each target file depend on
      only its section of the input file.
      However, since the input file may contain a lot of data,
      we only want to open the input file if its timestamp has changed.
      This could done with a custom
      <CODE
CLASS="function"
>Decider</CODE
> function that might look something like this:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        def decide_if_changed(dependency, target, prev_ni):
            if self.get_timestamp() != prev_ni.timestamp:
                dep = str(dependency)
                tgt = str(target)
                if specific_part_of_file_has_changed(dep, tgt):
                    return True
            return False
        Decider(decide_if_changed)
      </PRE
><P
>&#13;
      Note that in the function definition,
      the <CODE
CLASS="varname"
>dependency</CODE
>
      (input file) is the first argument,
      and then the <CODE
CLASS="varname"
>target</CODE
>.
      Both of these are passed to the functions as
      SCons <CODE
CLASS="classname"
>Node</CODE
> objects,
      which we convert to strings using the Python
      <CODE
CLASS="function"
>str()</CODE
>.

      </P
><P
>&#13;
      The third argument, <CODE
CLASS="varname"
>prev_ni</CODE
>,
      is an object that holds the
      signature or timestamp information
      that was recorded about the dependency
      the last time the target was built.
      A <CODE
CLASS="varname"
>prev_ni</CODE
> object can hold
      different information,
      depending on the type of thing that the
      <CODE
CLASS="varname"
>dependency</CODE
> argument represents.
      For normal files,
      the <CODE
CLASS="varname"
>prev_ni</CODE
> object
      has the following attributes:

      </P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
>.csig</DT
><DD
><P
>&#13;        The <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>content signature</I
></SPAN
>,
        or MD5 checksum, of the contents of the
        <CODE
CLASS="varname"
>dependency</CODE
>
        file the list time the <CODE
CLASS="varname"
>target</CODE
> was built.
        </P
></DD
><DT
>.size</DT
><DD
><P
>&#13;        The size in bytes of the <CODE
CLASS="varname"
>dependency</CODE
>
        file the list time the target was built.
        </P
></DD
><DT
>.timestamp</DT
><DD
><P
>&#13;        The modification time of the <CODE
CLASS="varname"
>dependency</CODE
>
        file the list time the <CODE
CLASS="varname"
>target</CODE
> was built.
        </P
></DD
></DL
></DIV
><P
>&#13;
      Note that ignoring some of the arguments
      in your custom <CODE
CLASS="function"
>Decider</CODE
> function
      is a perfectly normal thing to do,
      if they don't impact the way you want to
      decide if the dependency file has changed.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN977"
>6.1.5. Mixing Different Ways of Deciding If a File Has Changed</A
></H3
><P
>&#13;
      The previous examples have all demonstrated calling
      the global <CODE
CLASS="function"
>Decider</CODE
> function
      to configure all dependency decisions that <SPAN
CLASS="application"
>SCons</SPAN
> makes.
      Sometimes, however, you want to be able to configure
      different decision-making for different targets.
      When that's necessary, you can use the
      <CODE
CLASS="function"
>env.Decider</CODE
>
      method to affect only the configuration
      decisions for targets built with a
      specific construction environment.

      </P
><P
>&#13;
      For example, if we arbitrarily want to build
      one program using MD5 checkums
      and another use file modification times
      from the same source
      we might configure it this way:

      </P
><PRE
CLASS="programlisting"
>&#13;        env1 = Environment(CPPPATH = ['.'])
        env2 = env1.Clone()
        env2.Decider('timestamp-match')
        env1.Program('prog-MD5', 'program1.c')
        env2.Program('prog-timestamp', 'program2.c')
      </PRE
><P
>&#13;
      If both of the programs include the same
      <TT
CLASS="filename"
>inc.h</TT
> file,
      then updating the modification time of
      <TT
CLASS="filename"
>inc.h</TT
>
      (using the <SPAN
CLASS="application"
>touch</SPAN
> command)
      will cause only <TT
CLASS="filename"
>prog-timestamp</TT
>
      to be rebuilt:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o program1.o -c -I. program1.c
         cc -o prog-MD5 program1.o
         cc -o program2.o -c -I. program2.c
         cc -o prog-timestamp program2.o
         % <KBD
CLASS="userinput"
>touch inc.h</KBD
>
         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o program2.o -c -I. program2.c
         cc -o prog-timestamp program2.o
      </PRE
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN994"
>6.2. Older Functions for Deciding When an Input File Has Changed</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> still supports two functions that used to be the
    primary methods for configuring the
    decision about whether or not an input file has changed.
    Although they're not officially deprecated yet,
    their use is discouraged,
    mainly because they rely on a somewhat
    confusing distinction between how
    source files and target files are handled.
    These functions are documented here mainly in case you
    encounter them in existing <TT
CLASS="filename"
>SConscript</TT
> files.

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN999"
>6.2.1. The <CODE
CLASS="function"
>SourceSignatures</CODE
> Function</A
></H3
><P
>&#13;
      The <CODE
CLASS="function"
>SourceSignatures</CODE
> function is fairly straightforward,
      and supports two different argument values
      to configure whether source file changes should be decided
      using MD5 signatures:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        SourceSignatures('MD5')
      </PRE
><P
>&#13;
      Or using time stamps:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        SourceSignatures('timestamp')
      </PRE
><P
>&#13;
      These are roughly equivalent to specifying
      <CODE
CLASS="function"
>Decider('MD5')</CODE
>
      or
      <CODE
CLASS="function"
>Decider('timestamp-match')</CODE
>,
      respectively,
      although it only affects how SCons makes
      decisions about dependencies on
      <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>source</I
></SPAN
> files--that is,
      files that are not built from any other files.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1011"
>6.2.2. The <CODE
CLASS="function"
>TargetSignatures</CODE
> Function</A
></H3
><P
>&#13;
      The <CODE
CLASS="function"
>TargetSignatures</CODE
> function
      specifies how <SPAN
CLASS="application"
>SCons</SPAN
> decides
      when a target file has changed
      <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>when it is used as a
      dependency of (input to) another target</I
></SPAN
>--that is,
      the <CODE
CLASS="function"
>TargetSignatures</CODE
> function configures
      how the signatures of "intermediate" target files
      are used when deciding if a "downstream" target file
      must be rebuilt.
      <A
NAME="AEN1019"
HREF="#FTN.AEN1019"
><SPAN
CLASS="footnote"
>[2]</SPAN
></A
>

      </P
><P
>&#13;
      The <CODE
CLASS="function"
>TargetSignatures</CODE
> function supports the same
      <TT
CLASS="literal"
>'MD5'</TT
> and <TT
CLASS="literal"
>'timestamp'</TT
>
      argument values that are supported by the <CODE
CLASS="function"
>SourceSignatures</CODE
>,
      with the same meanings, but applied to target files.
      That is, in the example:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        TargetSignatures('MD5')
      </PRE
><P
>&#13;
      The MD5 checksum of the <TT
CLASS="filename"
>hello.o</TT
> target file
      will be used to decide if it has changed since the last
      time the "downstream" <SPAN
CLASS="application"
>hello</SPAN
> target file was built.
      And in the example:
      
      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        TargetSignatures('timestamp')
      </PRE
><P
>&#13;
      The modification time of the <TT
CLASS="filename"
>hello.o</TT
> target file
      will be used to decide if it has changed since the last
      time the "downstream" <SPAN
CLASS="application"
>hello</SPAN
> target file was built.

      </P
><P
>&#13;
      The <CODE
CLASS="function"
>TargetSignatures</CODE
> function supports
      two additional argument values:
      <TT
CLASS="literal"
>'source'</TT
> and <TT
CLASS="literal"
>'build'</TT
>.
      The <TT
CLASS="literal"
>'source'</TT
> argument
      specifies that decisions involving
      whether target files have changed
      since a previous build
      should use the same behavior
      for the decisions configured for source files
      (using the <CODE
CLASS="function"
>SourceSignatures</CODE
> function).
      So in the example:

      </P
><PRE
CLASS="programlisting"
>&#13;        Program('hello.c')
        TargetSignatures('source')
        SourceSignatures('timestamp')
      </PRE
><P
>&#13;
      All files, both targets and sources,
      will use modification times
      when deciding if an input file
      has changed since the last
      time a target was built.

      </P
><P
>&#13;
      Lastly, the <TT
CLASS="literal"
>'build'</TT
> argument
      specifies that <SPAN
CLASS="application"
>SCons</SPAN
> should examine
      the build status of a target file
      and always rebuild a "downstream" target
      if the target file was itself rebuilt,
      without re-examining the contents or timestamp
      of the newly-built target file.
      If the target file was not rebuilt during
      this <SPAN
CLASS="application"
>scons</SPAN
> invocation,
      then the target file will be examined
      the same way as configured by
      the <CODE
CLASS="function"
>SourceSignature</CODE
> call
      to decide if it has changed.

      </P
><P
>&#13;
      This mimics the behavior of
      <TT
CLASS="literal"
>build signatures</TT
>
      in earlier versions of <SPAN
CLASS="application"
>SCons</SPAN
>.
      A <TT
CLASS="literal"
>build signature</TT
> re-combined
      signatures of all the input files
      that went into making the target file,
      so that the target file itself
      did not need to have its contents read
      to compute an MD5 signature.
      This can improve performance for some configurations,
      but is generally not as effective as using
      <TT
CLASS="literal"
>Decider('MD5-timestamp')</TT
>.

      </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1056"
>6.3. Implicit Dependencies:  The <CODE
CLASS="envar"
>$CPPPATH</CODE
> Construction Variable</A
></H2
><P
>&#13;
    Now suppose that our "Hello, World!" program
    actually has an <TT
CLASS="literal"
>#include</TT
> line
    to include the <TT
CLASS="filename"
>hello.h</TT
> file in the compilation:

    </P
><PRE
CLASS="programlisting"
>&#13;       #include &#60;hello.h&#62;
       int
       main()
       {
           printf("Hello, %s!\n", string);
       }
    </PRE
><P
>&#13;
    And, for completeness, the <TT
CLASS="filename"
>hello.h</TT
> file looks like this:

    </P
><PRE
CLASS="programlisting"
>&#13;       #define string    "world"
      </PRE
><P
>&#13;
    In this case, we want <SPAN
CLASS="application"
>SCons</SPAN
> to recognize that,
    if the contents of the <TT
CLASS="filename"
>hello.h</TT
> file change,
    the <SPAN
CLASS="application"
>hello</SPAN
> program must be recompiled.
    To do this, we need to modify the
    <TT
CLASS="filename"
>SConstruct</TT
> file like so:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('hello.c', CPPPATH = '.')
      </PRE
><P
>&#13;
    The <A
HREF="#cv-CPPPATH"
><CODE
CLASS="envar"
>$CPPPATH</CODE
></A
> value
    tells <SPAN
CLASS="application"
>SCons</SPAN
> to look in the current directory
    (<TT
CLASS="literal"
>'.'</TT
>)
    for any files included by C source files
    (<TT
CLASS="filename"
>.c</TT
> or <TT
CLASS="filename"
>.h</TT
> files).
    With this assignment in the <TT
CLASS="filename"
>SConstruct</TT
> file:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       cc -o hello.o -c -I. hello.c
       cc -o hello hello.o
       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       scons: `hello' is up to date.
       % <KBD
CLASS="userinput"
>edit hello.h</KBD
>
           [CHANGE THE CONTENTS OF hello.h]
       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       cc -o hello.o -c -I. hello.c
       cc -o hello hello.o
    </PRE
><P
>&#13;
    First, notice that <SPAN
CLASS="application"
>SCons</SPAN
>
    added the <TT
CLASS="literal"
>-I.</TT
> argument
    from the <CODE
CLASS="envar"
>$CPPPATH</CODE
> variable
    so that the compilation would find the
    <TT
CLASS="filename"
>hello.h</TT
> file in the local directory.

    </P
><P
>&#13;
    Second, realize that <SPAN
CLASS="application"
>SCons</SPAN
> knows that the <SPAN
CLASS="application"
>hello</SPAN
>
    program must be rebuilt
    because it scans the contents of
    the <TT
CLASS="filename"
>hello.c</TT
> file
    for the <TT
CLASS="literal"
>#include</TT
> lines that indicate
    another file is being included in the compilation.
    <SPAN
CLASS="application"
>SCons</SPAN
> records these as
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>implicit dependencies</I
></SPAN
>
    of the target file,
    Consequently,
    when the <TT
CLASS="filename"
>hello.h</TT
> file changes,
    <SPAN
CLASS="application"
>SCons</SPAN
> realizes that the <TT
CLASS="filename"
>hello.c</TT
> file includes it,
    and rebuilds the resulting <SPAN
CLASS="application"
>hello</SPAN
> program
    that depends on both the <TT
CLASS="filename"
>hello.c</TT
> and <TT
CLASS="filename"
>hello.h</TT
> files.

    </P
><P
>&#13;
    Like the <A
HREF="#cv-LIBPATH"
><CODE
CLASS="envar"
>$LIBPATH</CODE
></A
> variable,
    the <CODE
CLASS="envar"
>$CPPPATH</CODE
> variable
    may be a list of directories,
    or a string separated by
    the system-specific path separation character
    (':' on POSIX/Linux, ';' on Windows).
    Either way, <SPAN
CLASS="application"
>SCons</SPAN
> creates the
    right command-line options
    so that the following example:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('hello.c', CPPPATH = ['include', '/home/project/inc'])
    </PRE
><P
>&#13;
    Will look like this on POSIX or Linux:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       cc -o hello.o -c -Iinclude -I/home/project/inc hello.c
       cc -o hello hello.o
    </PRE
><P
>&#13;
    And like this on Windows:

    </P
><PRE
CLASS="screen"
>&#13;       C:\&#62;<KBD
CLASS="userinput"
>scons -Q hello.exe</KBD
>
       cl /nologo /Iinclude /I\home\project\inc /c hello.c /Fohello.obj
       link /nologo /OUT:hello.exe hello.obj
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1115"
>6.4. Caching Implicit Dependencies</A
></H2
><P
>&#13;
    Scanning each file for <TT
CLASS="literal"
>#include</TT
> lines
    does take some extra processing time.
    When you're doing a full build of a large system,
    the scanning time is usually a very small percentage
    of the overall time spent on the build.
    You're most likely to notice the scanning time,
    however, when you <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>rebuild</I
></SPAN
>
    all or part of a large system:
    <SPAN
CLASS="application"
>SCons</SPAN
> will likely take some extra time to "think about"
    what must be built before it issues the
    first build command
    (or decides that everything is up to date
    and nothing must be rebuilt).

 

    </P
><P
>&#13;
    In practice, having <SPAN
CLASS="application"
>SCons</SPAN
> scan files saves time
    relative to the amount of potential time
    lost to tracking down subtle problems
    introduced by incorrect dependencies.
    Nevertheless, the "waiting time"
    while <SPAN
CLASS="application"
>SCons</SPAN
> scans files can annoy
    individual developers waiting for their builds to finish.
    Consequently, <SPAN
CLASS="application"
>SCons</SPAN
> lets you cache
    the implicit dependencies
    that its scanners find,
    for use by later builds.
    You can do this by specifying the
    <TT
CLASS="literal"
>--implicit-cache</TT
> option on the command line:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q --implicit-cache hello</KBD
>
       cc -o hello.o -c hello.c
       cc -o hello hello.o
       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       scons: `hello' is up to date.
    </PRE
><P
>&#13;
    If you don't want to specify <TT
CLASS="literal"
>--implicit-cache</TT
>
    on the command line each time,
    you can make it the default behavior for your build
    by setting the <TT
CLASS="literal"
>implicit_cache</TT
> option
    in an <TT
CLASS="filename"
>SConscript</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;       SetOption('implicit_cache', 1)
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> does not cache implicit dependencies like this by default
    because the <TT
CLASS="literal"
>--implicit-cache</TT
> causes <SPAN
CLASS="application"
>SCons</SPAN
> to simply use the implicit
    dependencies stored during the last run, without any checking
    for whether or not those dependencies are still correct.
    Specifically, this means <TT
CLASS="literal"
>--implicit-cache</TT
> instructs <SPAN
CLASS="application"
>SCons</SPAN
>
    to <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
> rebuild "correctly" in the
    following cases:


    </P
><P
></P
><UL
><LI
><P
>&#13;
        When <TT
CLASS="literal"
>--implicit-cache</TT
> is used, <SPAN
CLASS="application"
>SCons</SPAN
> will ignore any changes that
        may have been made to search paths
        (like <CODE
CLASS="envar"
>$CPPPATH</CODE
> or <CODE
CLASS="envar"
>$LIBPATH</CODE
>,).
        This can lead to <SPAN
CLASS="application"
>SCons</SPAN
> not rebuilding a file if a change to
        <CODE
CLASS="envar"
>$CPPPATH</CODE
> would normally cause a different, same-named file from
        a different directory to be used.

        </P
></LI
><LI
><P
>&#13;
        When <TT
CLASS="literal"
>--implicit-cache</TT
> is used, <SPAN
CLASS="application"
>SCons</SPAN
> will not detect if a
        same-named file has been added to a directory that is earlier in
        the search path than the directory in which the file was found
        last time.

        </P
></LI
></UL
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1154"
>6.4.1. The <TT
CLASS="literal"
>--implicit-deps-changed</TT
> Option</A
></H3
><P
>&#13;
      When using cached implicit dependencies,
      sometimes you want to "start fresh"
      and have <SPAN
CLASS="application"
>SCons</SPAN
> re-scan the files
      for which it previously cached the dependencies.
      For example,
      if you have recently installed a new version of
      external code that you use for compilation,
      the external header files will have changed
      and the previously-cached implicit dependencies
      will be out of date.
      You can update them by
      running <SPAN
CLASS="application"
>SCons</SPAN
> with the <TT
CLASS="literal"
>--implicit-deps-changed</TT
> option:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q --implicit-deps-changed hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         scons: `hello' is up to date.
      </PRE
><P
>&#13;
      In this case, <SPAN
CLASS="application"
>SCons</SPAN
> will re-scan all of the implicit dependencies
      and cache updated copies of the information.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1166"
>6.4.2. The <TT
CLASS="literal"
>--implicit-deps-unchanged</TT
> Option</A
></H3
><P
>&#13;
      By default when caching dependencies,
      <SPAN
CLASS="application"
>SCons</SPAN
> notices when a file has been modified
      and re-scans the file for any updated
      implicit dependency information.
      Sometimes, however, you may want
      to force <SPAN
CLASS="application"
>SCons</SPAN
> to use the cached implicit dependencies,
      even if the source files changed.
      This can speed up a build for example,
      when you have changed your source files
      but know that you haven't changed
      any <TT
CLASS="literal"
>#include</TT
> lines.
      In this case,
      you can use the <TT
CLASS="literal"
>--implicit-deps-unchanged</TT
> option:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q --implicit-deps-unchanged hello</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
         scons: `hello' is up to date.
      </PRE
><P
>&#13;
      In this case,
      <SPAN
CLASS="application"
>SCons</SPAN
> will assume that the cached implicit
      dependencies are correct and
      will not bother to re-scan changed files.
      For typical builds after small,
      incremental changes to source files,
      the savings may not be very big,
      but sometimes every bit of
      improved performance counts.

      </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1179"
>6.5. Explicit Dependencies:  the <CODE
CLASS="function"
>Depends</CODE
> Function</A
></H2
><P
>&#13;
    Sometimes a file depends on another file
    that is not detected by an <SPAN
CLASS="application"
>SCons</SPAN
> scanner.
    For this situation,
    <SPAN
CLASS="application"
>SCons</SPAN
> allows you to specific explicitly that one file
    depends on another file,
    and must be rebuilt whenever that file changes.
    This is specified using the <CODE
CLASS="function"
>Depends</CODE
> method:

    </P
><PRE
CLASS="programlisting"
>&#13;       hello = Program('hello.c')
       Depends(hello, 'other_file')
    </PRE
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       cc -c hello.c -o hello.o
       cc -o hello hello.o
       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       scons: `hello' is up to date.
       % <KBD
CLASS="userinput"
>edit other_file</KBD
>
           [CHANGE THE CONTENTS OF other_file]
       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       cc -c hello.c -o hello.o
       cc -o hello hello.o
    </PRE
><P
>&#13;
    Note that the dependency
    (the second argument to <CODE
CLASS="function"
>Depends</CODE
>)
    may also be a list of Node objects
    (for example, as returned by a call to a Builder):

    </P
><PRE
CLASS="programlisting"
>&#13;       hello = Program('hello.c')
       goodbye = Program('goodbye.c')
       Depends(hello, goodbye)
    </PRE
><P
>&#13;
    in which case the dependency or dependencies
    will be built before the target(s):

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
       cc -c goodbye.c -o goodbye.o
       cc -o goodbye goodbye.o
       cc -c hello.c -o hello.o
       cc -o hello hello.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1198"
>6.6. Dependencies From External Files:  the <CODE
CLASS="function"
>ParseDepends</CODE
>
  Function</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> has built-in scanners for a number of languages. Sometimes
    these scanners fail to extract certain implicit dependencies due
    to limitations of the scanner implementation.

    </P
><P
>&#13;
    The following example illustrates a case where the built-in C
    scanner is unable to extract the implicit dependency on a header
    file.

    </P
><PRE
CLASS="programlisting"
>&#13;      #define FOO_HEADER &#60;foo.h&#62;
      #include FOO_HEADER

      int main() {
          return FOO;
      }
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c -I. hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>edit foo.h</KBD
>
         [CHANGE CONTENTS OF foo.h]
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      scons: `.' is up to date.
    </PRE
><P
>&#13;
    Apparently, the scanner does not know about the header dependency.
    Being not a full-fledged C preprocessor, the scanner does not
    expand the macro.

    </P
><P
>&#13;
    In these cases, you may also use the compiler to extract the
    implicit dependencies. <CODE
CLASS="function"
>ParseDepends</CODE
> can parse the contents of
    the compiler output in the style of <SPAN
CLASS="application"
>Make</SPAN
>, and explicitly
    establish all of the listed dependencies.

    </P
><P
>&#13;
    The following example uses <CODE
CLASS="function"
>ParseDepends</CODE
> to process a compiler
    generated dependency file which is generated as a side effect
    during compilation of the object file:

    </P
><PRE
CLASS="programlisting"
>&#13;      obj = Object('hello.c', CCFLAGS='-MD -MF hello.d', CPPPATH='.')
      SideEffect('hello.d', obj)
      ParseDepends('hello.d')
      Program('hello', obj)
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c -MD -MF hello.d -I. hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>edit foo.h</KBD
>
         [CHANGE CONTENTS OF foo.h]
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c -MD -MF hello.d -I. hello.c
    </PRE
><P
>&#13;
    Parsing dependencies from a compiler-generated
    <TT
CLASS="filename"
>.d</TT
> file has a chicken-and-egg problem, that
    causes unnecessary rebuilds:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c -MD -MF hello.d -I. hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q --debug=explain</KBD
>
      scons: rebuilding `hello.o' because `foo.h' is a new dependency
      cc -o hello.o -c -MD -MF hello.d -I. hello.c
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      scons: `.' is up to date.
    </PRE
><P
>&#13;
    In the first pass, the dependency file is generated while the
    object file is compiled. At that time, <SPAN
CLASS="application"
>SCons</SPAN
> does not know about
    the dependency on <TT
CLASS="filename"
>foo.h</TT
>. In the second pass,
    the object file is regenerated because <TT
CLASS="filename"
>foo.h</TT
>
    is detected as a new dependency.

    </P
><P
>&#13;
    <CODE
CLASS="function"
>ParseDepends</CODE
> immediately reads the specified file at invocation
    time and just returns if the file does not exist. A dependency
    file generated during the build process is not automatically
    parsed again. Hence, the compiler-extracted dependencies are not
    stored in the signature database during the same build pass. This
    limitation of <CODE
CLASS="function"
>ParseDepends</CODE
> leads to unnecessary recompilations.
    Therefore, <CODE
CLASS="function"
>ParseDepends</CODE
> should only be used if scanners are not
    available for the employed language or not powerful enough for the
    specific task.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1234"
>6.7. Ignoring Dependencies:  the <CODE
CLASS="function"
>Ignore</CODE
> Function</A
></H2
><P
>&#13;
    Sometimes it makes sense
    to not rebuild a program,
    even if a dependency file changes.
    In this case,
    you would tell <SPAN
CLASS="application"
>SCons</SPAN
> specifically
    to ignore a dependency as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;      hello = Program('hello.c')
      Ignore(hello, 'hello.h')
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
      cc -c -o hello.o hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
      scons: `hello' is up to date.
      % <KBD
CLASS="userinput"
>edit hello.h</KBD
>
        [CHANGE THE CONTENTS OF hello.h]
      % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
      scons: `hello' is up to date.
    </PRE
><P
>&#13;
    Now, the above example is a little contrived,
    because it's hard to imagine a real-world situation
    where you wouldn't want to rebuild <SPAN
CLASS="application"
>hello</SPAN
>
    if the <TT
CLASS="filename"
>hello.h</TT
> file changed.
    A more realistic example
    might be if the <SPAN
CLASS="application"
>hello</SPAN
>
    program is being built in a
    directory that is shared between multiple systems
    that have different copies of the
    <TT
CLASS="filename"
>stdio.h</TT
> include file.
    In that case,
    <SPAN
CLASS="application"
>SCons</SPAN
> would notice the differences between
    the different systems' copies of <TT
CLASS="filename"
>stdio.h</TT
>
    and would rebuild <SPAN
CLASS="application"
>hello</SPAN
>
    each time you change systems.
    You could avoid these rebuilds as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;       hello = Program('hello.c', CPPPATH=['/usr/include'])
       Ignore(hello, '/usr/include/stdio.h')
    </PRE
><P
>&#13;    <CODE
CLASS="function"
>Ignore</CODE
> can also be used to prevent a generated file from being built 
    by default. This is due to the fact that directories depend on 
    their contents.  So to ignore a generated file from the default build, 
    you specify that the directory should ignore the generated file.
    Note that the file will still be built if the user specifically 
    requests the target on scons command line, or if the file is
    a dependency of another file which is requested and/or is built
    by default.
    </P
><PRE
CLASS="programlisting"
>&#13;      hello_obj=Object('hello.c')
      hello = Program(hello_obj)
      Ignore('.',[hello,hello_obj])
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      scons: `.' is up to date.
      % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q hello</KBD
>
      scons: `hello' is up to date.
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1261"
>6.8. Order-Only Dependencies:  the <CODE
CLASS="function"
>Requires</CODE
> Function</A
></H2
><P
>&#13;
    Occasionally,
    it may be useful to specify that a certain
    file or directory must, if necessary,
    be built or created before some other target is built,
    but that changes to that file or directory
    do <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
    require that the target itself be rebuilt.
    Such a relationship is called an
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>order-only dependency</I
></SPAN
>
    because it only affects the order in which
    things must be built--the dependency before the target--but
    it is not a strict dependency relationship
    because the target should not
    change in response to changes in the dependent file.

    </P
><P
>&#13;
    For example, suppose that you want to create a file
    every time you run a build
    that identifies the time the build was performed,
    the version number, etc.,
    and which is included in every program that you build.
    The version file's contents will change every build.
    If you specify a normal dependency relationship,
    then every program that depends on
    that file would be rebuilt every time you ran <SPAN
CLASS="application"
>SCons</SPAN
>.
    For example, we could use some Python code in
    a <TT
CLASS="filename"
>SConstruct</TT
> file to create a new <TT
CLASS="filename"
>version.c</TT
> file
    with a string containing the current date every time
    we run <SPAN
CLASS="application"
>SCons</SPAN
>,
    and then link a program with the resulting object file
    by listing <TT
CLASS="filename"
>version.c</TT
> in the sources:

    </P
><PRE
CLASS="programlisting"
>&#13;      import time

      version_c_text = """
      char *date = "%s";
      """ % time.ctime(time.time())
      open('version.c', 'w').write(version_c_text)

      hello = Program(['hello.c', 'version.c'])
    </PRE
><P
>&#13;
    If we list <TT
CLASS="filename"
>version.c</TT
> as an actual source file,
    though, then <TT
CLASS="filename"
>version.o</TT
>
    will get rebuilt every time we run <SPAN
CLASS="application"
>SCons</SPAN
>
    (because the <TT
CLASS="filename"
>SConstruct</TT
> file itself changes
    the contents of <TT
CLASS="filename"
>version.c</TT
>)
    and the <TT
CLASS="filename"
>hello</TT
> executable
    will get re-linked every time
    (because the <TT
CLASS="filename"
>version.o</TT
> file changes):

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      gcc -o hello.o -c hello.c
      gcc -o version.o -c version.c
      gcc -o hello hello.o version.o
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      gcc -o version.o -c version.c
      gcc -o hello hello.o version.o
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      gcc -o version.o -c version.c
      gcc -o hello hello.o version.o
    </PRE
><P
>&#13;
    One solution is to use the <CODE
CLASS="function"
>Requires</CODE
> function
    to specify that the <TT
CLASS="filename"
>version.o</TT
>
    must be rebuilt before it is used by the link step,
    but that changes to <TT
CLASS="filename"
>version.o</TT
>
    should not actually cause the <TT
CLASS="filename"
>hello</TT
>
    executable to be re-linked:

    </P
><PRE
CLASS="programlisting"
>&#13;      import time

      version_c_text = """
      char *date = "%s";
      """ % time.ctime(time.time())
      open('version.c', 'w').write(version_c_text)

      version_obj = Object('version.c')

      hello = Program('hello.c',
                      LINKFLAGS = str(version_obj[0]))

      Requires(hello, version_obj)
    </PRE
><P
>&#13;
    Notice that because we can no longer list <TT
CLASS="filename"
>version.c</TT
>
    as one of the sources for the <TT
CLASS="filename"
>hello</TT
> program,
    we have to find some other way to get it into the link command line.
    For this example, we're cheating a bit and stuffing the
    object file name (extracted from <TT
CLASS="literal"
>version_obj</TT
>
    list returned by the <CODE
CLASS="function"
>Object</CODE
> call)
    into the <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
> variable,
    because <CODE
CLASS="envar"
>$LINKFLAGS</CODE
> is already included
    in the <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
> command line.

    </P
><P
>&#13;
    With these changes,
    we get the desired behavior of
    re-building the <TT
CLASS="filename"
>version.o</TT
> file,
    and therefore re-linking the <TT
CLASS="filename"
>hello</TT
> executable,
    only when the <TT
CLASS="filename"
>hello.c</TT
> has changed:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o version.o -c version.c
      cc -o hello version.o hello.o
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      scons: `.' is up to date.
      % <KBD
CLASS="userinput"
>edit hello.c</KBD
>
          [CHANGE THE CONTENTS OF hello.c]
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello version.o hello.o
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      scons: `.' is up to date.
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1312"
>6.9. The <CODE
CLASS="function"
>AlwaysBuild</CODE
> Function</A
></H2
><P
>&#13;
    How <SPAN
CLASS="application"
>SCons</SPAN
> handles dependencies can also be affected
    by the <CODE
CLASS="function"
>AlwaysBuild</CODE
> method.
    When a file is passed to the <CODE
CLASS="function"
>AlwaysBuild</CODE
> method,
    like so:

    </P
><PRE
CLASS="programlisting"
>&#13;      hello = Program('hello.c')
      AlwaysBuild(hello)
    </PRE
><P
>&#13;
    Then the specified target file (<SPAN
CLASS="application"
>hello</SPAN
> in our example)
    will always be considered out-of-date and
    rebuilt whenever that target file is evaluated
    while walking the dependency graph:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello hello.o
    </PRE
><P
>&#13;
    The <CODE
CLASS="function"
>AlwaysBuild</CODE
> function has a somewhat misleading name,
    because it does not actually mean the target file will
    be rebuilt every single time <SPAN
CLASS="application"
>SCons</SPAN
> is invoked.
    Instead, it means that the target will, in fact,
    be rebuilt whenever the target file is encountered
    while evaluating the targets specified on
    the command line (and their dependencies).
    So specifying some other target on the command line,
    a target that does <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
    itself depend on the <CODE
CLASS="function"
>AlwaysBuild</CODE
> target,
    will still be rebuilt only if it's out-of-date
    with respect to its dependencies:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q hello.o</KBD
>
      scons: `hello.o' is up to date.
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-environments"
></A
>Chapter 7. Environments</H1
><P
>&#13;
  An <TT
CLASS="literal"
>environment</TT
>
  is a collection of values that
  can affect how a program executes.
  <SPAN
CLASS="application"
>SCons</SPAN
> distinguishes between three
  different types of environments
  that can affect the behavior of <SPAN
CLASS="application"
>SCons</SPAN
> itself
  (subject to the configuration in the <TT
CLASS="filename"
>SConscript</TT
> files),
  as well as the compilers and other tools it executes:

  </P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
>External Environment</DT
><DD
><P
>&#13;
    The <TT
CLASS="literal"
>external environment</TT
>
    is the set of variables in the user's environment
    at the time the user runs <SPAN
CLASS="application"
>SCons</SPAN
>.
    These variables are available within the <TT
CLASS="filename"
>SConscript</TT
> files
    through the Python <TT
CLASS="literal"
>os.environ</TT
> dictionary.
    See <A
HREF="#sect-external-environments"
>Section 7.1</A
>, below.

    </P
></DD
><DT
><TT
CLASS="literal"
>Construction Environment</TT
></DT
><DD
><P
>&#13;
    A <TT
CLASS="literal"
>construction environment</TT
>
    is a distinct object creating within
    a <TT
CLASS="filename"
>SConscript</TT
> file and
    and which contains values that
    affect how <SPAN
CLASS="application"
>SCons</SPAN
> decides
    what action to use to build a target,
    and even to define which targets
    should be built from which sources.
    One of the most powerful features of <SPAN
CLASS="application"
>SCons</SPAN
>
    is the ability to create multiple <TT
CLASS="literal"
>construction environments</TT
>,
    including the ability to clone a new, customized
    <TT
CLASS="literal"
>construction environment</TT
> from an existing <TT
CLASS="literal"
>construction environment</TT
>.
    See <A
HREF="#sect-construction-environments"
>Section 7.2</A
>, below.

    </P
></DD
><DT
>Execution Environment</DT
><DD
><P
>&#13;
    An <TT
CLASS="literal"
>execution environment</TT
>
    is the values that <SPAN
CLASS="application"
>SCons</SPAN
> sets
    when executing an external
    command (such as a compiler or linker)
    to build one or more targets.
    Note that this is not the same as
    the <TT
CLASS="literal"
>external environment</TT
>
    (see above).
    See <A
HREF="#sect-execution-environments"
>Section 7.3</A
>, below.

    </P
></DD
></DL
></DIV
><P
>&#13;
  Unlike <SPAN
CLASS="application"
>Make</SPAN
>,  <SPAN
CLASS="application"
>SCons</SPAN
> does not automatically
  copy or import values between different environments
  (with the exception of explicit clones of <TT
CLASS="literal"
>construction environments</TT
>,
  which inherit values from their parent).
  This is a deliberate design choice
  to make sure that builds are,
  by default, repeatable regardless of
  the values in the user's external environment.
  This avoids a whole class of problems with builds
  where a developer's local build works
  because a custom variable setting
  causes a different comiler or build option to be used,
  but the checked-in change breaks the official build
  because it uses different environment variable settings.

  </P
><P
>&#13;
  Note that the <TT
CLASS="filename"
>SConscript</TT
> writer can
  easily arrange for variables to be
  copied or imported between environments,
  and this is often very useful
  (or even downright necessary)
  to make it easy for developers
  to customize the build in appropriate ways.
  The point is <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
  that copying variables between different environments
  is evil and must always be avoided.
  Instead, it should be up to the
  implementer of the build system
  to make conscious choices
  about how and when to import
  a variable from one environment to another,
  making informed decisions about
  striking the right balance
  between making the build
  repeatable on the one hand
  and convenient to use on the other.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="sect-external-environments"
>7.1. Using Values From the External Environment</A
></H2
><P
>&#13;
  The <TT
CLASS="literal"
>external environment</TT
>
  variable settings that
  the user has in force
  when executing <SPAN
CLASS="application"
>SCons</SPAN
>
  are available through the normal Python
  <CODE
CLASS="envar"
>os.environ</CODE
>
  dictionary.
  This means that you must add an
  <TT
CLASS="literal"
>import os</TT
> statuement
  to any <TT
CLASS="filename"
>SConscript</TT
> file
  in which you want to use
  values from the user's external environment.

  </P
><PRE
CLASS="programlisting"
>&#13;     import os
   </PRE
><P
>&#13;
  More usefully, you can use the
  <CODE
CLASS="envar"
>os.environ</CODE
>
  dictionary in your <TT
CLASS="filename"
>SConscript</TT
>
  files to initialize <TT
CLASS="literal"
>construction environments</TT
>
  with values from the user's external environment.
  See the next section,
  <A
HREF="#sect-construction-environments"
>Section 7.2</A
>,
  for information on how to do this.

  </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="sect-construction-environments"
>7.2. Construction Environments</A
></H2
><P
>&#13;
      It is rare that all of the software in a large,
      complicated system needs to be built the same way.
      For example, different source files may need different options
      enabled on the command line,
      or different executable programs need to be linked
      with different libraries.
      <SPAN
CLASS="application"
>SCons</SPAN
> accommodates these different build
      requirements by allowing you to create and
      configure multiple <TT
CLASS="literal"
>construction environments</TT
>
      that control how the software is built.
      A <TT
CLASS="literal"
>construction environment</TT
> is an object
      that has a number of associated
      <TT
CLASS="literal"
>construction variables</TT
>, each with a name and a value.
      (A construction environment also has an attached
      set of <CODE
CLASS="classname"
>Builder</CODE
> methods,
      about which we'll learn more later.)

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1400"
>7.2.1. Creating a <TT
CLASS="literal"
>Construction Environment</TT
>:  the <CODE
CLASS="function"
>Environment</CODE
> Function</A
></H3
><P
>&#13;
        A <TT
CLASS="literal"
>construction environment</TT
> is created by the <CODE
CLASS="function"
>Environment</CODE
> method:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
       </PRE
><P
>&#13;
        By default, <SPAN
CLASS="application"
>SCons</SPAN
> initializes every
        new construction environment
        with a set of <TT
CLASS="literal"
>construction variables</TT
>
        based on the tools that it finds on your system,
        plus the default set of builder methods
        necessary for using those tools.
        The construction variables
        are initialized with values describing
        the C compiler,
        the Fortran compiler,
        the linker,
        etc.,
        as well as the command lines to invoke them.

      </P
><P
>&#13;
        When you initialize a construction environment
        you can set the values of the
        environment's <TT
CLASS="literal"
>construction variables</TT
>
        to control how a program is built.
        For example:

      </P
><PRE
CLASS="programlisting"
>&#13;     import os

         env = Environment(CC = 'gcc',
                           CCFLAGS = '-O2')

         env.Program('foo.c')
       </PRE
><P
>&#13;
        The construction environment in this example
        is still initialized with the same default
        construction variable values,
        except that the user has explicitly specified use of the
        GNU C compiler <SPAN
CLASS="application"
>gcc</SPAN
>,
        and further specifies that the <TT
CLASS="literal"
>-O2</TT
>
        (optimization level two)
        flag should be used when compiling the object file.
        In other words, the explicit initializations of
        <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
> and <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>
        override the default values in the newly-created
        construction environment.
        So a run from this example would look like:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         gcc -o foo.o -c -O2 foo.c
         gcc -o foo foo.o
      </PRE
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1423"
>7.2.2. Fetching Values From a <TT
CLASS="literal"
>Construction Environment</TT
></A
></H3
><P
>&#13;
      You can fetch individual construction variables
      using the normal syntax
      for accessing individual named items in a Python dictionary:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         print "CC is:", env['CC']
      </PRE
><P
>&#13;
      This example <TT
CLASS="filename"
>SConstruct</TT
> file doesn't build anything,
      but because it's actually a Python script,
      it will print the value of <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
> for us:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         CC is: cc
         scons: `.' is up to date.
      </PRE
><P
>&#13;
      A construction environment, however,
      is actually an object with associated methods, etc.
      If you want to have direct access to only the
      dictionary of construction variables,
      you can fetch this using the <TT
CLASS="literal"
>Dictionary</TT
> method:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(FOO = 'foo', BAR = 'bar')
         dict = env.Dictionary()
         for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']:
             print "key = %s, value = %s" % (key, dict[key])
      </PRE
><P
>&#13;
      This <TT
CLASS="filename"
>SConstruct</TT
> file
      will print the specified dictionary items for us on POSIX
      systems as follows:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         key = OBJSUFFIX, value = .o
         key = LIBSUFFIX, value = .a
         key = PROGSUFFIX, value = 
         scons: `.' is up to date.
      </PRE
><P
>&#13;
      And on Windows:

      </P
><PRE
CLASS="screen"
>&#13;         C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
         key = OBJSUFFIX, value = .obj
         key = LIBSUFFIX, value = .lib
         key = PROGSUFFIX, value = .exe
         scons: `.' is up to date.
      </PRE
><P
>&#13;
      If you want to loop and print the values of
      all of the construction variables in a construction environment,
      the Python code to do that in sorted order might look something like:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         dict = env.Dictionary()
         keys = dict.keys()
         keys.sort()
         for key in keys:
             print "construction variable = '%s', value = '%s'" % (key, dict[key])
      </PRE
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1446"
>7.2.3. Expanding Values From a <TT
CLASS="literal"
>Construction Environment</TT
>:  the <CODE
CLASS="function"
>subst</CODE
> Method</A
></H3
><P
>&#13;
      Another way to get information from
      a construction environment.
      is to use the <CODE
CLASS="function"
>subst</CODE
> method
      on a string containing <TT
CLASS="literal"
>$</TT
> expansions
      of construction variable names.
      As a simple example,
      the example from the previous
      section that used
      <TT
CLASS="literal"
>env['CC']</TT
>
      to fetch the value of <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>
      could also be written as:

      </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment()
        print "CC is:", env.subst('$CC')
      </PRE
><P
>&#13;
      One advantage of using
      <CODE
CLASS="function"
>subst</CODE
> to expand strings is
      that construction variables
      in the result get re-expanded until
      there are no expansions left in the string.
      So a simple fetch of a value like
      <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
>:

      </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment(CCFLAGS = '-DFOO')
        print "CCCOM is:", env['CCCOM']
      </PRE
><P
>&#13;
      Will print the unexpanded value of <CODE
CLASS="envar"
>$CCCOM</CODE
>,
      showing us the construction
      variables that still need to be expanded:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES
        scons: `.' is up to date.
      </PRE
><P
>&#13;
      Calling the <CODE
CLASS="function"
>subst</CODE
> method on <CODE
CLASS="varname"
>$CCOM</CODE
>,
      however:

      </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment(CCFLAGS = '-DFOO')
        print "CCCOM is:", env.subst('$CCCOM')
      </PRE
><P
>&#13;
      Will recursively expand all of
      the construction variables prefixed
      with <TT
CLASS="literal"
>$</TT
> (dollar signs),
      showing us the final output:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        CCCOM is: gcc -DFOO -c -o
        scons: `.' is up to date.
      </PRE
><P
>&#13;
      Note that because we're not expanding this
      in the context of building something
      there are no target or source files
      for <A
HREF="#cv-TARGET"
><CODE
CLASS="envar"
>$TARGET</CODE
></A
> and <A
HREF="#cv-SOURCES"
><CODE
CLASS="envar"
>$SOURCES</CODE
></A
> to expand.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1479"
>7.2.4. Controlling the Default <TT
CLASS="literal"
>Construction Environment</TT
>:  the <CODE
CLASS="function"
>DefaultEnvironment</CODE
> Function</A
></H3
><P
>&#13;
      All of the <CODE
CLASS="classname"
>Builder</CODE
> functions that we've introduced so far,
      like <CODE
CLASS="function"
>Program</CODE
> and <CODE
CLASS="function"
>Library</CODE
>,
      actually use a default <TT
CLASS="literal"
>construction environment</TT
>
      that contains settings
      for the various compilers
      and other tools that
      <SPAN
CLASS="application"
>SCons</SPAN
> configures by default,
      or otherwise knows about
      and has discovered on your system.
      The goal of the default construction environment
      is to make many configurations to "just work"
      to build software using
      readily available tools
      with a minimum of configuration changes.

      </P
><P
>&#13;
      You can, however, control the settings
      in the default contstruction environment
      by using the <CODE
CLASS="function"
>DefaultEnvironment</CODE
> function
      to initialize various settings:

      </P
><PRE
CLASS="programlisting"
>&#13;
      DefaultEnvironment(CC = '/usr/local/bin/gcc')

      </PRE
><P
>&#13;
      When configured as above,
      all calls to the <CODE
CLASS="function"
>Program</CODE
>
      or <CODE
CLASS="function"
>Object</CODE
> Builder
      will build object files with the
      <TT
CLASS="filename"
>/usr/local/bin/gcc</TT
>
      compiler.

      </P
><P
>&#13;
      Note that the <CODE
CLASS="function"
>DefaultEnvironment</CODE
> function
      returns the initialized
      default construction environment object,
      which can then be manipulated like any
      other construction environment.
      So the following
      would be equivalent to the
      previous example,
      setting the <CODE
CLASS="envar"
>$CC</CODE
>
      variable to <TT
CLASS="filename"
>/usr/local/bin/gcc</TT
>
      but as a separate step after
      the default construction environment has been initialized:

      </P
><PRE
CLASS="programlisting"
>&#13;
      env = DefaultEnvironment()
      env['CC'] = '/usr/local/bin/gcc'

      </PRE
><P
>&#13;
      One very common use of the <CODE
CLASS="function"
>DefaultEnvironment</CODE
> function
      is to speed up <SPAN
CLASS="application"
>SCons</SPAN
> initialization.
      As part of trying to make most default
      configurations "just work,"
      <SPAN
CLASS="application"
>SCons</SPAN
> will actually
      search the local system for installed
      compilers and other utilities.
      This search can take time,
      especially on systems with
      slow or networked file systems.
      If you know which compiler(s) and/or
      other utilities you want to configure,
      you can control the search
      that <SPAN
CLASS="application"
>SCons</SPAN
> performs
      by specifying some specific
      tool modules with which to
      initialize the default construction environment:

      </P
><PRE
CLASS="programlisting"
>&#13;
      env = DefaultEnvironment(tools = ['gcc', 'gnulink'],
                               CC = '/usr/local/bin/gcc')

      </PRE
><P
>&#13;
      So the above example would tell <SPAN
CLASS="application"
>SCons</SPAN
>
      to explicitly configure the default environment
      to use its normal GNU Compiler and GNU Linker settings
      (without having to search for them,
      or any other utilities for that matter),
      and specifically to use the compiler found at
      <TT
CLASS="filename"
>/usr/local/bin/gcc</TT
>.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1510"
>7.2.5. Multiple <TT
CLASS="literal"
>Construction Environments</TT
></A
></H3
><P
>&#13;
      The real advantage of construction environments
      is that you can create as many different construction
      environments as you need,
      each tailored to a different way to build
      some piece of software or other file.
      If, for example, we need to build
      one program with the <TT
CLASS="literal"
>-O2</TT
> flag
      and another with the <TT
CLASS="literal"
>-g</TT
> (debug) flag,
      we would do this like so:

      </P
><PRE
CLASS="programlisting"
>&#13;         opt = Environment(CCFLAGS = '-O2')
         dbg = Environment(CCFLAGS = '-g')

         opt.Program('foo', 'foo.c')

         dbg.Program('bar', 'bar.c')
      </PRE
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o bar.o -c -g bar.c
         cc -o bar bar.o
         cc -o foo.o -c -O2 foo.c
         cc -o foo foo.o
      </PRE
><P
>&#13;
      We can even use multiple construction environments to build
      multiple versions of a single program.
      If you do this by simply trying to use the
      <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
> builder with both environments, though,
      like this:

      </P
><PRE
CLASS="programlisting"
>&#13;         opt = Environment(CCFLAGS = '-O2')
         dbg = Environment(CCFLAGS = '-g')

         opt.Program('foo', 'foo.c')

         dbg.Program('foo', 'foo.c')
      </PRE
><P
>&#13;
      Then <SPAN
CLASS="application"
>SCons</SPAN
> generates the following error:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         
         scons: *** Two environments with different actions were specified for the same target: foo.o
         File "/home/my/project/SConstruct", line 6, in &#60;module&#62;
      </PRE
><P
>&#13;
      This is because the two <CODE
CLASS="function"
>Program</CODE
> calls have
      each implicitly told <SPAN
CLASS="application"
>SCons</SPAN
> to generate an object file named
      <TT
CLASS="filename"
>foo.o</TT
>,
      one with a <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
> value of
      <TT
CLASS="literal"
>-O2</TT
>
      and one with a <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
> value of
      <TT
CLASS="literal"
>-g</TT
>.
      <SPAN
CLASS="application"
>SCons</SPAN
> can't just decide that one of them
      should take precedence over the other,
      so it generates the error.
      To avoid this problem,
      we must explicitly specify
      that each environment compile
      <TT
CLASS="filename"
>foo.c</TT
>
      to a separately-named object file
      using the <A
HREF="#b-Object"
><CODE
CLASS="function"
>Object</CODE
></A
> builder, like so:

      </P
><PRE
CLASS="programlisting"
>&#13;         opt = Environment(CCFLAGS = '-O2')
         dbg = Environment(CCFLAGS = '-g')

         o = opt.Object('foo-opt', 'foo.c')
         opt.Program(o)

         d = dbg.Object('foo-dbg', 'foo.c')
         dbg.Program(d)
      </PRE
><P
>&#13;
      Notice that each call to the <CODE
CLASS="function"
>Object</CODE
> builder
      returns a value,
      an internal <SPAN
CLASS="application"
>SCons</SPAN
> object that
      represents the object file that will be built.
      We then use that object
      as input to the <CODE
CLASS="function"
>Program</CODE
> builder.
      This avoids having to specify explicitly
      the object file name in multiple places,
      and makes for a compact, readable
      <TT
CLASS="filename"
>SConstruct</TT
> file.
      Our <SPAN
CLASS="application"
>SCons</SPAN
> output then looks like:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o foo-dbg.o -c -g foo.c
         cc -o foo-dbg foo-dbg.o
         cc -o foo-opt.o -c -O2 foo.c
         cc -o foo-opt foo-opt.o
      </PRE
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1550"
>7.2.6. Making Copies of <TT
CLASS="literal"
>Construction Environments</TT
>:  the <CODE
CLASS="function"
>Clone</CODE
> Method</A
></H3
><P
>&#13;
      Sometimes you want more than one construction environment
      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 construction environment,
      you can use the <CODE
CLASS="function"
>Clone</CODE
> method
      to create a copy of a construction environment.

      </P
><P
>&#13;
      Like the <CODE
CLASS="function"
>Environment</CODE
> call that creates a construction environment,
      the <CODE
CLASS="function"
>Clone</CODE
> method takes <TT
CLASS="literal"
>construction variable</TT
> assignments,
      which will override the values in the copied construction environment.
      For example, suppose we want to use <SPAN
CLASS="application"
>gcc</SPAN
>
      to create three versions of a program,
      one optimized, one debug, and one with neither.
      We could do this by creating a "base" construction environment
      that sets <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
> to <SPAN
CLASS="application"
>gcc</SPAN
>,
      and then creating two copies,
      one which sets <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
> for optimization
      and the other which sets <CODE
CLASS="envar"
>$CCFLAGS</CODE
> for debugging:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(CC = 'gcc')
         opt = env.Clone(CCFLAGS = '-O2')
         dbg = env.Clone(CCFLAGS = '-g')

         env.Program('foo', 'foo.c')

         o = opt.Object('foo-opt', 'foo.c')
         opt.Program(o)

         d = dbg.Object('foo-dbg', 'foo.c')
         dbg.Program(d)
      </PRE
><P
>&#13;
      Then our output would look like:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         gcc -o foo.o -c foo.c
         gcc -o foo foo.o
         gcc -o foo-dbg.o -c -g foo.c
         gcc -o foo-dbg foo-dbg.o
         gcc -o foo-opt.o -c -O2 foo.c
         gcc -o foo-opt foo-opt.o
      </PRE
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1571"
>7.2.7. Replacing Values:  the <CODE
CLASS="function"
>Replace</CODE
> Method</A
></H3
><P
>&#13;
      You can replace existing construction variable values
      using the <CODE
CLASS="function"
>Replace</CODE
> method:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(CCFLAGS = '-DDEFINE1')
         env.Replace(CCFLAGS = '-DDEFINE2')
         env.Program('foo.c')
      </PRE
><P
>&#13;
      The replacing value
      (<TT
CLASS="literal"
>-DDEFINE2</TT
> in the above example)
      completely replaces the value in the
      construction environment:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o foo.o -c -DDEFINE2 foo.c
         cc -o foo foo.o
      </PRE
><P
>&#13;
      You can safely call <CODE
CLASS="function"
>Replace</CODE
>
      for construction variables that
      don't exist in the construction environment:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         env.Replace(NEW_VARIABLE = 'xyzzy')
         print "NEW_VARIABLE =", env['NEW_VARIABLE']
      </PRE
><P
>&#13;
      In this case,
      the construction variable simply
      gets added to the construction environment:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         NEW_VARIABLE = xyzzy
         scons: `.' is up to date.
      </PRE
><P
>&#13;
      Because the variables
      aren't expanded until the construction environment
      is actually used to build the targets,
      and because <SPAN
CLASS="application"
>SCons</SPAN
> function and method calls
      are order-independent,
      the last replacement "wins"
      and is used to build all targets,
      regardless of the order in which
      the calls to Replace() are
      interspersed with calls to
      builder methods:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(CCFLAGS = '-DDEFINE1')
         print "CCFLAGS =", env['CCFLAGS']
         env.Program('foo.c')

         env.Replace(CCFLAGS = '-DDEFINE2')
         print "CCFLAGS =", env['CCFLAGS']
         env.Program('bar.c')
      </PRE
><P
>&#13;
      The timing of when the replacement
      actually occurs relative
      to when the targets get built
      becomes apparent
      if we run <SPAN
CLASS="application"
>scons</SPAN
> without the <TT
CLASS="literal"
>-Q</TT
>
      option:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons</KBD
>
         scons: Reading SConscript files ...
         CCFLAGS = -DDEFINE1
         CCFLAGS = -DDEFINE2
         scons: done reading SConscript files.
         scons: Building targets ...
         cc -o bar.o -c -DDEFINE2 bar.c
         cc -o bar bar.o
         cc -o foo.o -c -DDEFINE2 foo.c
         cc -o foo foo.o
         scons: done building targets.
      </PRE
><P
>&#13;
      Because the replacement occurs while
      the <TT
CLASS="filename"
>SConscript</TT
> files are being read,
      the <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>
      variable has already been set to
      <TT
CLASS="literal"
>-DDEFINE2</TT
>
      by the time the <TT
CLASS="filename"
>foo.o</TT
> target is built,
      even though the call to the <CODE
CLASS="function"
>Replace</CODE
>
      method does not occur until later in
      the <TT
CLASS="filename"
>SConscript</TT
> file.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1603"
>7.2.8. Setting Values Only If They're Not Already Defined:  the <CODE
CLASS="function"
>SetDefault</CODE
> Method</A
></H3
><P
>&#13;
      Sometimes it's useful to be able to specify
      that a construction variable should be
      set to a value only if the construction environment
      does not already have that variable defined
      You can do this with the <CODE
CLASS="function"
>SetDefault</CODE
> method,
      which behaves similarly to the <CODE
CLASS="function"
>set_default</CODE
>
      method of Python dictionary objects:

      </P
><PRE
CLASS="programlisting"
>&#13;      env.SetDefault(SPECIAL_FLAG = '-extra-option')
      </PRE
><P
>&#13;
      This is especially useful
      when writing your own <TT
CLASS="literal"
>Tool</TT
> modules
      to apply variables to construction environments.
      

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1612"
>7.2.9. Appending to the End of Values:  the <CODE
CLASS="function"
>Append</CODE
> Method</A
></H3
><P
>&#13;
      You can append a value to
      an existing construction variable
      using the <CODE
CLASS="function"
>Append</CODE
> method:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(CCFLAGS = ['-DMY_VALUE'])
         env.Append(CCFLAGS = ['-DLAST'])
         env.Program('foo.c')
      </PRE
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> then supplies both the <TT
CLASS="literal"
>-DMY_VALUE</TT
> and
      <TT
CLASS="literal"
>-DLAST</TT
> flags when compiling the object file:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o foo.o -c -DMY_VALUE -DLAST foo.c
         cc -o foo foo.o
      </PRE
><P
>&#13;
      If the construction variable doesn't already exist,
      the <CODE
CLASS="function"
>Append</CODE
> method will create it:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         env.Append(NEW_VARIABLE = 'added')
         print "NEW_VARIABLE =", env['NEW_VARIABLE']
      </PRE
><P
>&#13;
      Which yields:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         NEW_VARIABLE = added
         scons: `.' is up to date.
      </PRE
><P
>&#13;
      Note that the <CODE
CLASS="function"
>Append</CODE
> function tries to be "smart"
      about how the new value is appended to the old value.
      If both are strings, the previous and new strings
      are simply concatenated.
      Similarly, if both are lists,
      the lists are concatenated.
      If, however, one is a string and the other is a list,
      the string is added as a new element to the list.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1632"
>7.2.10. Appending Unique Values:  the <CODE
CLASS="function"
>AppendUnique</CODE
> Method</A
></H3
><P
>&#13;
      Some times it's useful to add a new value
      only if the existing construction variable
      doesn't already contain the value.
      This can be done using the <CODE
CLASS="function"
>AppendUnique</CODE
> method:

      </P
><PRE
CLASS="programlisting"
>&#13;      env.AppendUnique(CCFLAGS=['-g'])
      </PRE
><P
>&#13;
      In the above example,
      the <TT
CLASS="literal"
>-g</TT
> would be added
      only if the <CODE
CLASS="envar"
>$CCFLAGS</CODE
> variable
      does not already contain a <TT
CLASS="literal"
>-g</TT
> value.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1642"
>7.2.11. Appending to the Beginning of Values:  the <CODE
CLASS="function"
>Prepend</CODE
> Method</A
></H3
><P
>&#13;
      You can append a value to the beginning of
      an existing construction variable
      using the <CODE
CLASS="function"
>Prepend</CODE
> method:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(CCFLAGS = ['-DMY_VALUE'])
         env.Prepend(CCFLAGS = ['-DFIRST'])
         env.Program('foo.c')
      </PRE
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> then supplies both the <TT
CLASS="literal"
>-DFIRST</TT
> and
      <TT
CLASS="literal"
>-DMY_VALUE</TT
> flags when compiling the object file:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o foo.o -c -DFIRST -DMY_VALUE foo.c
         cc -o foo foo.o
      </PRE
><P
>&#13;
      If the construction variable doesn't already exist,
      the <CODE
CLASS="function"
>Prepend</CODE
> method will create it:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         env.Prepend(NEW_VARIABLE = 'added')
         print "NEW_VARIABLE =", env['NEW_VARIABLE']
      </PRE
><P
>&#13;
      Which yields:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         NEW_VARIABLE = added
         scons: `.' is up to date.
      </PRE
><P
>&#13;
      Like the <CODE
CLASS="function"
>Append</CODE
> function,
      the <CODE
CLASS="function"
>Prepend</CODE
> function tries to be "smart"
      about how the new value is appended to the old value.
      If both are strings, the previous and new strings
      are simply concatenated.
      Similarly, if both are lists,
      the lists are concatenated.
      If, however, one is a string and the other is a list,
      the string is added as a new element to the list.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1663"
>7.2.12. Prepending Unique Values:  the <CODE
CLASS="function"
>PrependUnique</CODE
> Method</A
></H3
><P
>&#13;
      Some times it's useful to add a new value
      to the beginning of a construction variable
      only if the existing value
      doesn't already contain the to-be-added value.
      This can be done using the <CODE
CLASS="function"
>PrependUnique</CODE
> method:

      </P
><PRE
CLASS="programlisting"
>&#13;      env.PrependUnique(CCFLAGS=['-g'])
      </PRE
><P
>&#13;
      In the above example,
      the <TT
CLASS="literal"
>-g</TT
> would be added
      only if the <CODE
CLASS="envar"
>$CCFLAGS</CODE
> variable
      does not already contain a <TT
CLASS="literal"
>-g</TT
> value.

      </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="sect-execution-environments"
>7.3. Controlling the Execution Environment for Issued Commands</A
></H2
><P
>&#13;
      When <SPAN
CLASS="application"
>SCons</SPAN
> builds a target file,
      it does not execute the commands with
      the same external environment
      that you used to execute <SPAN
CLASS="application"
>SCons</SPAN
>.
      Instead, it uses the dictionary
      stored in the <A
HREF="#cv-ENV"
><CODE
CLASS="envar"
>$ENV</CODE
></A
> construction variable
      as the external environment
      for executing commands.

    </P
><P
>&#13;
      The most important ramification of this behavior
      is that the <CODE
CLASS="varname"
>PATH</CODE
> environment variable,
      which controls where the operating system
      will look for commands and utilities,
      is not the same as in the external environment
      from which you called <SPAN
CLASS="application"
>SCons</SPAN
>.
      This means that <SPAN
CLASS="application"
>SCons</SPAN
> will not, by default,
      necessarily find all of the tools
      that you can execute from the command line.

    </P
><P
>&#13;
      The default value of the <CODE
CLASS="varname"
>PATH</CODE
> environment variable
      on a POSIX system
      is <TT
CLASS="literal"
>/usr/local/bin:/bin:/usr/bin</TT
>.
      The default value of the <CODE
CLASS="varname"
>PATH</CODE
> environment variable
      on a Windows system comes from the Windows registry
      value for the command interpreter.
      If you want to execute any commands--compilers, linkers, etc.--that
      are not in these default locations,
      you need to set the <CODE
CLASS="varname"
>PATH</CODE
> value
      in the <CODE
CLASS="envar"
>$ENV</CODE
> dictionary
      in your construction environment.

    </P
><P
>&#13;
      The simplest way to do this is to initialize explicitly
      the value when you create the construction environment;
      this is one way to do that:

    </P
><PRE
CLASS="programlisting"
>&#13;      path = ['/usr/local/bin', '/bin', '/usr/bin']
      env = Environment(ENV = {'PATH' : path})
    </PRE
><P
>&#13;
    Assign a dictionary to the <CODE
CLASS="envar"
>$ENV</CODE
>
    construction variable in this way
    completely resets the external environment
    so that the only variable that will be
    set when external commands are executed
    will be the <CODE
CLASS="varname"
>PATH</CODE
> value.
    If you want to use the rest of
    the values in <CODE
CLASS="envar"
>$ENV</CODE
> and only
    set the value of <CODE
CLASS="varname"
>PATH</CODE
>,
    the most straightforward way is probably:

    </P
><PRE
CLASS="programlisting"
>&#13;      env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin']
    </PRE
><P
>&#13;
    Note that <SPAN
CLASS="application"
>SCons</SPAN
> does allow you to define
    the directories in the <CODE
CLASS="varname"
>PATH</CODE
> in a string,
    separated by the pathname-separator character
    for your system (':' on POSIX systems, ';' on Windows):

    </P
><PRE
CLASS="programlisting"
>&#13;      env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'
    </PRE
><P
>&#13;
    But doing so makes your <TT
CLASS="filename"
>SConscript</TT
> file less portable,
    (although in this case that may not be a huge concern
    since the directories you list are likley system-specific, anyway).

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1704"
>7.3.1. Propagating <CODE
CLASS="varname"
>PATH</CODE
> From the External Environment</A
></H3
><P
>&#13;
      You may want to propagate the external <CODE
CLASS="varname"
>PATH</CODE
>
      to the execution environment for commands.
      You do this by initializing the <CODE
CLASS="varname"
>PATH</CODE
>
      variable with the <CODE
CLASS="varname"
>PATH</CODE
> value from
      the <TT
CLASS="literal"
>os.environ</TT
>
      dictionary,
      which is Python's way of letting you
      get at the external environment:

      </P
><PRE
CLASS="programlisting"
>&#13;        import os
        env = Environment(ENV = {'PATH' : os.environ['PATH']})
      </PRE
><P
>&#13;
      Alternatively, you may find it easier
      to just propagate the entire external
      environment to the execution environment
      for commands.
      This is simpler to code than explicity
      selecting the <CODE
CLASS="varname"
>PATH</CODE
> value:

      </P
><PRE
CLASS="programlisting"
>&#13;        import os
        env = Environment(ENV = os.environ)
      </PRE
><P
>&#13;
      Either of these will guarantee that
      <SPAN
CLASS="application"
>SCons</SPAN
> will be able to execute
      any command that you can execute from the command line.
      The drawback is that the build can behave
      differently if it's run by people with
      different <CODE
CLASS="varname"
>PATH</CODE
> values in their environment--for example,
      if both the <TT
CLASS="literal"
>/bin</TT
> and
      <TT
CLASS="literal"
>/usr/local/bin</TT
> directories
      have different <SPAN
CLASS="application"
>cc</SPAN
> commands,
      then which one will be used to compile programs
      will depend on which directory is listed
      first in the user's <CODE
CLASS="varname"
>PATH</CODE
> variable.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN1723"
>7.3.2. Adding to <CODE
CLASS="varname"
>PATH</CODE
> Values in the Execution Environment</A
></H3
><P
>&#13;
      One of the most common requirements
      for manipulating a variable in the execution environment
      is to add one or more custom directories to a search
      like the <CODE
CLASS="envar"
>$PATH</CODE
> variable on Linux or POSIX systems,
      or the <CODE
CLASS="envar"
>%PATH%</CODE
> variable on Windows,
      so that a locally-installed compiler or other utility
      can be found when <SPAN
CLASS="application"
>SCons</SPAN
> tries to execute it to update a target.
      <SPAN
CLASS="application"
>SCons</SPAN
> provides <CODE
CLASS="function"
>PrependENVPath</CODE
> and <CODE
CLASS="function"
>AppendENVPath</CODE
> functions
      to make adding things to execution variables convenient.
      You call these functions by specifying the variable
      to which you want the value added,
      and then value itself.
      So to add some <TT
CLASS="filename"
>/usr/local</TT
> directories
      to the <CODE
CLASS="envar"
>$PATH</CODE
> and <CODE
CLASS="envar"
>$LIB</CODE
> variables,
      you might:

      </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment(ENV = os.environ)
        env.PrependENVPath('PATH', '/usr/local/bin')
        env.AppendENVPath('LIB', '/usr/local/lib')
      </PRE
><P
>&#13;
      Note that the added values are strings,
      and if you want to add multiple directories to
      a variable like <CODE
CLASS="envar"
>$PATH</CODE
>,
      you must include the path separate character
      (<TT
CLASS="literal"
>:</TT
> on Linux or POSIX,
      <TT
CLASS="literal"
>;</TT
> on Windows)
      in the string.

      </P
></DIV
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-mergeflags"
></A
>Chapter 8. Merging Options into the Environment: the <CODE
CLASS="function"
>MergeFlags</CODE
> Function</H1
><P
>&#13;
 <SPAN
CLASS="application"
>SCons</SPAN
> construction environments have a <CODE
CLASS="function"
>MergeFlags</CODE
> method
 that merges a dictionary of values into the construction environment.
 <CODE
CLASS="function"
>MergeFlags</CODE
> treats each value in the dictionary
 as a list of options such as one might pass to a command
 (such as a compiler or linker).
 <CODE
CLASS="function"
>MergeFlags</CODE
> will not duplicate an option
 if it already exists in the construction environment variable.

 </P
><P
>&#13;
 <CODE
CLASS="function"
>MergeFlags</CODE
> tries to be intelligent about merging options.
 When merging options to any variable
 whose name ends in <CODE
CLASS="varname"
>PATH</CODE
>,
 <CODE
CLASS="function"
>MergeFlags</CODE
> keeps the leftmost occurrence of the option,
 because in typical lists of directory paths,
 the first occurrence "wins."
 When merging options to any other variable name,
 <CODE
CLASS="function"
>MergeFlags</CODE
> keeps the rightmost occurrence of the option,
 because in a list of typical command-line options,
 the last occurrence "wins."

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    env.Append(CCFLAGS = '-option -O3 -O1')
    flags = { 'CCFLAGS' : '-whatever -O3' }
    env.MergeFlags(flags)
    print env['CCFLAGS']
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    ['-option', '-O1', '-whatever', '-O3']
    scons: `.' is up to date.
 </PRE
><P
>&#13;
 Note that the default value for <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>
 
 is an internal <SPAN
CLASS="application"
>SCons</SPAN
> object
 which automatically converts
 the options we specified as a string into a list.

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    env.Append(CPPPATH = ['/include', '/usr/local/include', '/usr/include'])
    flags = { 'CPPPATH' : ['/usr/opt/include', '/usr/local/include'] }
    env.MergeFlags(flags)
    print env['CPPPATH']
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    ['/include', '/usr/local/include', '/usr/include', '/usr/opt/include']
    scons: `.' is up to date.
 </PRE
><P
>&#13;
 Note that the default value for <A
HREF="#cv-CPPPATH"
><CODE
CLASS="envar"
>$CPPPATH</CODE
></A
>
 
 is a normal Python list,
 so we must specify its values as a list
 in the dictionary we pass to the <CODE
CLASS="function"
>MergeFlags</CODE
> function.

 </P
><P
>&#13;
 If <CODE
CLASS="function"
>MergeFlags</CODE
> is passed anything other than a dictionary,
 it calls the <CODE
CLASS="function"
>ParseFlags</CODE
> method to convert it into a dictionary.

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    env.Append(CCFLAGS = '-option -O3 -O1')
    env.Append(CPPPATH = ['/include', '/usr/local/include', '/usr/include'])
    env.MergeFlags('-whatever -I/usr/opt/include -O3 -I/usr/local/include')
    print env['CCFLAGS']
    print env['CPPPATH']
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    ['-option', '-O1', '-whatever', '-O3']
    ['/include', '/usr/local/include', '/usr/include', '/usr/opt/include']
    scons: `.' is up to date.
 </PRE
><P
>&#13;
 In the combined example above,
 <CODE
CLASS="function"
>ParseFlags</CODE
> has sorted the options into their corresponding variables
 and returned a dictionary for <CODE
CLASS="function"
>MergeFlags</CODE
> to apply
 to the construction variables
 in the specified construction environment.

 </P
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-parseflags"
></A
>Chapter 9. Separating Compile Arguments into their Variables:  the <CODE
CLASS="function"
>ParseFlags</CODE
> Function</H1
><P
>&#13;
 <SPAN
CLASS="application"
>SCons</SPAN
> has a bewildering array of construction variables
 for different types of options when building programs.
 Sometimes you may not know exactly which variable
 should be used for a particular option.

 </P
><P
>&#13;
 <SPAN
CLASS="application"
>SCons</SPAN
> construction environments have a <CODE
CLASS="function"
>ParseFlags</CODE
> method
 that takes a set of typical command-line options
 and distrbutes them into the appropriate construction variables.
 Historically, it was created to support the <CODE
CLASS="function"
>ParseConfig</CODE
> method,
 so it focuses on options used by the GNU Compiler Collection (GCC)
 for the C and C++ toolchains.

 </P
><P
>&#13;
 <CODE
CLASS="function"
>ParseFlags</CODE
> returns a dictionary containing the options
 distributed into their respective construction variables.
 Normally, this dictionary would be passed to <CODE
CLASS="function"
>MergeFlags</CODE
>
 to merge the options into a <TT
CLASS="literal"
>construction environment</TT
>,
 but the dictionary can be edited if desired to provide
 additional functionality.
 (Note that if the flags are not going to be edited,
 calling <CODE
CLASS="function"
>MergeFlags</CODE
> with the options directly
 will avoid an additional step.)

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    d = env.ParseFlags("-I/opt/include -L/opt/lib -lfoo")
    l = d.items()
    l.sort()
    for k,v in l:
        if v:
            print k, v
    env.MergeFlags(d)
    env.Program('f1.c')
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cc -o f1.o -c -I/opt/include f1.c
    cc -o f1 f1.o -L/opt/lib -lfoo
 </PRE
><P
>&#13;
 Note that if the options are limited to generic types
 like those above,
 they will be correctly translated for other platform types:

 </P
><PRE
CLASS="screen"
>&#13;    C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cl /nologo /I\opt\include /c f1.c /Fof1.obj
    link /nologo /OUT:f1.exe /LIBPATH:\opt\lib foo.lib f1.obj
 </PRE
><P
>&#13;
 Since the assumption is that the flags are used for the GCC toolchain,
 unrecognized flags are placed in <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>
 so they will be used for both C and C++ compiles:

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    d = env.ParseFlags("-whatever")
    l = d.items()
    l.sort()
    for k,v in l:
        if v:
            print k, v
    env.MergeFlags(d)
    env.Program('f1.c')
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    CCFLAGS -whatever
    cc -o f1.o -c -whatever f1.c
    cc -o f1 f1.o
 </PRE
><P
>&#13;
 <CODE
CLASS="function"
>ParseFlags</CODE
> will also accept a (recursive) list of strings as input;
 the list is flattened before the strings are processed:

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    d = env.ParseFlags(["-I/opt/include", ["-L/opt/lib", "-lfoo"]])
    l = d.items()
    l.sort()
    for k,v in l:
        if v:
            print k, v
    env.MergeFlags(d)
    env.Program('f1.c')
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cc -o f1.o -c -I/opt/include f1.c
    cc -o f1 f1.o -L/opt/lib -lfoo
 </PRE
><P
>&#13;
 If a string begins with a "!" (an exclamation mark, often called a bang),
 the string is passed to the shell for execution.
 The output of the command is then parsed:

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    d = env.ParseFlags(["!echo -I/opt/include", "!echo -L/opt/lib", "-lfoo"])
    l = d.items()
    l.sort()
    for k,v in l:
        if v:
            print k, v
    env.MergeFlags(d)
    env.Program('f1.c')
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    CPPPATH ['/opt/include']
    LIBPATH ['/opt/lib']
    LIBS ['foo']
    cc -o f1.o -c -I/opt/include f1.c
    cc -o f1 f1.o -L/opt/lib -lfoo
 </PRE
><P
>&#13;
 <CODE
CLASS="function"
>ParseFlags</CODE
> is regularly updated for new options;
 consult the man page for details about those currently recognized.

 </P
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-parseconfig"
></A
>Chapter 10. Finding Installed Library Information:  the <CODE
CLASS="function"
>ParseConfig</CODE
> Function</H1
><P
>&#13;
 Configuring the right options to build programs to work with
 libraries--especially shared libraries--that are available
 on POSIX systems can be very complicated.
 To help this situation,
 various utilies with names that end in <TT
CLASS="filename"
>config</TT
>
 return the command-line options for the GNU Compiler Collection (GCC)
 that are needed to use these libraries;
 for example, the command-line options
 to use a library named <TT
CLASS="filename"
>lib</TT
>
 would be found by calling a utility named <TT
CLASS="filename"
>lib-config</TT
>.

 </P
><P
>&#13;
 A more recent convention is that these options
 are available from the generic <TT
CLASS="filename"
>pkg-config</TT
> program,
 which has common framework, error handling, and the like,
 so that all the package creator has to do is provide the set of strings
 for his particular package.

 </P
><P
>&#13;
 <SPAN
CLASS="application"
>SCons</SPAN
> construction environments have a <CODE
CLASS="function"
>ParseConfig</CODE
> method
 that executes a <TT
CLASS="filename"
>*config</TT
> utility
 (either <TT
CLASS="filename"
>pkg-config</TT
> or a
 more specific utility)
 and configures the appropriate construction variables
 in the environment
 based on the command-line options
 returned by the specified command.

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    env['CPPPATH'] = ['/lib/compat']
    env.ParseConfig("pkg-config x11 --cflags --libs")
    print env['CPPPATH']
 </PRE
><P
>&#13;
 <SPAN
CLASS="application"
>SCons</SPAN
> will execute the specified command string,
 parse the resultant flags,
 and add the flags to the appropriate environment variables.

 </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    ['/lib/compat', '/usr/X11/include']
    scons: `.' is up to date.
 </PRE
><P
>&#13;
 In the example above, <SPAN
CLASS="application"
>SCons</SPAN
> has added the include directory to
 <CODE
CLASS="varname"
>CPPPATH</CODE
>.
 (Depending upon what other flags are emitted by the
 <TT
CLASS="filename"
>pkg-config</TT
> command,
 other variables may have been extended as well.)

 </P
><P
>&#13;
 Note that the options are merged with existing options using
 the <CODE
CLASS="function"
>MergeFlags</CODE
> method,
 so that each option only occurs once in the construction variable:

 </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    env.ParseConfig("pkg-config x11 --cflags --libs")
    env.ParseConfig("pkg-config x11 --cflags --libs")
    print env['CPPPATH']
 </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    ['/usr/X11/include']
    scons: `.' is up to date.
 </PRE
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-output"
></A
>Chapter 11. Controlling Build Output</H1
><P
>&#13;
  A key aspect of creating a usable build configuration
  is providing good output from the build
  so its users can readily understand
  what the build is doing
  and get information about how to control the build.
  <SPAN
CLASS="application"
>SCons</SPAN
> provides several ways of
  controlling output from the build configuration
  to help make the build
  more useful and understandable.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1846"
>11.1. Providing Build Help:  the <CODE
CLASS="function"
>Help</CODE
> Function</A
></H2
><P
>&#13;
    It's often very useful to be able to give
    users some help that describes the
    specific targets, build options, etc.,
    that can be used for your build.
    <SPAN
CLASS="application"
>SCons</SPAN
> provides the <CODE
CLASS="function"
>Help</CODE
> function
    to allow you to specify this help text:

    </P
><PRE
CLASS="programlisting"
>&#13;       Help("""
       Type: 'scons program' to build the production program,
             'scons debug' to build the debug version.
       """)
    </PRE
><P
>&#13;
    (Note the above use of the Python triple-quote syntax,
    which comes in very handy for
    specifying multi-line strings like help text.)

    </P
><P
>&#13;
    When the <TT
CLASS="filename"
>SConstruct</TT
> or <TT
CLASS="filename"
>SConscript</TT
> files
    contain such a call to the <CODE
CLASS="function"
>Help</CODE
> function,
    the specified help text will be displayed in response to
    the <SPAN
CLASS="application"
>SCons</SPAN
> <TT
CLASS="literal"
>-h</TT
> option:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -h</KBD
>
       scons: Reading SConscript files ...
       scons: done reading SConscript files.
       
       Type: 'scons program' to build the production program,
             'scons debug' to build the debug version.
       
       Use scons -H for help about command-line options.
    </PRE
><P
>&#13;
    The <TT
CLASS="filename"
>SConscript</TT
> files may contain
    multiple calls to the <CODE
CLASS="function"
>Help</CODE
> function,
    in which case the specified text(s)
    will be concatenated when displayed.
    This allows you to split up the
    help text across multiple <TT
CLASS="filename"
>SConscript</TT
> files.
    In this situation, the order in
    which the <TT
CLASS="filename"
>SConscript</TT
> files are called
    will determine the order in which the <CODE
CLASS="function"
>Help</CODE
> functions are called,
    which will determine the order in which
    the various bits of text will get concatenated.

    </P
><P
>&#13;
    Another use would be to make the help text conditional
    on some variable.
    For example, suppose you only want to display
    a line about building a Windows-only
    version of a program when actually
    run on Windows.
    The following <TT
CLASS="filename"
>SConstruct</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()

       Help("\nType: 'scons program' to build the production program.\n")

       if env['PLATFORM'] == 'win32':
           Help("\nType: 'scons windebug' to build the Windows debug version.\n")
    </PRE
><P
>&#13;
    Will display the complete help text on Windows:

    </P
><PRE
CLASS="screen"
>&#13;       C:\&#62;<KBD
CLASS="userinput"
>scons -h</KBD
>
       scons: Reading SConscript files ...
       scons: done reading SConscript files.
       
       Type: 'scons program' to build the production program.
       
       Type: 'scons windebug' to build the Windows debug version.
       
       Use scons -H for help about command-line options.
    </PRE
><P
>&#13;
    But only show the relevant option on a Linux or UNIX system:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -h</KBD
>
       scons: Reading SConscript files ...
       scons: done reading SConscript files.
       
       Type: 'scons program' to build the production program.
       
       Use scons -H for help about command-line options.
    </PRE
><P
>&#13;
    If there is no <CODE
CLASS="function"
>Help</CODE
> text in the <TT
CLASS="filename"
>SConstruct</TT
> or
    <TT
CLASS="filename"
>SConscript</TT
> files,
    <SPAN
CLASS="application"
>SCons</SPAN
> will revert to displaying its
    standard list that describes the <SPAN
CLASS="application"
>SCons</SPAN
> command-line
    options.
    This list is also always displayed whenever
    the <TT
CLASS="literal"
>-H</TT
> option is used.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1884"
>11.2. Controlling How <SPAN
CLASS="application"
>SCons</SPAN
> Prints Build Commands:  the <CODE
CLASS="envar"
>$*COMSTR</CODE
> Variables</A
></H2
><P
>&#13;
    Sometimes the commands executed
    to compile object files or link programs
    (or build other targets)
    can get very long,
    long enough to make it difficult for users
    to distinguish error messages or
    other important build output
    from the commands themselves.
    All of the default <CODE
CLASS="envar"
>$*COM</CODE
> variables
    that specify the command lines
    used to build various types of target files
    have a corresponding <CODE
CLASS="envar"
>$*COMSTR</CODE
> variable
    that can be set to an alternative
    string that will be displayed
    when the target is built.

    </P
><P
>&#13;
    For example, suppose you want to
    have <SPAN
CLASS="application"
>SCons</SPAN
> display a
    <TT
CLASS="literal"
>"Compiling"</TT
>
    message whenever it's compiling an object file,
    and a
    <TT
CLASS="literal"
>"Linking"</TT
>
    when it's linking an executable.
    You could write a <TT
CLASS="filename"
>SConstruct</TT
> file
    that looks like:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment(CCCOMSTR = "Compiling $TARGET",
                         LINKCOMSTR = "Linking $TARGET")
       env.Program('foo.c')
    </PRE
><P
>&#13;
    Which would then yield the output:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       Compiling foo.o
       Linking foo
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> performs complete variable substitution
    on <CODE
CLASS="envar"
>$*COMSTR</CODE
> variables,
    so they have access to all of the
    standard variables like <CODE
CLASS="envar"
>$TARGET</CODE
> <CODE
CLASS="envar"
>$SOURCES</CODE
>, etc.,
    as well as any construction variables
    that happen to be configured in
    the construction environment
    used to build a specific target.

    </P
><P
>&#13;
    Of course, sometimes it's still important to
    be able to see the exact command
    that <SPAN
CLASS="application"
>SCons</SPAN
> will execute to build a target.
    For example, you may simply need to verify
    that <SPAN
CLASS="application"
>SCons</SPAN
> is configured to supply
    the right options to the compiler,
    or a developer may want to
    cut-and-paste a comiloe command
    to add a few options
    for a custom test.

    </P
><P
>&#13;
    One common way to give users
    control over whether or not
    <SPAN
CLASS="application"
>SCons</SPAN
> should print the actual command line
    or a short, configured summary
    is to add support for a
    <CODE
CLASS="varname"
>VERBOSE</CODE
>
    command-line variable to your <TT
CLASS="filename"
>SConstruct</TT
> file.
    A simple configuration for this might look like:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       if ARGUMENTS.get('VERBOSE') != "1':
           env['CCCOMSTR'] = "Compiling $TARGET"
           env['LINKCOMSTR'] = "Linking $TARGET"
       env.Program('foo.c')
    </PRE
><P
>&#13;

    By only setting the appropriate
    <CODE
CLASS="envar"
>$*COMSTR</CODE
> variables
    if the user specifies
    <TT
CLASS="literal"
>VERBOSE=1</TT
>
    on the command line,
    the user has control
    over how <SPAN
CLASS="application"
>SCons</SPAN
>
    displays these particular command lines:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       Compiling foo.o
       Linking foo
       % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
       Removed foo.o
       Removed foo
       % <KBD
CLASS="userinput"
>scons -Q VERBOSE=1</KBD
>
       cc -o foo.o -c foo.c
       cc -o foo foo.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1921"
>11.3. Providing Build Progress Output:  the <CODE
CLASS="function"
>Progress</CODE
> Function</A
></H2
><P
>&#13;
    Another aspect of providing good build output
    is to give the user feedback
    about what <SPAN
CLASS="application"
>SCons</SPAN
> is doing
    even when nothing is being built at the moment.
    This can be especially true for large builds
    when most of the targets are already up-to-date.
    Because <SPAN
CLASS="application"
>SCons</SPAN
> can take a long time
    making absolutely sure that every
    target is, in fact, up-to-date
    with respect to a lot of dependency files,
    it can be easy for users to mistakenly
    conclude that <SPAN
CLASS="application"
>SCons</SPAN
> is hung
    or that there is some other problem with the build.

    </P
><P
>&#13;
    One way to deal with this perception
    is to configure <SPAN
CLASS="application"
>SCons</SPAN
> to print something to
    let the user know what it's "thinking about."
    The <CODE
CLASS="function"
>Progress</CODE
> function
    allows you to specify a string
    that will be printed for every file
    that <SPAN
CLASS="application"
>SCons</SPAN
> is "considering"
    while it is traversing the dependency graph
    to decide what targets are or are not up-to-date.

    </P
><PRE
CLASS="programlisting"
>&#13;        Progress('Evaluating $TARGET\n')
        Program('f1.c')
        Program('f2.c')
    </PRE
><P
>&#13;
    Note that the <CODE
CLASS="function"
>Progress</CODE
> function does not
    arrange for a newline to be printed automatically
    at the end of the string (as does the Python
    <TT
CLASS="literal"
>print</TT
> statement),
    and we must specify the
    <TT
CLASS="literal"
>\n</TT
>
    that we want printed at the end of the configured string.
    This configuration, then,
    will have <SPAN
CLASS="application"
>SCons</SPAN
>
    print that it is <TT
CLASS="literal"
>Evaluating</TT
>
    each file that it encounters
    in turn as it traverses the dependency graph:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       Evaluating SConstruct
       Evaluating f1.c
       Evaluating f1.o
       cc -o f1.o -c f1.c
       Evaluating f1
       cc -o f1 f1.o
       Evaluating f2.c
       Evaluating f2.o
       cc -o f2.o -c f2.c
       Evaluating f2
       cc -o f2 f2.o
       Evaluating .
    </PRE
><P
>&#13;
    Of course, normally you don't want to add
    all of these additional lines to your build output,
    as that can make it difficult for the user
    to find errors or other important messages.
    A more useful way to display
    this progress might be
    to have the file names printed
    directly to the user's screen,
    not to the same standard output
    stream where build output is printed,
    and to use a carriage return character
    (<TT
CLASS="literal"
>\r</TT
>)
    so that each file name gets re-printed on the same line.
    Such a configuration would look like:

    </P
><PRE
CLASS="programlisting"
>&#13;        Progress('$TARGET\r',
                 file=open('/dev/tty', 'w'),
                 overwrite=True)
        Program('f1.c')
        Program('f2.c')
    </PRE
><P
>&#13;
    Note that we also specified the
    <TT
CLASS="literal"
>overwrite=True</TT
> argument
    to the <CODE
CLASS="function"
>Progress</CODE
> function,
    which causes <SPAN
CLASS="application"
>SCons</SPAN
> to
    "wipe out" the previous string with space characters
    before printing the next <CODE
CLASS="function"
>Progress</CODE
> string.
    Without the
    <TT
CLASS="literal"
>overwrite=True</TT
> argument,
    a shorter file name would not overwrite
    all of the charactes in a longer file name that 
    precedes it,
    making it difficult to tell what the
    actual file name is on the output.
    Also note that we opened up the
    <TT
CLASS="filename"
>/dev/tty</TT
> file
    for direct access (on POSIX) to
    the user's screen.
    On Windows, the equivalent would be to open
    the <TT
CLASS="filename"
>con:</TT
> file name.

    </P
><P
>&#13;
    Also, it's important to know that although you can use
    <TT
CLASS="literal"
>$TARGET</TT
> to substitute the name of
    the node in the string,
    the <CODE
CLASS="function"
>Progress</CODE
> function does <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
    perform general variable substitution
    (because there's not necessarily a construction
    environment involved in evaluating a node
    like a source file, for example).

    </P
><P
>&#13;
    You can also specify a list of strings
    to the <CODE
CLASS="function"
>Progress</CODE
> function,
    in which case <SPAN
CLASS="application"
>SCons</SPAN
> will
    display each string in turn.
    This can be used to implement a "spinner"
    by having <SPAN
CLASS="application"
>SCons</SPAN
> cycle through a
    sequence of strings:

    </P
><PRE
CLASS="programlisting"
>&#13;        Progress(['-\r', '\\\r', '|\r', '/\r'], interval=5)
        Program('f1.c')
        Program('f2.c')
    </PRE
><P
>&#13;
    Note that here we have also used the
    <TT
CLASS="literal"
>interval=</TT
>
    keyword argument to have <SPAN
CLASS="application"
>SCons</SPAN
>
    only print a new "spinner" string
    once every five evaluated nodes.
    Using an <TT
CLASS="literal"
>interval=</TT
> count,
    even with strings that use <TT
CLASS="literal"
>$TARGET</TT
> like
    our examples above,
    can be a good way to lessen the
    work that <SPAN
CLASS="application"
>SCons</SPAN
> expends printing <CODE
CLASS="function"
>Progress</CODE
> strings,
    while still giving the user feedback
    that indicates <SPAN
CLASS="application"
>SCons</SPAN
> is still
    working on evaluating the build.

    </P
><P
>&#13;
    Lastly, you can have direct control
    over how to print each evaluated node
    by passing a Python function
    (or other Python callable)
    to the <CODE
CLASS="function"
>Progress</CODE
> function.
    Your function will be called
    for each evaluated node,
    allowing you to
    implement more sophisticated logic
    like adding a counter:

    </P
><PRE
CLASS="programlisting"
>&#13;        screen = open('/dev/tty', 'w')
        count = 0
        def progress_function(node)
            count += 1
            screen.write('Node %4d: %s\r' % (count, node))

        Progress(progress_function)
    </PRE
><P
>&#13;
    Of course, if you choose,
    you could completely ignore the
    <CODE
CLASS="varname"
>node</CODE
> argument to the function,
    and just print a count,
    or anything else you wish.

    </P
><P
>&#13;
    (Note that there's an obvious follow-on question here:
    how would you find the total number of nodes
    that <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>will be</I
></SPAN
>
    evaluated so you can tell the user how
    close the build is to finishing?
    Unfortunately, in the general case,
    there isn't a good way to do that,
    short of having <SPAN
CLASS="application"
>SCons</SPAN
> evaluate its
    dependency graph twice,
    first to count the total and
    the second time to actually build the targets.
    This would be necessary because
    you can't know in advance which
    target(s) the user actually requested
    to be built.
    The entire build may consist of thousands of Nodes,
    for example,
    but maybe the user specifically requested
    that only a single object file be built.)

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN1977"
>11.4. Printing Detailed Build Status:  the <CODE
CLASS="function"
>GetBuildFailures</CODE
> Function</A
></H2
><P
>&#13;
    SCons, like most build tools, returns zero status to
    the shell on success and nonzero status on failure.
    Sometimes it's useful to give more information about
    the build status at the end of the run, for instance
    to print an informative message, send an email, or
    page the poor slob who broke the build.

    </P
><P
>&#13;
    SCons provides a <CODE
CLASS="function"
>GetBuildFailures</CODE
> method that
    you can use in a python <CODE
CLASS="function"
>atexit</CODE
> function
    to get a list of objects describing the actions that failed
    while attempting to build targets.  There can be more
    than one if you're using <TT
CLASS="literal"
>-j</TT
>.  Here's a 
    simple example:

    </P
><PRE
CLASS="programlisting"
>&#13;        import atexit

        def print_build_failures():
            from SCons.Script import GetBuildFailures
            for bf in GetBuildFailures():
                print "%s failed: %s" % (bf.node, bf.errstr)
        atexit.register(print_build_failures)
    </PRE
><P
>&#13;
    The <CODE
CLASS="function"
>atexit.register</CODE
> call
    registers <CODE
CLASS="function"
>print_build_failures</CODE
>
    as an <CODE
CLASS="function"
>atexit</CODE
> callback, to be called
    before <SPAN
CLASS="application"
>SCons</SPAN
> exits.  When that function is called,
    it calls <CODE
CLASS="function"
>GetBuildFailures</CODE
> to fetch the list of failed objects.
    See the man page
    for the detailed contents of the returned objects;
    some of the more useful attributes are 
    <TT
CLASS="literal"
>.node</TT
>,
    <TT
CLASS="literal"
>.errstr</TT
>,
    <TT
CLASS="literal"
>.filename</TT
>, and
    <TT
CLASS="literal"
>.command</TT
>.
    The <TT
CLASS="literal"
>filename</TT
> is not necessarily
    the same file as the <TT
CLASS="literal"
>node</TT
>; the
    <TT
CLASS="literal"
>node</TT
> is the target that was
    being built when the error occurred, while the 
    <TT
CLASS="literal"
>filename</TT
>is the file or dir that
    actually caused the error.
    Note:  only call <CODE
CLASS="function"
>GetBuildFailures</CODE
> at the end of the
    build; calling it at any other time is undefined.

    </P
><P
>   

    Here is a more complete example showing how to
    turn each element of <CODE
CLASS="function"
>GetBuildFailures</CODE
> into a string:

    </P
><PRE
CLASS="programlisting"
>&#13;        # Make the build fail if we pass fail=1 on the command line
        if ARGUMENTS.get('fail', 0):
            Command('target', 'source', ['/bin/false'])

        def bf_to_str(bf):
            """Convert an element of GetBuildFailures() to a string
            in a useful way."""
            import SCons.Errors
            if bf is None: # unknown targets product None in list
                return '(unknown tgt)'
            elif isinstance(bf, SCons.Errors.StopError):
                return str(bf)
            elif bf.node:
                return str(bf.node) + ': ' + bf.errstr
            elif bf.filename:
                return bf.filename + ': ' + bf.errstr
            return 'unknown failure: ' + bf.errstr
        import atexit

        def build_status():
            """Convert the build status to a 2-tuple, (status, msg)."""
            from SCons.Script import GetBuildFailures
            bf = GetBuildFailures()
            if bf:
                # bf is normally a list of build failures; if an element is None,
                # it's because of a target that scons doesn't know anything about.
                status = 'failed'
                failures_message = "\n".join(["Failed building %s" % bf_to_str(x)
                                   for x in bf if x is not None])
            else:
                # if bf is None, the build completed successfully.
                status = 'ok'
                failures_message = ''
            return (status, failures_message)

        def display_build_status():
            """Display the build status.  Called by atexit.
            Here you could do all kinds of complicated things."""
            status, failures_message = build_status()
            if status == 'failed':
               print "FAILED!!!!"  # could display alert, ring bell, etc.
            elif status == 'ok':
               print "Build succeeded."
            print failures_message

        atexit.register(display_build_status)
    </PRE
><P
>&#13;    
    When this runs, you'll see the appropriate output:

    </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q</KBD
>
          scons: `.' is up to date.
          Build succeeded.
          % <KBD
CLASS="userinput"
>scons -Q fail=1</KBD
>
          scons: *** Source `source' not found, needed by target `target'.  Stop.
          FAILED!!!!
          Failed building Source `source' not found, needed by target `target'.
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-command-line"
></A
>Chapter 12. Controlling a Build From the Command Line</H1
><P
>&#13;
  <SPAN
CLASS="application"
>SCons</SPAN
> provides a number of ways
  for the writer of the <TT
CLASS="filename"
>SConscript</TT
> files
  to give the users who will run <SPAN
CLASS="application"
>SCons</SPAN
>
  a great deal of control over the build execution.
  The arguments that the user can specify on
  the command line are broken down into three types:

  </P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
>Options</DT
><DD
><P
>&#13;
    Command-line options always begin with
    one or two <TT
CLASS="literal"
>-</TT
> (hyphen) characters.
    <SPAN
CLASS="application"
>SCons</SPAN
> provides ways for you to examind
    and set options values from within your <TT
CLASS="filename"
>SConscript</TT
> files,
    as well as the ability to define your own
    custom options.
    See <A
HREF="#sect-command-line-options"
>Section 12.1</A
>, below.

    </P
></DD
><DT
>Variables</DT
><DD
><P
>&#13;
    Any command-line argument containing an <TT
CLASS="literal"
>=</TT
>
    (equal sign) is considered a variable setting with the form
    <CODE
CLASS="varname"
>variable</CODE
>=<CODE
CLASS="varname"
>value</CODE
>
    <SPAN
CLASS="application"
>SCons</SPAN
> provides direct access to
    all of the command-line variable settings,
    the ability to apply command-line variable settings
    to construction environments,
    and functions for configuring 
    specific types of variables
    (Boolean values, path names, etc.)
    with automatic validation of the user's specified values.
    See <A
HREF="#sect-command-line-variables"
>Section 12.2</A
>, below.

    </P
></DD
><DT
>Targets</DT
><DD
><P
>&#13;
    Any command-line argument that is not an option
    or a variable setting
    (does not begin with a hyphen
    and does not contain an equal sign)
    is considered a target that the user
    (presumably) wants <SPAN
CLASS="application"
>SCons</SPAN
> to build.
    A list of Node objects representing
    the target or targets to build.
    <SPAN
CLASS="application"
>SCons</SPAN
> provides access to the list of specified targets,
    as well as ways to set the default list of targets
    from within the <TT
CLASS="filename"
>SConscript</TT
> files.
    See <A
HREF="#sect-command-line-targets"
>Section 12.3</A
>, below.

    </P
></DD
></DL
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="sect-command-line-options"
>12.1. Command-Line Options</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> has many <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>command-line options</I
></SPAN
>
    that control its behavior.
    A <SPAN
CLASS="application"
>SCons</SPAN
> <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>command-line option</I
></SPAN
>
    always begins with one or two <TT
CLASS="literal"
>-</TT
> (hyphen)
    characters.

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2048"
>12.1.1. Not Having to Specify Command-Line Options Each Time:  the <CODE
CLASS="varname"
>SCONSFLAGS</CODE
> Environment Variable</A
></H3
><P
>&#13;
      Users may find themselves supplying
      the same command-line options every time
      they run <SPAN
CLASS="application"
>SCons</SPAN
>.
      For example, you might find it saves time
      to specify a value of <TT
CLASS="literal"
>-j 2</TT
>
      to have <SPAN
CLASS="application"
>SCons</SPAN
> run up to two build commands in parallel.
      To avoid having to type <TT
CLASS="literal"
>-j 2</TT
> by hand
      every time,
      you can set the external environment variable
      <CODE
CLASS="varname"
>SCONSFLAGS</CODE
> to a string containing
      command-line options that you want <SPAN
CLASS="application"
>SCons</SPAN
> to use.

      </P
><P
>&#13;
      If, for example,
      you're using a POSIX shell that's
      compatible with the Bourne shell,
      and you always want <SPAN
CLASS="application"
>SCons</SPAN
> to use the
      <TT
CLASS="literal"
>-Q</TT
> option,
      you can set the <CODE
CLASS="varname"
>SCONSFLAGS</CODE
>
      environment as follows:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons</KBD
>
        scons: Reading SConscript files ...
        scons: done reading SConscript files.
        scons: Building targets ...
            ... [build output] ...
        scons: done building targets.
        % <KBD
CLASS="userinput"
>export SCONSFLAGS="-Q"</KBD
>
        % <KBD
CLASS="userinput"
>scons</KBD
>
            ... [build output] ...
      </PRE
><P
>&#13;
      Users of <SPAN
CLASS="application"
>csh</SPAN
>-style shells on POSIX systems
      can set the <CODE
CLASS="varname"
>SCONSFLAGS</CODE
> environment as follows:

      </P
><PRE
CLASS="screen"
>&#13;        $ <KBD
CLASS="userinput"
>setenv SCONSFLAGS "-Q"</KBD
>
      </PRE
><P
>&#13;
      Windows users may typically want to set the
      <CODE
CLASS="varname"
>SCONSFLAGS</CODE
> in the appropriate tab of the
      <TT
CLASS="literal"
>System Properties</TT
> window.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2074"
>12.1.2. Getting Values Set by Command-Line Options:  the <CODE
CLASS="function"
>GetOption</CODE
> Function</A
></H3
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> provides the <CODE
CLASS="function"
>GetOption</CODE
> function
      to get the values set by the various command-line options.
      One common use of this is to check whether or not
      the <TT
CLASS="literal"
>-h</TT
> or <TT
CLASS="literal"
>--help</TT
> option
      has been specified.
      Normally, <SPAN
CLASS="application"
>SCons</SPAN
> does not print its help text
      until after it has read all of the <TT
CLASS="filename"
>SConscript</TT
> files,
      because it's possible that help text has been added
      by some subsidiary <TT
CLASS="filename"
>SConscript</TT
> file deep in the
      source tree hierarchy.
      Of course, reading all of the <TT
CLASS="filename"
>SConscript</TT
> files
      takes extra time.

      </P
><P
>&#13;
      If you know that your configuration does not define
      any additional help text in subsidiary <TT
CLASS="filename"
>SConscript</TT
> files,
      you can speed up the command-line help available to users
      by using the <CODE
CLASS="function"
>GetOption</CODE
> function to load the
      subsidiary <TT
CLASS="filename"
>SConscript</TT
> files only if the
      the user has <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
> specified
      the <TT
CLASS="literal"
>-h</TT
> or <TT
CLASS="literal"
>--help</TT
> option,
      like so:

      </P
><PRE
CLASS="programlisting"
></PRE
><P
>&#13;
      In general, the string that you pass to the
      <CODE
CLASS="function"
>GetOption</CODE
> function to fetch the value of a command-line
      option setting is the same as the "most common" long option name
      (beginning with two hyphen characters),
      although there are some exceptions.
      The list of <SPAN
CLASS="application"
>SCons</SPAN
> command-line options
      and the <CODE
CLASS="function"
>GetOption</CODE
> strings for fetching them,
      are available in the
      <A
HREF="#sect-command-line-option-strings"
>Section 12.1.4</A
> section,
      below.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2099"
>12.1.3. Setting Values of Command-Line Options:  the <CODE
CLASS="function"
>SetOption</CODE
> Function</A
></H3
><P
>&#13;
      You can also set the values of <SPAN
CLASS="application"
>SCons</SPAN
>
      command-line options from within the <TT
CLASS="filename"
>SConscript</TT
> files
      by using the <CODE
CLASS="function"
>SetOption</CODE
> function.
      The strings that you use to set the values of <SPAN
CLASS="application"
>SCons</SPAN
>
      command-line options are available in the
      <A
HREF="#sect-command-line-option-strings"
>Section 12.1.4</A
> section,
      below.

      </P
><P
>&#13;
      One use of the <CODE
CLASS="function"
>SetOption</CODE
> function is to
      specify a value for the <TT
CLASS="literal"
>-j</TT
>
      or <TT
CLASS="literal"
>--jobs</TT
> option,
      so that users get the improved performance
      of a parallel build without having to specify the option by hand.
      A complicating factor is that a good value
      for the <TT
CLASS="literal"
>-j</TT
> option is
      somewhat system-dependent.
      One rough guideline is that the more processors
      your system has,
      the higher you want to set the
      <TT
CLASS="literal"
>-j</TT
> value,
      in order to take advantage of the number of CPUs.

      </P
><P
>&#13;
      For example, suppose the administrators
      of your development systems
      have standardized on setting a
      <CODE
CLASS="varname"
>NUM_CPU</CODE
> environment variable
      to the number of processors on each system.
      A little bit of Python code
      to access the environment variable
      and the <CODE
CLASS="function"
>SetOption</CODE
> function
      provide the right level of flexibility:

      </P
><PRE
CLASS="programlisting"
>&#13;        import os
        num_cpu = int(os.environ.get('NUM_CPU', 2))
        SetOption('num_jobs', num_cpu)
        print "running with -j", GetOption('num_jobs')
      </PRE
><P
>&#13;
      The above snippet of code
      sets the value of the <TT
CLASS="literal"
>--jobs</TT
> option
      to the value specified in the
      <CODE
CLASS="varname"
>$NUM_CPU</CODE
> environment variable.
      (This is one of the exception cases
      where the string is spelled differently from
      the from command-line option.
      The string for fetching or setting the <TT
CLASS="literal"
>--jobs</TT
>
      value is <TT
CLASS="literal"
>num_jobs</TT
>
      for historical reasons.)
      The code in this example prints the <TT
CLASS="literal"
>num_jobs</TT
>
      value for illustrative purposes.
      It uses a default value of <TT
CLASS="literal"
>2</TT
>
      to provide some minimal parallelism even on
      single-processor systems:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        running with -j 2
        scons: `.' is up to date.
      </PRE
><P
>&#13;
      But if the <CODE
CLASS="varname"
>$NUM_CPU</CODE
>
      environment variable is set,
      then we use that for the default number of jobs:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>export NUM_CPU="4"</KBD
>
        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        running with -j 4
        scons: `.' is up to date.
      </PRE
><P
>&#13;
      But any explicit
      <TT
CLASS="literal"
>-j</TT
> or <TT
CLASS="literal"
>--jobs</TT
>
      value the user specifies an the command line is used first,
      regardless of whether or not
      the <CODE
CLASS="varname"
>$NUM_CPU</CODE
> environment
      variable is set:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q -j 7</KBD
>
        running with -j 7
        scons: `.' is up to date.
        % <KBD
CLASS="userinput"
>export NUM_CPU="4"</KBD
>
        % <KBD
CLASS="userinput"
>scons -Q -j 3</KBD
>
        running with -j 3
        scons: `.' is up to date.
      </PRE
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="sect-command-line-option-strings"
>12.1.4. Strings for Getting or Setting Values of <SPAN
CLASS="application"
>SCons</SPAN
> Command-Line Options</A
></H3
><P
>&#13;
      The strings that you can pass to the <CODE
CLASS="function"
>GetOption</CODE
>
      and <CODE
CLASS="function"
>SetOption</CODE
> functions usually correspond to the
      first long-form option name
      (beginning with two hyphen characters:  <TT
CLASS="literal"
>--</TT
>),
      after replacing any remaining hyphen characters
      with underscores.

      </P
><P
>&#13;
      The full list of strings and the variables they
      correspond to is as follows:

      </P
><DIV
CLASS="informaltable"
><P
></P
><A
NAME="AEN2148"
></A
><TABLE
BORDER="1"
CLASS="CALSTABLE"
><COL><COL><THEAD
><TR
><TH
>String for <CODE
CLASS="function"
>GetOption</CODE
> and <CODE
CLASS="function"
>SetOption</CODE
></TH
><TH
>Command-Line Option(s)</TH
></TR
></THEAD
><TBODY
><TR
><TD
><TT
CLASS="literal"
>cache_debug</TT
></TD
><TD
><CODE
CLASS="option"
>--cache-debug</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>cache_disable</TT
></TD
><TD
><CODE
CLASS="option"
>--cache-disable</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>cache_force</TT
></TD
><TD
><CODE
CLASS="option"
>--cache-force</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>cache_show</TT
></TD
><TD
><CODE
CLASS="option"
>--cache-show</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>clean</TT
></TD
><TD
><CODE
CLASS="option"
>-c</CODE
>,
           <CODE
CLASS="option"
>--clean</CODE
>,
           <CODE
CLASS="option"
>--remove</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>config</TT
></TD
><TD
><CODE
CLASS="option"
>--config</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>directory</TT
></TD
><TD
><CODE
CLASS="option"
>-C</CODE
>,
             <CODE
CLASS="option"
>--directory</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>diskcheck</TT
></TD
><TD
><CODE
CLASS="option"
>--diskcheck</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>duplicate</TT
></TD
><TD
><CODE
CLASS="option"
>--duplicate</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>file</TT
></TD
><TD
><CODE
CLASS="option"
>-f</CODE
>,
             <CODE
CLASS="option"
>--file</CODE
>,
             <CODE
CLASS="option"
>--makefile </CODE
>,
             <CODE
CLASS="option"
>--sconstruct</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>help</TT
></TD
><TD
><CODE
CLASS="option"
>-h</CODE
>,
             <CODE
CLASS="option"
>--help</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>ignore_errors</TT
></TD
><TD
><CODE
CLASS="option"
>--ignore-errors</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>implicit_cache</TT
></TD
><TD
><CODE
CLASS="option"
>--implicit-cache</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>implicit_deps_changed</TT
></TD
><TD
><CODE
CLASS="option"
>--implicit-deps-changed</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>implicit_deps_unchanged</TT
></TD
><TD
><CODE
CLASS="option"
>--implicit-deps-unchanged</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>interactive</TT
></TD
><TD
><CODE
CLASS="option"
>--interact</CODE
>,
             <CODE
CLASS="option"
>--interactive</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>keep_going</TT
></TD
><TD
><CODE
CLASS="option"
>-k</CODE
>,
             <CODE
CLASS="option"
>--keep-going</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>max_drift</TT
></TD
><TD
><CODE
CLASS="option"
>--max-drift</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>no_exec</TT
></TD
><TD
><CODE
CLASS="option"
>-n</CODE
>,
             <CODE
CLASS="option"
>--no-exec</CODE
>,
             <CODE
CLASS="option"
>--just-print</CODE
>,
             <CODE
CLASS="option"
>--dry-run</CODE
>,
             <CODE
CLASS="option"
>--recon</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>no_site_dir</TT
></TD
><TD
><CODE
CLASS="option"
>--no-site-dir</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>num_jobs</TT
></TD
><TD
><CODE
CLASS="option"
>-j</CODE
>,
             <CODE
CLASS="option"
>--jobs</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>profile_file</TT
></TD
><TD
><CODE
CLASS="option"
>--profile</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>question</TT
></TD
><TD
><CODE
CLASS="option"
>-q</CODE
>,
             <CODE
CLASS="option"
>--question</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>random</TT
></TD
><TD
><CODE
CLASS="option"
>--random</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>repository</TT
></TD
><TD
><CODE
CLASS="option"
>-Y</CODE
>,
             <CODE
CLASS="option"
>--repository</CODE
>,
             <CODE
CLASS="option"
>--srcdir</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>silent</TT
></TD
><TD
><CODE
CLASS="option"
>-s</CODE
>,
             <CODE
CLASS="option"
>--silent</CODE
>,
             <CODE
CLASS="option"
>--quiet</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>site_dir</TT
></TD
><TD
><CODE
CLASS="option"
>--site-dir</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>stack_size</TT
></TD
><TD
><CODE
CLASS="option"
>--stack-size</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>taskmastertrace_file</TT
></TD
><TD
><CODE
CLASS="option"
>--taskmastertrace</CODE
></TD
></TR
><TR
><TD
><TT
CLASS="literal"
>warn</TT
></TD
><TD
><CODE
CLASS="option"
>--warn</CODE
> <CODE
CLASS="option"
>--warning</CODE
></TD
></TR
></TBODY
></TABLE
><P
></P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2327"
>12.1.5. Adding Custom Command-Line Options:  the <CODE
CLASS="function"
>AddOption</CODE
> Function</A
></H3
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> also allows you to define your own
      command-line options with the <CODE
CLASS="function"
>AddOption</CODE
> function.
      The <CODE
CLASS="function"
>AddOption</CODE
> function takes the same arguments
      as the <CODE
CLASS="function"
>optparse.add_option</CODE
> function
      from the standard Python library.
      <A
NAME="AEN2335"
HREF="#FTN.AEN2335"
><SPAN
CLASS="footnote"
>[3]</SPAN
></A
>
      Once you have added a custom command-line option
      with the <CODE
CLASS="function"
>AddOption</CODE
> function,
      the value of the option (if any) is immediately available
      using the standard <CODE
CLASS="function"
>GetOption</CODE
> function.
      (The value can also be set using <CODE
CLASS="function"
>SetOption</CODE
>,
      although that's not very useful in practice
      because a default value can be specified in
      directly in the <CODE
CLASS="function"
>AddOption</CODE
> call.)

      </P
><P
>&#13;
      One useful example of using this functionality
      is to provide a <CODE
CLASS="option"
>--prefix</CODE
> for users:

      </P
><PRE
CLASS="programlisting"
>&#13;        AddOption('--prefix',
                  dest='prefix',
                  type='string',
                  nargs=1,
                  action='store',
                  metavar='DIR',
                  help='installation prefix')

        env = Environment(PREFIX = GetOption('prefix'))

        installed_foo = env.Install('$PREFIX/usr/bin', 'foo.in')
        Default(installed_foo)
      </PRE
><P
>&#13;
      The above code uses the <CODE
CLASS="function"
>GetOption</CODE
> function
      to set the <CODE
CLASS="varname"
>$PREFIX</CODE
>
      construction variable to any
      value that the user specifies with a command-line
      option of <TT
CLASS="literal"
>--prefix</TT
>.
      Because <CODE
CLASS="varname"
>$PREFIX</CODE
>
      will expand to a null string if it's not initialized,
      running <SPAN
CLASS="application"
>SCons</SPAN
> without the
      option of <TT
CLASS="literal"
>--prefix</TT
>
      will install the file in the
      <TT
CLASS="filename"
>/usr/bin/</TT
> directory:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q -n</KBD
>
        Install file: "foo.in" as "/usr/bin/foo.in"
      </PRE
><P
>&#13;
      But specifying <TT
CLASS="literal"
>--prefix=/tmp/install</TT
>
      on the command line causes the file to be installed in the
      <TT
CLASS="filename"
>/tmp/install/usr/bin/</TT
> directory:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q -n --prefix=/tmp/install</KBD
>
        Install file: "foo.in" as "/tmp/install/usr/bin/foo.in"
      </PRE
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="sect-command-line-variables"
>12.2. Command-Line <CODE
CLASS="varname"
>variable</CODE
>=<CODE
CLASS="varname"
>value</CODE
> Build Variables</A
></H2
><P
>&#13;
    You may want to control various aspects
    of your build by allowing the user
    to specify <CODE
CLASS="varname"
>variable</CODE
>=<CODE
CLASS="varname"
>value</CODE
>
    values on the command line.
    For example, suppose you
    want users to be able to
    build a debug version of a program
    by running <SPAN
CLASS="application"
>SCons</SPAN
> as follows:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q debug=1</KBD
>
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> provides an <CODE
CLASS="varname"
>ARGUMENTS</CODE
> dictionary
    that stores all of the
    <CODE
CLASS="varname"
>variable</CODE
>=<CODE
CLASS="varname"
>value</CODE
>
    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 <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>always</I
></SPAN
>
    specify a variable,
    you probably want to use
    the Python
    <TT
CLASS="literal"
>ARGUMENTS.get()</TT
> function,
    which allows you to specify a default value
    to be used if there is no specification
    on the command line.)

    </P
><P
>&#13;
    The following code sets the <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
> construction
    variable in response to the <CODE
CLASS="varname"
>debug</CODE
>
    flag being set in the <CODE
CLASS="varname"
>ARGUMENTS</CODE
> dictionary:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       debug = ARGUMENTS.get('debug', 0)
       if int(debug):
           env.Append(CCFLAGS = '-g')
       env.Program('prog.c')
    </PRE
><P
>&#13;
    This results in the <CODE
CLASS="varname"
>-g</CODE
>
    compiler option being used when
    <TT
CLASS="literal"
>debug=1</TT
>
    is used on the command line:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q debug=0</KBD
>
       cc -o prog.o -c prog.c
       cc -o prog prog.o
       % <KBD
CLASS="userinput"
>scons -Q debug=0</KBD
>
       scons: `.' is up to date.
       % <KBD
CLASS="userinput"
>scons -Q debug=1</KBD
>
       cc -o prog.o -c -g prog.c
       cc -o prog prog.o
       % <KBD
CLASS="userinput"
>scons -Q debug=1</KBD
>
       scons: `.' is up to date.
    </PRE
><P
>&#13;
    Notice that <SPAN
CLASS="application"
>SCons</SPAN
> 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 <TT
CLASS="literal"
>debug</TT
>
    argument has changed.

    </P
><P
>&#13;
    The <CODE
CLASS="varname"
>ARGUMENTS</CODE
> dictionary has two minor drawbacks.
    First, because it is a dictionary,
    it can only store one value for each specified keyword,
    and thus only "remembers" the last setting
    for each keyword on the command line.
    This makes the <CODE
CLASS="varname"
>ARGUMENTS</CODE
> dictionary
    inappropriate if users should be able to
    specify multiple values
    on the command line for a given keyword.
    Second, it does not preserve
    the order in which the variable settings
    were specified,
    which is a problem if
    you want the configuration to
    behave differently in response
    to the order in which the build
    variable settings were specified on the command line.

    </P
><P
>&#13;
    To accomodate these requirements,
    <SPAN
CLASS="application"
>SCons</SPAN
> provides an <CODE
CLASS="varname"
>ARGLIST</CODE
> variable
    that gives you direct access to
    <CODE
CLASS="varname"
>variable</CODE
>=<CODE
CLASS="varname"
>value</CODE
>
    settings on the command line,
    in the exact order they were specified,
    and without removing any duplicate settings.
    Each element in the <CODE
CLASS="varname"
>ARGLIST</CODE
> variable
    is itself a two-element list
    containing the keyword and the value
    of the setting,
    and you must loop through,
    or otherwise select from,
    the elements of <CODE
CLASS="varname"
>ARGLIST</CODE
> to
    process the specific settings you want
    in whatever way is appropriate for your configuration.
    For example,
    the following code to let the user
    add to the <CODE
CLASS="varname"
>CPPDEFINES</CODE
> construction variable
    by specifying multiple
    <CODE
CLASS="varname"
>define=</CODE
>
    settings on the command line:

    </P
><PRE
CLASS="programlisting"
>&#13;       cppdefines = []
       for key, value in ARGLIST:
           if key == 'define':
               cppdefines.append(value)
       env = Environment(CPPDEFINES = cppdefines)
       env.Object('prog.c')
    </PRE
><P
>&#13;
    Yields the followig output:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q define=FOO</KBD
>
       cc -o prog.o -c -DFOO prog.c
       % <KBD
CLASS="userinput"
>scons -Q define=FOO define=BAR</KBD
>
       cc -o prog.o -c -DFOO -DBAR prog.c
    </PRE
><P
>&#13;
    Note that the <CODE
CLASS="varname"
>ARGLIST</CODE
> and <CODE
CLASS="varname"
>ARGUMENTS</CODE
>
    variables do not interfere with each other,
    but merely provide slightly different views
    into how the user specified
    <CODE
CLASS="varname"
>variable</CODE
>=<CODE
CLASS="varname"
>value</CODE
>
    settings on the command line.
    You can use both variables in the same
    <SPAN
CLASS="application"
>SCons</SPAN
> configuration.
    In general, the <CODE
CLASS="varname"
>ARGUMENTS</CODE
> dictionary
    is more convenient to use,
    (since you can just fetch variable
    settings through a dictionary access),
    and the <CODE
CLASS="varname"
>ARGLIST</CODE
> list
    is more flexible
    (since you can examine the
    specific order in which
    the user's command-line variabe settings).

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2420"
>12.2.1. Controlling Command-Line Build Variables</A
></H3
><P
>&#13;
      Being able to use a command-line build variable like
      <TT
CLASS="literal"
>debug=1</TT
> is handy,
      but it can be a chore to write specific Python code
      to recognize each such variable,
      check for errors and provide appropriate messages,
      and apply the values to a construction variable.
      To help with this,
      <SPAN
CLASS="application"
>SCons</SPAN
> supports a class to
      define such build variables easily,
      and a mechanism to apply the
      build variables to a construction environment.
      This allows you to control how the build variables affect
      construction environments.

      </P
><P
>&#13;
      For example, suppose that you want users to set
      a <CODE
CLASS="varname"
>RELEASE</CODE
> 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 <TT
CLASS="literal"
>-D</TT
> 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
      <A
HREF="#cv-CPPDEFINES"
><CODE
CLASS="envar"
>$CPPDEFINES</CODE
></A
> construction variable:

      </P
><PRE
CLASS="programlisting"
>&#13;           vars = Variables()
           vars.Add('RELEASE', 'Set to 1 to build for release', 0)
           env = Environment(variables = vars,
                             CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
           env.Program(['foo.c', 'bar.c'])
      </PRE
><P
>&#13;
      This <TT
CLASS="filename"
>SConstruct</TT
> file first creates a <CODE
CLASS="function"
>Variables</CODE
> object
      (the <TT
CLASS="literal"
>vars = Variables()</TT
> call),
      and then uses the object's <CODE
CLASS="function"
>Add</CODE
>
      method to indicate that the <CODE
CLASS="varname"
>RELEASE</CODE
>
      variable can be set on the command line,
      and that its default value will be <TT
CLASS="literal"
>0</TT
>
      (the third argument to the <CODE
CLASS="function"
>Add</CODE
> method).
      The second argument is a line of help text;
      we'll learn how to use it in the next section.

      </P
><P
>&#13;
      We then pass the created <CODE
CLASS="function"
>Variables</CODE
>
      object as a <CODE
CLASS="varname"
>variables</CODE
> keyword argument
      to the <CODE
CLASS="function"
>Environment</CODE
> call
      used to create the construction environment.
      This then allows a user to set the
      <CODE
CLASS="varname"
>RELEASE</CODE
> build variable on the command line
      and have the variable show up in
      the command line used to build each object from
      a C source file:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q RELEASE=1</KBD
>
        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
      </PRE
><P
>&#13;
      NOTE:  Before <SPAN
CLASS="application"
>SCons</SPAN
> release 0.98.1, these build variables
      were known as "command-line build options."
      The class was actually named the <CODE
CLASS="function"
>Options</CODE
> class,
      and in the sections below,
      the various functions were named
      <CODE
CLASS="function"
>BoolOption</CODE
>, <CODE
CLASS="function"
>EnumOption</CODE
>, <CODE
CLASS="function"
>ListOption</CODE
>,
      <CODE
CLASS="function"
>PathOption</CODE
>, <CODE
CLASS="function"
>PackageOption</CODE
> and <CODE
CLASS="function"
>AddOptions</CODE
>.
      These older names still work,
      and you may encounter them in older
      <TT
CLASS="filename"
>SConscript</TT
> fles,
      but their use is discouraged
      and will be officially deprecated some day.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2456"
>12.2.2. Providing Help for Command-Line Build Variables</A
></H3
><P
>&#13;
      To make command-line build variables most useful,
      you ideally want to provide
      some help text that will describe
      the available variables
      when the user runs <TT
CLASS="literal"
>scons -h</TT
>.
      You could write this text by hand,
      but <SPAN
CLASS="application"
>SCons</SPAN
> provides an easier way.
      <CODE
CLASS="function"
>Variables</CODE
> objects support a
      <CODE
CLASS="function"
>GenerateHelpText</CODE
> method
      that will, as its name suggests,
      generate text that describes
      the various variables that
      have been added to it.
      You then pass the output from this method to
      the <CODE
CLASS="function"
>Help</CODE
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;           vars = Variables('custom.py')
           vars.Add('RELEASE', 'Set to 1 to build for release', 0)
           env = Environment(variables = vars)
           Help(vars.GenerateHelpText(env))
      </PRE
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> will now display some useful text
      when the <TT
CLASS="literal"
>-h</TT
> option is used:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q -h</KBD
>
        
        RELEASE: Set to 1 to build for release
            default: 0
            actual: 0
        
        Use scons -H for help about command-line options.
      </PRE
><P
>&#13;
      Notice that the help output shows the default value,
      and the current actual value of the build variable.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2471"
>12.2.3. Reading Build Variables From a File</A
></H3
><P
>&#13;
      Giving the user a way to specify the
      value of a build variable on the command line
      is useful,
      but can still be tedious
      if users must specify the variable
      every time they run <SPAN
CLASS="application"
>SCons</SPAN
>.
      We can let users provide customized build variable settings
      in a local file by providing a
      file name when we create the
      <CODE
CLASS="function"
>Variables</CODE
> object:

      </P
><PRE
CLASS="programlisting"
>&#13;           vars = Variables('custom.py')
           vars.Add('RELEASE', 'Set to 1 to build for release', 0)
           env = Environment(variables = vars,
                             CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
           env.Program(['foo.c', 'bar.c'])
           Help(vars.GenerateHelpText(env))
      </PRE
><P
>&#13;
      This then allows the user to control the <CODE
CLASS="varname"
>RELEASE</CODE
>
      variable by setting it in the <TT
CLASS="filename"
>custom.py</TT
> file:

      </P
><PRE
CLASS="programlisting"
>&#13;        RELEASE = 1
        </PRE
><P
>&#13;
      Note that this file is actually executed
      like a Python script.
      Now when we run <SPAN
CLASS="application"
>SCons</SPAN
>:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        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
      </PRE
><P
>&#13;
      And if we change the contents of <TT
CLASS="filename"
>custom.py</TT
> to:

      </P
><PRE
CLASS="programlisting"
>&#13;        RELEASE = 0
      </PRE
><P
>&#13;
      The object files are rebuilt appropriately
      with the new variable:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        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
      </PRE
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2491"
>12.2.4. Pre-Defined Build Variable Functions</A
></H3
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> provides a number of functions
      that provide ready-made behaviors
      for various types of command-line build variables.

      </P
><DIV
CLASS="section"
><HR><H4
CLASS="section"
><A
NAME="AEN2495"
>12.2.4.1. True/False Values:  the <CODE
CLASS="function"
>BoolVariable</CODE
> Build Variable Function</A
></H4
><P
>&#13;
        It's often handy to be able to specify a
        variable that controls a simple Boolean variable
        with a <TT
CLASS="literal"
>true</TT
> or <TT
CLASS="literal"
>false</TT
> value.
        It would be even more handy to accomodate
        users who have different preferences for how to represent
        <TT
CLASS="literal"
>true</TT
> or <TT
CLASS="literal"
>false</TT
> values.
        The <CODE
CLASS="function"
>BoolVariable</CODE
> function
        makes it easy to accomodate these
        common representations of
        <TT
CLASS="literal"
>true</TT
> or <TT
CLASS="literal"
>false</TT
>.

        </P
><P
>&#13;
        The <CODE
CLASS="function"
>BoolVariable</CODE
> function takes three arguments:
        the name of the build variable,
        the default value of the build variable,
        and the help string for the variable.
        It then returns appropriate information for
        passing to the <CODE
CLASS="function"
>Add</CODE
> method of a <CODE
CLASS="function"
>Variables</CODE
> object, like so:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(BoolVariable('RELEASE', 'Set to build for release', 0))
             env = Environment(variables = vars,
                               CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        With this build variable,
        the <CODE
CLASS="varname"
>RELEASE</CODE
> variable can now be enabled by
        setting it to the value <TT
CLASS="literal"
>yes</TT
>
        or <TT
CLASS="literal"
>t</TT
>:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q RELEASE=yes foo.o</KBD
>
          cc -o foo.o -c -DRELEASE_BUILD=True foo.c
        </PRE
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q RELEASE=t foo.o</KBD
>
          cc -o foo.o -c -DRELEASE_BUILD=True foo.c
        </PRE
><P
>&#13;
        Other values that equate to <TT
CLASS="literal"
>true</TT
> include
        <TT
CLASS="literal"
>y</TT
>,
        <TT
CLASS="literal"
>1</TT
>,
        <TT
CLASS="literal"
>on</TT
>
        and
        <TT
CLASS="literal"
>all</TT
>.

        </P
><P
>&#13;
        Conversely, <CODE
CLASS="varname"
>RELEASE</CODE
> may now be given a <TT
CLASS="literal"
>false</TT
>
        value by setting it to
        <TT
CLASS="literal"
>no</TT
>
        or
        <TT
CLASS="literal"
>f</TT
>:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q RELEASE=no foo.o</KBD
>
          cc -o foo.o -c -DRELEASE_BUILD=False foo.c
        </PRE
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q RELEASE=f foo.o</KBD
>
          cc -o foo.o -c -DRELEASE_BUILD=False foo.c
        </PRE
><P
>&#13;
        Other values that equate to <TT
CLASS="literal"
>false</TT
> include
        <TT
CLASS="literal"
>n</TT
>,
        <TT
CLASS="literal"
>0</TT
>,
        <TT
CLASS="literal"
>off</TT
>
        and
        <TT
CLASS="literal"
>none</TT
>.

        </P
><P
>&#13;
        Lastly, if a user tries to specify
        any other value,
        <SPAN
CLASS="application"
>SCons</SPAN
> supplies an appropriate error message:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q RELEASE=bad_value foo.o</KBD
>
          
          scons: *** Error converting option: RELEASE
          Invalid value for boolean option: bad_value
          File "/home/my/project/SConstruct", line 4, in &#60;module&#62;
        </PRE
></DIV
><DIV
CLASS="section"
><HR><H4
CLASS="section"
><A
NAME="AEN2544"
>12.2.4.2. Single Value From a List:  the <CODE
CLASS="function"
>EnumVariable</CODE
> Build Variable Function</A
></H4
><P
>&#13;
        Suppose that we want a user to be able to
        set a <CODE
CLASS="varname"
>COLOR</CODE
> variable
        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 <CODE
CLASS="function"
>EnumVariable</CODE
>,
        which takes a list of <CODE
CLASS="varname"
>allowed_values</CODE
>        in addition to the variable name,
        default value,
        and help text arguments:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
                                 allowed_values=('red', 'green', 'blue')))
             env = Environment(variables = vars,
                               CPPDEFINES={'COLOR' : '"${COLOR}"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        The user can now explicity set the <CODE
CLASS="varname"
>COLOR</CODE
> build variable
        to any of the specified allowed values:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLOR=red foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="red" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLOR=blue foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="blue" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLOR=green foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="green" foo.c
        </PRE
><P
>&#13;
        But, almost more importantly,
        an attempt to set <CODE
CLASS="varname"
>COLOR</CODE
>
        to a value that's not in the list
        generates an error message:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLOR=magenta foo.o</KBD
>
          
          scons: *** Invalid value for option COLOR: magenta
          File "/home/my/project/SConstruct", line 5, in &#60;module&#62;
        </PRE
><P
>&#13;
        The <CODE
CLASS="function"
>EnumVariable</CODE
> 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 <TT
CLASS="literal"
>navy</TT
> as a synonym for
        <TT
CLASS="literal"
>blue</TT
>.
        We do this by adding a <CODE
CLASS="varname"
>map</CODE
> dictionary
        that will map its key values
        to the desired legal value:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
                                 allowed_values=('red', 'green', 'blue'),
                                 map={'navy':'blue'}))
             env = Environment(variables = vars,
                               CPPDEFINES={'COLOR' : '"${COLOR}"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        As desired, the user can then use
        <TT
CLASS="literal"
>navy</TT
> on the command line,
        and <SPAN
CLASS="application"
>SCons</SPAN
> will translate it into <TT
CLASS="literal"
>blue</TT
>
        when it comes time to use the <CODE
CLASS="varname"
>COLOR</CODE
>
        variable to build a target:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLOR=navy foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="blue" foo.c
        </PRE
><P
>&#13;
        By default, when using the <CODE
CLASS="function"
>EnumVariable</CODE
> function,
        arguments that differ
        from the legal values
        only in case
        are treated as illegal values:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLOR=Red foo.o</KBD
>
          
          scons: *** Invalid value for option COLOR: Red
          File "/home/my/project/SConstruct", line 5, in &#60;module&#62;
          % <KBD
CLASS="userinput"
>scons -Q COLOR=BLUE foo.o</KBD
>
          
          scons: *** Invalid value for option COLOR: BLUE
          File "/home/my/project/SConstruct", line 5, in &#60;module&#62;
          % <KBD
CLASS="userinput"
>scons -Q COLOR=nAvY foo.o</KBD
>
          
          scons: *** Invalid value for option COLOR: nAvY
          File "/home/my/project/SConstruct", line 5, in &#60;module&#62;
        </PRE
><P
>&#13;
        The <CODE
CLASS="function"
>EnumVariable</CODE
> function can take an additional
        <CODE
CLASS="varname"
>ignorecase</CODE
> keyword argument that,
        when set to <TT
CLASS="literal"
>1</TT
>,
        tells <SPAN
CLASS="application"
>SCons</SPAN
> to allow case differences
        when the values are specified:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
                                 allowed_values=('red', 'green', 'blue'),
                                 map={'navy':'blue'},
                                 ignorecase=1))
             env = Environment(variables = vars,
                               CPPDEFINES={'COLOR' : '"${COLOR}"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        Which yields the output:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLOR=Red foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="Red" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLOR=BLUE foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="BLUE" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLOR=nAvY foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="blue" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLOR=green foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="green" foo.c
        </PRE
><P
>&#13;
        Notice that an <CODE
CLASS="varname"
>ignorecase</CODE
> value of <TT
CLASS="literal"
>1</TT
>
        preserves the case-spelling that the user supplied.
        If you want <SPAN
CLASS="application"
>SCons</SPAN
> to translate the names
        into lower-case,
        regardless of the case used by the user,
        specify an <CODE
CLASS="varname"
>ignorecase</CODE
> value of <TT
CLASS="literal"
>2</TT
>:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
                                 allowed_values=('red', 'green', 'blue'),
                                 map={'navy':'blue'},
                                 ignorecase=2))
             env = Environment(variables = vars,
                               CPPDEFINES={'COLOR' : '"${COLOR}"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        Now <SPAN
CLASS="application"
>SCons</SPAN
> will use values of
        <TT
CLASS="literal"
>red</TT
>,
        <TT
CLASS="literal"
>green</TT
> or
        <TT
CLASS="literal"
>blue</TT
>
        regardless of how the user spells
        those values on the command line:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLOR=Red foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="red" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLOR=nAvY foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="blue" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLOR=GREEN foo.o</KBD
>
          cc -o foo.o -c -DCOLOR="green" foo.c
        </PRE
></DIV
><DIV
CLASS="section"
><HR><H4
CLASS="section"
><A
NAME="AEN2609"
>12.2.4.3. Multiple Values From a List:  the <CODE
CLASS="function"
>ListVariable</CODE
> Build Variable Function</A
></H4
><P
>&#13;
        Another way in which you might want to allow users
        to control a build variable is to
        specify a list of one or more legal values.
        <SPAN
CLASS="application"
>SCons</SPAN
> supports this through the <CODE
CLASS="function"
>ListVariable</CODE
> function.
        If, for example, we want a user to be able to set a
        <CODE
CLASS="varname"
>COLORS</CODE
> variable to one or more of the legal list of values:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(ListVariable('COLORS', 'List of colors', 0,
                                 ['red', 'green', 'blue']))
             env = Environment(variables = vars,
                               CPPDEFINES={'COLORS' : '"${COLORS}"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        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:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLORS=red,blue foo.o</KBD
>
          cc -o foo.o -c -DCOLORS="red blue" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLORS=blue,green,red foo.o</KBD
>
          cc -o foo.o -c -DCOLORS="blue green red" foo.c
        </PRE
><P
>&#13;
        In addition, the <CODE
CLASS="function"
>ListVariable</CODE
> function
        allows the user to specify explicit keywords of
        <TT
CLASS="literal"
>all</TT
> or <TT
CLASS="literal"
>none</TT
>
        to select all of the legal values,
        or none of them, respectively:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLORS=all foo.o</KBD
>
          cc -o foo.o -c -DCOLORS="red green blue" foo.c
          % <KBD
CLASS="userinput"
>scons -Q COLORS=none foo.o</KBD
>
          cc -o foo.o -c -DCOLORS="" foo.c
        </PRE
><P
>&#13;
        And, of course, an illegal value
        still generates an error message:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q COLORS=magenta foo.o</KBD
>
          
          scons: *** Error converting option: COLORS
          Invalid value(s) for option: magenta
          File "/home/my/project/SConstruct", line 5, in &#60;module&#62;
        </PRE
></DIV
><DIV
CLASS="section"
><HR><H4
CLASS="section"
><A
NAME="AEN2631"
>12.2.4.4. Path Names:  the <CODE
CLASS="function"
>PathVariable</CODE
> Build Variable Function</A
></H4
><P
>&#13;
        <SPAN
CLASS="application"
>SCons</SPAN
> supports a <CODE
CLASS="function"
>PathVariable</CODE
> function
        to make it easy to create a build variable
        to control an expected path name.
        If, for example, you need to
        define a variable in the preprocessor
        that controls the location of a
        configuration file:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(PathVariable('CONFIG',
                                 'Path to configuration file',
                                 '/etc/my_config'))
             env = Environment(variables = vars,
                               CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        This then allows the user to
        override the <CODE
CLASS="varname"
>CONFIG</CODE
> build variable
        on the command line as necessary:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q foo.o</KBD
>
          cc -o foo.o -c -DCONFIG_FILE="/etc/my_config" foo.c
          % <KBD
CLASS="userinput"
>scons -Q CONFIG=/usr/local/etc/other_config foo.o</KBD
>
          scons: `foo.o' is up to date.
        </PRE
><P
>&#13;
        By default, <CODE
CLASS="function"
>PathVariable</CODE
> checks to make sure
        that the specified path exists and generates an error if it
        doesn't:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q CONFIG=/does/not/exist foo.o</KBD
>
          
          scons: *** Path for option CONFIG does not exist: /does/not/exist
          File "/home/my/project/SConstruct", line 6, in &#60;module&#62;
        </PRE
><P
>&#13;
        <CODE
CLASS="function"
>PathVariable</CODE
> 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 <CODE
CLASS="function"
>PathVariable.PathIsFile</CODE
> method:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(PathVariable('CONFIG',
                                 'Path to configuration file',
                                 '/etc/my_config',
                                 PathVariable.PathIsFile))
             env = Environment(variables = vars,
                               CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        Conversely, to ensure that any specified paths are
        directories and not files,
        use the <CODE
CLASS="function"
>PathVariable.PathIsDir</CODE
> method:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(PathVariable('DBDIR',
                                 'Path to database directory',
                                 '/var/my_dbdir',
                                 PathVariable.PathIsDir))
             env = Environment(variables = vars,
                               CPPDEFINES={'DBDIR' : '"$DBDIR"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        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 <CODE
CLASS="function"
>PathVariable.PathIsDirCreate</CODE
> method:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(PathVariable('DBDIR',
                                 'Path to database directory',
                                 '/var/my_dbdir',
                                 PathVariable.PathIsDirCreate))
             env = Environment(variables = vars,
                               CPPDEFINES={'DBDIR' : '"$DBDIR"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        Lastly, if you don't care whether the path exists,
        is a file, or a directory,
        use the <CODE
CLASS="function"
>PathVariable.PathAccept</CODE
> method
        to accept any path that the user supplies:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(PathVariable('OUTPUT',
                                 'Path to output file or directory',
                                 None,
                                 PathVariable.PathAccept))
             env = Environment(variables = vars,
                               CPPDEFINES={'OUTPUT' : '"$OUTPUT"'})
             env.Program('foo.c')
        </PRE
></DIV
><DIV
CLASS="section"
><HR><H4
CLASS="section"
><A
NAME="AEN2660"
>12.2.4.5. Enabled/Disabled Path Names: the <CODE
CLASS="function"
>PackageVariable</CODE
> Build Variable Function</A
></H4
><P
>&#13;
        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 <TT
CLASS="literal"
>yes</TT
> or <TT
CLASS="literal"
>no</TT
> keywords,
        in addition to allow them
        to supply an explicit path name.
        <SPAN
CLASS="application"
>SCons</SPAN
> supports the <CODE
CLASS="function"
>PackageVariable</CODE
>
        function to support this:

        </P
><PRE
CLASS="programlisting"
>&#13;             vars = Variables('custom.py')
             vars.Add(PackageVariable('PACKAGE',
                                    'Location package',
                                    '/opt/location'))
             env = Environment(variables = vars,
                               CPPDEFINES={'PACKAGE' : '"$PACKAGE"'})
             env.Program('foo.c')
        </PRE
><P
>&#13;
        When the <TT
CLASS="filename"
>SConscript</TT
> file uses the <CODE
CLASS="function"
>PackageVariable</CODE
> 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:

        </P
><PRE
CLASS="screen"
>&#13;          % <KBD
CLASS="userinput"
>scons -Q foo.o</KBD
>
          cc -o foo.o -c -DPACKAGE="/opt/location" foo.c
          % <KBD
CLASS="userinput"
>scons -Q PACKAGE=/usr/local/location foo.o</KBD
>
          cc -o foo.o -c -DPACKAGE="/usr/local/location" foo.c
          % <KBD
CLASS="userinput"
>scons -Q PACKAGE=yes foo.o</KBD
>
          cc -o foo.o -c -DPACKAGE="True" foo.c
          % <KBD
CLASS="userinput"
>scons -Q PACKAGE=no foo.o</KBD
>
          cc -o foo.o -c -DPACKAGE="False" foo.c
        </PRE
></DIV
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2677"
>12.2.5. Adding Multiple Command-Line Build Variables at Once</A
></H3
><P
>&#13;
      Lastly, <SPAN
CLASS="application"
>SCons</SPAN
> provides a way to add
      multiple build variables to a <CODE
CLASS="function"
>Variables</CODE
> object at once.
      Instead of having to call the <CODE
CLASS="function"
>Add</CODE
> method
      multiple times,
      you can call the <CODE
CLASS="function"
>AddVariables</CODE
>
      method with a list of build variables
      to be added to the object.
      Each build variable is specified
      as either a tuple of arguments,
      just like you'd pass to the <CODE
CLASS="function"
>Add</CODE
> method itself,
      or as a call to one of the pre-defined
      functions for pre-packaged command-line build variables.
      in any order:

      </P
><PRE
CLASS="programlisting"
>&#13;          vars = Variables()
          vars.AddVariables(
              ('RELEASE', 'Set to 1 to build for release', 0),
              ('CONFIG', 'Configuration file', '/etc/my_config'),
              BoolVariable('warnings', 'compilation with -Wall and similiar', 1),
              EnumVariable('debug', 'debug output and symbols', 'no',
                         allowed_values=('yes', 'no', 'full'),
                         map={}, ignorecase=0),  # case sensitive
              ListVariable('shared',
                         'libraries to build as shared libraries',
                         'all',
                         names = list_of_libs),
              PackageVariable('x11',
                            'use X11 installed here (yes = search some places)',
                            'yes'),
              PathVariable('qtdir', 'where the root of Qt is installed', qtdir),
          )
      </PRE
><P
>&#13;      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2687"
>12.2.6. Handling Unknown Command-Line Build Variables:  the <CODE
CLASS="function"
>UnknownVariables</CODE
> Function</A
></H3
><P
>&#13;
      Users may, of course,
      occasionally misspell variable names in their command-line settings.
      <SPAN
CLASS="application"
>SCons</SPAN
> does not generate an error or warning
      for any unknown variables the users specifies on the command line.
      (This is in no small part because you may be
      processing the arguments directly using the <CODE
CLASS="varname"
>ARGUMENTS</CODE
> dictionary,
      and therefore <SPAN
CLASS="application"
>SCons</SPAN
> can't know in the general case
      whether a given "misspelled" variable is
      really unknown and a potential problem,
      or something that your <TT
CLASS="filename"
>SConscript</TT
> file
      will handle directly with some Python code.)

      </P
><P
>&#13;
      If, however, you're using a <CODE
CLASS="function"
>Variables</CODE
> object to
      define a specific set of command-line build variables
      that you expect users to be able to set,
      you may want to provide an error
      message or warning of your own
      if the user supplies a variable setting
      that is <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
> among
      the defined list of variable names known to the <CODE
CLASS="function"
>Variables</CODE
> object.
      You can do this by calling the <CODE
CLASS="function"
>UnknownVariables</CODE
>
      method of the <CODE
CLASS="function"
>Variables</CODE
> object:

      </P
><PRE
CLASS="programlisting"
>&#13;           vars = Variables(None)
           vars.Add('RELEASE', 'Set to 1 to build for release', 0)
           env = Environment(variables = vars,
                             CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
           unknown = vars.UnknownVariables()
           if unknown:
               print "Unknown variables:", unknown.keys()
               Exit(1)
           env.Program('foo.c')
      </PRE
><P
>&#13;
      The <CODE
CLASS="function"
>UnknownVariables</CODE
> method returns a dictionary
      containing the keywords and values
      of any variables the user specified on the command line
      that are <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
      among the variables known to the <CODE
CLASS="function"
>Variables</CODE
> object
      (from having been specified using
      the <CODE
CLASS="function"
>Variables</CODE
> object's<CODE
CLASS="function"
>Add</CODE
> method).
      In the examble above,
      we check for whether the dictionary
      returned by the <CODE
CLASS="function"
>UnknownVariables</CODE
> is non-empty,
      and if so print the Python list
      containing the names of the unknwown variables
      and then call the <CODE
CLASS="function"
>Exit</CODE
> function
      to terminate <SPAN
CLASS="application"
>SCons</SPAN
>:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q NOT_KNOWN=foo</KBD
>
        Unknown variables: ['NOT_KNOWN']
      </PRE
><P
>&#13;
      Of course, you can process the items in the
      dictionary returned by the <CODE
CLASS="function"
>UnknownVariables</CODE
> function
      in any way appropriate to your bulid configuration,
      including just printing a warning message
      but not exiting,
      logging an error somewhere,
      etc.

      </P
><P
>&#13;
      Note that you must delay the call of <CODE
CLASS="function"
>UnknownVariables</CODE
>
      until after you have applied the <CODE
CLASS="function"
>Variables</CODE
> object
      to a construction environment
      with the <TT
CLASS="literal"
>variables=</TT
>
      keyword argument of an <CODE
CLASS="function"
>Environment</CODE
> call.

      </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="sect-command-line-targets"
>12.3. Command-Line Targets</A
></H2
><DIV
CLASS="section"
><H3
CLASS="section"
><A
NAME="AEN2722"
>12.3.1. Fetching Command-Line Targets: the <CODE
CLASS="varname"
>COMMAND_LINE_TARGETS</CODE
> Variable</A
></H3
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> supports a <CODE
CLASS="varname"
>COMMAND_LINE_TARGETS</CODE
> variable
      that lets you fetch 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 <CODE
CLASS="varname"
>COMMAND_LINE_TARGETS</CODE
> list:

      </P
><PRE
CLASS="programlisting"
>&#13;        if 'bar' in COMMAND_LINE_TARGETS:
            print "Don't forget to copy `bar' to the archive!"
        Default(Program('foo.c'))
        Program('bar.c')
      </PRE
><P
>&#13;
      Then, running <SPAN
CLASS="application"
>SCons</SPAN
> with the default target
      works as it always does,
      but explicity specifying the <SPAN
CLASS="application"
>bar</SPAN
> target
      on the command line generates the warning message:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        cc -o foo.o -c foo.c
        cc -o foo foo.o
        % <KBD
CLASS="userinput"
>scons -Q bar</KBD
>
        Don't forget to copy `bar' to the archive!
        cc -o bar.o -c bar.c
        cc -o bar bar.o
      </PRE
><P
>&#13;
      Another practical use for the <CODE
CLASS="varname"
>COMMAND_LINE_TARGETS</CODE
> variable
      might be to speed up a build
      by only reading certain subsidiary <TT
CLASS="filename"
>SConscript</TT
>
      files if a specific target is requested.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2739"
>12.3.2. Controlling the Default Targets:  the <CODE
CLASS="function"
>Default</CODE
> Function</A
></H3
><P
>&#13;
      One of the most basic things you can control
      is which targets <SPAN
CLASS="application"
>SCons</SPAN
> will build by default--that is,
      when there are no targets specified on the command line.
      As mentioned previously,
      <SPAN
CLASS="application"
>SCons</SPAN
> 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 <CODE
CLASS="function"
>Default</CODE
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         hello = env.Program('hello.c')
         env.Program('goodbye.c')
         Default(hello)
      </PRE
><P
>&#13;
      This <TT
CLASS="filename"
>SConstruct</TT
> file knows how to build two programs,
      <SPAN
CLASS="application"
>hello</SPAN
> and <SPAN
CLASS="application"
>goodbye</SPAN
>,
      but only builds the
      <SPAN
CLASS="application"
>hello</SPAN
> program by default:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         scons: `hello' is up to date.
         % <KBD
CLASS="userinput"
>scons -Q goodbye</KBD
>
         cc -o goodbye.o -c goodbye.c
         cc -o goodbye goodbye.o
      </PRE
><P
>&#13;
      Note that, even when you use the <CODE
CLASS="function"
>Default</CODE
>
      function in your <TT
CLASS="filename"
>SConstruct</TT
> file,
      you can still explicitly specify the current directory
      (<TT
CLASS="literal"
>.</TT
>) on the command line
      to tell <SPAN
CLASS="application"
>SCons</SPAN
> to build
      everything in (or below) the current directory:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q .</KBD
>
         cc -o goodbye.o -c goodbye.c
         cc -o goodbye goodbye.o
         cc -o hello.o -c hello.c
         cc -o hello hello.o
      </PRE
><P
>&#13;
      You can also call the <CODE
CLASS="function"
>Default</CODE
>
      function more than once,
      in which case each call
      adds to the list of targets to be built by default:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         prog1 = env.Program('prog1.c')
         Default(prog1)
         prog2 = env.Program('prog2.c')
         prog3 = env.Program('prog3.c')
         Default(prog3)
      </PRE
><P
>&#13;
      Or you can specify more than one target
      in a single call to the <CODE
CLASS="function"
>Default</CODE
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         prog1 = env.Program('prog1.c')
         prog2 = env.Program('prog2.c')
         prog3 = env.Program('prog3.c')
         Default(prog1, prog3)
      </PRE
><P
>&#13;
      Either of these last two examples
      will build only the
      <SPAN
CLASS="application"
>prog1</SPAN
>
      and
      <SPAN
CLASS="application"
>prog3</SPAN
>
      programs by default:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         cc -o prog1.o -c prog1.c
         cc -o prog1 prog1.o
         cc -o prog3.o -c prog3.c
         cc -o prog3 prog3.o
         % <KBD
CLASS="userinput"
>scons -Q .</KBD
>
         cc -o prog2.o -c prog2.c
         cc -o prog2 prog2.o
      </PRE
><P
>&#13;
      You can list a directory as
      an argument to <CODE
CLASS="function"
>Default</CODE
>:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         env.Program(['prog1/main.c', 'prog1/foo.c'])
         env.Program(['prog2/main.c', 'prog2/bar.c'])
         Default('prog1')
      </PRE
><P
>&#13;
      In which case only the target(s) in that
      directory will be built by default:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         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
         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         scons: `prog1' is up to date.
         % <KBD
CLASS="userinput"
>scons -Q .</KBD
>
         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
      </PRE
><P
>&#13;
      Lastly, if for some reason you don't want
      any targets built by default,
      you can use the Python <TT
CLASS="literal"
>None</TT
>
      variable:

      </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         prog1 = env.Program('prog1.c')
         prog2 = env.Program('prog2.c')
         Default(None)
      </PRE
><P
>&#13;
      Which would produce build output like:

      </P
><PRE
CLASS="screen"
>&#13;         % <KBD
CLASS="userinput"
>scons -Q</KBD
>
         scons: *** No targets specified and no Default() targets found.  Stop.
         % <KBD
CLASS="userinput"
>scons -Q .</KBD
>
         cc -o prog1.o -c prog1.c
         cc -o prog1 prog1.o
         cc -o prog2.o -c prog2.c
         cc -o prog2 prog2.o
      </PRE
><DIV
CLASS="section"
><HR><H4
CLASS="section"
><A
NAME="AEN2790"
>12.3.2.1. Fetching the List of Default Targets: the <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> Variable</A
></H4
><P
>&#13;
        <SPAN
CLASS="application"
>SCons</SPAN
> supports a <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> variable
        that lets you get at the current list of default targets.
        The <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> variable has
        two important differences from the <CODE
CLASS="varname"
>COMMAND_LINE_TARGETS</CODE
> variable.
        First, the <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> variable is a list of
        internal <SPAN
CLASS="application"
>SCons</SPAN
> 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 <CODE
CLASS="function"
>map</CODE
> function
        to run the list through <CODE
CLASS="function"
>str</CODE
>:

        </P
><PRE
CLASS="programlisting"
>&#13;           prog1 = Program('prog1.c')
           Default(prog1)
           print "DEFAULT_TARGETS is", map(str, DEFAULT_TARGETS)
        </PRE
><P
>&#13;
        (Keep in mind that all of the manipulation of the
        <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> list takes place during the
        first phase when <SPAN
CLASS="application"
>SCons</SPAN
> is reading up the <TT
CLASS="filename"
>SConscript</TT
> files,
        which is obvious if
        we leave off the <TT
CLASS="literal"
>-Q</TT
> flag when we run <SPAN
CLASS="application"
>SCons</SPAN
>:)

        </P
><PRE
CLASS="screen"
>&#13;           % <KBD
CLASS="userinput"
>scons</KBD
>
           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.
        </PRE
><P
>&#13;
        Second,
        the contents of the <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> list change
        in response to calls to the <CODE
CLASS="function"
>Default</CODE
>: function,
        as you can see from the following <TT
CLASS="filename"
>SConstruct</TT
> file:

        </P
><PRE
CLASS="programlisting"
>&#13;           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)
        </PRE
><P
>&#13;
        Which yields the output:

        </P
><PRE
CLASS="screen"
>&#13;           % <KBD
CLASS="userinput"
>scons</KBD
>
           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.
        </PRE
><P
>&#13;
        In practice, this simply means that you
        need to pay attention to the order in
        which you call the <CODE
CLASS="function"
>Default</CODE
> function
        and refer to the <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> list,
        to make sure that you don't examine the
        list before you've added the default targets
        you expect to find in it.

        </P
></DIV
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN2822"
>12.3.3. Fetching the List of Build Targets, Regardless of Origin: the <CODE
CLASS="varname"
>BUILD_TARGETS</CODE
> Variable</A
></H3
><P
>&#13;
      We've already been introduced to the
      <CODE
CLASS="varname"
>COMMAND_LINE_TARGETS</CODE
> variable,
      which contains a list of targets specified on the command line,
      and the <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> variable,
      which contains a list of targets specified
      via calls to the <CODE
CLASS="function"
>Default</CODE
> method or function.
      Sometimes, however,
      you want a list of whatever targets
      <SPAN
CLASS="application"
>SCons</SPAN
> will try to build,
      regardless of whether the targets came from the
      command line or a <CODE
CLASS="function"
>Default</CODE
> call.
      You could code this up by hand, as follows:

      </P
><PRE
CLASS="programlisting"
>&#13;        if COMMAND_LINE_TARGETS:
            targets = COMMAND_LINE_TARGETS
        else:
            targets = DEFAULT_TARGETS
      </PRE
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
>, however, provides a convenient
      <CODE
CLASS="varname"
>BUILD_TARGETS</CODE
> variable
      that eliminates the need for this by-hand manipulation.
      Essentially, the <CODE
CLASS="varname"
>BUILD_TARGETS</CODE
> 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 <CODE
CLASS="function"
>Default</CODE
> method or function.

      </P
><P
>&#13;
      Because <CODE
CLASS="varname"
>BUILD_TARGETS</CODE
> may contain a list of <SPAN
CLASS="application"
>SCons</SPAN
> 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 <CODE
CLASS="varname"
>DEFAULT_TARGETS</CODE
> list:

      </P
><PRE
CLASS="programlisting"
>&#13;        prog1 = Program('prog1.c')
        Program('prog2.c')
        Default(prog1)
        print "BUILD_TARGETS is", map(str, BUILD_TARGETS)
      </PRE
><P
>&#13;
      Notice how the value of <CODE
CLASS="varname"
>BUILD_TARGETS</CODE
>
      changes depending on whether a target is
      specified on the command line:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        BUILD_TARGETS is ['prog1']
        cc -o prog1.o -c prog1.c
        cc -o prog1 prog1.o
        % <KBD
CLASS="userinput"
>scons -Q prog2</KBD
>
        BUILD_TARGETS is ['prog2']
        cc -o prog2.o -c prog2.c
        cc -o prog2 prog2.o
        % <KBD
CLASS="userinput"
>scons -Q -c .</KBD
>
        BUILD_TARGETS is ['.']
        Removed prog1.o
        Removed prog1
        Removed prog2.o
        Removed prog2
      </PRE
></DIV
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-install"
></A
>Chapter 13. Installing Files in Other Directories:  the <CODE
CLASS="function"
>Install</CODE
> Builder</H1
><P
>&#13;
  Once a program is built,
  it is often appropriate to install it in another
  directory for public use.
  You use the <CODE
CLASS="function"
>Install</CODE
> method 
  to arrange for a program, or any other file,
  to be copied into a destination directory:

  </P
><PRE
CLASS="programlisting"
>&#13;     env = Environment()
     hello = env.Program('hello.c')
     env.Install('/usr/bin', hello)
  </PRE
><P
>&#13;
  Note, however, that installing a file is
  still considered a type of file "build."
  This is important when you remember that
  the default behavior of <SPAN
CLASS="application"
>SCons</SPAN
> is
  to build files in or below the current directory.
  If, as in the example above,
  you are installing files in a directory
  outside of the top-level <TT
CLASS="filename"
>SConstruct</TT
> file's directory tree,
  you must specify that directory
  (or a higher directory, such as <TT
CLASS="literal"
>/</TT
>)
  for it to install anything there:

  </P
><PRE
CLASS="screen"
>&#13;     % <KBD
CLASS="userinput"
>scons -Q</KBD
>
     cc -o hello.o -c hello.c
     cc -o hello hello.o
     % <KBD
CLASS="userinput"
>scons -Q /usr/bin</KBD
>
     Install file: "hello" as "/usr/bin/hello"
  </PRE
><P
>&#13;
  It can, however, be cumbersome to remember
  (and type) the specific destination directory
  in which the program (or any other file)
  should be installed.
  This is an area where the <CODE
CLASS="function"
>Alias</CODE
>
  function comes in handy,
  allowing you, for example,
  to create a pseudo-target named <TT
CLASS="literal"
>install</TT
>
  that can expand to the specified destination directory:

  </P
><PRE
CLASS="programlisting"
>&#13;     env = Environment()
     hello = env.Program('hello.c')
     env.Install('/usr/bin', hello)
     env.Alias('install', '/usr/bin')
  </PRE
><P
>&#13;
  This then yields the more natural
  ability to install the program
  in its destination as follows:

  </P
><PRE
CLASS="screen"
>&#13;     % <KBD
CLASS="userinput"
>scons -Q</KBD
>
     cc -o hello.o -c hello.c
     cc -o hello hello.o
     % <KBD
CLASS="userinput"
>scons -Q install</KBD
>
     Install file: "hello" as "/usr/bin/hello"
  </PRE
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2869"
>13.1. Installing Multiple Files in a Directory</A
></H2
><P
>&#13;
    You can install multiple files into a directory
    simply by calling the <CODE
CLASS="function"
>Install</CODE
> function multiple times:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       hello = env.Program('hello.c')
       goodbye = env.Program('goodbye.c')
       env.Install('/usr/bin', hello)
       env.Install('/usr/bin', goodbye)
       env.Alias('install', '/usr/bin')
    </PRE
><P
>&#13;
    Or, more succinctly, listing the multiple input
    files in a list
    (just like you can do with any other builder):

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       hello = env.Program('hello.c')
       goodbye = env.Program('goodbye.c')
       env.Install('/usr/bin', [hello, goodbye])
       env.Alias('install', '/usr/bin')
    </PRE
><P
>&#13;
    Either of these two examples yields:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q install</KBD
>
       cc -o goodbye.o -c goodbye.c
       cc -o goodbye goodbye.o
       Install file: "goodbye" as "/usr/bin/goodbye"
       cc -o hello.o -c hello.c
       cc -o hello hello.o
       Install file: "hello" as "/usr/bin/hello"
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2879"
>13.2. Installing a File Under a Different Name</A
></H2
><P
>&#13;
    The <CODE
CLASS="function"
>Install</CODE
> method preserves the name
    of the file when it is copied into the
    destination directory.
    If you need to change the name of the file
    when you copy it, use the <CODE
CLASS="function"
>InstallAs</CODE
> function:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       hello = env.Program('hello.c')
       env.InstallAs('/usr/bin/hello-new', hello)
       env.Alias('install', '/usr/bin')
    </PRE
><P
>&#13;
    This installs the <TT
CLASS="literal"
>hello</TT
>
    program with the name <TT
CLASS="literal"
>hello-new</TT
>
    as follows:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q install</KBD
>
       cc -o hello.o -c hello.c
       cc -o hello hello.o
       Install file: "hello" as "/usr/bin/hello-new"
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2890"
>13.3. Installing Multiple Files Under Different Names</A
></H2
><P
>&#13;
    Lastly, if you have multiple files that all
    need to be installed with different file names,
    you can either call the <CODE
CLASS="function"
>InstallAs</CODE
> function
    multiple times, or as a shorthand,
    you can supply same-length lists
    for both the target and source arguments:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       hello = env.Program('hello.c')
       goodbye = env.Program('goodbye.c')
       env.InstallAs(['/usr/bin/hello-new',
                      '/usr/bin/goodbye-new'],
                     [hello, goodbye])
       env.Alias('install', '/usr/bin')
    </PRE
><P
>&#13;
    In this case, the <CODE
CLASS="function"
>InstallAs</CODE
> function
    loops through both lists simultaneously,
    and copies each source file into its corresponding
    target file name:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q install</KBD
>
       cc -o goodbye.o -c goodbye.c
       cc -o goodbye goodbye.o
       Install file: "goodbye" as "/usr/bin/goodbye-new"
       cc -o hello.o -c hello.c
       cc -o hello hello.o
       Install file: "hello" as "/usr/bin/hello-new"
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-factories"
></A
>Chapter 14. Platform-Independent File System Manipulation</H1
><P
>&#13;
  <SPAN
CLASS="application"
>SCons</SPAN
> provides a number of platform-independent functions,
  called <TT
CLASS="literal"
>factories</TT
>,
  that perform common file system manipulations
  like copying, moving or deleting files and directories,
  or making directories.
  These functions are <TT
CLASS="literal"
>factories</TT
>
  because they don't perform the action
  at the time they're called,
  they each return an <CODE
CLASS="classname"
>Action</CODE
> object
  that can be executed at the appropriate time.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2906"
>14.1. Copying Files or Directories:  The <CODE
CLASS="function"
>Copy</CODE
> Factory</A
></H2
><P
>&#13;
    Suppose you want to arrange to make a copy of a file,
    and don't have a suitable pre-existing builder.
    <A
NAME="AEN2910"
HREF="#FTN.AEN2910"
><SPAN
CLASS="footnote"
>[4]</SPAN
></A
>
    One way would be to use the <CODE
CLASS="function"
>Copy</CODE
> action factory
    in conjunction with the <CODE
CLASS="function"
>Command</CODE
> builder:

    </P
><PRE
CLASS="programlisting"
>&#13;        Command("file.out", "file.in", Copy("$TARGET", "$SOURCE"))
    </PRE
><P
>&#13;
    Notice that the action returned by the <CODE
CLASS="function"
>Copy</CODE
> factory
    will expand the <A
HREF="#cv-TARGET"
><CODE
CLASS="envar"
>$TARGET</CODE
></A
> and <A
HREF="#cv-SOURCE"
><CODE
CLASS="envar"
>$SOURCE</CODE
></A
> strings
    at the time <TT
CLASS="filename"
>file.out</TT
> is built,
    and that the order of the arguments
    is the same as that of a builder itself--that is,
    target first, followed by source:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       Copy("file.out", "file.in")
    </PRE
><P
>&#13;
    You can, of course, name a file explicitly
    instead of using <CODE
CLASS="envar"
>$TARGET</CODE
> or <CODE
CLASS="envar"
>$SOURCE</CODE
>:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", [], Copy("$TARGET", "file.in"))
    </PRE
><P
>&#13;
    Which executes as:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Copy("file.out", "file.in")
    </PRE
><P
>&#13;
    The usefulness of the <CODE
CLASS="function"
>Copy</CODE
> factory
    becomes more apparent when
    you use it in a list of actions
    passed to the <CODE
CLASS="function"
>Command</CODE
> builder.
    For example, suppose you needed to run a
    file through a utility that only modifies files in-place,
    and can't "pipe" input to output.
    One solution is to copy the source file
    to a temporary file name,
    run the utility,
    and then copy the modified temporary file to the target,
    which the <CODE
CLASS="function"
>Copy</CODE
> factory makes extremely easy:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", "file.in",
              [
                Copy("tempfile", "$SOURCE"),
                "modify tempfile",
                Copy("$TARGET", "tempfile"),
              ])
    </PRE
><P
>&#13;
    The output then looks like:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Copy("tempfile", "file.in")
      modify tempfile
      Copy("file.out", "tempfile")
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2940"
>14.2. Deleting Files or Directories:  The <CODE
CLASS="function"
>Delete</CODE
> Factory</A
></H2
><P
>&#13;
    If you need to delete a file,
    then the <CODE
CLASS="function"
>Delete</CODE
> factory
    can be used in much the same way as
    the <CODE
CLASS="function"
>Copy</CODE
> factory.
    For example, if we want to make sure that
    the temporary file
    in our last example doesn't exist before
    we copy to it,
    we could add <CODE
CLASS="function"
>Delete</CODE
> to the beginning
    of the command list:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", "file.in",
              [
                Delete("tempfile"),
                Copy("tempfile", "$SOURCE"),
                "modify tempfile",
                Copy("$TARGET", "tempfile"),
              ])
    </PRE
><P
>&#13;
    When then executes as follows:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Delete("tempfile")
      Copy("tempfile", "file.in")
      modify tempfile
      Copy("file.out", "tempfile")
    </PRE
><P
>&#13;
    Of course, like all of these <CODE
CLASS="classname"
>Action</CODE
> factories,
    the <CODE
CLASS="function"
>Delete</CODE
> factory also expands
    <A
HREF="#cv-TARGET"
><CODE
CLASS="envar"
>$TARGET</CODE
></A
> and <A
HREF="#cv-SOURCE"
><CODE
CLASS="envar"
>$SOURCE</CODE
></A
> variables appropriately.
    For example:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", "file.in",
              [
                Delete("$TARGET"),
                Copy("$TARGET", "$SOURCE")
              ])
    </PRE
><P
>&#13;
    Executes as:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Delete("file.out")
      Copy("file.out", "file.in")
    </PRE
><P
>&#13;
    Note, however, that you typically don't need to
    call the <CODE
CLASS="function"
>Delete</CODE
> factory explicitly in this way;
    by default, <SPAN
CLASS="application"
>SCons</SPAN
> deletes its target(s)
    for you before executing any action.

    </P
><P
>&#13;
    One word of caution about using the <CODE
CLASS="function"
>Delete</CODE
> factory:
    it has the same variable expansions available
    as any other factory, including the <CODE
CLASS="envar"
>$SOURCE</CODE
> variable.
    Specifying <TT
CLASS="literal"
>Delete("$SOURCE")</TT
>
    is not something you usually want to do!

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2969"
>14.3. Moving (Renaming) Files or Directories:  The <CODE
CLASS="function"
>Move</CODE
> Factory</A
></H2
><P
>&#13;
    The <CODE
CLASS="function"
>Move</CODE
> factory
    allows you to rename a file or directory.
    For example, if we don't want to copy the temporary file,
    we could use:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", "file.in",
              [
                Copy("tempfile", "$SOURCE"),
                "modify tempfile",
                Move("$TARGET", "tempfile"),
              ])
    </PRE
><P
>&#13;
    Which would execute as:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Copy("tempfile", "file.in")
      modify tempfile
      Move("file.out", "tempfile")
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2978"
>14.4. Updating the Modification Time of a File:  The <CODE
CLASS="function"
>Touch</CODE
> Factory</A
></H2
><P
>&#13;
    If you just need to update the
    recorded modification time for a file,
    use the <CODE
CLASS="function"
>Touch</CODE
> factory:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", "file.in",
              [
                Copy("$TARGET", "$SOURCE"),
                Touch("$TARGET"),
              ])
    </PRE
><P
>&#13;
    Which executes as:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Copy("file.out", "file.in")
      Touch("file.out")
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2987"
>14.5. Creating a Directory:  The <CODE
CLASS="function"
>Mkdir</CODE
> Factory</A
></H2
><P
>&#13;
    If you need to create a directory,
    use the <CODE
CLASS="function"
>Mkdir</CODE
> factory.
    For example, if we need to process
    a file in a temporary directory
    in which the processing tool
    will create other files that we don't care about, 
    you could use:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", "file.in",
              [
                Delete("tempdir"),
                Mkdir("tempdir"),
                Copy("tempdir/${SOURCE.file}", "$SOURCE"),
                "process tempdir",
                Move("$TARGET", "tempdir/output_file"),
                Delete("tempdir"),
              ])
    </PRE
><P
>&#13;
    Which executes as:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Delete("tempdir")
      Mkdir("tempdir")
      Copy("tempdir/file.in", "file.in")
      process tempdir
      Move("file.out", "tempdir/output_file")
      scons: *** [file.out] No such file or directory
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN2996"
>14.6. Changing File or Directory Permissions:  The <CODE
CLASS="function"
>Chmod</CODE
> Factory</A
></H2
><P
>&#13;
    To change permissions on a file or directory,
    use the <CODE
CLASS="function"
>Chmod</CODE
> factory.
    The permission argument uses POSIX-style
    permission bits and should typically
    be expressed as an octal,
    not decimal, number:

    </P
><PRE
CLASS="programlisting"
>&#13;      Command("file.out", "file.in",
              [
                Copy("$TARGET", "$SOURCE"),
                Chmod("$TARGET", 0755),
              ])
    </PRE
><P
>&#13;
    Which executes:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Copy("file.out", "file.in")
      Chmod("file.out", 0755)
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3005"
>14.7. Executing an action immediately:  the <CODE
CLASS="function"
>Execute</CODE
> Function</A
></H2
><P
>&#13;
    We've been showing you how to use <CODE
CLASS="classname"
>Action</CODE
> factories
    in the <CODE
CLASS="function"
>Command</CODE
> function.
    You can also execute an <CODE
CLASS="classname"
>Action</CODE
> returned by a factory
    (or actually, any <CODE
CLASS="classname"
>Action</CODE
>)
    at the time the <TT
CLASS="filename"
>SConscript</TT
> file is read
    by using the <CODE
CLASS="function"
>Execute</CODE
> function.
    For example, if we need to make sure that
    a directory exists before we build any targets,

    </P
><PRE
CLASS="programlisting"
>&#13;      Execute(Mkdir('/tmp/my_temp_directory'))
    </PRE
><P
>&#13;
    Notice that this will
    create the directory while
    the <TT
CLASS="filename"
>SConscript</TT
> file is being read:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      Mkdir("/tmp/my_temp_directory")
      scons: done reading SConscript files.
      scons: Building targets ...
      scons: `.' is up to date.
      scons: done building targets.
    </PRE
><P
>&#13;
    If you're familiar with Python,
    you may wonder why you would want to use this
    instead of just calling the native Python
    <CODE
CLASS="function"
>os.mkdir()</CODE
> function.
    The advantage here is that the <CODE
CLASS="function"
>Mkdir</CODE
>
    action will behave appropriately if the user
    specifies the <SPAN
CLASS="application"
>SCons</SPAN
> <CODE
CLASS="option"
>-n</CODE
> or
    <CODE
CLASS="option"
>-q</CODE
> options--that is,
    it will print the action but not actually
    make the directory when <CODE
CLASS="option"
>-n</CODE
> is specified,
    or make the directory but not print the action
    when <CODE
CLASS="option"
>-q</CODE
> is specified.

    </P
><P
>&#13;
    The <CODE
CLASS="function"
>Execute</CODE
> function returns the exit status
    or return value of the underlying action being executed.
    It will also print an error message if the action
    fails and returns a non-zero value.
    <SPAN
CLASS="application"
>SCons</SPAN
> will <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>, however,
    actually stop the build if the action fails.
    If you want the build to stop
    in response to a failure in an action called by <CODE
CLASS="function"
>Execute</CODE
>,
    you must do so by explicitly
    checking the return value
    and calling the <CODE
CLASS="function"
>Exit</CODE
> function
    (or a Python equivalent):

    </P
><PRE
CLASS="programlisting"
>&#13;    if Execute(Mkdir('/tmp/my_temp_directory')):
        # A problem occurred while making the temp directory.
        Exit(1)
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-file-removal"
></A
>Chapter 15. Controlling Removal of Targets</H1
><P
>&#13;
  There are two occasions when <SPAN
CLASS="application"
>SCons</SPAN
> will,
  by default, remove target files.
  The first is when <SPAN
CLASS="application"
>SCons</SPAN
> determines that
  an target file needs to be rebuilt
  and removes the existing version of the target
  before executing
  The second is when <SPAN
CLASS="application"
>SCons</SPAN
> is invoked with the
  <TT
CLASS="literal"
>-c</TT
> option to "clean"
  a tree of its built targets.

  These behaviours can be suppressed with the
  <CODE
CLASS="function"
>Precious</CODE
> and <CODE
CLASS="function"
>NoClean</CODE
> functions, respectively.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3044"
>15.1. Preventing target removal during build: the <CODE
CLASS="function"
>Precious</CODE
> Function</A
></H2
><P
>&#13;
    By default, <SPAN
CLASS="application"
>SCons</SPAN
> removes targets before building them.
    Sometimes, however, this is not what you want.
    For example, you may want to update a library incrementally,
    not by having it deleted and then rebuilt from all
    of the constituent object files.
    In such cases, you can use the
    <CODE
CLASS="function"
>Precious</CODE
> method to prevent
    <SPAN
CLASS="application"
>SCons</SPAN
> from removing the target before it is built:

    </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment(RANLIBCOM='')
        lib = env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
        env.Precious(lib)
    </PRE
><P
>&#13;
    Although the output doesn't look any different,
    <SPAN
CLASS="application"
>SCons</SPAN
> does not, in fact,
    delete the target library before rebuilding it:

    </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        cc -o f1.o -c f1.c
        cc -o f2.o -c f2.c
        cc -o f3.o -c f3.c
        ar rc libfoo.a f1.o f2.o f3.o
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> will, however, still delete files marked as <CODE
CLASS="function"
>Precious</CODE
>
    when the <TT
CLASS="literal"
>-c</TT
> option is used.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3060"
>15.2. Preventing target removal during clean: the <CODE
CLASS="function"
>NoClean</CODE
> Function</A
></H2
><P
>&#13;
    By default, <SPAN
CLASS="application"
>SCons</SPAN
> removes all built targets when invoked
    with the <TT
CLASS="literal"
>-c</TT
> option to clean a source tree
    of built targets.
    Sometimes, however, this is not what you want.
    For example, you may want to remove only intermediate generated files
    (such as object files),
    but leave the final targets
    (the libraries)
    untouched.

    In such cases, you can use the <CODE
CLASS="function"
>NoClean</CODE
> method to prevent <SPAN
CLASS="application"
>SCons</SPAN
>
    from removing a target during a clean:

    </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment(RANLIBCOM='')
        lib = env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
        env.NoClean(lib)
    </PRE
><P
>&#13;
    Notice that the <TT
CLASS="filename"
>libfoo.a</TT
>
    is not listed as a removed file:

    </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        cc -o f1.o -c f1.c
        cc -o f2.o -c f2.c
        cc -o f3.o -c f3.c
        ar rc libfoo.a f1.o f2.o f3.o
        % <KBD
CLASS="userinput"
>scons -c</KBD
>
        scons: Reading SConscript files ...
        scons: done reading SConscript files.
        scons: Cleaning targets ...
        Removed f1.o
        Removed f2.o
        Removed f3.o
        scons: done cleaning targets.
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3074"
>15.3. Removing additional files during clean: the <CODE
CLASS="function"
>Clean</CODE
> Function</A
></H2
><P
>&#13;
    There may be additional files that you want removed
    when the <TT
CLASS="literal"
>-c</TT
> option is used,
    but which <SPAN
CLASS="application"
>SCons</SPAN
> doesn't know about
    because they're not normal target files.
    For example, perhaps a command you invoke
    creates a log file as
    part of building the target file you want.
    You would like the log file cleaned,
    but you don't want to have to teach
    SCons that the command
    "builds" two files.

    </P
><P
>&#13;
    You can use the <CODE
CLASS="function"
>Clean</CODE
> function to arrange for additional files
    to be removed when the <TT
CLASS="literal"
>-c</TT
> option is used.
    Notice, however, that the <CODE
CLASS="function"
>Clean</CODE
> function takes two arguments,
    and the <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>second</I
></SPAN
> argument
    is the name of the additional file you want cleaned
    (<TT
CLASS="filename"
>foo.log</TT
> in this example):

    </P
><PRE
CLASS="programlisting"
>&#13;        t = Command('foo.out', 'foo.in', 'build -o $TARGET $SOURCE')
        Clean(t, 'foo.log')
    </PRE
><P
>&#13;
    The first argument is the target with which you want
    the cleaning of this additional file associated.
    In the above example,
    we've used the return value from the
    <CODE
CLASS="function"
>Command</CODE
> function,
    which represents the
    <TT
CLASS="filename"
>foo.out</TT
>
    target.
    Now whenever the
    <TT
CLASS="filename"
>foo.out</TT
> target is cleaned
    by the <TT
CLASS="literal"
>-c</TT
> option,
    the <TT
CLASS="filename"
>foo.log</TT
> file
    will be removed as well:

    </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        build -o foo.out foo.in
        % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
        Removed foo.out
        Removed foo.log
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-hierarchical"
></A
>Chapter 16. Hierarchical Builds</H1
><P
>&#13;
  The source code for large software projects
  rarely stays in a single directory,
  but is nearly always divided into a
  hierarchy of directories.
  Organizing a large software build using <SPAN
CLASS="application"
>SCons</SPAN
>
  involves creating a hierarchy of build scripts
  using the <TT
CLASS="filename"
>SConscript</TT
> function.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3101"
>16.1. <TT
CLASS="filename"
>SConscript</TT
> Files</A
></H2
><P
>&#13;
    As we've already seen,
    the build script at the top of the tree is called <TT
CLASS="filename"
>SConstruct</TT
>.
    The top-level <TT
CLASS="filename"
>SConstruct</TT
> file can
    use the <TT
CLASS="filename"
>SConscript</TT
> function to
    include other subsidiary scripts in the build.
    These subsidiary scripts can, in turn,
    use the <TT
CLASS="filename"
>SConscript</TT
> function
    to include still other scripts in the build.
    By convention, these subsidiary scripts are usually
    named <TT
CLASS="filename"
>SConscript</TT
>.
    For example, a top-level <TT
CLASS="filename"
>SConstruct</TT
> file might
    arrange for four subsidiary scripts to be included
    in the build as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;      SConscript(['drivers/display/SConscript',
                  'drivers/mouse/SConscript',
                  'parser/SConscript',
                  'utilities/SConscript'])
    </PRE
><P
>&#13;
    In this case, the <TT
CLASS="filename"
>SConstruct</TT
> file
    lists all of the <TT
CLASS="filename"
>SConscript</TT
> files in the build explicitly.
    (Note, however, that not every directory in the tree
    necessarily has an <TT
CLASS="filename"
>SConscript</TT
> file.)
    Alternatively, the <TT
CLASS="literal"
>drivers</TT
>
    subdirectory might contain an intermediate
    <TT
CLASS="filename"
>SConscript</TT
> file,
    in which case the <TT
CLASS="filename"
>SConscript</TT
> call in
    the top-level <TT
CLASS="filename"
>SConstruct</TT
> file
    would look like:

    </P
><PRE
CLASS="programlisting"
>&#13;      SConscript(['drivers/SConscript',
                  'parser/SConscript',
                  'utilities/SConscript'])
    </PRE
><P
>&#13;
    And the subsidiary <TT
CLASS="filename"
>SConscript</TT
> file in the
    <TT
CLASS="literal"
>drivers</TT
> subdirectory
    would look like:

    </P
><PRE
CLASS="programlisting"
>&#13;      SConscript(['display/SConscript',
                  'mouse/SConscript'])
    </PRE
><P
>&#13;
    Whether you list all of the <TT
CLASS="filename"
>SConscript</TT
> files in the
    top-level <TT
CLASS="filename"
>SConstruct</TT
> file,
    or place a subsidiary <TT
CLASS="filename"
>SConscript</TT
> file in
    intervening directories,
    or use some mix of the two schemes,
    is up to you and the needs of your software.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3129"
>16.2. Path Names Are Relative to the <TT
CLASS="filename"
>SConscript</TT
> Directory</A
></H2
><P
>&#13;
    Subsidiary <TT
CLASS="filename"
>SConscript</TT
> files make it easy to create a build
    hierarchy because all of the file and directory names
    in a subsidiary <TT
CLASS="filename"
>SConscript</TT
> files are interpreted
    relative to the directory in which the <TT
CLASS="filename"
>SConscript</TT
> file lives.
    Typically, this allows the <TT
CLASS="filename"
>SConscript</TT
> file containing the
    instructions to build a target file
    to live in the same directory as the source files
    from which the target will be built,
    making it easy to update how the software is built
    whenever files are added or deleted
    (or other changes are made).

    </P
><P
>&#13;
    For example, suppose we want to build two programs
    <TT
CLASS="filename"
>prog1</TT
> and <TT
CLASS="filename"
>prog2</TT
> in two separate directories
    with the same names as the programs.
    One typical way to do this would be
    with a top-level <TT
CLASS="filename"
>SConstruct</TT
> file like this:

    </P
><PRE
CLASS="programlisting"
>&#13;      SConscript(['prog1/SConscript',
                  'prog2/SConscript'])
    </PRE
><P
>&#13;
    And subsidiary <TT
CLASS="filename"
>SConscript</TT
> files that look like this:

    </P
><PRE
CLASS="programlisting"
>&#13;      env = Environment()
      env.Program('prog1', ['main.c', 'foo1.c', 'foo2.c'])
      </PRE
><P
>&#13;
    And this:

    </P
><PRE
CLASS="programlisting"
>&#13;      env = Environment()
      env.Program('prog2', ['main.c', 'bar1.c', 'bar2.c'])
      </PRE
><P
>&#13;
    Then, when we run <SPAN
CLASS="application"
>SCons</SPAN
> in the top-level directory,
    our build looks like:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o prog1/foo1.o -c prog1/foo1.c
       cc -o prog1/foo2.o -c prog1/foo2.c
       cc -o prog1/main.o -c prog1/main.c
       cc -o prog1/prog1 prog1/main.o prog1/foo1.o prog1/foo2.o
       cc -o prog2/bar1.o -c prog2/bar1.c
       cc -o prog2/bar2.o -c prog2/bar2.c
       cc -o prog2/main.o -c prog2/main.c
       cc -o prog2/prog2 prog2/main.o prog2/bar1.o prog2/bar2.o
    </PRE
><P
>&#13;
    Notice the following:

    First, you can have files with the same names
    in multiple directories, like main.c in the above example.

    Second, unlike standard recursive use of <SPAN
CLASS="application"
>Make</SPAN
>,
    <SPAN
CLASS="application"
>SCons</SPAN
> stays in the top-level directory
    (where the <TT
CLASS="filename"
>SConstruct</TT
> file lives)
    and issues commands that use the path names
    from the top-level directory to the
    target and source files within the hierarchy.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3155"
>16.3. Top-Level Path Names in Subsidiary <TT
CLASS="filename"
>SConscript</TT
> Files</A
></H2
><P
>&#13;
    If you need to use a file from another directory,
    it's sometimes more convenient to specify
    the path to a file in another directory
    from the top-level <TT
CLASS="filename"
>SConstruct</TT
> directory,
    even when you're using that file in
    a subsidiary <TT
CLASS="filename"
>SConscript</TT
> file in a subdirectory.
    You can tell <SPAN
CLASS="application"
>SCons</SPAN
> to interpret a path name
    as relative to the top-level <TT
CLASS="filename"
>SConstruct</TT
> directory,
    not the local directory of the <TT
CLASS="filename"
>SConscript</TT
> file,
    by appending a <TT
CLASS="literal"
>#</TT
> (hash mark)
    to the beginning of the path name:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       env.Program('prog', ['main.c', '#lib/foo1.c', 'foo2.c'])
    </PRE
><P
>&#13;
    In this example,
    the <TT
CLASS="literal"
>lib</TT
> directory is
    directly underneath the top-level <TT
CLASS="filename"
>SConstruct</TT
> directory.
    If the above <TT
CLASS="filename"
>SConscript</TT
> file is in a subdirectory
    named <TT
CLASS="literal"
>src/prog</TT
>,
    the output would look like:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o lib/foo1.o -c lib/foo1.c
       cc -o src/prog/foo2.o -c src/prog/foo2.c
       cc -o src/prog/main.o -c src/prog/main.c
       cc -o src/prog/prog src/prog/main.o lib/foo1.o src/prog/foo2.o
    </PRE
><P
>&#13;
    (Notice that the <TT
CLASS="literal"
>lib/foo1.o</TT
> object file
    is built in the same directory as its source file.
    See <A
HREF="#chap-separate"
>Chapter 17</A
>, below,
    for information about
    how to build the object file in a different subdirectory.)

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3176"
>16.4. Absolute Path Names</A
></H2
><P
>&#13;
    Of course, you can always specify
    an absolute path name for a file--for example:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       env.Program('prog', ['main.c', '/usr/joe/lib/foo1.c', 'foo2.c'])
    </PRE
><P
>&#13;
    Which, when executed, would yield:

    </P
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       cc -o src/prog/foo2.o -c src/prog/foo2.c
       cc -o src/prog/main.o -c src/prog/main.c
       cc -o /usr/joe/lib/foo1.o -c /usr/joe/lib/foo1.c
       cc -o src/prog/prog src/prog/main.o /usr/joe/lib/foo1.o src/prog/foo2.o
    </PRE
><P
>&#13;
    (As was the case with top-relative path names,
    notice that the <TT
CLASS="literal"
>/usr/joe/lib/foo1.o</TT
> object file
    is built in the same directory as its source file.
    See <A
HREF="#chap-separate"
>Chapter 17</A
>, below,
    for information about
    how to build the object file in a different subdirectory.)

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3186"
>16.5. Sharing Environments (and Other Variables) Between <TT
CLASS="filename"
>SConscript</TT
> Files</A
></H2
><P
>&#13;
    In the previous example,
    each of the subsidiary <TT
CLASS="filename"
>SConscript</TT
> files
    created its own construction environment
    by calling <CODE
CLASS="function"
>Environment</CODE
> separately.
    This obviously works fine,
    but if each program must be built
    with the same construction variables,
    it's cumbersome and error-prone to initialize
    separate construction environments
    in the same way over and over in each subsidiary
    <TT
CLASS="filename"
>SConscript</TT
> file.

    </P
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> supports the ability to <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>export</I
></SPAN
> variables
    from a parent <TT
CLASS="filename"
>SConscript</TT
> file
    to its subsidiary <TT
CLASS="filename"
>SConscript</TT
> files,
    which allows you to share common initialized
    values throughout your build hierarchy.

    </P
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN3198"
>16.5.1. Exporting Variables</A
></H3
><P
>&#13;
      There are two ways to export a variable,
      such as a construction environment,
      from an <TT
CLASS="filename"
>SConscript</TT
> file,
      so that it may be used by other <TT
CLASS="filename"
>SConscript</TT
> files.
      First, you can call the <CODE
CLASS="function"
>Export</CODE
>
      function with a list of variables,
      or a string of white-space separated variable names.
      Each call to <CODE
CLASS="function"
>Export</CODE
> adds one
      or more variables to a global list
      of variables that are available for import
      by other <TT
CLASS="filename"
>SConscript</TT
> files.

      </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment()
        Export('env')
      </PRE
><P
>&#13;
      You may export more than one variable name at a time:

      </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment()
        debug = ARGUMENTS['debug']
        Export('env', 'debug')
      </PRE
><P
>&#13;
      Because white space is not legal in Python variable names,
      the <CODE
CLASS="function"
>Export</CODE
> function will even automatically split
      a string into separate names for you:

      </P
><PRE
CLASS="programlisting"
>&#13;        Export('env debug')
      </PRE
><P
>&#13;
      Second, you can specify a list of
      variables to export as a second argument
      to the <TT
CLASS="filename"
>SConscript</TT
> function call:

      </P
><PRE
CLASS="programlisting"
>&#13;        SConscript('src/SConscript', 'env')
      </PRE
><P
>&#13;
      Or as the <CODE
CLASS="varname"
>exports</CODE
> keyword argument:

      </P
><PRE
CLASS="programlisting"
>&#13;        SConscript('src/SConscript', exports='env')
      </PRE
><P
>&#13;
      These calls export the specified variables
      to only the listed <TT
CLASS="filename"
>SConscript</TT
> files.
      You may, however, specify more than one
      <TT
CLASS="filename"
>SConscript</TT
> file in a list:

      </P
><PRE
CLASS="programlisting"
>&#13;        SConscript(['src1/SConscript',
                    'src2/SConscript'], exports='env')
      </PRE
><P
>&#13;
      This is functionally equivalent to
      calling the <TT
CLASS="filename"
>SConscript</TT
> function
      multiple times with the same <CODE
CLASS="varname"
>exports</CODE
> argument,
      one per <TT
CLASS="filename"
>SConscript</TT
> file.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN3226"
>16.5.2. Importing Variables</A
></H3
><P
>&#13;
      Once a variable has been exported from a calling
      <TT
CLASS="filename"
>SConscript</TT
> file,
      it may be used in other <TT
CLASS="filename"
>SConscript</TT
> files
      by calling the <CODE
CLASS="function"
>Import</CODE
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;        Import('env')
        env.Program('prog', ['prog.c'])
      </PRE
><P
>&#13;
      The <CODE
CLASS="function"
>Import</CODE
> call makes the <TT
CLASS="literal"
>env</TT
> construction
      environment available to the <TT
CLASS="filename"
>SConscript</TT
> file,
      after which the variable can be used to build
      programs, libraries, etc.

      </P
><P
>&#13;
      Like the <CODE
CLASS="function"
>Export</CODE
> function,
      the <CODE
CLASS="function"
>Import</CODE
> function can be used
      with multiple variable names:

      </P
><PRE
CLASS="programlisting"
>&#13;        Import('env', 'debug')
        env = env.Clone(DEBUG = debug)
        env.Program('prog', ['prog.c'])
      </PRE
><P
>&#13;
      And the <CODE
CLASS="function"
>Import</CODE
> function will similarly
      split a string along white-space
      into separate variable names:

      </P
><PRE
CLASS="programlisting"
>&#13;        Import('env debug')
        env = env.Clone(DEBUG = debug)
        env.Program('prog', ['prog.c'])
      </PRE
><P
>&#13;
      Lastly, as a special case,
      you may import all of the variables that
      have been exported by supplying an asterisk
      to the <CODE
CLASS="function"
>Import</CODE
> function:

      </P
><PRE
CLASS="programlisting"
>&#13;        Import('*')
        env = env.Clone(DEBUG = debug)
        env.Program('prog', ['prog.c'])
      </PRE
><P
>&#13;
      If you're dealing with a lot of <TT
CLASS="filename"
>SConscript</TT
> files,
      this can be a lot simpler than keeping
      arbitrary lists of imported variables in each file.

      </P
></DIV
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN3249"
>16.5.3. Returning Values From an <TT
CLASS="filename"
>SConscript</TT
> File</A
></H3
><P
>&#13;
      Sometimes, you would like to be able to
      use information from a subsidiary
      <TT
CLASS="filename"
>SConscript</TT
> file in some way.
      For example,
      suppose that you want to create one
      library from source files
      scattered throughout a number
      of subsidiary <TT
CLASS="filename"
>SConscript</TT
> files.
      You can do this by using the <CODE
CLASS="function"
>Return</CODE
>
      function to return values
      from the subsidiary <TT
CLASS="filename"
>SConscript</TT
> files
      to the calling file.

      </P
><P
>&#13;
      If, for example, we have two subdirectories
      <SPAN
CLASS="application"
>foo</SPAN
> and <SPAN
CLASS="application"
>bar</SPAN
>
      that should each contribute a source
      file to a Library,
      what we'd like to be able to do is
      collect the object files
      from the subsidiary <TT
CLASS="filename"
>SConscript</TT
> calls
      like this:

      </P
><PRE
CLASS="programlisting"
>&#13;          env = Environment()
          Export('env')
          objs = []
          for subdir in ['foo', 'bar']:
              o = SConscript('%s/SConscript' % subdir)
              objs.append(o)
          env.Library('prog', objs)
      </PRE
><P
>&#13;
      We can do this by using the <CODE
CLASS="function"
>Return</CODE
>
      function in the
      <TT
CLASS="literal"
>foo/SConscript</TT
> file like this:

      </P
><PRE
CLASS="programlisting"
>&#13;          Import('env')
          obj = env.Object('foo.c')
          Return('obj')
        </PRE
><P
>&#13;
      (The corresponding
      <TT
CLASS="literal"
>bar/SConscript</TT
>
      file should be pretty obvious.)
      Then when we run <SPAN
CLASS="application"
>SCons</SPAN
>,
      the object files from the subsidiary subdirectories
      are all correctly archived in the desired library:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        cc -o bar/bar.o -c bar/bar.c
        cc -o foo/foo.o -c foo/foo.c
        ar rc libprog.a foo/foo.o bar/bar.o
        ranlib libprog.a
      </PRE
></DIV
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-separate"
></A
>Chapter 17. Separating Source and Build Directories</H1
><P
>&#13;
  It's often useful to keep any built files completely
  separate from the source files.
  In <SPAN
CLASS="application"
>SCons</SPAN
>, this is usually done by creating one or more separate
  <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>variant directory trees</I
></SPAN
>
  that are used to hold the built objects files, libraries,
  and executable programs, etc.
  for a specific flavor, or variant, of build.
  <SPAN
CLASS="application"
>SCons</SPAN
> provides two ways to do this,
  one through the <TT
CLASS="filename"
>SConscript</TT
> function that we've already seen,
  and the second through a more flexible <CODE
CLASS="function"
>VariantDir</CODE
> function.

  </P
><P
>&#13;
  One historical note:  the <CODE
CLASS="function"
>VariantDir</CODE
> function
  used to be called <CODE
CLASS="function"
>BuildDir</CODE
>.
  That name is still supported
  but has been deprecated
  because the <SPAN
CLASS="application"
>SCons</SPAN
> functionality
  differs from the model of a "build directory"
  implemented by other build systems like the GNU Autotools.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3283"
>17.1. Specifying a Variant Directory Tree as Part of an <TT
CLASS="filename"
>SConscript</TT
> Call</A
></H2
><P
>&#13;
    The most straightforward way to establish a variant directory tree
    uses the fact that the usual way to
    set up a build hierarchy is to have an
    <TT
CLASS="filename"
>SConscript</TT
> file in the source subdirectory.
    If you then pass a <CODE
CLASS="varname"
>variant_dir</CODE
> argument to the
    <TT
CLASS="filename"
>SConscript</TT
> function call:

    </P
><PRE
CLASS="programlisting"
>&#13;      SConscript('src/SConscript', variant_dir='build')
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> will then build all of the files in
    the <TT
CLASS="filename"
>build</TT
> subdirectory:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>ls src</KBD
>
      SConscript  hello.c
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o build/hello.o -c build/hello.c
      cc -o build/hello build/hello.o
      % <KBD
CLASS="userinput"
>ls build</KBD
>
      SConscript  hello  hello.c  hello.o
    </PRE
><P
>&#13;
    But wait a minute--what's going on here?
    <SPAN
CLASS="application"
>SCons</SPAN
> created the object file
    <TT
CLASS="filename"
>build/hello.o</TT
>
    in the <TT
CLASS="filename"
>build</TT
> subdirectory,
    as expected.
    But even though our <TT
CLASS="filename"
>hello.c</TT
> file lives in the <TT
CLASS="filename"
>src</TT
> subdirectory,
    <SPAN
CLASS="application"
>SCons</SPAN
> has actually compiled a
    <TT
CLASS="filename"
>build/hello.c</TT
> file
    to create the object file.

    </P
><P
>&#13;
    What's happened is that <SPAN
CLASS="application"
>SCons</SPAN
> has <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>duplicated</I
></SPAN
>
    the <TT
CLASS="filename"
>hello.c</TT
> file from the <TT
CLASS="filename"
>src</TT
> subdirectory
    to the <TT
CLASS="filename"
>build</TT
> subdirectory,
    and built the program from there.
    The next section explains why <SPAN
CLASS="application"
>SCons</SPAN
> does this.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3313"
>17.2. Why <SPAN
CLASS="application"
>SCons</SPAN
> Duplicates Source Files in a Variant Directory Tree</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> duplicates source files in variant directory trees
    because it's the most straightforward way to guarantee a correct build
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>regardless of include-file directory paths,
    relative references between files,
    or tool support for putting files in different locations</I
></SPAN
>,
    and the <SPAN
CLASS="application"
>SCons</SPAN
> philosophy is to, by default,
    guarantee a correct build in all cases.

    </P
><P
>&#13;
    The most direct reason to duplicate source files
    in variant directories
    is simply that some tools (mostly older vesions)
    are written to only build their output files
    in the same directory as the source files.
    In this case, the choices are either
    to build the output file in the source directory
    and move it to the variant directory,
    or to duplicate the source files in the variant directory.

    </P
><P
>&#13;
    Additionally,
    relative references between files
    can cause problems if we don't
    just duplicate the hierarchy of source files
    in the variant directory.
    You can see this at work in
    use of the C preprocessor <TT
CLASS="literal"
>#include</TT
>
    mechanism with double quotes, not angle brackets:

    </P
><PRE
CLASS="programlisting"
>&#13;      #include "file.h"
    </PRE
><P
>&#13;
    The <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>de facto</I
></SPAN
> standard behavior
    for most C compilers in this case
    is to first look in the same directory
    as the source file that contains the <TT
CLASS="literal"
>#include</TT
> line,
    then to look in the directories in the preprocessor search path.
    Add to this that the <SPAN
CLASS="application"
>SCons</SPAN
> implementation of
    support for code repositories
    (described below)
    means not all of the files
    will be found in the same directory hierarchy,
    and the simplest way to make sure
    that the right include file is found
    is to duplicate the source files into the variant directory,
    which provides a correct build
    regardless of the original location(s) of the source files.

    </P
><P
>&#13;
    Although source-file duplication guarantees a correct build
    even in these end-cases,
    it <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>can</I
></SPAN
> usually be safely disabled.
    The next section describes
    how you can disable the duplication of source files
    in the variant directory.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3330"
>17.3. Telling <SPAN
CLASS="application"
>SCons</SPAN
> to Not Duplicate Source Files in the Variant Directory Tree</A
></H2
><P
>&#13;
    In most cases and with most tool sets,
    <SPAN
CLASS="application"
>SCons</SPAN
> can place its target files in a build subdirectory
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>without</I
></SPAN
>
    duplicating the source files
    and everything will work just fine.
    You can disable the default <SPAN
CLASS="application"
>SCons</SPAN
> behavior
    by specifying <TT
CLASS="literal"
>duplicate=0</TT
>
    when you call the <TT
CLASS="filename"
>SConscript</TT
> function:

    </P
><PRE
CLASS="programlisting"
>&#13;      SConscript('src/SConscript', variant_dir='build', duplicate=0)
    </PRE
><P
>&#13;
    When this flag is specified,
    <SPAN
CLASS="application"
>SCons</SPAN
> uses the variant directory
    like most people expect--that is,
    the output files are placed in the variant directory
    while the source files stay in the source directory:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>ls src</KBD
>
      SConscript
      hello.c
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -c src/hello.c -o build/hello.o
      cc -o build/hello build/hello.o
      % <KBD
CLASS="userinput"
>ls build</KBD
>
      hello
      hello.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3346"
>17.4. The <CODE
CLASS="function"
>VariantDir</CODE
> Function</A
></H2
><P
>&#13;
    Use the <CODE
CLASS="function"
>VariantDir</CODE
> function to establish that target
    files should be built in a separate directory
    from the source files:

    </P
><PRE
CLASS="programlisting"
>&#13;      VariantDir('build', 'src')
      env = Environment()
      env.Program('build/hello.c')
    </PRE
><P
>&#13;
    Note that when you're not using
    an <TT
CLASS="filename"
>SConscript</TT
> file in the <TT
CLASS="filename"
>src</TT
> subdirectory,
    you must actually specify that
    the program must be built from
    the <TT
CLASS="filename"
>build/hello.c</TT
>
    file that <SPAN
CLASS="application"
>SCons</SPAN
> will duplicate in the
    <TT
CLASS="filename"
>build</TT
> subdirectory.

    </P
><P
>&#13;
    When using the <CODE
CLASS="function"
>VariantDir</CODE
> function directly,
    <SPAN
CLASS="application"
>SCons</SPAN
> still duplicates the source files
    in the variant directory by default:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>ls src</KBD
>
      hello.c
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o build/hello.o -c build/hello.c
      cc -o build/hello build/hello.o
      % <KBD
CLASS="userinput"
>ls build</KBD
>
      hello  hello.c  hello.o
    </PRE
><P
>&#13;
    You can specify the same <TT
CLASS="literal"
>duplicate=0</TT
> argument
    that you can specify for an <TT
CLASS="filename"
>SConscript</TT
> call:

    </P
><PRE
CLASS="programlisting"
>&#13;      VariantDir('build', 'src', duplicate=0)
      env = Environment()
      env.Program('build/hello.c')
    </PRE
><P
>&#13;
    In which case <SPAN
CLASS="application"
>SCons</SPAN
>
    will disable duplication of the source files:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>ls src</KBD
>
      hello.c
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o build/hello.o -c src/hello.c
      cc -o build/hello build/hello.o
      % <KBD
CLASS="userinput"
>ls build</KBD
>
      hello  hello.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3375"
>17.5. Using <CODE
CLASS="function"
>VariantDir</CODE
> With an <TT
CLASS="filename"
>SConscript</TT
> File</A
></H2
><P
>&#13;
    Even when using the <CODE
CLASS="function"
>VariantDir</CODE
> function,
    it's much more natural to use it with
    a subsidiary <TT
CLASS="filename"
>SConscript</TT
> file.
    For example, if the
    <TT
CLASS="filename"
>src/SConscript</TT
>
    looks like this:

    </P
><PRE
CLASS="programlisting"
>&#13;      env = Environment()
      env.Program('hello.c')
    </PRE
><P
>&#13;
    Then our <TT
CLASS="filename"
>SConstruct</TT
> file could look like:

    </P
><PRE
CLASS="programlisting"
>&#13;      VariantDir('build', 'src')
      SConscript('build/SConscript')
      </PRE
><P
>&#13;
    Yielding the following output:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>ls src</KBD
>
      SConscript  hello.c
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o build/hello.o -c build/hello.c
      cc -o build/hello build/hello.o
      % <KBD
CLASS="userinput"
>ls build</KBD
>
      SConscript  hello  hello.c  hello.o
    </PRE
><P
>&#13;
    Notice that this is completely equivalent
    to the use of <TT
CLASS="filename"
>SConscript</TT
> that we
    learned about in the previous section.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3394"
>17.6. Using <CODE
CLASS="function"
>Glob</CODE
> with <CODE
CLASS="function"
>VariantDir</CODE
></A
></H2
><P
>&#13;
    The <CODE
CLASS="function"
>Glob</CODE
> file name pattern matching function
    works just as usual when using <CODE
CLASS="function"
>VariantDir</CODE
>.
    For example, if the
    <TT
CLASS="filename"
>src/SConscript</TT
>
    looks like this:

    </P
><PRE
CLASS="programlisting"
>&#13;      env = Environment()
      env.Program('hello', Glob('*.c'))
    </PRE
><P
>&#13;
    Then with the same <TT
CLASS="filename"
>SConstruct</TT
> file as in the previous section,
    and source files <TT
CLASS="filename"
>f1.c</TT
>
    and <TT
CLASS="filename"
>f2.c</TT
> in src,
    we would see the following output:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>ls src</KBD
>
      SConscript  f1.c  f2.c  f2.h
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o build/f1.o -c build/f1.c
      cc -o build/f2.o -c build/f2.c
      cc -o build/hello build/f1.o build/f2.o
      % <KBD
CLASS="userinput"
>ls build</KBD
>
      SConscript  f1.c  f1.o  f2.c  f2.h  f2.o  hello
    </PRE
><P
>&#13;
    The <CODE
CLASS="function"
>Glob</CODE
> function returns Nodes in the
    <TT
CLASS="filename"
>build/</TT
> tree, as you'd expect.

    </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-variants"
></A
>Chapter 18. Variant Builds</H1
><P
>&#13;
  The <CODE
CLASS="varname"
>variant_dir</CODE
> keyword argument of
  the <TT
CLASS="filename"
>SConscript</TT
> function provides everything
  we need to show how easy it is to create
  variant builds using <SPAN
CLASS="application"
>SCons</SPAN
>.
  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.

  </P
><PRE
CLASS="programlisting"
>&#13;    platform = ARGUMENTS.get('OS', Platform())

    include = "#export/$PLATFORM/include"
    lib = "#export/$PLATFORM/lib"
    bin = "#export/$PLATFORM/bin"

    env = Environment(PLATFORM = platform,
                      BINDIR = bin,
                      INCDIR = include,
                      LIBDIR = lib,
                      CPPPATH = [include],
                      LIBPATH = [lib],
                      LIBS = 'world')

    Export('env')

    env.SConscript('src/SConscript', variant_dir='build/$PLATFORM')
  </PRE
><P
>&#13;
  This SConstruct file,
  when run on a Linux system, yields:

  </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q OS=linux</KBD
>
    Install file: "build/linux/world/world.h" as "export/linux/include/world.h"
    cc -o build/linux/hello/hello.o -c -Iexport/linux/include build/linux/hello/hello.c
    cc -o build/linux/world/world.o -c -Iexport/linux/include build/linux/world/world.c
    ar rc build/linux/world/libworld.a build/linux/world/world.o
    ranlib build/linux/world/libworld.a
    Install file: "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 file: "build/linux/hello/hello" as "export/linux/bin/hello"
  </PRE
><P
>&#13;
  The same SConstruct file on Windows would build:

  </P
><PRE
CLASS="screen"
>&#13;    C:\&#62;<KBD
CLASS="userinput"
>scons -Q OS=windows</KBD
>
    Install file: "build/windows/world/world.h" as "export/windows/include/world.h"
    cl /nologo /Iexport\windows\include /c build\windows\hello\hello.c /Fobuild\windows\hello\hello.obj
    cl /nologo /Iexport\windows\include /c build\windows\world\world.c /Fobuild\windows\world\world.obj
    lib /nologo /OUT:build\windows\world\world.lib build\windows\world\world.obj
    Install file: "build/windows/world/world.lib" as "export/windows/lib/world.lib"
    link /nologo /OUT:build\windows\hello\hello.exe /LIBPATH:export\windows\lib world.lib build\windows\hello\hello.obj
    Install file: "build/windows/hello/hello.exe" as "export/windows/bin/hello.exe"
  </PRE
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-builders-writing"
></A
>Chapter 19. Writing Your Own Builders</H1
><P
>&#13;
  Although <SPAN
CLASS="application"
>SCons</SPAN
> 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 <SPAN
CLASS="application"
>SCons</SPAN
>
  Fortunately, <SPAN
CLASS="application"
>SCons</SPAN
> makes it very easy
  to define your own <CODE
CLASS="classname"
>Builder</CODE
> objects
  for any custom file types you want to build.
  (In fact, the <SPAN
CLASS="application"
>SCons</SPAN
> interfaces for creating
  <CODE
CLASS="classname"
>Builder</CODE
> objects are flexible enough and easy enough to use
  that all of the the <SPAN
CLASS="application"
>SCons</SPAN
> built-in <CODE
CLASS="classname"
>Builder</CODE
> objects
  are created the mechanisms described in this section.)

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3438"
>19.1. Writing Builders That Execute External Commands</A
></H2
><P
>&#13;
    The simplest <CODE
CLASS="classname"
>Builder</CODE
> to create is
    one that executes an external command.
    For example, if we want to build
    an output file by running the contents
    of the input file through a command named
    <TT
CLASS="literal"
>foobuild</TT
>,
    creating that <CODE
CLASS="classname"
>Builder</CODE
> might look like:

    </P
><PRE
CLASS="programlisting"
>&#13;       bld = Builder(action = 'foobuild &#60; $SOURCE &#62; $TARGET')
    </PRE
><P
>&#13;
    All the above line does is create a free-standing
    <CODE
CLASS="classname"
>Builder</CODE
> object.
    The next section will show us how to actually use it.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3447"
>19.2. Attaching a Builder to a <TT
CLASS="literal"
>Construction Environment</TT
></A
></H2
><P
>&#13;
    A <CODE
CLASS="classname"
>Builder</CODE
> object isn't useful
    until it's attached to a <TT
CLASS="literal"
>construction environment</TT
>
    so that we can call it to arrange
    for files to be built.
    This is done through the <A
HREF="#cv-BUILDERS"
><CODE
CLASS="envar"
>$BUILDERS</CODE
></A
>
    <TT
CLASS="literal"
>construction variable</TT
> in an environment.
    The <CODE
CLASS="envar"
>$BUILDERS</CODE
> variable is a Python dictionary
    that maps the names by which you want to call
    various <CODE
CLASS="classname"
>Builder</CODE
> objects to the objects themselves.
    For example, if we want to call the
    <CODE
CLASS="classname"
>Builder</CODE
> we just defined by the name
    <CODE
CLASS="function"
>Foo</CODE
>,
    our <TT
CLASS="filename"
>SConstruct</TT
> file might look like:

    </P
><PRE
CLASS="programlisting"
>&#13;       bld = Builder(action = 'foobuild &#60; $SOURCE &#62; $TARGET')
       env = Environment(BUILDERS = {'Foo' : bld})
    </PRE
><P
>&#13;
    With the <CODE
CLASS="classname"
>Builder</CODE
> so attached to our <TT
CLASS="literal"
>construction environment</TT
>
    we can now actually call it like so:

    </P
><PRE
CLASS="programlisting"
>&#13;       env.Foo('file.foo', 'file.input')
    </PRE
><P
>&#13;
    Then when we run <SPAN
CLASS="application"
>SCons</SPAN
> it looks like:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      foobuild &#60; file.input &#62; file.foo
    </PRE
><P
>&#13;
    Note, however, that the default <CODE
CLASS="envar"
>$BUILDERS</CODE
>
    variable in a <TT
CLASS="literal"
>construction environment</TT
>
    comes with a default set of <CODE
CLASS="classname"
>Builder</CODE
> objects
    already defined:
    <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
>, <A
HREF="#b-Library"
><CODE
CLASS="function"
>Library</CODE
></A
>, etc.
    And when we explicitly set the <CODE
CLASS="envar"
>$BUILDERS</CODE
> variable
    when we create the <TT
CLASS="literal"
>construction environment</TT
>,
    the default <CODE
CLASS="classname"
>Builder</CODE
>s are no longer part of
    the environment:

    </P
><PRE
CLASS="programlisting"
>&#13;       bld = Builder(action = 'foobuild &#60; $SOURCE &#62; $TARGET')
       env = Environment(BUILDERS = {'Foo' : bld})
       env.Foo('file.foo', 'file.input')
       env.Program('hello.c')
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      AttributeError: SConsEnvironment instance has no attribute 'Program':
        File "/home/my/project/SConstruct", line 4:
          env.Program('hello.c')
    </PRE
><P
>&#13;
    To be able to use both our own defined <CODE
CLASS="classname"
>Builder</CODE
> objects
    and the default <CODE
CLASS="classname"
>Builder</CODE
> objects in the same <TT
CLASS="literal"
>construction environment</TT
>,
    you can either add to the <CODE
CLASS="envar"
>$BUILDERS</CODE
> variable
    using the <CODE
CLASS="function"
>Append</CODE
> function:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       bld = Builder(action = 'foobuild &#60; $SOURCE &#62; $TARGET')
       env.Append(BUILDERS = {'Foo' : bld})
       env.Foo('file.foo', 'file.input')
       env.Program('hello.c')
    </PRE
><P
>&#13;
    Or you can explicitly set the appropriately-named
    key in the <CODE
CLASS="envar"
>$BUILDERS</CODE
> dictionary:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       bld = Builder(action = 'foobuild &#60; $SOURCE &#62; $TARGET')
       env['BUILDERS']['Foo'] = bld
       env.Foo('file.foo', 'file.input')
       env.Program('hello.c')
    </PRE
><P
>&#13;
    Either way, the same <TT
CLASS="literal"
>construction environment</TT
>
    can then use both the newly-defined
    <CODE
CLASS="function"
>Foo</CODE
> <CODE
CLASS="classname"
>Builder</CODE
>
    and the default <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
> <CODE
CLASS="classname"
>Builder</CODE
>:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      foobuild &#60; file.input &#62; file.foo
      cc -o hello.o -c hello.c
      cc -o hello hello.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3503"
>19.3. Letting <SPAN
CLASS="application"
>SCons</SPAN
> Handle The File Suffixes</A
></H2
><P
>&#13;
    By supplying additional information
    when you create a <CODE
CLASS="classname"
>Builder</CODE
>,
    you can let <SPAN
CLASS="application"
>SCons</SPAN
> add appropriate file
    suffixes to the target and/or the source file.
    For example, rather than having to specify
    explicitly that you want the <TT
CLASS="literal"
>Foo</TT
>
    <CODE
CLASS="classname"
>Builder</CODE
> to build the <TT
CLASS="literal"
>file.foo</TT
>
    target file from the <TT
CLASS="literal"
>file.input</TT
> source file,
    you can give the <TT
CLASS="literal"
>.foo</TT
>
    and <TT
CLASS="literal"
>.input</TT
> suffixes to the <CODE
CLASS="classname"
>Builder</CODE
>,
    making for more compact and readable calls to
    the <TT
CLASS="literal"
>Foo</TT
> <CODE
CLASS="classname"
>Builder</CODE
>:

    </P
><PRE
CLASS="programlisting"
>&#13;       bld = Builder(action = 'foobuild &#60; $SOURCE &#62; $TARGET',
                     suffix = '.foo',
                     src_suffix = '.input')
       env = Environment(BUILDERS = {'Foo' : bld})
       env.Foo('file1')
       env.Foo('file2')
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      foobuild &#60; file1.input &#62; file1.foo
      foobuild &#60; file2.input &#62; file2.foo
    </PRE
><P
>&#13;
    You can also supply a <TT
CLASS="literal"
>prefix</TT
> keyword argument
    if it's appropriate to have <SPAN
CLASS="application"
>SCons</SPAN
> append a prefix
    to the beginning of target file names.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3524"
>19.4. Builders That Execute Python Functions</A
></H2
><P
>&#13;
    In <SPAN
CLASS="application"
>SCons</SPAN
>, you don't have to call an external command
    to build a file.
    You can, instead, define a Python function
    that a <CODE
CLASS="classname"
>Builder</CODE
> object can invoke
    to build your target file (or files).
    Such a <TT
CLASS="literal"
>builder function</TT
> definition looks like:

    </P
><PRE
CLASS="programlisting"
>&#13;       def build_function(target, source, env):
           # Code to build "target" from "source"
           return None
    </PRE
><P
>&#13;
    The arguments of a <TT
CLASS="literal"
>builder function</TT
> are:

    </P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
>target</DT
><DD
><P
>&#13;
      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 <CODE
CLASS="function"
>str</CODE
> function.

      </P
></DD
><DT
>source</DT
><DD
><P
>&#13;
      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 <CODE
CLASS="function"
>str</CODE
> function.

      </P
></DD
><DT
>env</DT
><DD
><P
>&#13;
      The <TT
CLASS="literal"
>construction environment</TT
> 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.

      </P
></DD
></DL
></DIV
><P
>&#13;
    The builder function must
    return a <TT
CLASS="literal"
>0</TT
> or <TT
CLASS="literal"
>None</TT
> 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,

    </P
><P
>&#13;
    Once you've defined the Python function
    that will build your target file,
    defining a <CODE
CLASS="classname"
>Builder</CODE
> object for it is as
    simple as specifying the name of the function,
    instead of an external command,
    as the <CODE
CLASS="classname"
>Builder</CODE
>'s
    <TT
CLASS="literal"
>action</TT
>
    argument:

    </P
><PRE
CLASS="programlisting"
>&#13;       def build_function(target, source, env):
           # Code to build "target" from "source"
           return None
       bld = Builder(action = build_function,
                     suffix = '.foo',
                     src_suffix = '.input')
       env = Environment(BUILDERS = {'Foo' : bld})
       env.Foo('file')
    </PRE
><P
>&#13;
    And notice that the output changes slightly,
    reflecting the fact that a Python function,
    not an external command,
    is now called to build the target file:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      build_function(["file.foo"], ["file.input"])
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3560"
>19.5. Builders That Create Actions Using a <TT
CLASS="literal"
>Generator</TT
></A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> Builder objects can create an action "on the fly"
    by using a function called a <TT
CLASS="literal"
>generator</TT
>.
    This provides a great deal of flexibility to
    construct just the right list of commands
    to build your target.
    A <TT
CLASS="literal"
>generator</TT
> looks like:

    </P
><PRE
CLASS="programlisting"
>&#13;       def generate_actions(source, target, env, for_signature):
           return 'foobuild &#60; %s &#62; %s' % (target[0], source[0])
    </PRE
><P
>&#13;
    The arguments of a <TT
CLASS="literal"
>generator</TT
> are:

    </P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
>source</DT
><DD
><P
>&#13;
      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 <CODE
CLASS="function"
>str</CODE
> function.

      </P
></DD
><DT
>target</DT
><DD
><P
>&#13;
      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 <CODE
CLASS="function"
>str</CODE
> function.

      </P
></DD
><DT
>env</DT
><DD
><P
>&#13;
      The <TT
CLASS="literal"
>construction environment</TT
> 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.

      </P
></DD
><DT
>for_signature</DT
><DD
><P
>&#13;
      A flag that specifies whether the
      generator is being called to contribute to a build signature,
      as opposed to actually executing the command.

      

      </P
></DD
></DL
></DIV
><P
>&#13;
    The <TT
CLASS="literal"
>generator</TT
> must return a
    command string or other action that will be used to
    build the specified target(s) from the specified source(s).

    </P
><P
>&#13;
    Once you've defined a <TT
CLASS="literal"
>generator</TT
>,
    you create a <CODE
CLASS="classname"
>Builder</CODE
> to use it
    by specifying the generator keyword argument
    instead of <TT
CLASS="literal"
>action</TT
>.

    </P
><PRE
CLASS="programlisting"
>&#13;       def generate_actions(source, target, env, for_signature):
           return 'foobuild &#60; %s &#62; %s' % (source[0], target[0])
       bld = Builder(generator = generate_actions,
                     suffix = '.foo',
                     src_suffix = '.input')
       env = Environment(BUILDERS = {'Foo' : bld})
       env.Foo('file')
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      foobuild &#60; file.input &#62; file.foo
    </PRE
><P
>&#13;
    Note that it's illegal to specify both an
    <TT
CLASS="literal"
>action</TT
>
    and a
    <TT
CLASS="literal"
>generator</TT
>
    for a <CODE
CLASS="classname"
>Builder</CODE
>.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3603"
>19.6. Builders That Modify the Target or Source Lists Using an <TT
CLASS="literal"
>Emitter</TT
></A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> supports the ability for a Builder to modify the
    lists of target(s) from the specified source(s).
    You do this by defining an <TT
CLASS="literal"
>emitter</TT
> function
    that takes as its arguments
    the list of the targets passed to the builder,
    the list of the sources passed to the builder,
    and the construction environment.
    The emitter function should return the modified
    lists of targets that should be built
    and sources from which the targets will be built.

    </P
><P
>&#13;
    For example, suppose you want to define a Builder
    that always calls a <TT
CLASS="filename"
>foobuild</TT
> program,
    and you want to automatically add
    a new target file named
    <TT
CLASS="filename"
>new_target</TT
>
    and a new source file named
    <TT
CLASS="filename"
>new_source</TT
>
    whenever it's called.
    The <TT
CLASS="filename"
>SConstruct</TT
> file might look like this:

    </P
><PRE
CLASS="programlisting"
>&#13;       def modify_targets(target, source, env):
           target.append('new_target')
           source.append('new_source')
           return target, source
       bld = Builder(action = 'foobuild $TARGETS - $SOURCES',
                     suffix = '.foo',
                     src_suffix = '.input',
                     emitter = modify_targets)
       env = Environment(BUILDERS = {'Foo' : bld})
       env.Foo('file')
    </PRE
><P
>&#13;    
    And would yield the following output:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      foobuild file.foo new_target - file.input new_source
    </PRE
><P
>&#13;
    One very flexible thing that you can is specify
    use a construction variable to specify
    different emitter functions for different
    construction variable.
    To do this, specify a string
    containing a construction variable
    expansion as the emitter when you call
    the <CODE
CLASS="classname"
>Builder</CODE
> function,
    and set that construction variable to
    the desired emitter function
    in different construction environments:

    </P
><PRE
CLASS="programlisting"
>&#13;        bld = Builder(action = 'my_command $SOURCES &#62; $TARGET',
                      suffix = '.foo',
                      src_suffix = '.input',
                      emitter = '$MY_EMITTER')
        def modify1(target, source, env):
            return target, source + ['modify1.in']
        def modify2(target, source, env):
            return target, source + ['modify2.in']
        env1 = Environment(BUILDERS = {'Foo' : bld},
                           MY_EMITTER = modify1)
        env2 = Environment(BUILDERS = {'Foo' : bld},
                           MY_EMITTER = modify2)
        env1.Foo('file1')
        env2.Foo('file2')
        import os
        env1['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd()
        env2['ENV']['PATH'] = env2['ENV']['PATH'] + os.pathsep + os.getcwd()
      

    </PRE
><PRE
CLASS="programlisting"
>&#13;      bld = Builder(action = 'my_command $SOURCES &#62; $TARGET',
                    suffix = '.foo',
                    src_suffix = '.input',
                    emitter = '$MY_EMITTER')
      def modify1(target, source, env):
          return target, source + ['modify1.in']
      def modify2(target, source, env):
          return target, source + ['modify2.in']
      env1 = Environment(BUILDERS = {'Foo' : bld},
                         MY_EMITTER = modify1)
      env2 = Environment(BUILDERS = {'Foo' : bld},
                         MY_EMITTER = modify2)
      env1.Foo('file1')
      env2.Foo('file2')
      
    </PRE
><P
>&#13;
    In this example, the <TT
CLASS="filename"
>modify1.in</TT
>
    and <TT
CLASS="filename"
>modify2.in</TT
> files
    get added to the source lists
    of the different commands:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      my_command file1.input modify1.in &#62; file1.foo
      my_command file2.input modify2.in &#62; file2.foo
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3627"
>19.7. Where To Put Your Custom Builders and Tools</A
></H2
><P
>&#13;
  The <TT
CLASS="filename"
>site_scons</TT
> directory gives you a place to
  put Python modules you can import into your SConscripts
  (site_scons), add-on tools that can integrate into <SPAN
CLASS="application"
>SCons</SPAN
>
  (site_scons/site_tools), and a site_scons/site_init.py file that
  gets read before any <TT
CLASS="filename"
>SConstruct</TT
> or <TT
CLASS="filename"
>SConscript</TT
>, allowing you to
  change <SPAN
CLASS="application"
>SCons</SPAN
>'s default behavior.

  </P
><P
>&#13;
  If you get a tool from somewhere (the <SPAN
CLASS="application"
>SCons</SPAN
> wiki or a third party,
  for instance) and you'd like to use it in your project, the
  <TT
CLASS="filename"
>site_scons</TT
> dir is the simplest place to put it.
  Tools come in two flavors; either a Python function that operates on
  an <CODE
CLASS="function"
>Environment</CODE
> or a Python file containing two functions, exists()
  and generate().

  </P
><P
>&#13;
  A single-function Tool can just be included in your
  <TT
CLASS="filename"
>site_scons/site_init.py</TT
> file where it will be
  parsed and made available for use.  For instance, you could have a
  <TT
CLASS="filename"
>site_scons/site_init.py</TT
> file like this:

  </P
><PRE
CLASS="programlisting"
>&#13;      def TOOL_ADD_HEADER(env):
         """A Tool to add a header from $HEADER to the source file"""
         add_header = Builder(action=['echo "$HEADER" &#62; $TARGET',
                                      'cat $SOURCE &#62;&#62; $TARGET'])
         env.Append(BUILDERS = {'AddHeader' : add_header})
         env['HEADER'] = '' # set default value
  </PRE
><P
>&#13;
  and a <TT
CLASS="filename"
>SConstruct</TT
> like this:

  </P
><PRE
CLASS="programlisting"
>&#13;      # Use TOOL_ADD_HEADER from site_scons/site_init.py
      env=Environment(tools=['default', TOOL_ADD_HEADER], HEADER="=====")
      env.AddHeader('tgt', 'src')
  </PRE
><P
>&#13;
    The <CODE
CLASS="function"
>TOOL_ADD_HEADER</CODE
> tool method will be
    called to add the <CODE
CLASS="function"
>AddHeader</CODE
> tool to the
    environment.

  </P
><P
>&#13;    Similarly, a more full-fledged tool with
    <CODE
CLASS="function"
>exists()</CODE
> and <CODE
CLASS="function"
>generate()</CODE
>
    methods can be installed in
    <TT
CLASS="filename"
>site_scons/site_tools/toolname.py</TT
>.  Since
    <TT
CLASS="filename"
>site_scons/site_tools</TT
> is automatically added
    to the head of the tool search path, any tool found there will be
    available to all environments.  Furthermore, a tool found there
    will override a built-in tool of the same name, so if you need to
    change the behavior of a built-in tool, site_scons gives you the
    hook you need.
  </P
><P
>&#13;    Many people have a library of utility Python functions they'd like
    to include in <TT
CLASS="filename"
>SConscript</TT
>s; just put that module in
    <TT
CLASS="filename"
>site_scons/my_utils.py</TT
> or any valid Python module name of your
    choice.  For instance you can do something like this in
    <TT
CLASS="filename"
>site_scons/my_utils.py</TT
> to add a build_id method:
  </P
><PRE
CLASS="programlisting"
>&#13;      def build_id():
         """Return a build ID (stub version)"""
         return "100"
  </PRE
><P
>&#13;
  And then in your <TT
CLASS="filename"
>SConscript</TT
> or any sub-<TT
CLASS="filename"
>SConscript</TT
> anywhere in
  your build, you can import <TT
CLASS="filename"
>my_utils</TT
> and use it:

  </P
><PRE
CLASS="programlisting"
>&#13;      import my_utils
      print "build_id=" + my_utils.build_id()
  </PRE
><P
>&#13;
    If you have a machine-wide site dir you'd like to use instead of
    <TT
CLASS="filename"
>./site_scons</TT
>, use the
    <TT
CLASS="literal"
>--site-dir</TT
> option to point to your dir.
    <TT
CLASS="filename"
>site_init.py</TT
> and
    <TT
CLASS="filename"
>site_tools</TT
> will be located under that dir.
    To avoid using a <TT
CLASS="filename"
>site_scons</TT
> dir at all, even
    if it exists, use the <TT
CLASS="literal"
>--no-site-dir</TT
> option.

  </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-builders-commands"
></A
>Chapter 20. Not Writing a Builder:  the <CODE
CLASS="function"
>Command</CODE
> Builder</H1
><P
>&#13;
  Creating a <CODE
CLASS="classname"
>Builder</CODE
> and attaching it to a <TT
CLASS="literal"
>construction environment</TT
>
  allows for a lot of flexibility when you
  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 group of files).
  For these situations, <SPAN
CLASS="application"
>SCons</SPAN
> supports a
  <CODE
CLASS="function"
>Command</CODE
> <CODE
CLASS="classname"
>Builder</CODE
> that arranges
  for a specific action to be executed
  to build a specific file or files.
  This looks a lot like the other builders
  (like <A
HREF="#b-Program"
><CODE
CLASS="function"
>Program</CODE
></A
>, <A
HREF="#b-Object"
><CODE
CLASS="function"
>Object</CODE
></A
>, etc.),
  but takes as an additional argument
  the command to be executed to build the file:

  </P
><PRE
CLASS="programlisting"
>&#13;     env = Environment()
     env.Command('foo.out', 'foo.in', "sed 's/x/y/' &#60; $SOURCE &#62; $TARGET")
  </PRE
><P
>&#13;
  When executed,
  <SPAN
CLASS="application"
>SCons</SPAN
> runs the specified command,
  substituting <A
HREF="#cv-SOURCE"
><CODE
CLASS="envar"
>$SOURCE</CODE
></A
> and <A
HREF="#cv-TARGET"
><CODE
CLASS="envar"
>$TARGET</CODE
></A
>
  as expected:

  </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    sed 's/x/y/' &#60; foo.in &#62; foo.out
  </PRE
><P
>&#13;
  This is often more convenient than
  creating a <CODE
CLASS="classname"
>Builder</CODE
> object
  and adding it to the <A
HREF="#cv-BUILDERS"
><CODE
CLASS="envar"
>$BUILDERS</CODE
></A
> variable
  of a <TT
CLASS="literal"
>construction environment</TT
>

  </P
><P
>&#13;
  Note that the action you specify to the
  <CODE
CLASS="function"
>Command</CODE
> <CODE
CLASS="classname"
>Builder</CODE
> can be any legal <SPAN
CLASS="application"
>SCons</SPAN
> <CODE
CLASS="classname"
>Action</CODE
>,
  such as a Python function:

  </P
><PRE
CLASS="programlisting"
>&#13;     env = Environment()
     def build(target, source, env):
         # Whatever it takes to build
         return None
     env.Command('foo.out', 'foo.in', build)
  </PRE
><P
>&#13;
  Which executes as follows:

  </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    build(["foo.out"], ["foo.in"])
  </PRE
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-add-method"
></A
>Chapter 21. Pseudo-Builders:  the AddMethod function</H1
><P
>&#13;
  The <CODE
CLASS="function"
>AddMethod</CODE
> function is used to add a method
  to an environment.  It's typically used to add a "pseudo-builder,"
  a function that looks like a <CODE
CLASS="classname"
>Builder</CODE
> but
  wraps up calls to multiple other <CODE
CLASS="classname"
>Builder</CODE
>s
  or otherwise processes its arguments
  before calling one or more <CODE
CLASS="classname"
>Builder</CODE
>s.
  In the following example,
  we want to install the program into the standard
  <TT
CLASS="filename"
>/usr/bin</TT
> directory hierarchy,
  but also copy it into a local <TT
CLASS="filename"
>install/bin</TT
>
  directory from which a package might be built:

  </P
><PRE
CLASS="programlisting"
>&#13;     def install_in_bin_dirs(env, source):
         """Install source in both bin dirs"""
         i1 = env.Install("$BIN", source)
         i2 = env.Install("$LOCALBIN", source)
         return [i1[0], i2[0]] # Return a list, like a normal builder
     env = Environment(BIN='/usr/bin', LOCALBIN='#install/bin')
     env.AddMethod(install_in_bin_dirs, "InstallInBinDirs")
     env.InstallInBinDirs(Program('hello.c')) # installs hello in both bin dirs     
  </PRE
><P
>&#13;  This produces the following:
  </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q /</KBD
>
    cc -o hello.o -c hello.c
    cc -o hello hello.o
    Install file: "hello" as "/usr/bin/hello"
    Install file: "hello" as "install/bin/hello"
  </PRE
><P
>&#13;
  As mentioned, a psuedo-builder also provides more flexibility
  in parsing arguments than you can get with a <CODE
CLASS="classname"
>Builder</CODE
>.
  The next example shows a pseudo-builder with a
  named argument that modifies the filename, and a separate argument
  for the resource file (rather than having the builder figure it out
  by file extension).  This example also demonstrates using the global
  <CODE
CLASS="function"
>AddMethod</CODE
> function to add a method to the global Environment class,
  so it will be used in all subsequently created environments.

  </P
><PRE
CLASS="programlisting"
>&#13;     def BuildTestProg(env, testfile, resourcefile, testdir="tests"):
         """Build the test program;
         prepends "test_" to src and target,
         and puts target into testdir."""
         srcfile = "test_%s.c" % testfile
         target = "%s/test_%s" % (testdir, testfile)
         if env['PLATFORM'] == 'win32':
             resfile = env.RES(resourcefile)
             p = env.Program(target, [srcfile, resfile])
         else:
             p = env.Program(target, srcfile)
         return p
     AddMethod(Environment, BuildTestProg)

     env = Environment()
     env.BuildTestProg('stuff', resourcefile='res.rc')
  </PRE
><P
>&#13;  This produces the following on Linux:
  </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q</KBD
>
    cc -o test_stuff.o -c test_stuff.c
    cc -o tests/test_stuff test_stuff.o
  </PRE
><P
>&#13;  And the following on Windows:
  </P
><PRE
CLASS="screen"
>&#13;    C:\&#62;<KBD
CLASS="userinput"
>scons -Q</KBD
>
    rc /fores.res res.rc
    cl /nologo /c test_stuff.c /Fotest_stuff.obj
    link /nologo /OUT:tests\test_stuff.exe test_stuff.obj res.res
  </PRE
><P
>&#13;  Using <CODE
CLASS="function"
>AddMethod</CODE
> is better than just adding an instance method
  to a <TT
CLASS="literal"
>construction environment</TT
> because it gets called as a proper method,
  and because <CODE
CLASS="function"
>AddMethod</CODE
> provides for copying the method
  to any clones of the <TT
CLASS="literal"
>construction environment</TT
> instance.
  </P
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-scanners"
></A
>Chapter 22. Writing Scanners</H1
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> has built-in scanners that know how to look in
    C, Fortran and IDL source files for information about
    other files that targets built from those files depend on--for example,
    in the case of files that use the C preprocessor,
    the <TT
CLASS="filename"
>.h</TT
> files that are specified
    using <TT
CLASS="literal"
>#include</TT
> lines in the source.
    You can use the same mechanisms that <SPAN
CLASS="application"
>SCons</SPAN
> uses to create
    its built-in scanners to write scanners of your own for file types
    that <SPAN
CLASS="application"
>SCons</SPAN
> does not know how to scan "out of the box."

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3743"
>22.1. A Simple Scanner Example</A
></H2
><P
>&#13;
      Suppose, for example, that we want to create a simple scanner
      for <TT
CLASS="filename"
>.foo</TT
> files.
      A <TT
CLASS="filename"
>.foo</TT
> file contains some text that
      will be processed,
      and can include other files on lines that begin
      with <TT
CLASS="literal"
>include</TT
>
      followed by a file name:

    </P
><PRE
CLASS="programlisting"
>&#13;      include filename.foo
    </PRE
><P
>&#13;
      Scanning a file will be handled by a Python function
      that you must supply.
      Here is a function that will use the Python
      <TT
CLASS="filename"
>re</TT
> module
      to scan for the <TT
CLASS="literal"
>include</TT
> lines in our example:

    </P
><PRE
CLASS="programlisting"
>&#13;      import re
      
      include_re = re.compile(r'^include\s+(\S+)$', re.M)
      
      def kfile_scan(node, env, path, arg):
          contents = node.get_contents()
          return include_re.findall(contents)
    </PRE
><P
>&#13;
      The scanner function must
      accept the four specified arguments
      and return a list of implicit dependencies.
      Presumably, these would be dependencies found
      from examining the contents of the file,
      although the function can perform any
      manipulation at all to generate the list of
      dependencies.

    </P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
>node</DT
><DD
><P
>&#13;
      An <SPAN
CLASS="application"
>SCons</SPAN
> node object representing the file being scanned.
      The path name to the file can be
      used by converting the node to a string
      using the <TT
CLASS="literal"
>str()</TT
> function,
      or an internal <SPAN
CLASS="application"
>SCons</SPAN
> <TT
CLASS="literal"
>get_contents()</TT
>
      object method can be used to fetch the contents.

      </P
></DD
><DT
>env</DT
><DD
><P
>&#13;
      The construction environment in effect for this scan.
      The scanner function may choose to use construction
      variables from this environment to affect its behavior.

      </P
></DD
><DT
>path</DT
><DD
><P
>&#13;
      A list of directories that form the search path for included files
      for this scanner.
      This is how <SPAN
CLASS="application"
>SCons</SPAN
> handles the <A
HREF="#cv-CPPPATH"
><CODE
CLASS="envar"
>$CPPPATH</CODE
></A
> and <A
HREF="#cv-LIBPATH"
><CODE
CLASS="envar"
>$LIBPATH</CODE
></A
>
      variables.

      </P
></DD
><DT
>arg</DT
><DD
><P
>&#13;
      An optional argument that you can choose to
      have passed to this scanner function by
      various scanner instances.

      </P
></DD
></DL
></DIV
><P
>&#13;
    A Scanner object is created using the <CODE
CLASS="classname"
>Scanner</CODE
> function,
    which typically takes an <TT
CLASS="literal"
>skeys</TT
> argument
    to associate the type of file suffix with this scanner.
    The Scanner object must then be associated with the
    <A
HREF="#cv-SCANNERS"
><CODE
CLASS="envar"
>$SCANNERS</CODE
></A
> construction variable of a construction environment,
    typically by using the <CODE
CLASS="function"
>Append</CODE
> method:

    </P
><PRE
CLASS="programlisting"
>&#13;       kscan = Scanner(function = kfile_scan,
                       skeys = ['.k'])
       env.Append(SCANNERS = kscan)
    </PRE
><P
>&#13;
    When we put it all together, it looks like:

    </P
><PRE
CLASS="programlisting"
>&#13;        import re

        include_re = re.compile(r'^include\s+(\S+)$', re.M)

        def kfile_scan(node, env, path):
            contents = node.get_contents()
            includes = include_re.findall(contents)
            return includes

        kscan = Scanner(function = kfile_scan,
                        skeys = ['.k'])

        env = Environment(ENV = {'PATH' : '/usr/local/bin'})
        env.Append(SCANNERS = kscan)

        env.Command('foo', 'foo.k', 'kprocess &#60; $SOURCES &#62; $TARGET')
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-repositories"
></A
>Chapter 23. Building From Code Repositories</H1
><P
>&#13;
  Often, a software project will have
  one or more central repositories,
  directory trees that contain
  source code, or derived files, or both.
  You can eliminate additional unnecessary
  rebuilds of files by having <SPAN
CLASS="application"
>SCons</SPAN
>
  use files from one or more code repositories
  to build files in your local build tree.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3794"
>23.1. The <CODE
CLASS="function"
>Repository</CODE
> Method</A
></H2
><P
>&#13;
    It's often useful to allow multiple programmers working
    on a project to build software from
    source files and/or derived files that
    are stored in a centrally-accessible repository,
    a directory copy of the source code tree.
    (Note that this is not the sort of repository
    maintained by a source code management system
    like BitKeeper, CVS, or Subversion.)
    
    You use the <CODE
CLASS="function"
>Repository</CODE
> method
    to tell <SPAN
CLASS="application"
>SCons</SPAN
> to search one or more
    central code repositories (in order)
    for any source files and derived files
    that are not present in the local build tree:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       env.Program('hello.c')
       Repository('/usr/repository1', '/usr/repository2')
    </PRE
><P
>&#13;
    Multiple calls to the <CODE
CLASS="function"
>Repository</CODE
> method
    will simply add repositories to the global list
    that <SPAN
CLASS="application"
>SCons</SPAN
> maintains,
    with the exception that <SPAN
CLASS="application"
>SCons</SPAN
> will automatically eliminate
    the current directory and any non-existent
    directories from the list.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3805"
>23.2. Finding source files in repositories</A
></H2
><P
>&#13;
    The above example
    specifies that <SPAN
CLASS="application"
>SCons</SPAN
>
    will first search for files under
    the <TT
CLASS="filename"
>/usr/repository1</TT
> tree
    and next under the <TT
CLASS="filename"
>/usr/repository2</TT
> tree.
    <SPAN
CLASS="application"
>SCons</SPAN
> expects that any files it searches
    for will be found in the same position
    relative to the top-level directory.
    In the above example, if the <TT
CLASS="filename"
>hello.c</TT
> file is not
    found in the local build tree,
    <SPAN
CLASS="application"
>SCons</SPAN
> will search first for
    a <TT
CLASS="filename"
>/usr/repository1/hello.c</TT
> file
    and then for a <TT
CLASS="filename"
>/usr/repository2/hello.c</TT
> file
    to use in its place.

    </P
><P
>&#13;
    So given the <TT
CLASS="filename"
>SConstruct</TT
> file above,
    if the <TT
CLASS="filename"
>hello.c</TT
> file exists in the local
    build directory,
    <SPAN
CLASS="application"
>SCons</SPAN
> will rebuild the <SPAN
CLASS="application"
>hello</SPAN
> program
    as normal:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
    </PRE
><P
>&#13;
    If, however, there is no local <TT
CLASS="filename"
>hello.c</TT
> file,
    but one exists in <TT
CLASS="filename"
>/usr/repository1</TT
>,
    <SPAN
CLASS="application"
>SCons</SPAN
> will recompile the <SPAN
CLASS="application"
>hello</SPAN
> program
    from the source file it finds in the repository:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c /usr/repository1/hello.c
      cc -o hello hello.o
    </PRE
><P
>&#13;
    And similarly, if there is no local <TT
CLASS="filename"
>hello.c</TT
> file
    and no <TT
CLASS="filename"
>/usr/repository1/hello.c</TT
>,
    but one exists in <TT
CLASS="filename"
>/usr/repository2</TT
>:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c /usr/repository2/hello.c
      cc -o hello hello.o
    </PRE
><P
>&#13;
    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3837"
>23.3. Finding <TT
CLASS="literal"
>#include</TT
> files in repositories</A
></H2
><P
>&#13;
    We've already seen that SCons will scan the contents of
    a source file for <TT
CLASS="literal"
>#include</TT
> file names
    and realize that targets built from that source file
    also depend on the <TT
CLASS="literal"
>#include</TT
> file(s).
    For each directory in the <A
HREF="#cv-CPPPATH"
><CODE
CLASS="envar"
>$CPPPATH</CODE
></A
> list,
    <SPAN
CLASS="application"
>SCons</SPAN
> will actually search the corresponding directories
    in any repository trees and establish the
    correct dependencies on any
    <TT
CLASS="literal"
>#include</TT
> files that it finds
    in repository directory.

    </P
><P
>&#13;
    Unless the C compiler also knows about these directories
    in the repository trees, though,
    it will be unable to find the <TT
CLASS="literal"
>#include</TT
> files.
    If, for example, the <TT
CLASS="filename"
>hello.c</TT
> file in
    our previous example includes the <SPAN
CLASS="application"
>hello</SPAN
>.h;
    in its current directory,
    and the <SPAN
CLASS="application"
>hello</SPAN
>.h; only exists in the repository:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      hello.c:1: hello.h: No such file or directory
    </PRE
><P
>&#13;
    In order to inform the C compiler about the repositories,
    <SPAN
CLASS="application"
>SCons</SPAN
> will add appropriate
    <TT
CLASS="literal"
>-I</TT
> flags to the compilation commands
    for each directory in the <CODE
CLASS="envar"
>$CPPPATH</CODE
> list.
    So if we add the current directory to the
    construction environment <CODE
CLASS="envar"
>$CPPPATH</CODE
> like so:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment(CPPPATH = ['.'])
       env.Program('hello.c')
       Repository('/usr/repository1')
    </PRE
><P
>&#13;
    Then re-executing <SPAN
CLASS="application"
>SCons</SPAN
> yields:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c -I. -I/usr/repository1 hello.c
      cc -o hello hello.o
    </PRE
><P
>&#13;
    The order of the <TT
CLASS="literal"
>-I</TT
> options replicates,
    for the C preprocessor,
    the same repository-directory search path
    that <SPAN
CLASS="application"
>SCons</SPAN
> uses for its own dependency analysis.
    If there are multiple repositories and multiple <CODE
CLASS="envar"
>$CPPPATH</CODE
>
    directories, <SPAN
CLASS="application"
>SCons</SPAN
> will add the repository directories
    to the beginning of each <CODE
CLASS="envar"
>$CPPPATH</CODE
> directory,
    rapidly multiplying the number of <TT
CLASS="literal"
>-I</TT
> flags.
    If, for example, the <CODE
CLASS="envar"
>$CPPPATH</CODE
> contains three directories
    (and shorter repository path names!):

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment(CPPPATH = ['dir1', 'dir2', 'dir3'])
       env.Program('hello.c')
       Repository('/r1', '/r2')
    </PRE
><P
>&#13;
    Then we'll end up with nine <TT
CLASS="literal"
>-I</TT
> options
    on the command line,
    three (for each of the <CODE
CLASS="envar"
>$CPPPATH</CODE
> directories)
    times three (for the local directory plus the two repositories):

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c -Idir1 -I/r1/dir1 -I/r2/dir1 -Idir2 -I/r1/dir2 -I/r2/dir2 -Idir3 -I/r1/dir3 -I/r2/dir3 hello.c
      cc -o hello hello.o
    </PRE
><DIV
CLASS="section"
><HR><H3
CLASS="section"
><A
NAME="AEN3878"
>23.3.1. Limitations on <TT
CLASS="literal"
>#include</TT
> files in repositories</A
></H3
><P
>&#13;
      <SPAN
CLASS="application"
>SCons</SPAN
> relies on the C compiler's
      <TT
CLASS="literal"
>-I</TT
> options to control the order in which
      the preprocessor will search the repository directories
      for <TT
CLASS="literal"
>#include</TT
> files.
      This causes a problem, however, with how the C preprocessor
      handles <TT
CLASS="literal"
>#include</TT
> lines with
      the file name included in double-quotes.

      </P
><P
>&#13;
      As we've seen,
      <SPAN
CLASS="application"
>SCons</SPAN
> will compile the <TT
CLASS="filename"
>hello.c</TT
> file from
      the repository if it doesn't exist in
      the local directory.
      If, however, the <TT
CLASS="filename"
>hello.c</TT
> file in the repository contains
      a <TT
CLASS="literal"
>#include</TT
> line with the file name in
      double quotes:

      </P
><PRE
CLASS="programlisting"
>&#13;        #include "hello.h"
        int
        main(int argc, char *argv[])
        {
            printf(HELLO_MESSAGE);
            return (0);
        }
      </PRE
><P
>&#13;
      Then the C preprocessor will <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>always</I
></SPAN
>
      use a <TT
CLASS="filename"
>hello.h</TT
> file from the repository directory first,
      even if there is a <TT
CLASS="filename"
>hello.h</TT
> file in the local directory,
      despite the fact that the command line specifies
      <TT
CLASS="literal"
>-I</TT
> as the first option:

      </P
><PRE
CLASS="screen"
>&#13;        % <KBD
CLASS="userinput"
>scons -Q</KBD
>
        cc -o hello.o -c -I. -I/usr/repository1 /usr/repository1/hello.c
        cc -o hello hello.o
      </PRE
><P
>&#13;
      This behavior of the C preprocessor--always search
      for a <TT
CLASS="literal"
>#include</TT
> file in double-quotes
      first in the same directory as the source file,
      and only then search the <TT
CLASS="literal"
>-I</TT
>--can
      not, in general, be changed.
      In other words, it's a limitation
      that must be lived with if you want to use
      code repositories in this way.
      There are three ways you can possibly
      work around this C preprocessor behavior:

      </P
><P
></P
><OL
TYPE="1"
><LI
><P
>&#13;
        Some modern versions of C compilers do have an option
        to disable or control this behavior.
        If so, add that option to <A
HREF="#cv-CFLAGS"
><CODE
CLASS="envar"
>$CFLAGS</CODE
></A
>
        (or <A
HREF="#cv-CXXFLAGS"
><CODE
CLASS="envar"
>$CXXFLAGS</CODE
></A
> or both) in your construction environment(s).
        Make sure the option is used for all construction
        environments that use C preprocessing!

        </P
></LI
><LI
><P
>&#13;
        Change all occurrences of <TT
CLASS="literal"
>#include "file.h"</TT
>
        to <TT
CLASS="literal"
>#include &#60;file.h&#62;</TT
>.
        Use of <TT
CLASS="literal"
>#include</TT
> with angle brackets
        does not have the same behavior--the <TT
CLASS="literal"
>-I</TT
>
        directories are searched first
        for <TT
CLASS="literal"
>#include</TT
> files--which
        gives <SPAN
CLASS="application"
>SCons</SPAN
> direct control over the list of
        directories the C preprocessor will search.

        </P
></LI
><LI
><P
>&#13;
        Require that everyone working with compilation from
        repositories check out and work on entire directories of files,
        not individual files.
        (If you use local wrapper scripts around
        your source code control system's command,
        you could add logic to enforce this restriction there.

        </P
></LI
></OL
></DIV
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3919"
>23.4. Finding the <TT
CLASS="filename"
>SConstruct</TT
> file in repositories</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> will also search in repositories
    for the <TT
CLASS="filename"
>SConstruct</TT
> file and any specified <TT
CLASS="filename"
>SConscript</TT
> files.
    This poses a problem, though:  how can <SPAN
CLASS="application"
>SCons</SPAN
> search a
    repository tree for an <TT
CLASS="filename"
>SConstruct</TT
> file
    if the <TT
CLASS="filename"
>SConstruct</TT
> file itself contains the information
    about the pathname of the repository?
    To solve this problem, <SPAN
CLASS="application"
>SCons</SPAN
> allows you
    to specify repository directories
    on the command line using the <TT
CLASS="literal"
>-Y</TT
> option:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q -Y /usr/repository1 -Y /usr/repository2</KBD
>
    </PRE
><P
>&#13;
    When looking for source or derived files,
    <SPAN
CLASS="application"
>SCons</SPAN
> will first search the repositories
    specified on the command line,
    and then search the repositories
    specified in the <TT
CLASS="filename"
>SConstruct</TT
> or <TT
CLASS="filename"
>SConscript</TT
> files.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3937"
>23.5. Finding derived files in repositories</A
></H2
><P
>&#13;
    If a repository contains not only source files,
    but also derived files (such as object files,
    libraries, or executables), <SPAN
CLASS="application"
>SCons</SPAN
> will perform
    its normal MD5 signature calculation to
    decide if a derived file in a repository is up-to-date,
    or the derived file must be rebuilt in the local build directory.
    For the <SPAN
CLASS="application"
>SCons</SPAN
> signature calculation to work correctly,
    a repository tree must contain the <TT
CLASS="filename"
>.sconsign</TT
> files
    that <SPAN
CLASS="application"
>SCons</SPAN
> uses to keep track of signature information.

    </P
><P
>&#13;
    Usually, this would be done by a build integrator
    who would run <SPAN
CLASS="application"
>SCons</SPAN
> in the repository
    to create all of its derived files and <TT
CLASS="filename"
>.sconsign</TT
> files,
    or who would run <SPAN
CLASS="application"
>SCons</SPAN
> in a separate build directory
    and copy the resulting tree to the desired repository:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>cd /usr/repository1</KBD
>
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o file1.o -c file1.c
      cc -o file2.o -c file2.c
      cc -o hello.o -c hello.c
      cc -o hello hello.o file1.o file2.o
    </PRE
><P
>&#13;    
    (Note that this is safe even if the <TT
CLASS="filename"
>SConstruct</TT
> file
    lists <TT
CLASS="filename"
>/usr/repository1</TT
> as a repository,
    because <SPAN
CLASS="application"
>SCons</SPAN
> will remove the current build directory
    from its repository list for that invocation.)

    </P
><P
>&#13;
    Now, with the repository populated,
    we only need to create the one local source file
    we're interested in working with at the moment,
    and use the <TT
CLASS="literal"
>-Y</TT
> option to
    tell <SPAN
CLASS="application"
>SCons</SPAN
> to fetch any other files it needs
    from the repository:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>cd $HOME/build</KBD
>
      % <KBD
CLASS="userinput"
>edit hello.c</KBD
>
      % <KBD
CLASS="userinput"
>scons -Q -Y /usr/repository1</KBD
>
      cc -c -o hello.o hello.c
      cc -o hello hello.o /usr/repository1/file1.o /usr/repository1/file2.o
    </PRE
><P
>&#13;
    Notice that <SPAN
CLASS="application"
>SCons</SPAN
> realizes that it does not need to
    rebuild local copies <TT
CLASS="filename"
>file1.o</TT
> and <TT
CLASS="filename"
>file2.o</TT
> files,
    but instead uses the already-compiled files
    from the repository.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN3966"
>23.6. Guaranteeing local copies of files</A
></H2
><P
>&#13;
    If the repository tree contains the complete results of a build,
    and we try to build from the repository
    without any files in our local tree,
    something moderately surprising happens:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>mkdir $HOME/build2</KBD
>
      % <KBD
CLASS="userinput"
>cd $HOME/build2</KBD
>
      % <KBD
CLASS="userinput"
>scons -Q -Y /usr/all/repository hello</KBD
>
      scons: `hello' is up-to-date.
    </PRE
><P
>&#13;
    Why does <SPAN
CLASS="application"
>SCons</SPAN
> say that the <SPAN
CLASS="application"
>hello</SPAN
> program
    is up-to-date when there is no <SPAN
CLASS="application"
>hello</SPAN
> program
    in the local build directory?
    Because the repository (not the local directory)
    contains the up-to-date <SPAN
CLASS="application"
>hello</SPAN
> program,
    and <SPAN
CLASS="application"
>SCons</SPAN
> correctly determines that nothing
    needs to be done to rebuild that
    up-to-date copy of the file.

    </P
><P
>&#13;
    There are, however, many times when you want to ensure that a
    local copy of a file always exists.
    A packaging or testing script, for example,
    may assume that certain generated files exist locally.
    To tell <SPAN
CLASS="application"
>SCons</SPAN
> to make a copy of any up-to-date repository
    file in the local build directory,
    use the <CODE
CLASS="function"
>Local</CODE
> function:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       hello = env.Program('hello.c')
       Local(hello)
    </PRE
><P
>&#13;
    If we then run the same command,
    <SPAN
CLASS="application"
>SCons</SPAN
> will make a local copy of the program
    from the repository copy,
    and tell you that it is doing so:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Y /usr/all/repository hello</KBD
>
      Local copy of hello from /usr/all/repository/hello
      scons: `hello' is up-to-date.
    </PRE
><P
>&#13;
    (Notice that, because the act of making the local copy
    is not considered a "build" of the <SPAN
CLASS="application"
>hello</SPAN
> file,
    <SPAN
CLASS="application"
>SCons</SPAN
> still reports that it is up-to-date.)

    </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-sconf"
></A
>Chapter 24. Multi-Platform Configuration (<SPAN
CLASS="application"
>Autoconf</SPAN
> Functionality)</H1
><P
>&#13;
  <SPAN
CLASS="application"
>SCons</SPAN
> has integrated support for multi-platform build configuration
  similar to that offered by GNU <SPAN
CLASS="application"
>Autoconf</SPAN
>,
  such as
  figuring out what libraries or header files
  are available on the local system.
  This section describes how to use
  this <SPAN
CLASS="application"
>SCons</SPAN
> feature.

  </P
><DIV
CLASS="note"
><P
></P
><TABLE
CLASS="note"
WIDTH="100%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/note.gif"
HSPACE="5"
ALT="Note"></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>&#13;  This chapter is still under development,
  so not everything is explained as well as it should be.
  See the <SPAN
CLASS="application"
>SCons</SPAN
> man page for additional information.
  </P
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4000"
>24.1. <TT
CLASS="literal"
>Configure Contexts</TT
></A
></H2
><P
>&#13;
    The basic framework for multi-platform build configuration
    in <SPAN
CLASS="application"
>SCons</SPAN
> is to attach a <TT
CLASS="literal"
>configure context</TT
> to a
    construction environment by calling the <CODE
CLASS="function"
>Configure</CODE
> function,
    perform a number of checks for
    libraries, functions, header files, etc.,
    and to then call the configure context's <CODE
CLASS="function"
>Finish</CODE
> method
    to finish off the configuration:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    # Checks for libraries, header files, etc. go here!
    env = conf.Finish()
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> provides a number of basic checks,
    as well as a mechanism for adding your own custom checks.

    </P
><P
>&#13;
    Note that <SPAN
CLASS="application"
>SCons</SPAN
> uses its own dependency
    mechanism to determine when a check
    needs to be run--that is,
    <SPAN
CLASS="application"
>SCons</SPAN
> does not run the checks
    every time it is invoked,
    but caches the values returned by previous checks
    and uses the cached values unless something has changed.
    This saves a tremendous amount
    of developer time while working on
    cross-platform build issues.

    </P
><P
>&#13;
    The next sections describe
    the basic checks that <SPAN
CLASS="application"
>SCons</SPAN
> supports,
    as well as how to add your own custom checks.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4016"
>24.2. Checking for the Existence of Header Files</A
></H2
><P
>&#13;
    Testing the existence of a header file
    requires knowing what language the header file is.
    A configure context has a <CODE
CLASS="function"
>CheckCHeader</CODE
> method
    that checks for the existence of a C header file:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    if not conf.CheckCHeader('math.h'):
        print 'Math.h must be installed!'
        Exit(1)
    if conf.CheckCHeader('foo.h'):
        conf.env.Append('-DHAS_FOO_H')
    env = conf.Finish()
    </PRE
><P
>&#13;
    Note that you can choose to terminate
    the build if a given header file doesn't exist,
    or you can modify the construction environment
    based on the existence of a header file.

    </P
><P
>&#13;
    If you need to check for the existence
    a C++ header file,
    use the <CODE
CLASS="function"
>CheckCXXHeader</CODE
> method:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    if not conf.CheckCXXHeader('vector.h'):
        print 'vector.h must be installed!'
        Exit(1)
    env = conf.Finish()
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4025"
>24.3. Checking for the Availability of a Function</A
></H2
><P
>&#13;
    Check for the availability of a specific function
    using the <CODE
CLASS="function"
>CheckFunc</CODE
> method:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    if not conf.CheckFunc('strcpy'):
        print 'Did not find strcpy(), using local version'
        conf.env.Append('-Dstrcpy=my_local_strcpy')
    env = conf.Finish()
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4030"
>24.4. Checking for the Availability of a Library</A
></H2
><P
>&#13;
    Check for the availability of a library
    using the <CODE
CLASS="function"
>CheckLib</CODE
> method.
    You only specify the basename of the library,
    you don't need to add a <TT
CLASS="literal"
>lib</TT
>
    prefix or a <TT
CLASS="literal"
>.a</TT
> or <TT
CLASS="literal"
>.lib</TT
> suffix:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    if not conf.CheckLib('m'):
        print 'Did not find libm.a or m.lib, exiting!'
        Exit(1)
    env = conf.Finish()
    </PRE
><P
>&#13;
    Because the ability to use a library successfully
    often depends on having access to a header file
    that describes the library's interface,
    you can check for a library
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>and</I
></SPAN
> a header file
    at the same time by using the
    <CODE
CLASS="function"
>CheckLibWithHeader</CODE
> method:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    if not conf.CheckLibWithHeader('m', 'math.h', 'c'):
        print 'Did not find libm.a or m.lib, exiting!'
        Exit(1)
    env = conf.Finish()
    </PRE
><P
>&#13;
    This is essentially shorthand for
    separate calls to the <CODE
CLASS="function"
>CheckHeader</CODE
> and <CODE
CLASS="function"
>CheckLib</CODE
>
    functions.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4045"
>24.5. Checking for the Availability of a <TT
CLASS="literal"
>typedef</TT
></A
></H2
><P
>&#13;
    Check for the availability of a <TT
CLASS="literal"
>typedef</TT
>
    by using the <CODE
CLASS="function"
>CheckType</CODE
> method:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    if not conf.CheckType('off_t'):
        print 'Did not find off_t typedef, assuming int'
        conf.env.Append(CCFLAGS = '-Doff_t=int')
    env = conf.Finish()
    </PRE
><P
>&#13;
    You can also add a string that will be
    placed at the beginning of the test file
    that will be used to check for the <TT
CLASS="literal"
>typedef</TT
>.
    This provide a way to specify
    files that must be included to find the <TT
CLASS="literal"
>typedef</TT
>:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env)
    if not conf.CheckType('off_t', '#include &#60;sys/types.h&#62;\n'):
        print 'Did not find off_t typedef, assuming int'
        conf.env.Append(CCFLAGS = '-Doff_t=int')
    env = conf.Finish()
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4056"
>24.6. Adding Your Own Custom Checks</A
></H2
><P
>&#13;
    A custom check is a Python function
    that checks for a certain condition to exist
    on the running system,
    usually using methods that <SPAN
CLASS="application"
>SCons</SPAN
>
    supplies to take care of the details
    of checking whether a compilation succeeds,
    a link succeeds,
    a program is runnable,
    etc.
    A simple custom check for the existence of
    a specific library might look as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;    mylib_test_source_file = """
    #include &#60;mylib.h&#62;
    int main(int argc, char **argv)
    {
        MyLibrary mylib(argc, argv);
        return 0;
    }
    """

    def CheckMyLibrary(context):
        context.Message('Checking for MyLibrary...')
        result = context.TryLink(mylib_test_source_file, '.c')
        context.Result(result)
        return result
    </PRE
><P
>&#13;
    The <CODE
CLASS="function"
>Message</CODE
> and <CODE
CLASS="function"
>Result</CODE
> methods
    should typically begin and end a custom check to
    let the user know what's going on:
    the <CODE
CLASS="function"
>Message</CODE
> call prints the
    specified message (with no trailing newline)
    and the <CODE
CLASS="function"
>Result</CODE
> call prints
    <TT
CLASS="literal"
>ok</TT
> if the check succeeds and
    <TT
CLASS="literal"
>failed</TT
> if it doesn't.
    The <CODE
CLASS="function"
>TryLink</CODE
> method
    actually tests for whether the
    specified program text
    will successfully link.

    </P
><P
>&#13;
    (Note that a custom check can modify
    its check based on any arguments you
    choose to pass it,
    or by using or modifying the configure context environment
    in the <TT
CLASS="literal"
>context.env</TT
> attribute.)

    </P
><P
>&#13;
    This custom check function is
    then attached to the <TT
CLASS="literal"
>configure context</TT
>
    by passing a dictionary
    to the <CODE
CLASS="function"
>Configure</CODE
> call
    that maps a name of the check
    to the underlying function:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    conf = Configure(env, custom_tests = {'CheckMyLibrary' : CheckMyLibrary})
    </PRE
><P
>&#13;
    You'll typically want to make
    the check and the function name the same,
    as we've done here,
    to avoid potential confusion.

    </P
><P
>&#13;
    We can then put these pieces together
    and actually call the <TT
CLASS="literal"
>CheckMyLibrary</TT
> check
    as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;    mylib_test_source_file = """
    #include &#60;mylib.h&#62;
    int main(int argc, char **argv)
    {
        MyLibrary mylib(argc, argv);
        return 0;
    }
    """

    def CheckMyLibrary(context):
        context.Message('Checking for MyLibrary... ')
        result = context.TryLink(mylib_test_source_file, '.c')
        context.Result(result)
        return result

    env = Environment()
    conf = Configure(env, custom_tests = {'CheckMyLibrary' : CheckMyLibrary})
    if not conf.CheckMyLibrary():
        print 'MyLibrary is not installed!'
        Exit(1)
    env = conf.Finish()

    # We would then add actual calls like Program() to build
    # something using the "env" construction environment.
    </PRE
><P
>&#13;
    If MyLibrary is not installed on the system,
    the output will look like:

    </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons</KBD
>
    scons: Reading SConscript file ...
    Checking for MyLibrary... failed
    MyLibrary is not installed!
    </PRE
><P
>&#13;
    If MyLibrary is installed,
    the output will look like:

    </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons</KBD
>
    scons: Reading SConscript file ...
    Checking for MyLibrary... failed
    scons: done reading SConscript
    scons: Building targets ...
        .
        .
        .
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4085"
>24.7. Not Configuring When Cleaning Targets</A
></H2
><P
>&#13;
    Using multi-platform configuration
    as described in the previous sections
    will run the configuration commands
    even when invoking
    <KBD
CLASS="userinput"
>scons -c</KBD
>
    to clean targets:

    </P
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
    Checking for MyLibrary... ok
    Removed foo.o
    Removed foo
    </PRE
><P
>&#13;
    Although running the platform checks
    when removing targets doesn't hurt anything,
    it's usually unnecessary.
    You can avoid this by using the
    <CODE
CLASS="function"
>GetOption</CODE
>(); method to
    check whether the <CODE
CLASS="option"
>-c</CODE
> (clean)
    option has been invoked on the command line:

    </P
><PRE
CLASS="programlisting"
>&#13;    env = Environment()
    if not env.GetOption('clean'):
        conf = Configure(env, custom_tests = {'CheckMyLibrary' : CheckMyLibrary})
        if not conf.CheckMyLibrary():
            print 'MyLibrary is not installed!'
            Exit(1)
        env = conf.Finish()
    </PRE
><PRE
CLASS="screen"
>&#13;    % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
    Removed foo.o
    Removed foo
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-caching"
></A
>Chapter 25. Caching Built Files</H1
><P
>&#13;
  On multi-developer software projects,
  you can sometimes speed up every developer's builds a lot by
  allowing them to share the derived files that they build.
  <SPAN
CLASS="application"
>SCons</SPAN
> makes this easy, as well as reliable.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4101"
>25.1. Specifying the Shared Cache Directory</A
></H2
><P
>&#13;
    To enable sharing of derived files,
    use the <CODE
CLASS="function"
>CacheDir</CODE
> function
    in any <TT
CLASS="filename"
>SConscript</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;       CacheDir('/usr/local/build_cache')
    </PRE
><P
>&#13;
    Note that the directory you specify must already exist
    and be readable and writable by all developers
    who will be sharing derived files.
    It should also be in some central location
    that all builds will be able to access.
    In environments where developers are using separate systems
    (like individual workstations) for builds,
    this directory would typically be
    on a shared or NFS-mounted file system.

    </P
><P
>&#13;
    Here's what happens:
    When a build has a <CODE
CLASS="function"
>CacheDir</CODE
> specified,
    every time a file is built,
    it is stored in the shared cache directory
    along with its MD5 build signature.
      <A
NAME="AEN4110"
HREF="#FTN.AEN4110"
><SPAN
CLASS="footnote"
>[5]</SPAN
></A
>
    On subsequent builds,
    before an action is invoked to build a file,
    <SPAN
CLASS="application"
>SCons</SPAN
> will check the shared cache directory
    to see if a file with the exact same build
    signature already exists.
    If so, the derived file will not be built locally,
    but will be copied into the local build directory
    from the shared cache directory,
    like so:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
      Removed hello.o
      Removed hello
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Retrieved `hello.o' from cache
      Retrieved `hello' from cache
    </PRE
><P
>&#13;
    Note that the <CODE
CLASS="function"
>CacheDir</CODE
> feature still calculates
    MD5 build sigantures for the shared cache file names
    even if you configure <SPAN
CLASS="application"
>SCons</SPAN
> to use timestamps
    to decide if files are up to date.
    (See the <A
HREF="#chap-depends"
>Chapter 6</A
>
    chapter for information about the <CODE
CLASS="function"
>Decider</CODE
> function.)
    Consequently, using <CODE
CLASS="function"
>CacheDir</CODE
> may reduce or eliminate any
    potential performance improvements
    from using timestamps for up-to-date decisions.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4123"
>25.2. Keeping Build Output Consistent</A
></H2
><P
>&#13;
    One potential drawback to using a shared cache
    is that the output printed by <SPAN
CLASS="application"
>SCons</SPAN
>
    can be inconsistent from invocation to invocation,
    because any given file may be rebuilt one time
    and retrieved from the shared cache the next time.
    This can make analyzing build output more difficult,
    especially for automated scripts that
    expect consistent output each time.

    </P
><P
>&#13;
    If, however, you use the <TT
CLASS="literal"
>--cache-show</TT
> option,
    <SPAN
CLASS="application"
>SCons</SPAN
> will print the command line that it
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>would</I
></SPAN
> have executed
    to build the file,
    even when it is retrieving the file from the shared cache.
    This makes the build output consistent
    every time the build is run:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
      Removed hello.o
      Removed hello
      % <KBD
CLASS="userinput"
>scons -Q --cache-show</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
    </PRE
><P
>&#13;
    The trade-off, of course, is that you no longer
    know whether or not <SPAN
CLASS="application"
>SCons</SPAN
>
    has retrieved a derived file from cache
    or has rebuilt it locally.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4137"
>25.3. Not Using the Shared Cache for Specific Files</A
></H2
><P
>&#13;
    You may want to disable caching for certain
    specific files in your configuration.
    For example, if you only want to put
    executable files in a central cache,
    but not the intermediate object files,
    you can use the <CODE
CLASS="function"
>NoCache</CODE
>
    function to specify that the
    object files should not be cached:

    </P
><PRE
CLASS="programlisting"
>&#13;       env = Environment()
       obj = env.Object('hello.c')
       env.Program('hello.c')
       CacheDir('cache')
       NoCache('hello.o')
    </PRE
><P
>&#13;
    Then when you run <SPAN
CLASS="application"
>scons</SPAN
> after cleaning
    the built targets,
    it will recompile the object file locally
    (since it doesn't exist in the shared cache directory),
    but still realize that the shared cache directory
    contains an up-to-date executable program
    that can be retrieved instead of re-linking:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
      Removed hello.o
      Removed hello
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      Retrieved `hello' from cache
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4148"
>25.4. Disabling the Shared Cache</A
></H2
><P
>&#13;
    Retrieving an already-built file
    from the shared cache
    is usually a significant time-savings
    over rebuilding the file,
    but how much of a savings
    (or even whether it saves time at all)
    can depend a great deal on your
    system or network configuration.
    For example, retrieving cached files
    from a busy server over a busy network
    might end up being slower than
    rebuilding the files locally.

    </P
><P
>&#13;
    In these cases, you can specify
    the <TT
CLASS="literal"
>--cache-disable</TT
>
    command-line option to tell <SPAN
CLASS="application"
>SCons</SPAN
>
    to not retrieve already-built files from the
    shared cache directory:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
      Removed hello.o
      Removed hello
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Retrieved `hello.o' from cache
      Retrieved `hello' from cache
      % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
      Removed hello.o
      Removed hello
      % <KBD
CLASS="userinput"
>scons -Q --cache-disable</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4160"
>25.5. Populating a Shared Cache With Already-Built Files</A
></H2
><P
>&#13;
    Sometimes, you may have one or more derived files
    already built in your local build tree
    that you wish to make available to other people doing builds.
    For example, you may find it more effective to perform
    integration builds with the cache disabled
    (per the previous section)
    and only populate the shared cache directory
    with the built files after the integration build
    has completed successfully.
    This way, the cache will only get filled up
    with derived files that are part of a complete, successful build
    not with files that might be later overwritten
    while you debug integration problems.

    </P
><P
>&#13;
    In this case, you can use the
    the <TT
CLASS="literal"
>--cache-force</TT
> option
    to tell <SPAN
CLASS="application"
>SCons</SPAN
> to put all derived files in the cache,
    even if the files already exist in your local tree
    from having been built by a previous invocation:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --cache-disable</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q -c</KBD
>
      Removed hello.o
      Removed hello
      % <KBD
CLASS="userinput"
>scons -Q --cache-disable</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
      % <KBD
CLASS="userinput"
>scons -Q --cache-force</KBD
>
      scons: `.' is up to date.
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      scons: `.' is up to date.
    </PRE
><P
>&#13;
    Notice how the above sample run
    demonstrates that the <TT
CLASS="literal"
>--cache-disable</TT
>
    option avoids putting the built
    <TT
CLASS="filename"
>hello.o</TT
>
    and
    <TT
CLASS="filename"
>hello</TT
> files in the cache,
    but after using the <TT
CLASS="literal"
>--cache-force</TT
> option,
    the files have been put in the cache
    for the next invocation to retrieve.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4177"
>25.6. Minimizing Cache Contention:  the <TT
CLASS="literal"
>--random</TT
> Option</A
></H2
><P
>&#13;
    If you allow multiple builds to update the
    shared cache directory simultaneously,
    two builds that occur at the same time
    can sometimes start "racing"
    with one another to build the same files
    in the same order.
    If, for example,
    you are linking multiple files into an executable program:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('prog',
               ['f1.c', 'f2.c', 'f3.c', 'f4.c', 'f5.c'])
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> will normally build the input object files
    on which the program depends in their normal, sorted order:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o f1.o -c f1.c
      cc -o f2.o -c f2.c
      cc -o f3.o -c f3.c
      cc -o f4.o -c f4.c
      cc -o f5.o -c f5.c
      cc -o prog f1.o f2.o f3.o f4.o f5.o
    </PRE
><P
>&#13;
    But if two such builds take place simultaneously,
    they may each look in the cache at nearly the same
    time and both decide that <TT
CLASS="filename"
>f1.o</TT
>
    must be rebuilt and pushed into the shared cache directory,
    then both decide that <TT
CLASS="filename"
>f2.o</TT
>
    must be rebuilt (and pushed into the shared cache directory),
    then both decide that <TT
CLASS="filename"
>f3.o</TT
>
    must be rebuilt...
    This won't cause any actual build problems--both
    builds will succeed,
    generate correct output files,
    and populate the cache--but
    it does represent wasted effort.

    </P
><P
>&#13;
    To alleviate such contention for the cache,
    you can use the <TT
CLASS="literal"
>--random</TT
> command-line option
    to tell <SPAN
CLASS="application"
>SCons</SPAN
> to build dependencies
    in a random order:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --random</KBD
>
      cc -o f3.o -c f3.c
      cc -o f1.o -c f1.c
      cc -o f5.o -c f5.c
      cc -o f2.o -c f2.c
      cc -o f4.o -c f4.c
      cc -o prog f1.o f2.o f3.o f4.o f5.o
    </PRE
><P
>&#13;
    Multiple builds using the <TT
CLASS="literal"
>--random</TT
> option
    will usually build their dependencies in different,
    random orders,
    which minimizes the chances for a lot of
    contention for same-named files
    in the shared cache directory.
    Multiple simultaneous builds might still race to try to build
    the same target file on occasion,
    but long sequences of inefficient contention
    should be rare.

    </P
><P
>&#13;
    Note, of course,
    the <TT
CLASS="literal"
>--random</TT
> option
    will cause the output that <SPAN
CLASS="application"
>SCons</SPAN
> prints
    to be inconsistent from invocation to invocation,
    which may be an issue when
    trying to compare output from different build runs.

    </P
><P
>&#13;
    If you want to make sure dependencies will be built
    in a random order without having to specify
    the <TT
CLASS="literal"
>--random</TT
> on very command line,
    you can use the <CODE
CLASS="function"
>SetOption</CODE
> function to
    set the <TT
CLASS="literal"
>random</TT
> option
    within any <TT
CLASS="filename"
>SConscript</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;       Program('prog',
               ['f1.c', 'f2.c', 'f3.c', 'f4.c', 'f5.c'])

       SetOption('random', 1)
       Program('prog',
               ['f1.c', 'f2.c', 'f3.c', 'f4.c', 'f5.c'])
    </PRE
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-alias"
></A
>Chapter 26. Alias Targets</H1
><P
>&#13;
  We've already seen how you can use the <CODE
CLASS="function"
>Alias</CODE
>
  function to create a target named <TT
CLASS="literal"
>install</TT
>:

  </P
><PRE
CLASS="programlisting"
>&#13;     env = Environment()
     hello = env.Program('hello.c')
     env.Install('/usr/bin', hello)
     env.Alias('install', '/usr/bin')
  </PRE
><P
>&#13;
  You can then use this alias on the command line
  to tell <SPAN
CLASS="application"
>SCons</SPAN
> more naturally that you want to install files:

  </P
><PRE
CLASS="screen"
>&#13;     % <KBD
CLASS="userinput"
>scons -Q install</KBD
>
     cc -o hello.o -c hello.c
     cc -o hello hello.o
     Install file: "hello" as "/usr/bin/hello"
  </PRE
><P
>&#13;
  Like other <CODE
CLASS="classname"
>Builder</CODE
> methods, though,
  the <CODE
CLASS="function"
>Alias</CODE
> method returns an object
  representing the alias being built.
  You can then use this object as input to anothother <CODE
CLASS="classname"
>Builder</CODE
>.
  This is especially useful if you use such an object
  as input to another call to the <CODE
CLASS="function"
>Alias</CODE
> <CODE
CLASS="classname"
>Builder</CODE
>,
  allowing you to create a hierarchy
  of nested aliases:

  </P
><PRE
CLASS="programlisting"
>&#13;     env = Environment()
     p = env.Program('foo.c')
     l = env.Library('bar.c')
     env.Install('/usr/bin', p)
     env.Install('/usr/lib', l)
     ib = env.Alias('install-bin', '/usr/bin')
     il = env.Alias('install-lib', '/usr/lib')
     env.Alias('install', [ib, il])
  </PRE
><P
>&#13;
  This example defines separate <TT
CLASS="literal"
>install</TT
>,
  <TT
CLASS="literal"
>install-bin</TT
>,
  and <TT
CLASS="literal"
>install-lib</TT
> aliases,
  allowing you finer control over what gets installed:

  </P
><PRE
CLASS="screen"
>&#13;     % <KBD
CLASS="userinput"
>scons -Q install-bin</KBD
>
     cc -o foo.o -c foo.c
     cc -o foo foo.o
     Install file: "foo" as "/usr/bin/foo"
     % <KBD
CLASS="userinput"
>scons -Q install-lib</KBD
>
     cc -o bar.o -c bar.c
     ar rc libbar.a bar.o
     ranlib libbar.a
     Install file: "libbar.a" as "/usr/lib/libbar.a"
     % <KBD
CLASS="userinput"
>scons -Q -c /</KBD
>
     Removed foo.o
     Removed foo
     Removed /usr/bin/foo
     Removed bar.o
     Removed libbar.a
     Removed /usr/lib/libbar.a
     % <KBD
CLASS="userinput"
>scons -Q install</KBD
>
     cc -o foo.o -c foo.c
     cc -o foo foo.o
     Install file: "foo" as "/usr/bin/foo"
     cc -o bar.o -c bar.c
     ar rc libbar.a bar.o
     ranlib libbar.a
     Install file: "libbar.a" as "/usr/lib/libbar.a"
  </PRE
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-java"
></A
>Chapter 27. Java Builds</H1
><P
>&#13;
  So far, we've been using examples of
  building C and C++ programs
  to demonstrate the features of <SPAN
CLASS="application"
>SCons</SPAN
>.
  <SPAN
CLASS="application"
>SCons</SPAN
> also supports building Java programs,
  but Java builds are handled slightly differently,
  which reflects the ways in which
  the Java compiler and tools
  build programs differently than
  other languages' tool chains.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4237"
>27.1. Building Java Class Files:  the <CODE
CLASS="function"
>Java</CODE
> Builder</A
></H2
><P
>&#13;
    The basic activity when programming in Java,
    of course, is to take one or more <TT
CLASS="filename"
>.java</TT
> files
    containing Java source code
    and to call the Java compiler
    to turn them into one or more
    <TT
CLASS="filename"
>.class</TT
> files.
    In <SPAN
CLASS="application"
>SCons</SPAN
>, you do this
    by giving the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> Builder
    a target directory in which
    to put the <TT
CLASS="filename"
>.class</TT
> files,
    and a source directory that contains
    the <TT
CLASS="filename"
>.java</TT
> files:

    </P
><PRE
CLASS="programlisting"
>&#13;      Java('classes', 'src')
    </PRE
><P
>&#13;
    If the <TT
CLASS="filename"
>src</TT
> directory contains
    three <TT
CLASS="filename"
>.java</TT
> source files,
    then running <SPAN
CLASS="application"
>SCons</SPAN
> might look like this:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src src/Example1.java src/Example2.java src/Example3.java
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> will actually search the <TT
CLASS="filename"
>src</TT
>
    directory tree for all of the <TT
CLASS="filename"
>.java</TT
> files.
    The Java compiler will then create the
    necessary class files in the <TT
CLASS="filename"
>classes</TT
> subdirectory,
    based on the class names found in the <TT
CLASS="filename"
>.java</TT
> files.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4261"
>27.2. How <SPAN
CLASS="application"
>SCons</SPAN
> Handles Java Dependencies</A
></H2
><P
>&#13;
    In addition to searching the source directory for
    <TT
CLASS="filename"
>.java</TT
> files,
    <SPAN
CLASS="application"
>SCons</SPAN
> actually runs the <TT
CLASS="filename"
>.java</TT
> files
    through a stripped-down Java parser that figures out
    what classes are defined.
    In other words, <SPAN
CLASS="application"
>SCons</SPAN
> knows,
    without you having to tell it,
    what <TT
CLASS="filename"
>.class</TT
> files
    will be produced by the <SPAN
CLASS="application"
>javac</SPAN
> call.
    So our one-liner example from the preceding section:

    </P
><PRE
CLASS="programlisting"
>&#13;      Java('classes', 'src')
    </PRE
><P
>&#13;
    Will not only tell you reliably
    that the <TT
CLASS="filename"
>.class</TT
> files
    in the <TT
CLASS="filename"
>classes</TT
> subdirectory 
    are up-to-date:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src src/Example1.java src/Example2.java src/Example3.java
      % <KBD
CLASS="userinput"
>scons -Q classes</KBD
>
      scons: `classes' is up to date.
    </PRE
><P
>&#13;
    But it will also remove all of the generated
    <TT
CLASS="filename"
>.class</TT
> files,
    even for inner classes,
    without you having to specify them manually.
    For example, if our
    <TT
CLASS="filename"
>Example1.java</TT
>
    and
    <TT
CLASS="filename"
>Example3.java</TT
>
    files both define additional classes,
    and the class defined in <TT
CLASS="filename"
>Example2.java</TT
>
    has an inner class,
    running <KBD
CLASS="userinput"
>scons -c</KBD
>
    will clean up all of those <TT
CLASS="filename"
>.class</TT
> files
    as well:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src src/Example1.java src/Example2.java src/Example3.java
      % <KBD
CLASS="userinput"
>scons -Q -c classes</KBD
>
      Removed classes/Example1.class
      Removed classes/AdditionalClass1.class
      Removed classes/Example2$Inner2.class
      Removed classes/Example2.class
      Removed classes/Example3.class
      Removed classes/AdditionalClass3.class
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4288"
>27.3. Building Java Archive (<TT
CLASS="filename"
>.jar</TT
>) Files:  the <CODE
CLASS="function"
>Jar</CODE
> Builder</A
></H2
><P
>&#13;
    After building the class files,
    it's common to collect them into
    a Java archive (<TT
CLASS="filename"
>.jar</TT
>) file,
    which you do by calling the <A
HREF="#b-Jar"
><CODE
CLASS="function"
>Jar</CODE
></A
> Builder method.
    If you want to just collect all of the
    class files within a subdirectory,
    you can just specify that subdirectory
    as the <CODE
CLASS="function"
>Jar</CODE
> source:

    </P
><PRE
CLASS="programlisting"
>&#13;      Java(target = 'classes', source = 'src')
      Jar(target = 'test.jar', source = 'classes')
    </PRE
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> will then pass that directory
    to the <SPAN
CLASS="application"
>jar</SPAN
> command,
    which will collect all of the underlying
    <TT
CLASS="filename"
>.class</TT
> files:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src src/Example1.java src/Example2.java src/Example3.java
      jar cf test.jar classes
    </PRE
><P
>&#13;
    If you want to keep all of the
    <TT
CLASS="filename"
>.class</TT
> files
    for multiple programs in one location,
    and only archive some of them in
    each <TT
CLASS="filename"
>.jar</TT
> file,
    you can pass the <CODE
CLASS="function"
>Jar</CODE
> builder a
    list of files as its source.
    It's extremely simple to create multiple
    <TT
CLASS="filename"
>.jar</TT
> files this way,
    using the lists of target class files created
    by calls to the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> builder
    as sources to the various <CODE
CLASS="function"
>Jar</CODE
> calls:

    </P
><PRE
CLASS="programlisting"
>&#13;      prog1_class_files = Java(target = 'classes', source = 'prog1')
      prog2_class_files = Java(target = 'classes', source = 'prog2')
      Jar(target = 'prog1.jar', source = prog1_class_files)
      Jar(target = 'prog2.jar', source = prog2_class_files)
    </PRE
><P
>&#13;
    This will then create
    <TT
CLASS="filename"
>prog1.jar</TT
>
    and <TT
CLASS="filename"
>prog2.jar</TT
>
    next to the subdirectories
    that contain their <TT
CLASS="filename"
>.java</TT
> files:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath prog1 prog1/Example1.java prog1/Example2.java
      javac -d classes -sourcepath prog2 prog2/Example3.java prog2/Example4.java
      jar cf prog1.jar -C classes Example1.class -C classes Example2.class
      jar cf prog2.jar -C classes Example3.class -C classes Example4.class
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4319"
>27.4. Building C Header and Stub Files:  the <CODE
CLASS="function"
>JavaH</CODE
> Builder</A
></H2
><P
>&#13;
    You can generate C header and source files
    for implementing native methods,
    by using the <A
HREF="#b-JavaH"
><CODE
CLASS="function"
>JavaH</CODE
></A
> Builder.
    There are several ways of using the <CODE
CLASS="function"
>JavaH</CODE
> Builder.
    One typical invocation might look like:

    </P
><PRE
CLASS="programlisting"
>&#13;      classes = Java(target = 'classes', source = 'src/pkg/sub')
      JavaH(target = 'native', source = classes)
    </PRE
><P
>&#13;
    The source is a list of class files generated by the
    call to the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> Builder,
    and the target is the output directory in
    which we want the C header files placed.
    The target
    gets converted into the <CODE
CLASS="option"
>-d</CODE
>
    when <SPAN
CLASS="application"
>SCons</SPAN
> runs <SPAN
CLASS="application"
>javah</SPAN
>:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src/pkg/sub src/pkg/sub/Example1.java src/pkg/sub/Example2.java src/pkg/sub/Example3.java
      javah -d native -classpath classes pkg.sub.Example1 pkg.sub.Example2 pkg.sub.Example3
    </PRE
><P
>&#13;
    In this case,
    the call to <SPAN
CLASS="application"
>javah</SPAN
>
    will generate the header files
    <TT
CLASS="filename"
>native/pkg_sub_Example1.h</TT
>,
    <TT
CLASS="filename"
>native/pkg_sub_Example2.h</TT
>
    and
    <TT
CLASS="filename"
>native/pkg_sub_Example3.h</TT
>.
    Notice that <SPAN
CLASS="application"
>SCons</SPAN
> remembered that the class
    files were generated with a target directory of
    <TT
CLASS="filename"
>classes</TT
>,
    and that it then specified that target directory
    as the <CODE
CLASS="option"
>-classpath</CODE
> option
    to the call to <SPAN
CLASS="application"
>javah</SPAN
>.

    </P
><P
>&#13;
    Although it's more convenient to use
    the list of class files returned by
    the <CODE
CLASS="function"
>Java</CODE
> Builder
    as the source of a call to the <CODE
CLASS="function"
>JavaH</CODE
> Builder,
    you <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>can</I
></SPAN
>
    specify the list of class files
    by hand, if you prefer.
    If you do,
    you need to set the
    <A
HREF="#cv-JAVACLASSDIR"
><CODE
CLASS="envar"
>$JAVACLASSDIR</CODE
></A
> construction variable
    when calling <CODE
CLASS="function"
>JavaH</CODE
>:

    </P
><PRE
CLASS="programlisting"
>&#13;      Java(target = 'classes', source = 'src/pkg/sub')
      class_file_list = ['classes/pkg/sub/Example1.class',
                         'classes/pkg/sub/Example2.class',
                         'classes/pkg/sub/Example3.class']
      JavaH(target = 'native', source = class_file_list, JAVACLASSDIR = 'classes')
    </PRE
><P
>&#13;
    The <CODE
CLASS="envar"
>$JAVACLASSDIR</CODE
> value then
    gets converted into the <CODE
CLASS="option"
>-classpath</CODE
>
    when <SPAN
CLASS="application"
>SCons</SPAN
> runs <SPAN
CLASS="application"
>javah</SPAN
>:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src/pkg/sub src/pkg/sub/Example1.java src/pkg/sub/Example2.java src/pkg/sub/Example3.java
      javah -d native -classpath classes pkg.sub.Example1 pkg.sub.Example2 pkg.sub.Example3
    </PRE
><P
>&#13;
    Lastly, if you don't want a separate header file
    generated for each source file,
    you can specify an explicit File Node
    as the target of the <CODE
CLASS="function"
>JavaH</CODE
> Builder:

    </P
><PRE
CLASS="programlisting"
>&#13;      classes = Java(target = 'classes', source = 'src/pkg/sub')
      JavaH(target = File('native.h'), source = classes)
    </PRE
><P
>&#13;
    Because <SPAN
CLASS="application"
>SCons</SPAN
> assumes by default
    that the target of the <CODE
CLASS="function"
>JavaH</CODE
> builder is a directory,
    you need to use the <CODE
CLASS="function"
>File</CODE
> function
    to make sure that <SPAN
CLASS="application"
>SCons</SPAN
> doesn't
    create a directory named <TT
CLASS="filename"
>native.h</TT
>.
    When a file is used, though,
    <SPAN
CLASS="application"
>SCons</SPAN
> correctly converts the file name
    into the <SPAN
CLASS="application"
>javah</SPAN
> <CODE
CLASS="option"
>-o</CODE
> option:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src/pkg/sub src/pkg/sub/Example1.java src/pkg/sub/Example2.java src/pkg/sub/Example3.java
      javah -o native.h -classpath classes pkg.sub.Example1 pkg.sub.Example2 pkg.sub.Example3
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4373"
>27.5. Building RMI Stub and Skeleton Class Files:  the <CODE
CLASS="function"
>RMIC</CODE
> Builder</A
></H2
><P
>&#13;
    You can generate Remote Method Invocation stubs
    by using the <A
HREF="#b-RMIC"
><CODE
CLASS="function"
>RMIC</CODE
></A
> Builder.
    The source is a list of directories,
    typically returned by a call to the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> Builder,
    and the target is an output directory
    where the <TT
CLASS="filename"
>_Stub.class</TT
>
    and <TT
CLASS="filename"
>_Skel.class</TT
> files will
    be placed:

    </P
><PRE
CLASS="programlisting"
>&#13;      classes = Java(target = 'classes', source = 'src/pkg/sub')
      RMIC(target = 'outdir', source = classes)
    </PRE
><P
>&#13;
    As it did with the <A
HREF="#b-JavaH"
><CODE
CLASS="function"
>JavaH</CODE
></A
> Builder,
    <SPAN
CLASS="application"
>SCons</SPAN
> remembers the class directory
    and passes it as the <CODE
CLASS="option"
>-classpath</CODE
> option
    to <SPAN
CLASS="application"
>rmic</SPAN
>:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      javac -d classes -sourcepath src/pkg/sub src/pkg/sub/Example1.java src/pkg/sub/Example2.java
      rmic -d outdir -classpath classes pkg.sub.Example1 pkg.sub.Example2
    </PRE
><P
>&#13;
    This example would generate the files
    <TT
CLASS="filename"
>outdir/pkg/sub/Example1_Skel.class</TT
>,
    <TT
CLASS="filename"
>outdir/pkg/sub/Example1_Stub.class</TT
>,
    <TT
CLASS="filename"
>outdir/pkg/sub/Example2_Skel.class</TT
> and
    <TT
CLASS="filename"
>outdir/pkg/sub/Example2_Stub.class</TT
>.

    </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-misc"
></A
>Chapter 28. Miscellaneous Functionality</H1
><P
>&#13;
  <SPAN
CLASS="application"
>SCons</SPAN
> supports a lot of additional functionality
  that doesn't readily fit into the other chapters.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4401"
>28.1. Verifying the Python Version:  the <CODE
CLASS="function"
>EnsurePythonVersion</CODE
> Function</A
></H2
><P
>&#13;
    Although the <SPAN
CLASS="application"
>SCons</SPAN
> code itself will run 
    on any Python version 1.5.2 or later,
    you are perfectly free to make use of
    Python syntax and modules from more modern versions
    (for example, Python 2.4 or 2.5)
    when writing your <TT
CLASS="filename"
>SConscript</TT
> files
    or your own local modules.
    If you do this, it's usually helpful to
    configure <SPAN
CLASS="application"
>SCons</SPAN
> to exit gracefully with an error message
    if it's being run with a version of Python
    that simply won't work with your code.
    This is especially true if you're going to use <SPAN
CLASS="application"
>SCons</SPAN
>
    to build source code that you plan to distribute publicly,
    where you can't be sure of the Python version
    that an anonymous remote user might use
    to try to build your software.

    </P
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> provides an <CODE
CLASS="function"
>EnsurePythonVersion</CODE
> function for this.
    You simply pass it the major and minor versions
    numbers of the version of Python you require:

    </P
><PRE
CLASS="programlisting"
>&#13;      EnsurePythonVersion(2, 5)
    </PRE
><P
>&#13;
    And then <SPAN
CLASS="application"
>SCons</SPAN
> will exit with the following error
    message when a user runs it with an unsupported
    earlier version of Python:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      Python 2.5 or greater required, but you have Python 2.3.6
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4417"
>28.2. Verifying the SCons Version:  the <CODE
CLASS="function"
>EnsureSConsVersion</CODE
> Function</A
></H2
><P
>&#13;
    You may, of course, write your <TT
CLASS="filename"
>SConscript</TT
> files
    to use features that were only added in
    recent versions of <SPAN
CLASS="application"
>SCons</SPAN
>.
    When you publicly distribute software that is built using <SPAN
CLASS="application"
>SCons</SPAN
>,
    it's helpful to have <SPAN
CLASS="application"
>SCons</SPAN
>
    verify the version being used and
    exit gracefully with an error message
    if the user's version of <SPAN
CLASS="application"
>SCons</SPAN
> won't work
    with your <TT
CLASS="filename"
>SConscript</TT
> files.
    <SPAN
CLASS="application"
>SCons</SPAN
> provides an <CODE
CLASS="function"
>EnsureSConsVersion</CODE
> function
    that verifies the version of <SPAN
CLASS="application"
>SCons</SPAN
>
    in the same
    the <CODE
CLASS="function"
>EnsurePythonVersion</CODE
> function
    verifies the version of Python,
    by passing in the major and minor versions
    numbers of the version of SCons you require:

    </P
><PRE
CLASS="programlisting"
>&#13;      EnsureSConsVersion(1, 0)
    </PRE
><P
>&#13;
    And then <SPAN
CLASS="application"
>SCons</SPAN
> will exit with the following error
    message when a user runs it with an unsupported
    earlier version of <SPAN
CLASS="application"
>SCons</SPAN
>:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      SCons 1.0 or greater required, but you have SCons 0.98.5
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4437"
>28.3. Explicitly Terminating <SPAN
CLASS="application"
>SCons</SPAN
> While Reading <TT
CLASS="filename"
>SConscript</TT
> Files:  the <CODE
CLASS="function"
>Exit</CODE
> Function</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> supports an <CODE
CLASS="function"
>Exit</CODE
> function
    which can be used to terminate <SPAN
CLASS="application"
>SCons</SPAN
>
    while reading the <TT
CLASS="filename"
>SConscript</TT
> files,
    usually because you've detected a condition
    under which it doesn't make sense to proceed:

    </P
><PRE
CLASS="programlisting"
>&#13;      if ARGUMENTS.get('FUTURE'):
          print "The FUTURE option is not supported yet!"
          Exit(2)
      env = Environment()
      env.Program('hello.c')
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q FUTURE=1</KBD
>
      The FUTURE option is not supported yet!
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o hello.o -c hello.c
      cc -o hello hello.o
    </PRE
><P
>&#13;
    The <CODE
CLASS="function"
>Exit</CODE
> function takes as an argument
    the (numeric) exit status that you want <SPAN
CLASS="application"
>SCons</SPAN
> to exit with.
    If you don't specify a value,
    the default is to exit with <TT
CLASS="literal"
>0</TT
>,
    which indicates successful execution.

    </P
><P
>&#13;
    Note that the <CODE
CLASS="function"
>Exit</CODE
> function
    is equivalent to calling the Python
    <CODE
CLASS="function"
>sys.exit</CODE
> function
    (which the it actually calls),
    but because <CODE
CLASS="function"
>Exit</CODE
> is a <SPAN
CLASS="application"
>SCons</SPAN
> function,
    you don't have to import the Python
    <TT
CLASS="literal"
>sys</TT
> module to use it.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4461"
>28.4. Searching for Files:  the <CODE
CLASS="function"
>FindFile</CODE
> Function</A
></H2
><P
>&#13;
     The <CODE
CLASS="function"
>FindFile</CODE
> function searches for a file in a list of directories.
     If there is only one directory, it can be given as a simple string.
     The function returns a File node if a matching file exists,
     or None if no file is found.
     (See the documentation for the <CODE
CLASS="function"
>Glob</CODE
> function for an alternative way
     of searching for entries in a directory.)

    </P
><PRE
CLASS="programlisting"
>&#13;       # one directory
       print FindFile('missing', '.')
       t = FindFile('exists', '.')
       print t.__class__, t
    </PRE
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       None
       SCons.Node.FS.File exists
       scons: `.' is up to date.
    </PRE
><PRE
CLASS="programlisting"
>&#13;       # several directories
       includes = [ '.', 'include', 'src/include']
       headers = [ 'nonesuch.h', 'config.h', 'private.h', 'dist.h']
       for hdr in headers:
           print '%-12s' % ('%s:' % hdr), FindFile(hdr, includes)
</PRE
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       nonesuch.h:  None
       config.h:    config.h
       private.h:   src/include/private.h
       dist.h:      include/dist.h
       scons: `.' is up to date.
    </PRE
><P
>&#13;
     If the file exists in more than one directory,
     only the first occurrence is returned.

    </P
><PRE
CLASS="programlisting"
>&#13;        print FindFile('multiple', ['sub1', 'sub2', 'sub3'])
        print FindFile('multiple', ['sub2', 'sub3', 'sub1'])
        print FindFile('multiple', ['sub3', 'sub1', 'sub2'])
    </PRE
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       sub1/multiple
       sub2/multiple
       sub3/multiple
       scons: `.' is up to date.
    </PRE
><P
>&#13;
    In addition to existing files, <CODE
CLASS="function"
>FindFile</CODE
> will also find derived files
    (that is, non-leaf files) that haven't been built yet.
    (Leaf files should already exist, or the build will fail!)

    </P
><PRE
CLASS="programlisting"
>&#13;       # Neither file exists, so build will fail
       Command('derived', 'leaf', 'cat &#62;$TARGET $SOURCE')
       print FindFile('leaf', '.')
       print FindFile('derived', '.')
    </PRE
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       None
       derived
       scons: *** Source `leaf' not found, needed by target `derived'.  Stop.
    </PRE
><PRE
CLASS="programlisting"
>&#13;       # Neither file exists, so build will fail
       Command('derived', 'leaf', 'cat &#62;$TARGET $SOURCE')
       print FindFile('leaf', '.')
       print FindFile('derived', '.')

       # Only 'leaf' exists
       Command('derived', 'leaf', 'cat &#62;$TARGET $SOURCE')
       print FindFile('leaf', '.')
       print FindFile('derived', '.')
    </PRE
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       leaf
       derived
       cat &#62; derived leaf
    </PRE
><P
>&#13;
    If a source file exists, <CODE
CLASS="function"
>FindFile</CODE
> will correctly return the name
    in the build directory.

    </P
><PRE
CLASS="programlisting"
>&#13;       # Only 'src/leaf' exists
       VariantDir('build', 'src')
       print FindFile('leaf', 'build')
    </PRE
><PRE
CLASS="screen"
>&#13;       % <KBD
CLASS="userinput"
>scons -Q</KBD
>
       build/leaf
       scons: `.' is up to date.
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4490"
>28.5. Handling Nested Lists:  the <CODE
CLASS="function"
>Flatten</CODE
> Function</A
></H2
><P
>&#13;
    <SPAN
CLASS="application"
>SCons</SPAN
> supports a <CODE
CLASS="function"
>Flatten</CODE
> function
    which takes an input Python sequence
    (list or tuple)
    and returns a flattened list
    containing just the individual elements of
    the sequence.
    This can be handy when trying to examine
    a list composed of the lists
    returned by calls to various Builders.
    For example, you might collect
    object files built in different ways
    into one call to the <CODE
CLASS="function"
>Program</CODE
> Builder
    by just enclosing them in a list, as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;      objects = [
          Object('prog1.c'),
          Object('prog2.c', CCFLAGS='-DFOO'),
      ]
      Program(objects)
    </PRE
><P
>&#13;
    Because the Builder calls in <SPAN
CLASS="application"
>SCons</SPAN
>
    flatten their input lists,
    this works just fine to build the program:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o prog1.o -c prog1.c
      cc -o prog2.o -c -DFOO prog2.c
      cc -o prog1 prog1.o prog2.o
    </PRE
><P
>&#13;
    But if you were debugging your build
    and wanted to print the absolute path
    of each object file in the
    <CODE
CLASS="varname"
>objects</CODE
> list,
    you might try the following simple approach,
    trying to print each Node's
    <TT
CLASS="literal"
>abspath</TT
>
    attribute:

    </P
><PRE
CLASS="programlisting"
>&#13;      objects = [
          Object('prog1.c'),
          Object('prog2.c', CCFLAGS='-DFOO'),
      ]
      Program(objects)

      for object_file in objects:
          print object_file.abspath
    </PRE
><P
>&#13;
    This does not work as expected
    because each call to <CODE
CLASS="function"
>str</CODE
>
    is operating an embedded list returned by
    each <CODE
CLASS="function"
>Object</CODE
> call,
    not on the underlying Nodes within those lists:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      AttributeError: NodeList instance has no attribute 'abspath':
        File "/home/my/project/SConstruct", line 8:
          print object_file.abspath
    </PRE
><P
>&#13;
    The solution is to use the <CODE
CLASS="function"
>Flatten</CODE
> function
    so that you can pass each Node to
    the <CODE
CLASS="function"
>str</CODE
> separately:

    </P
><PRE
CLASS="programlisting"
>&#13;      objects = [
          Object('prog1.c'),
          Object('prog2.c', CCFLAGS='-DFOO'),
      ]
      Program(objects)

      for object_file in Flatten(objects):
          print object_file.abspath
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      /home/me/project/prog1.o
      /home/me/project/prog2.o
      cc -o prog1.o -c prog1.c
      cc -o prog2.o -c -DFOO prog2.c
      cc -o prog1 prog1.o prog2.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4517"
>28.6. Finding the Invocation Directory:  the <CODE
CLASS="function"
>GetLaunchDir</CODE
> Function</A
></H2
><P
>&#13;
    If you need to find the directory from
    which the user invoked the <SPAN
CLASS="application"
>scons</SPAN
> command,
    you can use the <CODE
CLASS="function"
>GetLaunchDir</CODE
> function:

    </P
><PRE
CLASS="programlisting"
>&#13;      env = Environment(
          LAUNCHDIR = GetLaunchDir(),
      )
      env.Command('directory_build_info',
                  '$LAUNCHDIR/build_info'
                  Copy('$TARGET', '$SOURCE'))
    </PRE
><P
>&#13;
    Because <SPAN
CLASS="application"
>SCons</SPAN
> is usually invoked from the top-level
    directory in which the <TT
CLASS="filename"
>SConstruct</TT
> file lives,
    the Python <CODE
CLASS="function"
>os.getcwd()</CODE
>
    is often equivalent.
    However, the <SPAN
CLASS="application"
>SCons</SPAN
>
    <TT
CLASS="literal"
>-u</TT
>,
    <TT
CLASS="literal"
>-U</TT
>
    and
    <TT
CLASS="literal"
>-D</TT
>
    command-line options,
    when invoked from a subdirectory,
    will cause <SPAN
CLASS="application"
>SCons</SPAN
> to change to the directory
    in which the <TT
CLASS="filename"
>SConstruct</TT
> file is found.
    When those options are used,
    <CODE
CLASS="function"
>GetLaunchDir</CODE
> will still return the path to the
    user's invoking subdirectory,
    allowing the <TT
CLASS="filename"
>SConscript</TT
> configuration
    to still get at configuration (or other) files
    from the originating directory.

    </P
></DIV
></DIV
><DIV
CLASS="chapter"
><HR><H1
><A
NAME="chap-troubleshooting"
></A
>Chapter 29. Troubleshooting</H1
><P
>&#13;
  The experience of configuring any
  software build tool to build a large code base
  usually, at some point,
  involves trying to figure out why
  the tool is behaving a certain way,
  and how to get it to behave the way you want.
  <SPAN
CLASS="application"
>SCons</SPAN
> is no different.
  This appendix contains a number of
  different ways in which you can
  get some additional insight into <SPAN
CLASS="application"
>SCons</SPAN
>' behavior.

  </P
><P
>&#13;
  Note that we're always interested in trying to
  improve how you can troubleshoot configuration problems.
  If you run into a problem that has
  you scratching your head,
  and which there just doesn't seem to be a good way to debug,
  odds are pretty good that someone else will run into
  the same problem, too.
  If so, please let the SCons development team know
  (preferably by filing a bug report
  or feature request at our project pages at tigris.org)
  so that we can use your feedback
  to try to come up with a better way to help you,
  and others, get the necessary insight into <SPAN
CLASS="application"
>SCons</SPAN
> behavior
  to help identify and fix configuration issues.

  </P
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4543"
>29.1. Why is That Target Being Rebuilt?  the <TT
CLASS="literal"
>--debug=explain</TT
> Option</A
></H2
><P
>&#13;
    Let's look at a simple example of
    a misconfigured build
    that causes a target to be rebuilt
    every time <SPAN
CLASS="application"
>SCons</SPAN
> is run:

    </P
><PRE
CLASS="programlisting"
>&#13;      # Intentionally misspell the output file name in the
      # command used to create the file:
      Command('file.out', 'file.in', 'cp $SOURCE file.oout')
    </PRE
><P
>&#13;
    (Note to Windows users:  The POSIX <SPAN
CLASS="application"
>cp</SPAN
> command
    copies the first file named on the command line
    to the second file.
    In our example, it copies the <TT
CLASS="filename"
>file.in</TT
> file
    to the <TT
CLASS="filename"
>file.out</TT
> file.)

    </P
><P
>&#13;
    Now if we run <SPAN
CLASS="application"
>SCons</SPAN
> multiple times on this example,
    we see that it re-runs the <SPAN
CLASS="application"
>cp</SPAN
>
    command every time:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cp file.in file.oout
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cp file.in file.oout
      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cp file.in file.oout
    </PRE
><P
>&#13;
    In this example,
    the underlying cause is obvious:
    we've intentionally misspelled the output file name
    in the <SPAN
CLASS="application"
>cp</SPAN
> command,
    so the command doesn't actually
    build the <TT
CLASS="filename"
>file.out</TT
> file that we've told <SPAN
CLASS="application"
>SCons</SPAN
> to expect.
    But if the problem weren't obvious,
    it would be helpful
    to specify the <TT
CLASS="literal"
>--debug=explain</TT
> option
    on the command line
    to have <SPAN
CLASS="application"
>SCons</SPAN
> tell us very specifically
    why it's decided to rebuild the target:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --debug=explain</KBD
>
      scons: building `file.out' because it doesn't exist
      cp file.in file.oout
    </PRE
><P
>&#13;
    If this had been a more complicated example
    involving a lot of build output,
    having <SPAN
CLASS="application"
>SCons</SPAN
> tell us that
    it's trying to rebuild the target file
    because it doesn't exist
    would be an important clue
    that something was wrong with
    the command that we invoked to build it.

    </P
><P
>&#13;
    The <TT
CLASS="literal"
>--debug=explain</TT
> option also comes in handy
    to help figure out what input file changed.
    Given a simple configuration that builds
    a program from three source files,
    changing one of the source files
    and rebuilding with the <TT
CLASS="literal"
>--debug=explain</TT
>
    option shows very specifically
    why <SPAN
CLASS="application"
>SCons</SPAN
> rebuilds the files that it does:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o file1.o -c file1.c
      cc -o file2.o -c file2.c
      cc -o file3.o -c file3.c
      cc -o prog file1.o file2.o file3.o
      % <KBD
CLASS="userinput"
>edit file2.c</KBD
>
          [CHANGE THE CONTENTS OF file2.c]
      % <KBD
CLASS="userinput"
>scons -Q --debug=explain</KBD
>
      scons: rebuilding `file2.o' because `file2.c' changed
      cc -o file2.o -c file2.c
      scons: rebuilding `prog' because `file2.o' changed
      cc -o prog file1.o file2.o file3.o
    </PRE
><P
>&#13;
    This becomes even more helpful
    in identifying when a file is rebuilt
    due to a change in an implicit dependency,
    such as an incuded <TT
CLASS="filename"
>.h</TT
> file.
    If the <TT
CLASS="filename"
>file1.c</TT
>
    and <TT
CLASS="filename"
>file3.c</TT
> files
    in our example
    both included a <TT
CLASS="filename"
>hello.h</TT
> file,
    then changing that included file
    and re-running <SPAN
CLASS="application"
>SCons</SPAN
> with the <TT
CLASS="literal"
>--debug=explain</TT
> option
    will pinpoint that it's the change to the included file
    that starts the chain of rebuilds:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      cc -o file1.o -c -I. file1.c
      cc -o file2.o -c -I. file2.c
      cc -o file3.o -c -I. file3.c
      cc -o prog file1.o file2.o file3.o
      % <KBD
CLASS="userinput"
>edit hello.h</KBD
>
          [CHANGE THE CONTENTS OF hello.h]
      % <KBD
CLASS="userinput"
>scons -Q --debug=explain</KBD
>
      scons: rebuilding `file1.o' because `hello.h' changed
      cc -o file1.o -c -I. file1.c
      scons: rebuilding `file3.o' because `hello.h' changed
      cc -o file3.o -c -I. file3.c
      scons: rebuilding `prog' because:
                 `file1.o' changed
                 `file3.o' changed
      cc -o prog file1.o file2.o file3.o
    </PRE
><P
>&#13;
    (Note that the <TT
CLASS="literal"
>--debug=explain</TT
> option will only tell you
    why <SPAN
CLASS="application"
>SCons</SPAN
> decided to rebuild necessary targets.
    It does not tell you what files it examined
    when deciding <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
    to rebuild a target file,
    which is often a more valuable question to answer.)

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4593"
>29.2. What's in That Construction Environment?  the <CODE
CLASS="function"
>Dump</CODE
> Method</A
></H2
><P
>&#13;
    When you create a construction environment,
    <SPAN
CLASS="application"
>SCons</SPAN
> populates it
    with construction variables that are set up
    for various compilers, linkers and utilities
    that it finds on your system.
    Although this is usually helpful and what you want,
    it might be frustrating if <SPAN
CLASS="application"
>SCons</SPAN
>
    doesn't set certain variables that you
    expect to be set.
    In situations like this,
    it's sometimes helpful to use the
    construction environment <CODE
CLASS="function"
>Dump</CODE
> method
    to print all or some of
    the construction variables.
    Note that the <CODE
CLASS="function"
>Dump</CODE
> method
    <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>returns</I
></SPAN
>
    the representation of the variables
    in the environment
    for you to print (or otherwise manipulate):

    </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         print env.Dump()
    </PRE
><P
>&#13;
    On a POSIX system with gcc installed,
    this might generate:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      { 'BUILDERS': {'_InternalInstall': &#60;function InstallBuilderWrapper at 0x700000&#62;, '_InternalInstallAs': &#60;function InstallAsBuilderWrapper at 0x700000&#62;},
        'CONFIGUREDIR': '#/.sconf_temp',
        'CONFIGURELOG': '#/config.log',
        'CPPSUFFIXES': [ '.c',
                         '.C',
                         '.cxx',
                         '.cpp',
                         '.c++',
                         '.cc',
                         '.h',
                         '.H',
                         '.hxx',
                         '.hpp',
                         '.hh',
                         '.F',
                         '.fpp',
                         '.FPP',
                         '.m',
                         '.mm',
                         '.S',
                         '.spp',
                         '.SPP'],
        'DSUFFIXES': ['.d'],
        'Dir': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'Dirs': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'ENV': {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'},
        'ESCAPE': &#60;function escape at 0x700000&#62;,
        'File': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'IDLSUFFIXES': ['.idl', '.IDL'],
        'INSTALL': &#60;function copyFunc at 0x700000&#62;,
        'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'],
        'LIBPREFIX': 'lib',
        'LIBPREFIXES': ['$LIBPREFIX'],
        'LIBSUFFIX': '.a',
        'LIBSUFFIXES': ['$LIBSUFFIX', '$SHLIBSUFFIX'],
        'MAXLINELENGTH': 128072,
        'OBJPREFIX': '',
        'OBJSUFFIX': '.o',
        'PLATFORM': 'posix',
        'PROGPREFIX': '',
        'PROGSUFFIX': '',
        'PSPAWN': &#60;function piped_env_spawn at 0x700000&#62;,
        'RDirs': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'SCANNERS': [],
        'SHELL': 'sh',
        'SHLIBPREFIX': '$LIBPREFIX',
        'SHLIBSUFFIX': '.so',
        'SHOBJPREFIX': '$OBJPREFIX',
        'SHOBJSUFFIX': '$OBJSUFFIX',
        'SPAWN': &#60;function spawnvpe_spawn at 0x700000&#62;,
        'TEMPFILE': &#60;class SCons.Platform.TempFileMunge at 0x700000&#62;,
        'TEMPFILEPREFIX': '@',
        'TOOLS': ['install', 'install'],
        '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
        '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
        '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
        '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
        '__RPATH': '$_RPATH',
        '_concat': &#60;function _concat at 0x700000&#62;,
        '_defines': &#60;function _defines at 0x700000&#62;,
        '_stripixes': &#60;function _stripixes at 0x700000&#62;}
      scons: done reading SConscript files.
      scons: Building targets ...
      scons: `.' is up to date.
      scons: done building targets.
    </PRE
><P
>&#13;
    On a Windows system with Visual C++
    the output might look like:

    </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      { 'BUILDERS': {'_InternalInstall': &#60;function InstallBuilderWrapper at 0x700000&#62;, 'Object': &#60;SCons.Builder.CompositeBuilder instance at 0x700000&#62;, 'PCH': &#60;SCons.Builder.BuilderBase instance at 0x700000&#62;, 'RES': &#60;SCons.Builder.BuilderBase instance at 0x700000&#62;, 'SharedObject': &#60;SCons.Builder.CompositeBuilder instance at 0x700000&#62;, 'StaticObject': &#60;SCons.Builder.CompositeBuilder instance at 0x700000&#62;, '_InternalInstallAs': &#60;function InstallAsBuilderWrapper at 0x700000&#62;},
        'CC': 'cl',
        'CCCOM': &#60;SCons.Action.FunctionAction instance at 0x700000&#62;,
        'CCCOMFLAGS': '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS',
        'CCFLAGS': ['/nologo'],
        'CCPCHFLAGS': ['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'],
        'CCPDBFLAGS': ['${(PDB and "/Z7") or ""}'],
        'CFILESUFFIX': '.c',
        'CFLAGS': [],
        'CONFIGUREDIR': '#/.sconf_temp',
        'CONFIGURELOG': '#/config.log',
        'CPPDEFPREFIX': '/D',
        'CPPDEFSUFFIX': '',
        'CPPSUFFIXES': [ '.c',
                         '.C',
                         '.cxx',
                         '.cpp',
                         '.c++',
                         '.cc',
                         '.h',
                         '.H',
                         '.hxx',
                         '.hpp',
                         '.hh',
                         '.F',
                         '.fpp',
                         '.FPP',
                         '.m',
                         '.mm',
                         '.S',
                         '.spp',
                         '.SPP'],
        'CXX': '$CC',
        'CXXCOM': '$CXX $CXXFLAGS $CCCOMFLAGS',
        'CXXFILESUFFIX': '.cc',
        'CXXFLAGS': ['$CCFLAGS', '$(', '/TP', '$)'],
        'DSUFFIXES': ['.d'],
        'Dir': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'Dirs': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'ENV': { 'INCLUDE': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\include',
                 'LIB': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\lib',
                 'PATH': 'C:\\Program Files\\Microsoft Visual Studio\\Common\\tools\\WIN95;C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\bin;C:\\Program Files\\Microsoft Visual Studio\\Common\\tools;C:\\Program Files\\Microsoft Visual Studio/VC98\\bin',
                 'PATHEXT': '.COM;.EXE;.BAT;.CMD',
                 'SystemRoot': 'C:/WINDOWS'},
        'ESCAPE': &#60;function escape at 0x700000&#62;,
        'File': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'IDLSUFFIXES': ['.idl', '.IDL'],
        'INCPREFIX': '/I',
        'INCSUFFIX': '',
        'INSTALL': &#60;function copyFunc at 0x700000&#62;,
        'LATEXSUFFIXES': ['.tex', '.ltx', '.latex'],
        'LIBPREFIX': '',
        'LIBPREFIXES': ['$LIBPREFIX'],
        'LIBSUFFIX': '.lib',
        'LIBSUFFIXES': ['$LIBSUFFIX'],
        'MAXLINELENGTH': 2048,
        'MSVS': {'VERSION': '6.0', 'VERSIONS': ['6.0']},
        'MSVS_VERSION': '6.0',
        'OBJPREFIX': '',
        'OBJSUFFIX': '.obj',
        'PCHCOM': '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS',
        'PCHPDBFLAGS': ['${(PDB and "/Yd") or ""}'],
        'PLATFORM': 'win32',
        'PROGPREFIX': '',
        'PROGSUFFIX': '.exe',
        'PSPAWN': &#60;function piped_spawn at 0x700000&#62;,
        'RC': 'rc',
        'RCCOM': &#60;SCons.Action.FunctionAction instance at 0x700000&#62;,
        'RCFLAGS': [],
        'RDirs': &#60;SCons.Defaults.Variable_Method_Caller instance at 0x700000&#62;,
        'SCANNERS': [],
        'SHCC': '$CC',
        'SHCCCOM': &#60;SCons.Action.FunctionAction instance at 0x700000&#62;,
        'SHCCFLAGS': ['$CCFLAGS'],
        'SHCFLAGS': ['$CFLAGS'],
        'SHCXX': '$CXX',
        'SHCXXCOM': '$SHCXX $SHCXXFLAGS $CCCOMFLAGS',
        'SHCXXFLAGS': ['$CXXFLAGS'],
        'SHELL': None,
        'SHLIBPREFIX': '',
        'SHLIBSUFFIX': '.dll',
        'SHOBJPREFIX': '$OBJPREFIX',
        'SHOBJSUFFIX': '$OBJSUFFIX',
        'SPAWN': &#60;function spawn at 0x700000&#62;,
        'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1,
        'TEMPFILE': &#60;class SCons.Platform.TempFileMunge at 0x700000&#62;,
        'TEMPFILEPREFIX': '@',
        'TOOLS': ['msvc', 'install', 'install'],
        '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
        '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
        '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
        '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
        '_concat': &#60;function _concat at 0x700000&#62;,
        '_defines': &#60;function _defines at 0x700000&#62;,
        '_stripixes': &#60;function _stripixes at 0x700000&#62;}
      scons: done reading SConscript files.
      scons: Building targets ...
      scons: `.' is up to date.
      scons: done building targets.
    </PRE
><P
>&#13;
    The construction environments in these examples have
    actually been restricted to just gcc and Visual C++,
    respectively.
    In a real-life situation,
    the construction environments will
    likely contain a great many more variables.
    Also note that we've massaged the example output above
    to make the memory address of all objects a constant 0x700000.
    In reality, you would see a different hexadecimal
    number for each object.

    </P
><P
>&#13;
    To make it easier to see just what you're
    interested in,
    the <CODE
CLASS="function"
>Dump</CODE
> method allows you to
    specify a specific constrcution variable
    that you want to disply.
    For example,
    it's not unusual to want to verify
    the external environment used to execute build commands,
    to make sure that the PATH and other
    environment variables are set up the way they should be.
    You can do this as follows:

    </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment()
         print env.Dump('ENV')
    </PRE
><P
>&#13;
    Which might display the following when executed on a POSIX system:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}
      scons: done reading SConscript files.
      scons: Building targets ...
      scons: `.' is up to date.
      scons: done building targets.
    </PRE
><P
>&#13;
    And the following when executed on a Windows system:

    </P
><PRE
CLASS="screen"
>&#13;      C:\&#62;<KBD
CLASS="userinput"
>scons</KBD
>
      scons: Reading SConscript files ...
      { 'INCLUDE': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\include',
        'LIB': 'C:\\Program Files\\Microsoft Visual Studio/VC98\\lib',
        'PATH': 'C:\\Program Files\\Microsoft Visual Studio\\Common\\tools\\WIN95;C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\bin;C:\\Program Files\\Microsoft Visual Studio\\Common\\tools;C:\\Program Files\\Microsoft Visual Studio/VC98\\bin',
        'PATHEXT': '.COM;.EXE;.BAT;.CMD',
        'SystemRoot': 'C:/WINDOWS'}
      scons: done reading SConscript files.
      scons: Building targets ...
      scons: `.' is up to date.
      scons: done building targets.
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4619"
>29.3. What Dependencies Does <SPAN
CLASS="application"
>SCons</SPAN
> Know About?  the <TT
CLASS="literal"
>--tree</TT
> Option</A
></H2
><P
>&#13;
    Sometimes the best way to try to figure out what
    <SPAN
CLASS="application"
>SCons</SPAN
> is doing is simply to take a look at the
    dependency graph that it constructs
    based on your <TT
CLASS="filename"
>SConscript</TT
> files.
    The <TT
CLASS="literal"
>--tree</TT
> option
    will display all or part of the
    <SPAN
CLASS="application"
>SCons</SPAN
> dependency graph in an
    "ASCII art" graphical format
    that shows the dependency hierarchy.

    </P
><P
>&#13;
    For example, given the following input <TT
CLASS="filename"
>SConstruct</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(CPPPATH = ['.'])
         env.Program('prog', ['f1.c', 'f2.c', 'f3.c'])
    </PRE
><P
>&#13;
    Running <SPAN
CLASS="application"
>SCons</SPAN
> with the <TT
CLASS="literal"
>--tree=all</TT
>
    option yields:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=all</KBD
>
      cc -o f1.o -c -I. f1.c
      cc -o f2.o -c -I. f2.c
      cc -o f3.o -c -I. f3.c
      cc -o prog f1.o f2.o f3.o
      +-.
        +-SConstruct
        +-f1.c
        +-f1.o
        | +-f1.c
        | +-inc.h
        +-f2.c
        +-f2.o
        | +-f2.c
        | +-inc.h
        +-f3.c
        +-f3.o
        | +-f3.c
        | +-inc.h
        +-inc.h
        +-prog
          +-f1.o
          | +-f1.c
          | +-inc.h
          +-f2.o
          | +-f2.c
          | +-inc.h
          +-f3.o
            +-f3.c
            +-inc.h
    </PRE
><P
>&#13;
    The tree will also be printed when the
    <TT
CLASS="literal"
>-n</TT
> (no execute) option is used,
    which allows you to examine the dependency graph
    for a configuration without actually
    rebuilding anything in the tree.

    </P
><P
>&#13;
    The <TT
CLASS="literal"
>--tree</TT
> option only prints
    the dependency graph for the specified targets
    (or the default target(s) if none are specified on the command line).
    So if you specify a target like <TT
CLASS="filename"
>f2.o</TT
>
    on the command line,
    the <TT
CLASS="literal"
>--tree</TT
> option will only
    print the dependency graph for that file:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=all f2.o</KBD
>
      cc -o f2.o -c -I. f2.c
      +-f2.o
        +-f2.c
        +-inc.h
    </PRE
><P
>&#13;
    This is, of course, useful for
    restricting the output from a very large
    build configuration to just a
    portion in which you're interested.
    Multiple targets are fine,
    in which case a tree will be printed
    for each specified target:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=all f1.o f3.o</KBD
>
      cc -o f1.o -c -I. f1.c
      +-f1.o
        +-f1.c
        +-inc.h
      cc -o f3.o -c -I. f3.c
      +-f3.o
        +-f3.c
        +-inc.h
    </PRE
><P
>&#13;
    The <TT
CLASS="literal"
>status</TT
> argument may be used
    to tell <SPAN
CLASS="application"
>SCons</SPAN
> to print status information about
    each file in the dependency graph:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=status</KBD
>
      cc -o f1.o -c -I. f1.c
      cc -o f2.o -c -I. f2.c
      cc -o f3.o -c -I. f3.c
      cc -o prog f1.o f2.o f3.o
       E         = exists
        R        = exists in repository only
         b       = implicit builder
         B       = explicit builder
          S      = side effect
           P     = precious
            A    = always build
             C   = current
              N  = no clean
               H = no cache
      
      [E b      ]+-.
      [E     C  ]  +-SConstruct
      [E     C  ]  +-f1.c
      [E B   C  ]  +-f1.o
      [E     C  ]  | +-f1.c
      [E     C  ]  | +-inc.h
      [E     C  ]  +-f2.c
      [E B   C  ]  +-f2.o
      [E     C  ]  | +-f2.c
      [E     C  ]  | +-inc.h
      [E     C  ]  +-f3.c
      [E B   C  ]  +-f3.o
      [E     C  ]  | +-f3.c
      [E     C  ]  | +-inc.h
      [E     C  ]  +-inc.h
      [E B   C  ]  +-prog
      [E B   C  ]    +-f1.o
      [E     C  ]    | +-f1.c
      [E     C  ]    | +-inc.h
      [E B   C  ]    +-f2.o
      [E     C  ]    | +-f2.c
      [E     C  ]    | +-inc.h
      [E B   C  ]    +-f3.o
      [E     C  ]      +-f3.c
      [E     C  ]      +-inc.h
    </PRE
><P
>&#13;
    Note that <TT
CLASS="literal"
>--tree=all,status</TT
> is equivalent;
    the <TT
CLASS="literal"
>all</TT
>
    is assumed if only <TT
CLASS="literal"
>status</TT
> is present.
    As an alternative to <TT
CLASS="literal"
>all</TT
>,
    you can specify <TT
CLASS="literal"
>--tree=derived</TT
>
    to have <SPAN
CLASS="application"
>SCons</SPAN
> only print derived targets
    in the tree output,
    skipping source files
    (like <TT
CLASS="filename"
>.c</TT
> and <TT
CLASS="filename"
>.h</TT
> files):

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=derived</KBD
>
      cc -o f1.o -c -I. f1.c
      cc -o f2.o -c -I. f2.c
      cc -o f3.o -c -I. f3.c
      cc -o prog f1.o f2.o f3.o
      +-.
        +-f1.o
        +-f2.o
        +-f3.o
        +-prog
          +-f1.o
          +-f2.o
          +-f3.o
    </PRE
><P
>&#13;
    You can use the <TT
CLASS="literal"
>status</TT
>
    modifier with <TT
CLASS="literal"
>derived</TT
> as well:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=derived,status</KBD
>
      cc -o f1.o -c -I. f1.c
      cc -o f2.o -c -I. f2.c
      cc -o f3.o -c -I. f3.c
      cc -o prog f1.o f2.o f3.o
       E         = exists
        R        = exists in repository only
         b       = implicit builder
         B       = explicit builder
          S      = side effect
           P     = precious
            A    = always build
             C   = current
              N  = no clean
               H = no cache
      
      [E b      ]+-.
      [E B   C  ]  +-f1.o
      [E B   C  ]  +-f2.o
      [E B   C  ]  +-f3.o
      [E B   C  ]  +-prog
      [E B   C  ]    +-f1.o
      [E B   C  ]    +-f2.o
      [E B   C  ]    +-f3.o
    </PRE
><P
>&#13;
    Note that the order of the <TT
CLASS="literal"
>--tree=</TT
>
    arguments doesn't matter;
    <TT
CLASS="literal"
>--tree=status,derived</TT
> is
    completely equivalent.

    </P
><P
>&#13;
    The default behavior of the <TT
CLASS="literal"
>--tree</TT
> option
    is to repeat all of the dependencies each time the library dependency
    (or any other dependency file) is encountered in the tree.
    If certain target files share other target files,
    such as two programs that use the same library:

    </P
><PRE
CLASS="programlisting"
>&#13;         env = Environment(CPPPATH = ['.'],
                           LIBS = ['foo'],
                           LIBPATH = ['.'])
         env.Library('foo', ['f1.c', 'f2.c', 'f3.c'])
         env.Program('prog1.c')
         env.Program('prog2.c')
    </PRE
><P
>&#13;
    Then there can be a <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>lot</I
></SPAN
> of repetition in the
    <TT
CLASS="literal"
>--tree=</TT
> output:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=all</KBD
>
      cc -o f1.o -c -I. f1.c
      cc -o f2.o -c -I. f2.c
      cc -o f3.o -c -I. f3.c
      ar rc libfoo.a f1.o f2.o f3.o
      ranlib libfoo.a
      cc -o prog1.o -c -I. prog1.c
      cc -o prog1 prog1.o -L. -lfoo
      cc -o prog2.o -c -I. prog2.c
      cc -o prog2 prog2.o -L. -lfoo
      +-.
        +-SConstruct
        +-f1.c
        +-f1.o
        | +-f1.c
        | +-inc.h
        +-f2.c
        +-f2.o
        | +-f2.c
        | +-inc.h
        +-f3.c
        +-f3.o
        | +-f3.c
        | +-inc.h
        +-inc.h
        +-libfoo.a
        | +-f1.o
        | | +-f1.c
        | | +-inc.h
        | +-f2.o
        | | +-f2.c
        | | +-inc.h
        | +-f3.o
        |   +-f3.c
        |   +-inc.h
        +-prog1
        | +-prog1.o
        | | +-prog1.c
        | | +-inc.h
        | +-libfoo.a
        |   +-f1.o
        |   | +-f1.c
        |   | +-inc.h
        |   +-f2.o
        |   | +-f2.c
        |   | +-inc.h
        |   +-f3.o
        |     +-f3.c
        |     +-inc.h
        +-prog1.c
        +-prog1.o
        | +-prog1.c
        | +-inc.h
        +-prog2
        | +-prog2.o
        | | +-prog2.c
        | | +-inc.h
        | +-libfoo.a
        |   +-f1.o
        |   | +-f1.c
        |   | +-inc.h
        |   +-f2.o
        |   | +-f2.c
        |   | +-inc.h
        |   +-f3.o
        |     +-f3.c
        |     +-inc.h
        +-prog2.c
        +-prog2.o
          +-prog2.c
          +-inc.h
    </PRE
><P
>&#13;
    In a large configuration with many internal libraries
    and include files,
    this can very quickly lead to huge output trees.
    To help make this more manageable,
    a <TT
CLASS="literal"
>prune</TT
> modifier may
    be added to the option list,
    in which case <SPAN
CLASS="application"
>SCons</SPAN
>
    will print the name of a target that has
    already been visited during the tree-printing
    in <TT
CLASS="literal"
>[square brackets]</TT
>
    as an indication that the dependencies
    of the target file may be found
    by looking farther up the tree:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --tree=prune</KBD
>
      cc -o f1.o -c -I. f1.c
      cc -o f2.o -c -I. f2.c
      cc -o f3.o -c -I. f3.c
      ar rc libfoo.a f1.o f2.o f3.o
      ranlib libfoo.a
      cc -o prog1.o -c -I. prog1.c
      cc -o prog1 prog1.o -L. -lfoo
      cc -o prog2.o -c -I. prog2.c
      cc -o prog2 prog2.o -L. -lfoo
      +-.
        +-SConstruct
        +-f1.c
        +-f1.o
        | +-f1.c
        | +-inc.h
        +-f2.c
        +-f2.o
        | +-f2.c
        | +-inc.h
        +-f3.c
        +-f3.o
        | +-f3.c
        | +-inc.h
        +-inc.h
        +-libfoo.a
        | +-[f1.o]
        | +-[f2.o]
        | +-[f3.o]
        +-prog1
        | +-prog1.o
        | | +-prog1.c
        | | +-inc.h
        | +-[libfoo.a]
        +-prog1.c
        +-[prog1.o]
        +-prog2
        | +-prog2.o
        | | +-prog2.c
        | | +-inc.h
        | +-[libfoo.a]
        +-prog2.c
        +-[prog2.o]
    </PRE
><P
>&#13;
    Like the <TT
CLASS="literal"
>status</TT
> keyword,
    the <TT
CLASS="literal"
>prune</TT
> argument by itself
    is equivalent to <TT
CLASS="literal"
>--tree=all,prune</TT
>.

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4689"
>29.4. How is <SPAN
CLASS="application"
>SCons</SPAN
> Constructing the Command Lines It Executes?  the <TT
CLASS="literal"
>--debug=presub</TT
> Option</A
></H2
><P
>&#13;
    Sometimes it's useful to look at the
    pre-substitution string
    that <SPAN
CLASS="application"
>SCons</SPAN
> uses to generate
    the command lines it executes.
    This can be done with the <TT
CLASS="literal"
>--debug=presub</TT
> option:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --debug=presub</KBD
>
      Building prog.o with action:
        $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCOMCOM $SOURCES
      cc -o prog.o -c -I. prog.c
      Building prog with action:
        $SMART_LINKCOM
      cc -o prog prog.o
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4698"
>29.5. Where is <SPAN
CLASS="application"
>SCons</SPAN
> Searching for Libraries?  the <TT
CLASS="literal"
>--debug=findlibs</TT
> Option</A
></H2
><P
>&#13;
    To get some insight into what library names
    <SPAN
CLASS="application"
>SCons</SPAN
> is searching for,
    and in which directories it is searching,
    Use the <TT
CLASS="literal"
>--debug=findlibs</TT
> option.
    Given the following input <TT
CLASS="filename"
>SConstruct</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;        env = Environment(LIBPATH = ['libs1', 'libs2'])
        env.Program('prog.c', LIBS=['foo', 'bar'])
    </PRE
><P
>&#13;
    And the libraries <TT
CLASS="filename"
>libfoo.a</TT
>
    and <TT
CLASS="filename"
>libbar.a</TT
>
    in <TT
CLASS="filename"
>libs1</TT
> and <TT
CLASS="filename"
>libs2</TT
>,
    respectively,
    use of the <TT
CLASS="literal"
>--debug=findlibs</TT
> option yields:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --debug=findlibs</KBD
>
        findlibs: looking for 'libfoo.a' in 'libs1' ...
        findlibs: ... FOUND 'libfoo.a' in 'libs1'
        findlibs: looking for 'libfoo.so' in 'libs1' ...
        findlibs: looking for 'libfoo.so' in 'libs2' ...
        findlibs: looking for 'libbar.a' in 'libs1' ...
        findlibs: looking for 'libbar.a' in 'libs2' ...
        findlibs: ... FOUND 'libbar.a' in 'libs2'
        findlibs: looking for 'libbar.so' in 'libs1' ...
        findlibs: looking for 'libbar.so' in 'libs2' ...
      cc -o prog.o -c prog.c
      cc -o prog prog.o -Llibs1 -Llibs2 -lfoo -lbar
    </PRE
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4715"
>29.6. Where is <SPAN
CLASS="application"
>SCons</SPAN
> Blowing Up?  the <TT
CLASS="literal"
>--debug=stacktrace</TT
> Option</A
></H2
><P
>&#13;
    In general, <SPAN
CLASS="application"
>SCons</SPAN
> tries to keep its error
    messages short and informative.
    That means we usually try to avoid showing
    the stack traces that are familiar
    to experienced Python programmers,
    since they usually contain much more
    information than is useful to most people.

    </P
><P
>&#13;
    For example, the following <TT
CLASS="filename"
>SConstruct</TT
> file:

    </P
><PRE
CLASS="programlisting"
>&#13;         Program('prog.c')
    </PRE
><P
>&#13;
    Generates the following error if the
    <TT
CLASS="filename"
>prog.c</TT
> file
    does not exist:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q</KBD
>
      scons: *** Source `prog.c' not found, needed by target `prog.o'.  Stop.
    </PRE
><P
>&#13;
    In this case,
    the error is pretty obvious.
    But if it weren't,
    and you wanted to try to get more information
    about the error,
    the <TT
CLASS="literal"
>--debug=stacktrace</TT
> option
    would show you exactly where in the <SPAN
CLASS="application"
>SCons</SPAN
> source code
    the problem occurs:

    </P
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --debug=stacktrace</KBD
>
      scons: *** Source `prog.c' not found, needed by target `prog.o'.  Stop.
      scons: internal stack trace:
        File "bootstrap/src/engine/SCons/Job.py", line 198, in start
        File "bootstrap/src/engine/SCons/Script/Main.py", line 169, in prepare
        File "bootstrap/src/engine/SCons/Taskmaster.py", line 184, in prepare
        File "bootstrap/src/engine/SCons/Executor.py", line 171, in prepare
    </PRE
><P
>&#13;
    Of course, if you do need to dive into the <SPAN
CLASS="application"
>SCons</SPAN
> source code,
    we'd like to know if, or how,
    the error messages or troubleshooting options
    could have been improved to avoid that.
    Not everyone has the necessary time or
    Python skill to dive into the source code,
    and we'd like to improve <SPAN
CLASS="application"
>SCons</SPAN
>
    for those people as well...

    </P
></DIV
><DIV
CLASS="section"
><HR><H2
CLASS="section"
><A
NAME="AEN4736"
>29.7. How is <SPAN
CLASS="application"
>SCons</SPAN
> Making Its Decisions?  the <TT
CLASS="literal"
>--taskmastertrace</TT
> Option</A
></H2
><P
>&#13;
    The internal <SPAN
CLASS="application"
>SCons</SPAN
> subsystem that handles walking
    the dependency graph
    and controls the decision-making about what to rebuild
    is the <TT
CLASS="literal"
>Taskmaster</TT
>.
    <SPAN
CLASS="application"
>SCons</SPAN
> supports a <TT
CLASS="literal"
>--taskmastertrace</TT
>
    option that tells the Taskmaster to print
    information about the children (dependencies)
    of the various Nodes on its walk down the graph,
    which specific dependent Nodes are being evaluated,
    and in what order.

    </P
><P
>&#13;
    The <TT
CLASS="literal"
>--taskmastertrace</TT
> option
    takes as an argument the name of a file in
    which to put the trace output,
    with <TT
CLASS="filename"
>-</TT
> (a single hyphen)
    indicating that the trace messages
    should be printed to the standard output:

    </P
><PRE
CLASS="programlisting"
>&#13;      env = Environment(CPPPATH = ['.'])
      env.Program('prog.c')
    </PRE
><PRE
CLASS="screen"
>&#13;      % <KBD
CLASS="userinput"
>scons -Q --taskmastertrace=- prog</KBD
>
      
      Taskmaster: Looking for a node to evaluate
      Taskmaster:     Considering node &#60;no_state   0   'prog'&#62; and its children:
      Taskmaster:        &#60;no_state   0   'prog.o'&#62;
      Taskmaster:      adjusting ref count: &#60;pending    1   'prog'&#62;
      Taskmaster:     Considering node &#60;no_state   0   'prog.o'&#62; and its children:
      Taskmaster:        &#60;no_state   0   'prog.c'&#62;
      Taskmaster:        &#60;no_state   0   'inc.h'&#62;
      Taskmaster:      adjusting ref count: &#60;pending    1   'prog.o'&#62;
      Taskmaster:      adjusting ref count: &#60;pending    2   'prog.o'&#62;
      Taskmaster:     Considering node &#60;no_state   0   'prog.c'&#62; and its children:
      Taskmaster: Evaluating &#60;pending    0   'prog.c'&#62;
      
      Taskmaster: Looking for a node to evaluate
      Taskmaster:     Considering node &#60;no_state   0   'inc.h'&#62; and its children:
      Taskmaster: Evaluating &#60;pending    0   'inc.h'&#62;
      
      Taskmaster: Looking for a node to evaluate
      Taskmaster:     Considering node &#60;pending    0   'prog.o'&#62; and its children:
      Taskmaster:        &#60;up_to_date 0   'prog.c'&#62;
      Taskmaster:        &#60;up_to_date 0   'inc.h'&#62;
      Taskmaster: Evaluating &#60;pending    0   'prog.o'&#62;
      cc -o prog.o -c -I. prog.c
      
      Taskmaster: Looking for a node to evaluate
      Taskmaster:     Considering node &#60;pending    0   'prog'&#62; and its children:
      Taskmaster:        &#60;executed   0   'prog.o'&#62;
      Taskmaster: Evaluating &#60;pending    0   'prog'&#62;
      cc -o prog prog.o
      
      Taskmaster: Looking for a node to evaluate
      Taskmaster: No candidate anymore.
    </PRE
><P
>&#13;
    The <TT
CLASS="literal"
>--taskmastertrace</TT
> option
    doesn't provide information about the actual
    calculations involved in deciding if a file is up-to-date,
    but it does show all of the dependencies
    it knows about for each Node,
    and the order in which those dependencies are evaluated.
    This can be useful as an alternate way to determine
    whether or not your <SPAN
CLASS="application"
>SCons</SPAN
> configuration,
    or the implicit dependency scan,
    has actually identified all the correct dependencies
    you want it to.

    </P
></DIV
></DIV
><DIV
CLASS="appendix"
><HR><H1
><A
NAME="app-variables"
></A
>Appendix A. Construction Variables</H1
><P
>&#13;
This appendix contains descriptions of all of the
construction variables that are <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>potentially</I
></SPAN
>
available "out of the box" in this version of SCons.
Whether or not setting a construction variable
in a construction environment
will actually have an effect depends on
whether any of the Tools and/or Builders
that use the variable have been
included in the construction environment.

</P
><P
>&#13;
In this appendix, we have
appended the initial <CODE
CLASS="envar"
>$</CODE
>
(dollar sign) to the beginning of each
variable name when it appears in the text,
but left off the dollar sign
in the left-hand column
where the name appears for each entry.

</P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
><A
NAME="cv-AR"
></A
><CODE
CLASS="envar"
>AR</CODE
></DT
><DD
><P
>&#13;The static library archiver.
</P
></DD
><DT
><A
NAME="cv-ARCHITECTURE"
></A
><CODE
CLASS="envar"
>ARCHITECTURE</CODE
></DT
><DD
><P
>&#13;Specifies the system architecture for which
the package is being built.
The default is the system architecture
of the machine on which SCons is running.
This is used to fill in the
<TT
CLASS="literal"
>Architecture:</TT
>
field in an Ipkg
<TT
CLASS="filename"
>control</TT
> file,
and as part of the name of a generated RPM file.
</P
></DD
><DT
><A
NAME="cv-ARCOM"
></A
><CODE
CLASS="envar"
>ARCOM</CODE
></DT
><DD
><P
>&#13;The command line used to generate a static library from object files.
</P
></DD
><DT
><A
NAME="cv-ARCOMSTR"
></A
><CODE
CLASS="envar"
>ARCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when an object file
is generated from an assembly-language source file.
If this is not set, then <A
HREF="#cv-ARCOM"
><CODE
CLASS="envar"
>$ARCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(ARCOMSTR = "Archiving $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-ARFLAGS"
></A
><CODE
CLASS="envar"
>ARFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the static library archiver.
</P
></DD
><DT
><A
NAME="cv-AS"
></A
><CODE
CLASS="envar"
>AS</CODE
></DT
><DD
><P
>&#13;The assembler.
</P
></DD
><DT
><A
NAME="cv-ASCOM"
></A
><CODE
CLASS="envar"
>ASCOM</CODE
></DT
><DD
><P
>&#13;The command line used to generate an object file
from an assembly-language source file.
</P
></DD
><DT
><A
NAME="cv-ASCOMSTR"
></A
><CODE
CLASS="envar"
>ASCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when an object file
is generated from an assembly-language source file.
If this is not set, then <A
HREF="#cv-ASCOM"
><CODE
CLASS="envar"
>$ASCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(ASCOMSTR = "Assembling $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-ASFLAGS"
></A
><CODE
CLASS="envar"
>ASFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the assembler.
</P
></DD
><DT
><A
NAME="cv-ASPPCOM"
></A
><CODE
CLASS="envar"
>ASPPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to assemble an assembly-language
source file into an object file
after first running the file through the C preprocessor.
Any options specified
in the <A
HREF="#cv-ASFLAGS"
><CODE
CLASS="envar"
>$ASFLAGS</CODE
></A
> and <A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
> construction variables
are included on this command line.
</P
></DD
><DT
><A
NAME="cv-ASPPCOMSTR"
></A
><CODE
CLASS="envar"
>ASPPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when an object file
is generated from an assembly-language source file
after first running the file through the C preprocessor.
If this is not set, then <A
HREF="#cv-ASPPCOM"
><CODE
CLASS="envar"
>$ASPPCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(ASPPCOMSTR = "Assembling $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-ASPPFLAGS"
></A
><CODE
CLASS="envar"
>ASPPFLAGS</CODE
></DT
><DD
><P
>&#13;General options when an assembling an assembly-language
source file into an object file
after first running the file through the C preprocessor.
The default is to use the value of <A
HREF="#cv-ASFLAGS"
><CODE
CLASS="envar"
>$ASFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-BIBTEX"
></A
><CODE
CLASS="envar"
>BIBTEX</CODE
></DT
><DD
><P
>&#13;The bibliography generator for the TeX formatter and typesetter and the
LaTeX structured formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-BIBTEXCOM"
></A
><CODE
CLASS="envar"
>BIBTEXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the bibliography generator for the
TeX formatter and typesetter and the LaTeX structured formatter and
typesetter.
</P
></DD
><DT
><A
NAME="cv-BIBTEXCOMSTR"
></A
><CODE
CLASS="envar"
>BIBTEXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when generating a bibliography
for TeX or LaTeX.
If this is not set, then <A
HREF="#cv-BIBTEXCOM"
><CODE
CLASS="envar"
>$BIBTEXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(BIBTEXCOMSTR = "Generating bibliography $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-BIBTEXFLAGS"
></A
><CODE
CLASS="envar"
>BIBTEXFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the bibliography generator for the TeX formatter
and typesetter and the LaTeX structured formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-BITKEEPER"
></A
><CODE
CLASS="envar"
>BITKEEPER</CODE
></DT
><DD
><P
>&#13;The BitKeeper executable.
</P
></DD
><DT
><A
NAME="cv-BITKEEPERCOM"
></A
><CODE
CLASS="envar"
>BITKEEPERCOM</CODE
></DT
><DD
><P
>&#13;The command line for
fetching source files using BitKeeper.
</P
></DD
><DT
><A
NAME="cv-BITKEEPERCOMSTR"
></A
><CODE
CLASS="envar"
>BITKEEPERCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when fetching
a source file using BitKeeper.
If this is not set, then <A
HREF="#cv-BITKEEPERCOM"
><CODE
CLASS="envar"
>$BITKEEPERCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-BITKEEPERGET"
></A
><CODE
CLASS="envar"
>BITKEEPERGET</CODE
></DT
><DD
><P
>&#13;The command (<A
HREF="#cv-BITKEEPER"
><CODE
CLASS="envar"
>$BITKEEPER</CODE
></A
>) and subcommand
for fetching source files using BitKeeper.
</P
></DD
><DT
><A
NAME="cv-BITKEEPERGETFLAGS"
></A
><CODE
CLASS="envar"
>BITKEEPERGETFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the BitKeeper
<B
CLASS="command"
>get</B
>
subcommand.
</P
></DD
><DT
><A
NAME="cv-BUILDERS"
></A
><CODE
CLASS="envar"
>BUILDERS</CODE
></DT
><DD
><P
>&#13;A dictionary mapping the names of the builders
available through this environment
to underlying Builder objects.
Builders named
Alias, CFile, CXXFile, DVI, Library, Object, PDF, PostScript, and Program
are available by default.
If you initialize this variable when an
Environment is created:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(BUILDERS = {'NewBuilder' : foo})
</PRE
><P
>&#13;the default Builders will no longer be available.
To use a new Builder object in addition to the default Builders,
add your new Builder object like this:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment()
env.Append(BUILDERS = {'NewBuilder' : foo})
</PRE
><P
>&#13;or this:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment()
env['BUILDERS]['NewBuilder'] = foo
</PRE
></DD
><DT
><A
NAME="cv-CC"
></A
><CODE
CLASS="envar"
>CC</CODE
></DT
><DD
><P
>&#13;The C compiler.
</P
></DD
><DT
><A
NAME="cv-CCCOM"
></A
><CODE
CLASS="envar"
>CCCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a C source file to a (static) object
file.  Any options specified in the <A
HREF="#cv-CFLAGS"
><CODE
CLASS="envar"
>$CFLAGS</CODE
></A
>, <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
> and
<A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
> construction variables are included on this command
line.
</P
></DD
><DT
><A
NAME="cv-CCCOMSTR"
></A
><CODE
CLASS="envar"
>CCCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a C source file
is compiled to a (static) object file.
If this is not set, then <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(CCCOMSTR = "Compiling static object $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-CCFLAGS"
></A
><CODE
CLASS="envar"
>CCFLAGS</CODE
></DT
><DD
><P
>&#13;General options that are passed to the C and C++ compilers.
</P
></DD
><DT
><A
NAME="cv-CCPCHFLAGS"
></A
><CODE
CLASS="envar"
>CCPCHFLAGS</CODE
></DT
><DD
><P
>&#13;Options added to the compiler command line
to support building with precompiled headers.
The default value expands expands to the appropriate
Microsoft Visual C++ command-line options
when the <A
HREF="#cv-PCH"
><CODE
CLASS="envar"
>$PCH</CODE
></A
> construction variable is set.
</P
></DD
><DT
><A
NAME="cv-CCPDBFLAGS"
></A
><CODE
CLASS="envar"
>CCPDBFLAGS</CODE
></DT
><DD
><P
>&#13;Options added to the compiler command line
to support storing debugging information in a
Microsoft Visual C++ PDB file.
The default value expands expands to appropriate
Microsoft Visual C++ command-line options
when the <A
HREF="#cv-PDB"
><CODE
CLASS="envar"
>$PDB</CODE
></A
> construction variable is set.</P
><P
>The Visual C++ compiler option that SCons uses by default
to generate PDB information is <CODE
CLASS="option"
>/Z7</CODE
>.
This works correctly with parallel (<CODE
CLASS="option"
>-j</CODE
>) builds
because it embeds the debug information in the intermediate object files,
as opposed to sharing a single PDB file between multiple object files.
This is also the only way to get debug information
embedded into a static library.
Using the <CODE
CLASS="option"
>/Zi</CODE
> instead may yield improved
link-time performance,
although parallel builds will no longer work.</P
><P
>You can generate PDB files with the <CODE
CLASS="option"
>/Zi</CODE
>
switch by overriding the default <A
HREF="#cv-CCPDBFLAGS"
><CODE
CLASS="envar"
>$CCPDBFLAGS</CODE
></A
> variable as follows:
</P
><PRE
CLASS="programlisting"
>&#13;env['CCPDBFLAGS'] = ['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}']
</PRE
><P
>&#13;An alternative would be to use the <CODE
CLASS="option"
>/Zi</CODE
>
to put the debugging information in a separate <TT
CLASS="filename"
>.pdb</TT
>
file for each object file by overriding
the <A
HREF="#cv-CCPDBFLAGS"
><CODE
CLASS="envar"
>$CCPDBFLAGS</CODE
></A
> variable as follows:
</P
><PRE
CLASS="programlisting"
>&#13;env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
</PRE
></DD
><DT
><A
NAME="cv-CCVERSION"
></A
><CODE
CLASS="envar"
>CCVERSION</CODE
></DT
><DD
><P
>&#13;The version number of the C compiler.
This may or may not be set,
depending on the specific C compiler being used.
</P
></DD
><DT
><A
NAME="cv-CFILESUFFIX"
></A
><CODE
CLASS="envar"
>CFILESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix for C source files.
This is used by the internal CFile builder
when generating C files from Lex (.l) or YACC (.y) input files.
The default suffix, of course, is
<TT
CLASS="filename"
>.c</TT
>
(lower case).
On case-insensitive systems (like Windows),
SCons also treats
<TT
CLASS="filename"
>.C</TT
>
(upper case) files
as C files.
</P
></DD
><DT
><A
NAME="cv-CFLAGS"
></A
><CODE
CLASS="envar"
>CFLAGS</CODE
></DT
><DD
><P
>&#13;General options that are passed to the C compiler (C only; not C++).
</P
></DD
><DT
><A
NAME="cv-CHANGE_SPECFILE"
></A
><CODE
CLASS="envar"
>CHANGE_SPECFILE</CODE
></DT
><DD
><P
>&#13;A hook for modifying the file that controls the packaging build
(the <TT
CLASS="filename"
>.spec</TT
> for RPM,
the <TT
CLASS="filename"
>control</TT
> for Ipkg,
the <TT
CLASS="filename"
>.wxs</TT
> for MSI).
If set, the function will be called
after the SCons template for the file has been written.
XXX
</P
></DD
><DT
><A
NAME="cv-CHANGELOG"
></A
><CODE
CLASS="envar"
>CHANGELOG</CODE
></DT
><DD
><P
>&#13;The name of a file containing the change log text
to be included in the package.
This is included as the
<TT
CLASS="literal"
>%changelog</TT
>
section of the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-_concat"
></A
><CODE
CLASS="envar"
>_concat</CODE
></DT
><DD
><P
>&#13;A function used to produce variables like <CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
>. It takes
four or five
arguments: a prefix to concatenate onto each element, a list of
elements, a suffix to concatenate onto each element, an environment
for variable interpolation, and an optional function that will be
called to transform the list before concatenation.
</P
><PRE
CLASS="programlisting"
>&#13;env['_CPPINCFLAGS'] = '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs)} $)',
</PRE
></DD
><DT
><A
NAME="cv-CONFIGUREDIR"
></A
><CODE
CLASS="envar"
>CONFIGUREDIR</CODE
></DT
><DD
><P
>&#13;The name of the directory in which
Configure context test files are written.
The default is
<TT
CLASS="filename"
>.sconf_temp</TT
>
in the top-level directory
containing the
<TT
CLASS="filename"
>SConstruct</TT
>
file.
</P
></DD
><DT
><A
NAME="cv-CONFIGURELOG"
></A
><CODE
CLASS="envar"
>CONFIGURELOG</CODE
></DT
><DD
><P
>&#13;The name of the Configure context log file.
The default is
<TT
CLASS="filename"
>config.log</TT
>
in the top-level directory
containing the
<TT
CLASS="filename"
>SConstruct</TT
>
file.
</P
></DD
><DT
><A
NAME="cv-_CPPDEFFLAGS"
></A
><CODE
CLASS="envar"
>_CPPDEFFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the C preprocessor command-line options
to define values.
The value of <CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
> is created
by appending <CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
> and <CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
>
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$CPPDEFINES</CODE
>.
</P
></DD
><DT
><A
NAME="cv-CPPDEFINES"
></A
><CODE
CLASS="envar"
>CPPDEFINES</CODE
></DT
><DD
><P
>&#13;A platform independent specification of C preprocessor definitions.
The definitions will be added to command lines
through the automatically-generated
<CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
> construction variable (see above),
which is constructed according to
the type of value of <CODE
CLASS="envar"
>$CPPDEFINES</CODE
>:</P
><P
>If <CODE
CLASS="envar"
>$CPPDEFINES</CODE
> is a string,
the values of the
<CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
> and <CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
>
construction variables
will be added to the beginning and end.
</P
><PRE
CLASS="programlisting"
>&#13;# Will add -Dxyz to POSIX compiler command lines,
# and /Dxyz to Microsoft Visual C++ command lines.
env = Environment(CPPDEFINES='xyz')
</PRE
><P
>&#13;If <CODE
CLASS="envar"
>$CPPDEFINES</CODE
> is a list,
the values of the
<CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
> and <CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
>
construction variables
will be appended to the beginning and end
of each element in the list.
If any element is a list or tuple,
then the first item is the name being
defined and the second item is its value:
</P
><PRE
CLASS="programlisting"
>&#13;# Will add -DB=2 -DA to POSIX compiler command lines,
# and /DB=2 /DA to Microsoft Visual C++ command lines.
env = Environment(CPPDEFINES=[('B', 2), 'A'])
</PRE
><P
>&#13;If <CODE
CLASS="envar"
>$CPPDEFINES</CODE
> is a dictionary,
the values of the
<CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
> and <CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
>
construction variables
will be appended to the beginning and end
of each item from the dictionary.
The key of each dictionary item
is a name being defined
to the dictionary item's corresponding value;
if the value is
<TT
CLASS="literal"
>None</TT
>,
then the name is defined without an explicit value.
Note that the resulting flags are sorted by keyword
to ensure that the order of the options on the
command line is consistent each time
<SPAN
CLASS="application"
>scons</SPAN
>
is run.
</P
><PRE
CLASS="programlisting"
>&#13;# Will add -DA -DB=2 to POSIX compiler command lines,
# and /DA /DB=2 to Microsoft Visual C++ command lines.
env = Environment(CPPDEFINES={'B':2, 'A':None})
</PRE
></DD
><DT
><A
NAME="cv-CPPDEFPREFIX"
></A
><CODE
CLASS="envar"
>CPPDEFPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used to specify preprocessor definitions
on the C compiler command line.
This will be appended to the beginning of each definition
in the <CODE
CLASS="envar"
>$CPPDEFINES</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-CPPDEFSUFFIX"
></A
><CODE
CLASS="envar"
>CPPDEFSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify preprocessor definitions
on the C compiler command line.
This will be appended to the end of each definition
in the <CODE
CLASS="envar"
>$CPPDEFINES</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-CPPFLAGS"
></A
><CODE
CLASS="envar"
>CPPFLAGS</CODE
></DT
><DD
><P
>&#13;User-specified C preprocessor options.
These will be included in any command that uses the C preprocessor,
including not just compilation of C and C++ source files
via the <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
>,
<A
HREF="#cv-SHCCCOM"
><CODE
CLASS="envar"
>$SHCCCOM</CODE
></A
>,
<A
HREF="#cv-CXXCOM"
><CODE
CLASS="envar"
>$CXXCOM</CODE
></A
> and
<A
HREF="#cv-SHCXXCOM"
><CODE
CLASS="envar"
>$SHCXXCOM</CODE
></A
> command lines,
but also the <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
>,
<A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>,
<A
HREF="#cv-F77PPCOM"
><CODE
CLASS="envar"
>$F77PPCOM</CODE
></A
> and
<A
HREF="#cv-SHF77PPCOM"
><CODE
CLASS="envar"
>$SHF77PPCOM</CODE
></A
> command lines
used to compile a Fortran source file,
and the <A
HREF="#cv-ASPPCOM"
><CODE
CLASS="envar"
>$ASPPCOM</CODE
></A
> command line
used to assemble an assembly language source file,
after first running each file through the C preprocessor.
Note that this variable does
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
contain
<CODE
CLASS="option"
>-I</CODE
>
(or similar) include search path options
that scons generates automatically from <A
HREF="#cv-CPPPATH"
><CODE
CLASS="envar"
>$CPPPATH</CODE
></A
>.
See <A
HREF="#cv-_CPPINCFLAGS"
><CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
></A
>, below,
for the variable that expands to those options.
</P
></DD
><DT
><A
NAME="cv-_CPPINCFLAGS"
></A
><CODE
CLASS="envar"
>_CPPINCFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the C preprocessor command-line options
for specifying directories to be searched for include files.
The value of <CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
> is created
by appending <CODE
CLASS="envar"
>$INCPREFIX</CODE
> and <CODE
CLASS="envar"
>$INCSUFFIX</CODE
>
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$CPPPATH</CODE
>.
</P
></DD
><DT
><A
NAME="cv-CPPPATH"
></A
><CODE
CLASS="envar"
>CPPPATH</CODE
></DT
><DD
><P
>&#13;The list of directories that the C preprocessor will search for include
directories. The C/C++ implicit dependency scanner will search these
directories for include files. Don't explicitly put include directory
arguments in CCFLAGS or CXXFLAGS because the result will be non-portable
and the directories will not be searched by the dependency scanner. Note:
directory names in CPPPATH will be looked-up relative to the SConscript
directory when they are used in a command. To force
<SPAN
CLASS="application"
>scons</SPAN
>
to look-up a directory relative to the root of the source tree use #:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(CPPPATH='#/include')
</PRE
><P
>&#13;The directory look-up can also be forced using the
<CODE
CLASS="function"
>Dir</CODE
>()
function:
</P
><PRE
CLASS="programlisting"
>&#13;include = Dir('include')
env = Environment(CPPPATH=include)
</PRE
><P
>&#13;The directory list will be added to command lines
through the automatically-generated
<CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
>
construction variable,
which is constructed by
appending the values of the
<CODE
CLASS="envar"
>$INCPREFIX</CODE
> and <CODE
CLASS="envar"
>$INCSUFFIX</CODE
>
construction variables
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$CPPPATH</CODE
>.
Any command lines you define that need
the CPPPATH directory list should
include <CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(CCCOM="my_compiler $_CPPINCFLAGS -c -o $TARGET $SOURCE")
</PRE
></DD
><DT
><A
NAME="cv-CPPSUFFIXES"
></A
><CODE
CLASS="envar"
>CPPSUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of suffixes of files that will be scanned
for C preprocessor implicit dependencies
(#include lines).
The default list is:
</P
><PRE
CLASS="programlisting"
>&#13;[".c", ".C", ".cxx", ".cpp", ".c++", ".cc",
 ".h", ".H", ".hxx", ".hpp", ".hh",
 ".F", ".fpp", ".FPP",
 ".m", ".mm",
 ".S", ".spp", ".SPP"]
</PRE
></DD
><DT
><A
NAME="cv-CVS"
></A
><CODE
CLASS="envar"
>CVS</CODE
></DT
><DD
><P
>&#13;The CVS executable.
</P
></DD
><DT
><A
NAME="cv-CVSCOFLAGS"
></A
><CODE
CLASS="envar"
>CVSCOFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the CVS checkout subcommand.
</P
></DD
><DT
><A
NAME="cv-CVSCOM"
></A
><CODE
CLASS="envar"
>CVSCOM</CODE
></DT
><DD
><P
>&#13;The command line used to
fetch source files from a CVS repository.
</P
></DD
><DT
><A
NAME="cv-CVSCOMSTR"
></A
><CODE
CLASS="envar"
>CVSCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when fetching
a source file from a CVS repository.
If this is not set, then <A
HREF="#cv-CVSCOM"
><CODE
CLASS="envar"
>$CVSCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-CVSFLAGS"
></A
><CODE
CLASS="envar"
>CVSFLAGS</CODE
></DT
><DD
><P
>&#13;General options that are passed to CVS.
By default, this is set to
<TT
CLASS="literal"
>-d $CVSREPOSITORY</TT
>
to specify from where the files must be fetched.
</P
></DD
><DT
><A
NAME="cv-CVSREPOSITORY"
></A
><CODE
CLASS="envar"
>CVSREPOSITORY</CODE
></DT
><DD
><P
>&#13;The path to the CVS repository.
This is referenced in the default
<A
HREF="#cv-CVSFLAGS"
><CODE
CLASS="envar"
>$CVSFLAGS</CODE
></A
> value.
</P
></DD
><DT
><A
NAME="cv-CXX"
></A
><CODE
CLASS="envar"
>CXX</CODE
></DT
><DD
><P
>&#13;The C++ compiler.
</P
></DD
><DT
><A
NAME="cv-CXXCOM"
></A
><CODE
CLASS="envar"
>CXXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a C++ source file to an object file.
Any options specified in the <A
HREF="#cv-CXXFLAGS"
><CODE
CLASS="envar"
>$CXXFLAGS</CODE
></A
> and
<A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
> construction variables
are included on this command line.
</P
></DD
><DT
><A
NAME="cv-CXXCOMSTR"
></A
><CODE
CLASS="envar"
>CXXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a C++ source file
is compiled to a (static) object file.
If this is not set, then <A
HREF="#cv-CXXCOM"
><CODE
CLASS="envar"
>$CXXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(CXXCOMSTR = "Compiling static object $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-CXXFILESUFFIX"
></A
><CODE
CLASS="envar"
>CXXFILESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix for C++ source files.
This is used by the internal CXXFile builder
when generating C++ files from Lex (.ll) or YACC (.yy) input files.
The default suffix is
<TT
CLASS="filename"
>.cc</TT
>.
SCons also treats files with the suffixes
<TT
CLASS="filename"
>.cpp</TT
>,
<TT
CLASS="filename"
>.cxx</TT
>,
<TT
CLASS="filename"
>.c++</TT
>,
and
<TT
CLASS="filename"
>.C++</TT
>
as C++ files,
and files with
<TT
CLASS="filename"
>.mm</TT
>
suffixes as Objective C++ files.
On case-sensitive systems (Linux, UNIX, and other POSIX-alikes),
SCons also treats
<TT
CLASS="filename"
>.C</TT
>
(upper case) files
as C++ files.
</P
></DD
><DT
><A
NAME="cv-CXXFLAGS"
></A
><CODE
CLASS="envar"
>CXXFLAGS</CODE
></DT
><DD
><P
>&#13;General options that are passed to the C++ compiler.
By default, this includes the value of <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>,
so that setting <CODE
CLASS="envar"
>$CCFLAGS</CODE
> affects both C and C++ compilation.
If you want to add C++-specific flags,
you must set or override the value of <A
HREF="#cv-CXXFLAGS"
><CODE
CLASS="envar"
>$CXXFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-CXXVERSION"
></A
><CODE
CLASS="envar"
>CXXVERSION</CODE
></DT
><DD
><P
>&#13;The version number of the C++ compiler.
This may or may not be set,
depending on the specific C++ compiler being used.
</P
></DD
><DT
><A
NAME="cv-DESCRIPTION"
></A
><CODE
CLASS="envar"
>DESCRIPTION</CODE
></DT
><DD
><P
>&#13;A long description of the project being packaged.
This is included in the relevant section
of the file that controls the packaging build.
</P
></DD
><DT
><A
NAME="cv-DESCRIPTION_lang"
></A
><CODE
CLASS="envar"
>DESCRIPTION_lang</CODE
></DT
><DD
><P
>&#13;A language-specific long description for
the specified <CODE
CLASS="varname"
>lang</CODE
>.
This is used to populate a
<TT
CLASS="literal"
>%description -l</TT
>
section of an RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-Dir"
></A
><CODE
CLASS="envar"
>Dir</CODE
></DT
><DD
><P
>&#13;A function that converts a string
into a Dir instance relative to the target being built.
</P
></DD
><DT
><A
NAME="cv-Dirs"
></A
><CODE
CLASS="envar"
>Dirs</CODE
></DT
><DD
><P
>&#13;A function that converts a list of strings
into a list of Dir instances relative to the target being built.
</P
></DD
><DT
><A
NAME="cv-DSUFFIXES"
></A
><CODE
CLASS="envar"
>DSUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of suffixes of files that will be scanned
for imported D package files.
The default list is:
</P
><PRE
CLASS="programlisting"
>&#13;['.d']
</PRE
></DD
><DT
><A
NAME="cv-DVIPDF"
></A
><CODE
CLASS="envar"
>DVIPDF</CODE
></DT
><DD
><P
>&#13;The TeX DVI file to PDF file converter.
</P
></DD
><DT
><A
NAME="cv-DVIPDFCOM"
></A
><CODE
CLASS="envar"
>DVIPDFCOM</CODE
></DT
><DD
><P
>&#13;The command line used to convert TeX DVI files into a PDF file.
</P
></DD
><DT
><A
NAME="cv-DVIPDFCOMSTR"
></A
><CODE
CLASS="envar"
>DVIPDFCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a TeX DVI file
is converted into a PDF file.
If this is not set, then <A
HREF="#cv-DVIPDFCOM"
><CODE
CLASS="envar"
>$DVIPDFCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-DVIPDFFLAGS"
></A
><CODE
CLASS="envar"
>DVIPDFFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the TeX DVI file to PDF file converter.
</P
></DD
><DT
><A
NAME="cv-DVIPS"
></A
><CODE
CLASS="envar"
>DVIPS</CODE
></DT
><DD
><P
>&#13;The TeX DVI file to PostScript converter.
</P
></DD
><DT
><A
NAME="cv-DVIPSFLAGS"
></A
><CODE
CLASS="envar"
>DVIPSFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the TeX DVI file to PostScript converter.
</P
></DD
><DT
><A
NAME="cv-ENV"
></A
><CODE
CLASS="envar"
>ENV</CODE
></DT
><DD
><P
>&#13;A dictionary of environment variables
to use when invoking commands. When
<CODE
CLASS="envar"
>$ENV</CODE
> is used in a command all list
values will be joined using the path separator and any other non-string
values will simply be coerced to a string.
Note that, by default,
<SPAN
CLASS="application"
>scons</SPAN
>
does
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
propagate the environment in force when you
execute
<SPAN
CLASS="application"
>scons</SPAN
>
to the commands used to build target files.
This is so that builds will be guaranteed
repeatable regardless of the environment
variables set at the time
<SPAN
CLASS="application"
>scons</SPAN
>
is invoked.</P
><P
>If you want to propagate your
environment variables
to the commands executed
to build target files,
you must do so explicitly:
</P
><PRE
CLASS="programlisting"
>&#13;import os
env = Environment(ENV = os.environ)
</PRE
><P
>&#13;Note that you can choose only to propagate
certain environment variables.
A common example is
the system
<CODE
CLASS="envar"
>PATH</CODE
>
environment variable,
so that
<SPAN
CLASS="application"
>scons</SPAN
>
uses the same utilities
as the invoking shell (or other process):
</P
><PRE
CLASS="programlisting"
>&#13;import os
env = Environment(ENV = {'PATH' : os.environ['PATH']})
</PRE
></DD
><DT
><A
NAME="cv-ESCAPE"
></A
><CODE
CLASS="envar"
>ESCAPE</CODE
></DT
><DD
><P
>&#13;A function that will be called to escape shell special characters in
command lines. The function should take one argument: the command line
string to escape; and should return the escaped command line.
</P
></DD
><DT
><A
NAME="cv-F77"
></A
><CODE
CLASS="envar"
>F77</CODE
></DT
><DD
><P
>&#13;The Fortran 77 compiler.
You should normally set the <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
> variable,
which specifies the default Fortran compiler
for all Fortran versions.
You only need to set <A
HREF="#cv-F77"
><CODE
CLASS="envar"
>$F77</CODE
></A
> if you need to use a specific compiler
or compiler version for Fortran 77 files.
</P
></DD
><DT
><A
NAME="cv-F77COM"
></A
><CODE
CLASS="envar"
>F77COM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 77 source file to an object file.
You only need to set <A
HREF="#cv-F77COM"
><CODE
CLASS="envar"
>$F77COM</CODE
></A
> if you need to use a specific
command line for Fortran 77 files.
You should normally set the <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
> variable,
which specifies the default command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-F77COMSTR"
></A
><CODE
CLASS="envar"
>F77COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 77 source file
is compiled to an object file.
If this is not set, then <A
HREF="#cv-F77COM"
><CODE
CLASS="envar"
>$F77COM</CODE
></A
> or <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-F77FILESUFFIXES"
></A
><CODE
CLASS="envar"
>F77FILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the F77 dialect will be used. By
default, this is ['.f77']
</P
></DD
><DT
><A
NAME="cv-F77FLAGS"
></A
><CODE
CLASS="envar"
>F77FLAGS</CODE
></DT
><DD
><P
>&#13;General user-specified options that are passed to the Fortran 77 compiler.
Note that this variable does
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
contain
<CODE
CLASS="option"
>-I</CODE
>
(or similar) include search path options
that scons generates automatically from <A
HREF="#cv-F77PATH"
><CODE
CLASS="envar"
>$F77PATH</CODE
></A
>.
See
<A
HREF="#cv-_F77INCFLAGS"
><CODE
CLASS="envar"
>$_F77INCFLAGS</CODE
></A
>
below,
for the variable that expands to those options.
You only need to set <A
HREF="#cv-F77FLAGS"
><CODE
CLASS="envar"
>$F77FLAGS</CODE
></A
> if you need to define specific
user options for Fortran 77 files.
You should normally set the <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
> variable,
which specifies the user-specified options
passed to the default Fortran compiler
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-_F77INCFLAGS"
></A
><CODE
CLASS="envar"
>_F77INCFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the Fortran 77 compiler command-line options
for specifying directories to be searched for include files.
The value of <A
HREF="#cv-_F77INCFLAGS"
><CODE
CLASS="envar"
>$_F77INCFLAGS</CODE
></A
> is created
by appending <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
to the beginning and end
of each directory in <A
HREF="#cv-F77PATH"
><CODE
CLASS="envar"
>$F77PATH</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-F77PATH"
></A
><CODE
CLASS="envar"
>F77PATH</CODE
></DT
><DD
><P
>&#13;The list of directories that the Fortran 77 compiler will search for include
directories. The implicit dependency scanner will search these
directories for include files. Don't explicitly put include directory
arguments in <A
HREF="#cv-F77FLAGS"
><CODE
CLASS="envar"
>$F77FLAGS</CODE
></A
> because the result will be non-portable
and the directories will not be searched by the dependency scanner. Note:
directory names in <A
HREF="#cv-F77PATH"
><CODE
CLASS="envar"
>$F77PATH</CODE
></A
> will be looked-up relative to the SConscript
directory when they are used in a command. To force
<SPAN
CLASS="application"
>scons</SPAN
>
to look-up a directory relative to the root of the source tree use #:
You only need to set <A
HREF="#cv-F77PATH"
><CODE
CLASS="envar"
>$F77PATH</CODE
></A
> if you need to define a specific
include path for Fortran 77 files.
You should normally set the <A
HREF="#cv-FORTRANPATH"
><CODE
CLASS="envar"
>$FORTRANPATH</CODE
></A
> variable,
which specifies the include path
for the default Fortran compiler
for all Fortran versions.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(F77PATH='#/include')
</PRE
><P
>&#13;The directory look-up can also be forced using the
<CODE
CLASS="function"
>Dir</CODE
>()
function:
</P
><PRE
CLASS="programlisting"
>&#13;include = Dir('include')
env = Environment(F77PATH=include)
</PRE
><P
>&#13;The directory list will be added to command lines
through the automatically-generated
<A
HREF="#cv-_F77INCFLAGS"
><CODE
CLASS="envar"
>$_F77INCFLAGS</CODE
></A
>
construction variable,
which is constructed by
appending the values of the
<A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
construction variables
to the beginning and end
of each directory in <A
HREF="#cv-F77PATH"
><CODE
CLASS="envar"
>$F77PATH</CODE
></A
>.
Any command lines you define that need
the F77PATH directory list should
include <A
HREF="#cv-_F77INCFLAGS"
><CODE
CLASS="envar"
>$_F77INCFLAGS</CODE
></A
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(F77COM="my_compiler $_F77INCFLAGS -c -o $TARGET $SOURCE")
</PRE
></DD
><DT
><A
NAME="cv-F77PPCOM"
></A
><CODE
CLASS="envar"
>F77PPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 77 source file to an object file
after first running the file through the C preprocessor.
Any options specified in the <A
HREF="#cv-F77FLAGS"
><CODE
CLASS="envar"
>$F77FLAGS</CODE
></A
> and <A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
> construction variables
are included on this command line.
You only need to set <A
HREF="#cv-F77PPCOM"
><CODE
CLASS="envar"
>$F77PPCOM</CODE
></A
> if you need to use a specific
C-preprocessor command line for Fortran 77 files.
You should normally set the <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
> variable,
which specifies the default C-preprocessor command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-F77PPCOMSTR"
></A
><CODE
CLASS="envar"
>F77PPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 77 source file
is compiled to an object file
after first running the file through the C preprocessor.
If this is not set, then <A
HREF="#cv-F77PPCOM"
><CODE
CLASS="envar"
>$F77PPCOM</CODE
></A
> or <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-F77PPFILESUFFIXES"
></A
><CODE
CLASS="envar"
>F77PPFILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the compilation + preprocessor pass for
F77 dialect will be used. By default, this is empty
</P
></DD
><DT
><A
NAME="cv-F90"
></A
><CODE
CLASS="envar"
>F90</CODE
></DT
><DD
><P
>&#13;The Fortran 90 compiler.
You should normally set the <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
> variable,
which specifies the default Fortran compiler
for all Fortran versions.
You only need to set <A
HREF="#cv-F90"
><CODE
CLASS="envar"
>$F90</CODE
></A
> if you need to use a specific compiler
or compiler version for Fortran 90 files.
</P
></DD
><DT
><A
NAME="cv-F90COM"
></A
><CODE
CLASS="envar"
>F90COM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 90 source file to an object file.
You only need to set <A
HREF="#cv-F90COM"
><CODE
CLASS="envar"
>$F90COM</CODE
></A
> if you need to use a specific
command line for Fortran 90 files.
You should normally set the <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
> variable,
which specifies the default command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-F90COMSTR"
></A
><CODE
CLASS="envar"
>F90COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 90 source file
is compiled to an object file.
If this is not set, then <A
HREF="#cv-F90COM"
><CODE
CLASS="envar"
>$F90COM</CODE
></A
> or <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-F90FILESUFFIXES"
></A
><CODE
CLASS="envar"
>F90FILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the F90 dialect will be used. By
default, this is ['.f90']
</P
></DD
><DT
><A
NAME="cv-F90FLAGS"
></A
><CODE
CLASS="envar"
>F90FLAGS</CODE
></DT
><DD
><P
>&#13;General user-specified options that are passed to the Fortran 90 compiler.
Note that this variable does
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
contain
<CODE
CLASS="option"
>-I</CODE
>
(or similar) include search path options
that scons generates automatically from <A
HREF="#cv-F90PATH"
><CODE
CLASS="envar"
>$F90PATH</CODE
></A
>.
See
<A
HREF="#cv-_F90INCFLAGS"
><CODE
CLASS="envar"
>$_F90INCFLAGS</CODE
></A
>
below,
for the variable that expands to those options.
You only need to set <A
HREF="#cv-F90FLAGS"
><CODE
CLASS="envar"
>$F90FLAGS</CODE
></A
> if you need to define specific
user options for Fortran 90 files.
You should normally set the <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
> variable,
which specifies the user-specified options
passed to the default Fortran compiler
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-_F90INCFLAGS"
></A
><CODE
CLASS="envar"
>_F90INCFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the Fortran 90 compiler command-line options
for specifying directories to be searched for include files.
The value of <A
HREF="#cv-_F90INCFLAGS"
><CODE
CLASS="envar"
>$_F90INCFLAGS</CODE
></A
> is created
by appending <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
to the beginning and end
of each directory in <A
HREF="#cv-F90PATH"
><CODE
CLASS="envar"
>$F90PATH</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-F90PATH"
></A
><CODE
CLASS="envar"
>F90PATH</CODE
></DT
><DD
><P
>&#13;The list of directories that the Fortran 90 compiler will search for include
directories. The implicit dependency scanner will search these
directories for include files. Don't explicitly put include directory
arguments in <A
HREF="#cv-F90FLAGS"
><CODE
CLASS="envar"
>$F90FLAGS</CODE
></A
> because the result will be non-portable
and the directories will not be searched by the dependency scanner. Note:
directory names in <A
HREF="#cv-F90PATH"
><CODE
CLASS="envar"
>$F90PATH</CODE
></A
> will be looked-up relative to the SConscript
directory when they are used in a command. To force
<SPAN
CLASS="application"
>scons</SPAN
>
to look-up a directory relative to the root of the source tree use #:
You only need to set <A
HREF="#cv-F90PATH"
><CODE
CLASS="envar"
>$F90PATH</CODE
></A
> if you need to define a specific
include path for Fortran 90 files.
You should normally set the <A
HREF="#cv-FORTRANPATH"
><CODE
CLASS="envar"
>$FORTRANPATH</CODE
></A
> variable,
which specifies the include path
for the default Fortran compiler
for all Fortran versions.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(F90PATH='#/include')
</PRE
><P
>&#13;The directory look-up can also be forced using the
<CODE
CLASS="function"
>Dir</CODE
>()
function:
</P
><PRE
CLASS="programlisting"
>&#13;include = Dir('include')
env = Environment(F90PATH=include)
</PRE
><P
>&#13;The directory list will be added to command lines
through the automatically-generated
<A
HREF="#cv-_F90INCFLAGS"
><CODE
CLASS="envar"
>$_F90INCFLAGS</CODE
></A
>
construction variable,
which is constructed by
appending the values of the
<A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
construction variables
to the beginning and end
of each directory in <A
HREF="#cv-F90PATH"
><CODE
CLASS="envar"
>$F90PATH</CODE
></A
>.
Any command lines you define that need
the F90PATH directory list should
include <A
HREF="#cv-_F90INCFLAGS"
><CODE
CLASS="envar"
>$_F90INCFLAGS</CODE
></A
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(F90COM="my_compiler $_F90INCFLAGS -c -o $TARGET $SOURCE")
</PRE
></DD
><DT
><A
NAME="cv-F90PPCOM"
></A
><CODE
CLASS="envar"
>F90PPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 90 source file to an object file
after first running the file through the C preprocessor.
Any options specified in the <A
HREF="#cv-F90FLAGS"
><CODE
CLASS="envar"
>$F90FLAGS</CODE
></A
> and <A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
> construction variables
are included on this command line.
You only need to set <A
HREF="#cv-F90PPCOM"
><CODE
CLASS="envar"
>$F90PPCOM</CODE
></A
> if you need to use a specific
C-preprocessor command line for Fortran 90 files.
You should normally set the <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
> variable,
which specifies the default C-preprocessor command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-F90PPCOMSTR"
></A
><CODE
CLASS="envar"
>F90PPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 90 source file
is compiled after first running the file through the C preprocessor.
If this is not set, then <A
HREF="#cv-F90PPCOM"
><CODE
CLASS="envar"
>$F90PPCOM</CODE
></A
> or <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-F90PPFILESUFFIXES"
></A
><CODE
CLASS="envar"
>F90PPFILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the compilation + preprocessor pass for
F90 dialect will be used. By default, this is empty
</P
></DD
><DT
><A
NAME="cv-F95"
></A
><CODE
CLASS="envar"
>F95</CODE
></DT
><DD
><P
>&#13;The Fortran 95 compiler.
You should normally set the <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
> variable,
which specifies the default Fortran compiler
for all Fortran versions.
You only need to set <A
HREF="#cv-F95"
><CODE
CLASS="envar"
>$F95</CODE
></A
> if you need to use a specific compiler
or compiler version for Fortran 95 files.
</P
></DD
><DT
><A
NAME="cv-F95COM"
></A
><CODE
CLASS="envar"
>F95COM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 95 source file to an object file.
You only need to set <A
HREF="#cv-F95COM"
><CODE
CLASS="envar"
>$F95COM</CODE
></A
> if you need to use a specific
command line for Fortran 95 files.
You should normally set the <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
> variable,
which specifies the default command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-F95COMSTR"
></A
><CODE
CLASS="envar"
>F95COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 95 source file
is compiled to an object file.
If this is not set, then <A
HREF="#cv-F95COM"
><CODE
CLASS="envar"
>$F95COM</CODE
></A
> or <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-F95FILESUFFIXES"
></A
><CODE
CLASS="envar"
>F95FILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the F95 dialect will be used. By
default, this is ['.f95']
</P
></DD
><DT
><A
NAME="cv-F95FLAGS"
></A
><CODE
CLASS="envar"
>F95FLAGS</CODE
></DT
><DD
><P
>&#13;General user-specified options that are passed to the Fortran 95 compiler.
Note that this variable does
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
contain
<CODE
CLASS="option"
>-I</CODE
>
(or similar) include search path options
that scons generates automatically from <A
HREF="#cv-F95PATH"
><CODE
CLASS="envar"
>$F95PATH</CODE
></A
>.
See
<A
HREF="#cv-_F95INCFLAGS"
><CODE
CLASS="envar"
>$_F95INCFLAGS</CODE
></A
>
below,
for the variable that expands to those options.
You only need to set <A
HREF="#cv-F95FLAGS"
><CODE
CLASS="envar"
>$F95FLAGS</CODE
></A
> if you need to define specific
user options for Fortran 95 files.
You should normally set the <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
> variable,
which specifies the user-specified options
passed to the default Fortran compiler
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-_F95INCFLAGS"
></A
><CODE
CLASS="envar"
>_F95INCFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the Fortran 95 compiler command-line options
for specifying directories to be searched for include files.
The value of <A
HREF="#cv-_F95INCFLAGS"
><CODE
CLASS="envar"
>$_F95INCFLAGS</CODE
></A
> is created
by appending <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
to the beginning and end
of each directory in <A
HREF="#cv-F95PATH"
><CODE
CLASS="envar"
>$F95PATH</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-F95PATH"
></A
><CODE
CLASS="envar"
>F95PATH</CODE
></DT
><DD
><P
>&#13;The list of directories that the Fortran 95 compiler will search for include
directories. The implicit dependency scanner will search these
directories for include files. Don't explicitly put include directory
arguments in <A
HREF="#cv-F95FLAGS"
><CODE
CLASS="envar"
>$F95FLAGS</CODE
></A
> because the result will be non-portable
and the directories will not be searched by the dependency scanner. Note:
directory names in <A
HREF="#cv-F95PATH"
><CODE
CLASS="envar"
>$F95PATH</CODE
></A
> will be looked-up relative to the SConscript
directory when they are used in a command. To force
<SPAN
CLASS="application"
>scons</SPAN
>
to look-up a directory relative to the root of the source tree use #:
You only need to set <A
HREF="#cv-F95PATH"
><CODE
CLASS="envar"
>$F95PATH</CODE
></A
> if you need to define a specific
include path for Fortran 95 files.
You should normally set the <A
HREF="#cv-FORTRANPATH"
><CODE
CLASS="envar"
>$FORTRANPATH</CODE
></A
> variable,
which specifies the include path
for the default Fortran compiler
for all Fortran versions.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(F95PATH='#/include')
</PRE
><P
>&#13;The directory look-up can also be forced using the
<CODE
CLASS="function"
>Dir</CODE
>()
function:
</P
><PRE
CLASS="programlisting"
>&#13;include = Dir('include')
env = Environment(F95PATH=include)
</PRE
><P
>&#13;The directory list will be added to command lines
through the automatically-generated
<A
HREF="#cv-_F95INCFLAGS"
><CODE
CLASS="envar"
>$_F95INCFLAGS</CODE
></A
>
construction variable,
which is constructed by
appending the values of the
<A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
construction variables
to the beginning and end
of each directory in <A
HREF="#cv-F95PATH"
><CODE
CLASS="envar"
>$F95PATH</CODE
></A
>.
Any command lines you define that need
the F95PATH directory list should
include <A
HREF="#cv-_F95INCFLAGS"
><CODE
CLASS="envar"
>$_F95INCFLAGS</CODE
></A
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(F95COM="my_compiler $_F95INCFLAGS -c -o $TARGET $SOURCE")
</PRE
></DD
><DT
><A
NAME="cv-F95PPCOM"
></A
><CODE
CLASS="envar"
>F95PPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 95 source file to an object file
after first running the file through the C preprocessor.
Any options specified in the <A
HREF="#cv-F95FLAGS"
><CODE
CLASS="envar"
>$F95FLAGS</CODE
></A
> and <A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
> construction variables
are included on this command line.
You only need to set <A
HREF="#cv-F95PPCOM"
><CODE
CLASS="envar"
>$F95PPCOM</CODE
></A
> if you need to use a specific
C-preprocessor command line for Fortran 95 files.
You should normally set the <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
> variable,
which specifies the default C-preprocessor command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-F95PPCOMSTR"
></A
><CODE
CLASS="envar"
>F95PPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 95 source file
is compiled to an object file
after first running the file through the C preprocessor.
If this is not set, then <A
HREF="#cv-F95PPCOM"
><CODE
CLASS="envar"
>$F95PPCOM</CODE
></A
> or <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-F95PPFILESUFFIXES"
></A
><CODE
CLASS="envar"
>F95PPFILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the compilation + preprocessor pass for
F95 dialect will be used. By default, this is empty
</P
></DD
><DT
><A
NAME="cv-File"
></A
><CODE
CLASS="envar"
>File</CODE
></DT
><DD
><P
>&#13;A function that converts a string into a File instance relative to the
target being built.
</P
></DD
><DT
><A
NAME="cv-FORTRAN"
></A
><CODE
CLASS="envar"
>FORTRAN</CODE
></DT
><DD
><P
>&#13;The default Fortran compiler
for all versions of Fortran.
</P
></DD
><DT
><A
NAME="cv-FORTRANCOM"
></A
><CODE
CLASS="envar"
>FORTRANCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran source file to an object file.
By default, any options specified
in the <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
>,
<A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
>,
<A
HREF="#cv-_CPPDEFFLAGS"
><CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
></A
>,
<A
HREF="#cv-_FORTRANMODFLAG"
><CODE
CLASS="envar"
>$_FORTRANMODFLAG</CODE
></A
>, and
<A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
> construction variables
are included on this command line.
</P
></DD
><DT
><A
NAME="cv-FORTRANCOMSTR"
></A
><CODE
CLASS="envar"
>FORTRANCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran source file
is compiled to an object file.
If this is not set, then <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-FORTRANFILESUFFIXES"
></A
><CODE
CLASS="envar"
>FORTRANFILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the FORTRAN dialect will be used. By
default, this is ['.f', '.for', '.ftn']
</P
></DD
><DT
><A
NAME="cv-FORTRANFLAGS"
></A
><CODE
CLASS="envar"
>FORTRANFLAGS</CODE
></DT
><DD
><P
>&#13;General user-specified options that are passed to the Fortran compiler.
Note that this variable does
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
contain
<CODE
CLASS="option"
>-I</CODE
>
(or similar) include or module search path options
that scons generates automatically from <A
HREF="#cv-FORTRANPATH"
><CODE
CLASS="envar"
>$FORTRANPATH</CODE
></A
>.
See
<A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
> and <A
HREF="#cv-_FORTRANMODFLAG"
><CODE
CLASS="envar"
>$_FORTRANMODFLAG</CODE
></A
>,
below,
for the variables that expand those options.
</P
></DD
><DT
><A
NAME="cv-_FORTRANINCFLAGS"
></A
><CODE
CLASS="envar"
>_FORTRANINCFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the Fortran compiler command-line options
for specifying directories to be searched for include
files and module files.
The value of <A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
> is created
by prepending/appending <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
to the beginning and end
of each directory in <A
HREF="#cv-FORTRANPATH"
><CODE
CLASS="envar"
>$FORTRANPATH</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-FORTRANMODDIR"
></A
><CODE
CLASS="envar"
>FORTRANMODDIR</CODE
></DT
><DD
><P
>&#13;Directory location where the Fortran compiler should place
any module files it generates.  This variable is empty, by default. Some
Fortran compilers will internally append this directory in the search path
for module files, as well.
</P
></DD
><DT
><A
NAME="cv-FORTRANMODDIRPREFIX"
></A
><CODE
CLASS="envar"
>FORTRANMODDIRPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used to specify a module directory on the Fortran compiler command
line.
This will be appended to the beginning of the directory
in the <A
HREF="#cv-FORTRANMODDIR"
><CODE
CLASS="envar"
>$FORTRANMODDIR</CODE
></A
> construction variables
when the <A
HREF="#cv-_FORTRANMODFLAG"
><CODE
CLASS="envar"
>$_FORTRANMODFLAG</CODE
></A
> variables is automatically generated.
</P
></DD
><DT
><A
NAME="cv-FORTRANMODDIRSUFFIX"
></A
><CODE
CLASS="envar"
>FORTRANMODDIRSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify a module directory on the Fortran compiler command
line.
This will be appended to the beginning of the directory
in the <A
HREF="#cv-FORTRANMODDIR"
><CODE
CLASS="envar"
>$FORTRANMODDIR</CODE
></A
> construction variables
when the <A
HREF="#cv-_FORTRANMODFLAG"
><CODE
CLASS="envar"
>$_FORTRANMODFLAG</CODE
></A
> variables is automatically generated.
</P
></DD
><DT
><A
NAME="cv-_FORTRANMODFLAG"
></A
><CODE
CLASS="envar"
>_FORTRANMODFLAG</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the Fortran compiler command-line option
for specifying the directory location where the Fortran
compiler should place any module files that happen to get
generated during compilation.
The value of <A
HREF="#cv-_FORTRANMODFLAG"
><CODE
CLASS="envar"
>$_FORTRANMODFLAG</CODE
></A
> is created
by prepending/appending <A
HREF="#cv-FORTRANMODDIRPREFIX"
><CODE
CLASS="envar"
>$FORTRANMODDIRPREFIX</CODE
></A
> and
<A
HREF="#cv-FORTRANMODDIRSUFFIX"
><CODE
CLASS="envar"
>$FORTRANMODDIRSUFFIX</CODE
></A
>
to the beginning and end of the directory in <A
HREF="#cv-FORTRANMODDIR"
><CODE
CLASS="envar"
>$FORTRANMODDIR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-FORTRANMODPREFIX"
></A
><CODE
CLASS="envar"
>FORTRANMODPREFIX</CODE
></DT
><DD
><P
>&#13;The module file prefix used by the Fortran compiler.  SCons assumes that
the Fortran compiler follows the quasi-standard naming convention for
module files of
<TT
CLASS="filename"
>module_name.mod</TT
>.
As a result, this variable is left empty, by default.  For situations in
which the compiler does not necessarily follow the normal convention,
the user may use this variable.  Its value will be appended to every
module file name as scons attempts to resolve dependencies.
</P
></DD
><DT
><A
NAME="cv-FORTRANMODSUFFIX"
></A
><CODE
CLASS="envar"
>FORTRANMODSUFFIX</CODE
></DT
><DD
><P
>&#13;The module file suffix used by the Fortran compiler.  SCons assumes that
the Fortran compiler follows the quasi-standard naming convention for
module files of
<TT
CLASS="filename"
>module_name.mod</TT
>.
As a result, this variable is set to ".mod", by default.  For situations
in which the compiler does not necessarily follow the normal convention,
the user may use this variable.  Its value will be appended to every
module file name as scons attempts to resolve dependencies.
</P
></DD
><DT
><A
NAME="cv-FORTRANPATH"
></A
><CODE
CLASS="envar"
>FORTRANPATH</CODE
></DT
><DD
><P
>&#13;The list of directories that the Fortran compiler will search for
include files and (for some compilers) module files. The Fortran implicit
dependency scanner will search these directories for include files (but
not module files since they are autogenerated and, as such, may not
actually exist at the time the scan takes place). Don't explicitly put
include directory arguments in FORTRANFLAGS because the result will be
non-portable and the directories will not be searched by the dependency
scanner. Note: directory names in FORTRANPATH will be looked-up relative
to the SConscript directory when they are used in a command. To force
<SPAN
CLASS="application"
>scons</SPAN
>
to look-up a directory relative to the root of the source tree use #:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(FORTRANPATH='#/include')
</PRE
><P
>&#13;The directory look-up can also be forced using the
<CODE
CLASS="function"
>Dir</CODE
>()
function:
</P
><PRE
CLASS="programlisting"
>&#13;include = Dir('include')
env = Environment(FORTRANPATH=include)
</PRE
><P
>&#13;The directory list will be added to command lines
through the automatically-generated
<A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
>
construction variable,
which is constructed by
appending the values of the
<A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
> and <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>
construction variables
to the beginning and end
of each directory in <A
HREF="#cv-FORTRANPATH"
><CODE
CLASS="envar"
>$FORTRANPATH</CODE
></A
>.
Any command lines you define that need
the FORTRANPATH directory list should
include <A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(FORTRANCOM="my_compiler $_FORTRANINCFLAGS -c -o $TARGET $SOURCE")
</PRE
></DD
><DT
><A
NAME="cv-FORTRANPPCOM"
></A
><CODE
CLASS="envar"
>FORTRANPPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran source file to an object file
after first running the file through the C preprocessor.
By default, any options specified in the <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
>,
<A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
>,
<A
HREF="#cv-_CPPDEFFLAGS"
><CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
></A
>,
<A
HREF="#cv-_FORTRANMODFLAG"
><CODE
CLASS="envar"
>$_FORTRANMODFLAG</CODE
></A
>, and
<A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
>
construction variables are included on this command line.
</P
></DD
><DT
><A
NAME="cv-FORTRANPPCOMSTR"
></A
><CODE
CLASS="envar"
>FORTRANPPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran source file
is compiled to an object file
after first running the file throught the C preprocessor.
If this is not set, then <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-FORTRANPPFILESUFFIXES"
></A
><CODE
CLASS="envar"
>FORTRANPPFILESUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of file extensions for which the compilation + preprocessor pass for
FORTRAN dialect will be used. By default, this is ['.fpp', '.FPP']
</P
></DD
><DT
><A
NAME="cv-FORTRANSUFFIXES"
></A
><CODE
CLASS="envar"
>FORTRANSUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of suffixes of files that will be scanned
for Fortran implicit dependencies
(INCLUDE lines and USE statements).
The default list is:
</P
><PRE
CLASS="programlisting"
>&#13;[".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP",
".f77", ".F77", ".f90", ".F90", ".f95", ".F95"]
</PRE
></DD
><DT
><A
NAME="cv-FRAMEWORKPATH"
></A
><CODE
CLASS="envar"
>FRAMEWORKPATH</CODE
></DT
><DD
><P
>&#13;On Mac OS X with gcc,
a list containing the paths to search for frameworks.
Used by the compiler to find framework-style includes like
#include &#60;Fmwk/Header.h&#62;.
Used by the linker to find user-specified frameworks when linking (see
<A
HREF="#cv-FRAMEWORKS"
><CODE
CLASS="envar"
>$FRAMEWORKS</CODE
></A
>).
For example:
</P
><PRE
CLASS="programlisting"
>&#13; env.AppendUnique(FRAMEWORKPATH='#myframeworkdir')
</PRE
><P
>&#13;will add
</P
><PRE
CLASS="programlisting"
>&#13;  ... -Fmyframeworkdir
</PRE
><P
>&#13;to the compiler and linker command lines.
</P
></DD
><DT
><A
NAME="cv-_FRAMEWORKPATH"
></A
><CODE
CLASS="envar"
>_FRAMEWORKPATH</CODE
></DT
><DD
><P
>&#13;On Mac OS X with gcc, an automatically-generated construction variable
containing the linker command-line options corresponding to
<A
HREF="#cv-FRAMEWORKPATH"
><CODE
CLASS="envar"
>$FRAMEWORKPATH</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-FRAMEWORKPATHPREFIX"
></A
><CODE
CLASS="envar"
>FRAMEWORKPATHPREFIX</CODE
></DT
><DD
><P
>&#13;On Mac OS X with gcc, the prefix to be used for the FRAMEWORKPATH entries.
(see <A
HREF="#cv-FRAMEWORKPATH"
><CODE
CLASS="envar"
>$FRAMEWORKPATH</CODE
></A
>).
The default value is
<CODE
CLASS="option"
>-F</CODE
>.
</P
></DD
><DT
><A
NAME="cv-FRAMEWORKPREFIX"
></A
><CODE
CLASS="envar"
>FRAMEWORKPREFIX</CODE
></DT
><DD
><P
>&#13;On Mac OS X with gcc,
the prefix to be used for linking in frameworks
(see <A
HREF="#cv-FRAMEWORKS"
><CODE
CLASS="envar"
>$FRAMEWORKS</CODE
></A
>).
The default value is
<CODE
CLASS="option"
>-framework</CODE
>.
</P
></DD
><DT
><A
NAME="cv-_FRAMEWORKS"
></A
><CODE
CLASS="envar"
>_FRAMEWORKS</CODE
></DT
><DD
><P
>&#13;On Mac OS X with gcc,
an automatically-generated construction variable
containing the linker command-line options
for linking with FRAMEWORKS.
</P
></DD
><DT
><A
NAME="cv-FRAMEWORKS"
></A
><CODE
CLASS="envar"
>FRAMEWORKS</CODE
></DT
><DD
><P
>&#13;On Mac OS X with gcc, a list of the framework names to be linked into a
program or shared library or bundle.
The default value is the empty list.
For example:
</P
><PRE
CLASS="programlisting"
>&#13; env.AppendUnique(FRAMEWORKS=Split('System Cocoa SystemConfiguration'))
</PRE
><P
>&#13;</P
></DD
><DT
><A
NAME="cv-FRAMEWORKSFLAGS"
></A
><CODE
CLASS="envar"
>FRAMEWORKSFLAGS</CODE
></DT
><DD
><P
>&#13;On Mac OS X with gcc,
general user-supplied frameworks options to be added at
the end of a command
line building a loadable module.
(This has been largely superceded by
the <A
HREF="#cv-FRAMEWORKPATH"
><CODE
CLASS="envar"
>$FRAMEWORKPATH</CODE
></A
>, <A
HREF="#cv-FRAMEWORKPATHPREFIX"
><CODE
CLASS="envar"
>$FRAMEWORKPATHPREFIX</CODE
></A
>,
<A
HREF="#cv-FRAMEWORKPREFIX"
><CODE
CLASS="envar"
>$FRAMEWORKPREFIX</CODE
></A
> and <A
HREF="#cv-FRAMEWORKS"
><CODE
CLASS="envar"
>$FRAMEWORKS</CODE
></A
> variables
described above.)
</P
></DD
><DT
><A
NAME="cv-GS"
></A
><CODE
CLASS="envar"
>GS</CODE
></DT
><DD
><P
>&#13;The Ghostscript program used to convert PostScript to PDF files.
</P
></DD
><DT
><A
NAME="cv-GSCOM"
></A
><CODE
CLASS="envar"
>GSCOM</CODE
></DT
><DD
><P
>&#13;The Ghostscript command line used to convert PostScript to PDF files.
</P
></DD
><DT
><A
NAME="cv-GSCOMSTR"
></A
><CODE
CLASS="envar"
>GSCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when
Ghostscript is used to convert
a PostScript file to a PDF file.
If this is not set, then <A
HREF="#cv-GSCOM"
><CODE
CLASS="envar"
>$GSCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-GSFLAGS"
></A
><CODE
CLASS="envar"
>GSFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the Ghostscript program
when converting PostScript to PDF files.
</P
></DD
><DT
><A
NAME="cv-IDLSUFFIXES"
></A
><CODE
CLASS="envar"
>IDLSUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of suffixes of files that will be scanned
for IDL implicit dependencies
(#include or import lines).
The default list is:
</P
><PRE
CLASS="programlisting"
>&#13;[".idl", ".IDL"]
</PRE
></DD
><DT
><A
NAME="cv-IMPLICIT_COMMAND_DEPENDENCIES"
></A
><CODE
CLASS="envar"
>IMPLICIT_COMMAND_DEPENDENCIES</CODE
></DT
><DD
><P
>&#13;Controls whether or not SCons will
add implicit dependencies for the commands
executed to build targets.</P
><P
>By default, SCons will add
to each target
an implicit dependency on the command
represented by the first argument on any
command line it executes.
The specific file for the dependency is
found by searching the
<CODE
CLASS="varname"
>PATH</CODE
>
variable in the
<CODE
CLASS="varname"
>ENV</CODE
>
environment used to execute the command.</P
><P
>If the construction variable
<CODE
CLASS="envar"
>$IMPLICIT_COMMAND_DEPENDENCIES</CODE
>
is set to a false value
(<TT
CLASS="literal"
>None</TT
>,
<TT
CLASS="literal"
>False</TT
>,
<TT
CLASS="literal"
>0</TT
>,
etc.),
then the implicit dependency will
not be added to the targets
built with that construction environment.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(IMPLICIT_COMMAND_DEPENDENCIES = 0)
</PRE
></DD
><DT
><A
NAME="cv-INCPREFIX"
></A
><CODE
CLASS="envar"
>INCPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used to specify an include directory on the C compiler command
line.
This will be appended to the beginning of each directory
in the <CODE
CLASS="envar"
>$CPPPATH</CODE
> and <CODE
CLASS="envar"
>$FORTRANPATH</CODE
> construction variables
when the <CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
> and <CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
>
variables are automatically generated.
</P
></DD
><DT
><A
NAME="cv-INCSUFFIX"
></A
><CODE
CLASS="envar"
>INCSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify an include directory on the C compiler command
line.
This will be appended to the end of each directory
in the <CODE
CLASS="envar"
>$CPPPATH</CODE
> and <CODE
CLASS="envar"
>$FORTRANPATH</CODE
> construction variables
when the <CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
> and <CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
>
variables are automatically generated.
</P
></DD
><DT
><A
NAME="cv-INSTALL"
></A
><CODE
CLASS="envar"
>INSTALL</CODE
></DT
><DD
><P
>&#13;A function to be called to install a file into a
destination file name.
The default function copies the file into the destination
(and sets the destination file's mode and permission bits
to match the source file's).
The function takes the following arguments:
</P
><PRE
CLASS="programlisting"
>&#13;def install(dest, source, env):
</PRE
><P
>&#13;<CODE
CLASS="varname"
>dest</CODE
>
is the path name of the destination file.
<CODE
CLASS="varname"
>source</CODE
>
is the path name of the source file.
<CODE
CLASS="varname"
>env</CODE
>
is the construction environment
(a dictionary of construction values)
in force for this file installation.
</P
></DD
><DT
><A
NAME="cv-INSTALLSTR"
></A
><CODE
CLASS="envar"
>INSTALLSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a file is
installed into a destination file name.
The default is:
</P
><PRE
CLASS="programlisting"
>&#13;Install file: "$SOURCE" as "$TARGET"
</PRE
></DD
><DT
><A
NAME="cv-INTEL_C_COMPILER_VERSION"
></A
><CODE
CLASS="envar"
>INTEL_C_COMPILER_VERSION</CODE
></DT
><DD
><P
>&#13;Set by the "intelc" Tool
to the major version number of the Intel C compiler
selected for use.
</P
></DD
><DT
><A
NAME="cv-JAR"
></A
><CODE
CLASS="envar"
>JAR</CODE
></DT
><DD
><P
>&#13;The Java archive tool.
</P
></DD
><DT
><A
NAME="cv-JARCHDIR"
></A
><CODE
CLASS="envar"
>JARCHDIR</CODE
></DT
><DD
><P
>&#13;The directory to which the Java archive tool should change
(using the
<CODE
CLASS="option"
>-C</CODE
>
option).
</P
></DD
><DT
><A
NAME="cv-JARCOM"
></A
><CODE
CLASS="envar"
>JARCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the Java archive tool.
</P
></DD
><DT
><A
NAME="cv-JARCOMSTR"
></A
><CODE
CLASS="envar"
>JARCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when the Java archive tool
is called
If this is not set, then <CODE
CLASS="envar"
>$JARCOM</CODE
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-JARFLAGS"
></A
><CODE
CLASS="envar"
>JARFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the Java archive tool.
By default this is set to
<CODE
CLASS="option"
>cf</CODE
>
to create the necessary
<B
CLASS="command"
>jar</B
>
file.
</P
></DD
><DT
><A
NAME="cv-JARSUFFIX"
></A
><CODE
CLASS="envar"
>JARSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix for Java archives:
<TT
CLASS="filename"
>.jar</TT
>
by default.
</P
></DD
><DT
><A
NAME="cv-JAVABOOTCLASSPATH"
></A
><CODE
CLASS="envar"
>JAVABOOTCLASSPATH</CODE
></DT
><DD
><P
>&#13;Specifies the list of directories that
will be added to the
<SPAN
CLASS="application"
>javac</SPAN
> command line
via the <CODE
CLASS="option"
>-bootclasspath</CODE
> option.
The individual directory names will be
separated by the operating system's path separate character
(<TT
CLASS="filename"
>:</TT
> on UNIX/Linux/POSIX,
<TT
CLASS="filename"
>;</TT
> on Windows).
</P
></DD
><DT
><A
NAME="cv-JAVAC"
></A
><CODE
CLASS="envar"
>JAVAC</CODE
></DT
><DD
><P
>&#13;The Java compiler.
</P
></DD
><DT
><A
NAME="cv-JAVACCOM"
></A
><CODE
CLASS="envar"
>JAVACCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a directory tree containing
Java source files to
corresponding Java class files.
Any options specified in the <A
HREF="#cv-JAVACFLAGS"
><CODE
CLASS="envar"
>$JAVACFLAGS</CODE
></A
> construction variable
are included on this command line.
</P
></DD
><DT
><A
NAME="cv-JAVACCOMSTR"
></A
><CODE
CLASS="envar"
>JAVACCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when compiling
a directory tree of Java source files to
corresponding Java class files.
If this is not set, then <A
HREF="#cv-JAVACCOM"
><CODE
CLASS="envar"
>$JAVACCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(JAVACCOMSTR = "Compiling class files $TARGETS from $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-JAVACFLAGS"
></A
><CODE
CLASS="envar"
>JAVACFLAGS</CODE
></DT
><DD
><P
>&#13;General options that are passed to the Java compiler.
</P
></DD
><DT
><A
NAME="cv-JAVACLASSDIR"
></A
><CODE
CLASS="envar"
>JAVACLASSDIR</CODE
></DT
><DD
><P
>&#13;The directory in which Java class files may be found.
This is stripped from the beginning of any Java .class
file names supplied to the
<TT
CLASS="literal"
>JavaH</TT
>
builder.
</P
></DD
><DT
><A
NAME="cv-JAVACLASSPATH"
></A
><CODE
CLASS="envar"
>JAVACLASSPATH</CODE
></DT
><DD
><P
>&#13;Specifies the list of directories that
will be searched for Java
<TT
CLASS="filename"
>.class</TT
> file.
The directories in this list will be added to the
<SPAN
CLASS="application"
>javac</SPAN
> and <SPAN
CLASS="application"
>javah</SPAN
> command lines
via the <CODE
CLASS="option"
>-classpath</CODE
> option.
The individual directory names will be
separated by the operating system's path separate character
(<TT
CLASS="filename"
>:</TT
> on UNIX/Linux/POSIX,
<TT
CLASS="filename"
>;</TT
> on Windows).</P
><P
>Note that this currently just adds the specified
directory via the <CODE
CLASS="option"
>-classpath</CODE
> option.
<SPAN
CLASS="application"
>SCons</SPAN
> does not currently search the
<CODE
CLASS="envar"
>$JAVACLASSPATH</CODE
> directories for dependency
<TT
CLASS="filename"
>.class</TT
> files.
</P
></DD
><DT
><A
NAME="cv-JAVACLASSSUFFIX"
></A
><CODE
CLASS="envar"
>JAVACLASSSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix for Java class files;
<TT
CLASS="filename"
>.class</TT
>
by default.
</P
></DD
><DT
><A
NAME="cv-JAVAH"
></A
><CODE
CLASS="envar"
>JAVAH</CODE
></DT
><DD
><P
>&#13;The Java generator for C header and stub files.
</P
></DD
><DT
><A
NAME="cv-JAVAHCOM"
></A
><CODE
CLASS="envar"
>JAVAHCOM</CODE
></DT
><DD
><P
>&#13;The command line used to generate C header and stub files
from Java classes.
Any options specified in the <A
HREF="#cv-JAVAHFLAGS"
><CODE
CLASS="envar"
>$JAVAHFLAGS</CODE
></A
> construction variable
are included on this command line.
</P
></DD
><DT
><A
NAME="cv-JAVAHCOMSTR"
></A
><CODE
CLASS="envar"
>JAVAHCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when C header and stub files
are generated from Java classes.
If this is not set, then <A
HREF="#cv-JAVAHCOM"
><CODE
CLASS="envar"
>$JAVAHCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(JAVAHCOMSTR = "Generating header/stub file(s) $TARGETS from $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-JAVAHFLAGS"
></A
><CODE
CLASS="envar"
>JAVAHFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the C header and stub file generator
for Java classes.
</P
></DD
><DT
><A
NAME="cv-JAVASOURCEPATH"
></A
><CODE
CLASS="envar"
>JAVASOURCEPATH</CODE
></DT
><DD
><P
>&#13;Specifies the list of directories that
will be searched for input
<TT
CLASS="filename"
>.java</TT
> file.
The directories in this list will be added to the
<SPAN
CLASS="application"
>javac</SPAN
> command line
via the <CODE
CLASS="option"
>-sourcepath</CODE
> option.
The individual directory names will be
separated by the operating system's path separate character
(<TT
CLASS="filename"
>:</TT
> on UNIX/Linux/POSIX,
<TT
CLASS="filename"
>;</TT
> on Windows).</P
><P
>Note that this currently just adds the specified
directory via the <CODE
CLASS="option"
>-sourcepath</CODE
> option.
<SPAN
CLASS="application"
>SCons</SPAN
> does not currently search the
<CODE
CLASS="envar"
>$JAVASOURCEPATH</CODE
> directories for dependency
<TT
CLASS="filename"
>.java</TT
> files.
</P
></DD
><DT
><A
NAME="cv-JAVASUFFIX"
></A
><CODE
CLASS="envar"
>JAVASUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix for Java files;
<TT
CLASS="filename"
>.java</TT
>
by default.
</P
></DD
><DT
><A
NAME="cv-JAVAVERSION"
></A
><CODE
CLASS="envar"
>JAVAVERSION</CODE
></DT
><DD
><P
>&#13;Specifies the Java version being used by the <CODE
CLASS="function"
>Java</CODE
> builder.
This is <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
> currently used to select one
version of the Java compiler vs. another.
Instead, you should set this to specify the version of Java
supported by your <SPAN
CLASS="application"
>javac</SPAN
> compiler.
The default is <TT
CLASS="literal"
>1.4</TT
>.</P
><P
>This is sometimes necessary because
Java 1.5 changed the file names that are created
for nested anonymous inner classes,
which can cause a mismatch with the files
that <SPAN
CLASS="application"
>SCons</SPAN
> expects will be generated by the <SPAN
CLASS="application"
>javac</SPAN
> compiler.
Setting <CODE
CLASS="envar"
>$JAVAVERSION</CODE
> to <TT
CLASS="literal"
>1.5</TT
>
(or <TT
CLASS="literal"
>1.6</TT
>, as appropriate)
can make <SPAN
CLASS="application"
>SCons</SPAN
> realize that a Java 1.5 or 1.6
build is actually up to date.
</P
></DD
><DT
><A
NAME="cv-LATEX"
></A
><CODE
CLASS="envar"
>LATEX</CODE
></DT
><DD
><P
>&#13;The LaTeX structured formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-LATEXCOM"
></A
><CODE
CLASS="envar"
>LATEXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the LaTeX structured formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-LATEXCOMSTR"
></A
><CODE
CLASS="envar"
>LATEXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when calling
the LaTeX structured formatter and typesetter.
If this is not set, then <A
HREF="#cv-LATEXCOM"
><CODE
CLASS="envar"
>$LATEXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(LATEXCOMSTR = "Building $TARGET from LaTeX input $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-LATEXFLAGS"
></A
><CODE
CLASS="envar"
>LATEXFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the LaTeX structured formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-LATEXRETRIES"
></A
><CODE
CLASS="envar"
>LATEXRETRIES</CODE
></DT
><DD
><P
>&#13;The maximum number of times that LaTeX
will be re-run if the
<TT
CLASS="filename"
>.log</TT
>
generated by the <A
HREF="#cv-LATEXCOM"
><CODE
CLASS="envar"
>$LATEXCOM</CODE
></A
> command
indicates that there are undefined references.
The default is to try to resolve undefined references
by re-running LaTeX up to three times.
</P
></DD
><DT
><A
NAME="cv-LATEXSUFFIXES"
></A
><CODE
CLASS="envar"
>LATEXSUFFIXES</CODE
></DT
><DD
><P
>&#13;The list of suffixes of files that will be scanned
for LaTeX implicit dependencies
(<TT
CLASS="literal"
>\include</TT
> or <TT
CLASS="literal"
>\import</TT
> files).
The default list is:
</P
><PRE
CLASS="programlisting"
>&#13;[".tex", ".ltx", ".latex"]
</PRE
></DD
><DT
><A
NAME="cv-LDMODULE"
></A
><CODE
CLASS="envar"
>LDMODULE</CODE
></DT
><DD
><P
>&#13;The linker for building loadable modules.
By default, this is the same as <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-LDMODULECOM"
></A
><CODE
CLASS="envar"
>LDMODULECOM</CODE
></DT
><DD
><P
>&#13;The command line for building loadable modules.
On Mac OS X, this uses the <A
HREF="#cv-LDMODULE"
><CODE
CLASS="envar"
>$LDMODULE</CODE
></A
>,
<A
HREF="#cv-LDMODULEFLAGS"
><CODE
CLASS="envar"
>$LDMODULEFLAGS</CODE
></A
> and
<A
HREF="#cv-FRAMEWORKSFLAGS"
><CODE
CLASS="envar"
>$FRAMEWORKSFLAGS</CODE
></A
> variables.
On other systems, this is the same as <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-LDMODULECOMSTR"
></A
><CODE
CLASS="envar"
>LDMODULECOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when building loadable modules.
If this is not set, then <A
HREF="#cv-LDMODULECOM"
><CODE
CLASS="envar"
>$LDMODULECOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-LDMODULEFLAGS"
></A
><CODE
CLASS="envar"
>LDMODULEFLAGS</CODE
></DT
><DD
><P
>&#13;General user options passed to the linker for building loadable modules.
</P
></DD
><DT
><A
NAME="cv-LDMODULEPREFIX"
></A
><CODE
CLASS="envar"
>LDMODULEPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for loadable module file names.
On Mac OS X, this is null;
on other systems, this is
the same as <A
HREF="#cv-SHLIBPREFIX"
><CODE
CLASS="envar"
>$SHLIBPREFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-LDMODULESUFFIX"
></A
><CODE
CLASS="envar"
>LDMODULESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for loadable module file names.
On Mac OS X, this is null;
on other systems, this is
the same as $SHLIBSUFFIX.
</P
></DD
><DT
><A
NAME="cv-LEX"
></A
><CODE
CLASS="envar"
>LEX</CODE
></DT
><DD
><P
>&#13;The lexical analyzer generator.
</P
></DD
><DT
><A
NAME="cv-LEXCOM"
></A
><CODE
CLASS="envar"
>LEXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the lexical analyzer generator
to generate a source file.
</P
></DD
><DT
><A
NAME="cv-LEXCOMSTR"
></A
><CODE
CLASS="envar"
>LEXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when generating a source file
using the lexical analyzer generator.
If this is not set, then <A
HREF="#cv-LEXCOM"
><CODE
CLASS="envar"
>$LEXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(LEXCOMSTR = "Lex'ing $TARGET from $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-LEXFLAGS"
></A
><CODE
CLASS="envar"
>LEXFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the lexical analyzer generator.
</P
></DD
><DT
><A
NAME="cv-_LIBDIRFLAGS"
></A
><CODE
CLASS="envar"
>_LIBDIRFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the linker command-line options
for specifying directories to be searched for library.
The value of <CODE
CLASS="envar"
>$_LIBDIRFLAGS</CODE
> is created
by appending <CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
> and <CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
>
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$LIBPATH</CODE
>.
</P
></DD
><DT
><A
NAME="cv-LIBDIRPREFIX"
></A
><CODE
CLASS="envar"
>LIBDIRPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used to specify a library directory on the linker command line.
This will be appended to the beginning of each directory
in the <CODE
CLASS="envar"
>$LIBPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_LIBDIRFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-LIBDIRSUFFIX"
></A
><CODE
CLASS="envar"
>LIBDIRSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify a library directory on the linker command line.
This will be appended to the end of each directory
in the <CODE
CLASS="envar"
>$LIBPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_LIBDIRFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-_LIBFLAGS"
></A
><CODE
CLASS="envar"
>_LIBFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the linker command-line options
for specifying libraries to be linked with the resulting target.
The value of <CODE
CLASS="envar"
>$_LIBFLAGS</CODE
> is created
by appending <CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
> and <CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
>
to the beginning and end
of each filename in <CODE
CLASS="envar"
>$LIBS</CODE
>.
</P
></DD
><DT
><A
NAME="cv-LIBLINKPREFIX"
></A
><CODE
CLASS="envar"
>LIBLINKPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used to specify a library to link on the linker command line.
This will be appended to the beginning of each library
in the <CODE
CLASS="envar"
>$LIBS</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_LIBFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-LIBLINKSUFFIX"
></A
><CODE
CLASS="envar"
>LIBLINKSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify a library to link on the linker command line.
This will be appended to the end of each library
in the <CODE
CLASS="envar"
>$LIBS</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_LIBFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-LIBPATH"
></A
><CODE
CLASS="envar"
>LIBPATH</CODE
></DT
><DD
><P
>&#13;The list of directories that will be searched for libraries.
The implicit dependency scanner will search these
directories for include files. Don't explicitly put include directory
arguments in <CODE
CLASS="envar"
>$LINKFLAGS</CODE
> or <CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
>
because the result will be non-portable
and the directories will not be searched by the dependency scanner. Note:
directory names in LIBPATH will be looked-up relative to the SConscript
directory when they are used in a command. To force
<SPAN
CLASS="application"
>scons</SPAN
>
to look-up a directory relative to the root of the source tree use #:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(LIBPATH='#/libs')
</PRE
><P
>&#13;The directory look-up can also be forced using the
<CODE
CLASS="function"
>Dir</CODE
>()
function:
</P
><PRE
CLASS="programlisting"
>&#13;libs = Dir('libs')
env = Environment(LIBPATH=libs)
</PRE
><P
>&#13;The directory list will be added to command lines
through the automatically-generated
<CODE
CLASS="envar"
>$_LIBDIRFLAGS</CODE
>
construction variable,
which is constructed by
appending the values of the
<CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
> and <CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
>
construction variables
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$LIBPATH</CODE
>.
Any command lines you define that need
the LIBPATH directory list should
include <CODE
CLASS="envar"
>$_LIBDIRFLAGS</CODE
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(LINKCOM="my_linker $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET $SOURCE")
</PRE
></DD
><DT
><A
NAME="cv-LIBPREFIX"
></A
><CODE
CLASS="envar"
>LIBPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for (static) library file names.
A default value is set for each platform
(posix, win32, os2, etc.),
but the value is overridden by individual tools
(ar, mslib, sgiar, sunar, tlib, etc.)
to reflect the names of the libraries they create.
</P
></DD
><DT
><A
NAME="cv-LIBPREFIXES"
></A
><CODE
CLASS="envar"
>LIBPREFIXES</CODE
></DT
><DD
><P
>&#13;A list of all legal prefixes for library file names.
When searching for library dependencies,
SCons will look for files with these prefixes,
the base library name,
and suffixes in the <CODE
CLASS="envar"
>$LIBSUFFIXES</CODE
> list.
</P
></DD
><DT
><A
NAME="cv-LIBS"
></A
><CODE
CLASS="envar"
>LIBS</CODE
></DT
><DD
><P
>&#13;A list of one or more libraries
that will be linked with
any executable programs
created by this environment.</P
><P
>The library list will be added to command lines
through the automatically-generated
<CODE
CLASS="envar"
>$_LIBFLAGS</CODE
>
construction variable,
which is constructed by
appending the values of the
<CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
> and <CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
>
construction variables
to the beginning and end
of each filename in <CODE
CLASS="envar"
>$LIBS</CODE
>.
Any command lines you define that need
the LIBS library list should
include <CODE
CLASS="envar"
>$_LIBFLAGS</CODE
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(LINKCOM="my_linker $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET $SOURCE")
</PRE
><P
>&#13;If you add a
File
object to the
<CODE
CLASS="envar"
>$LIBS</CODE
>
list, the name of that file will be added to
<CODE
CLASS="envar"
>$_LIBFLAGS</CODE
>,
and thus the link line, as is, without
<CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
>
or
<CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
>.
For example:
</P
><PRE
CLASS="programlisting"
>&#13;env.Append(LIBS=File('/tmp/mylib.so'))
</PRE
><P
>&#13;In all cases, scons will add dependencies from the executable program to
all the libraries in this list.
</P
></DD
><DT
><A
NAME="cv-LIBSUFFIX"
></A
><CODE
CLASS="envar"
>LIBSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for (static) library file names.
A default value is set for each platform
(posix, win32, os2, etc.),
but the value is overridden by individual tools
(ar, mslib, sgiar, sunar, tlib, etc.)
to reflect the names of the libraries they create.
</P
></DD
><DT
><A
NAME="cv-LIBSUFFIXES"
></A
><CODE
CLASS="envar"
>LIBSUFFIXES</CODE
></DT
><DD
><P
>&#13;A list of all legal suffixes for library file names.
When searching for library dependencies,
SCons will look for files with prefixes, in the <CODE
CLASS="envar"
>$LIBPREFIXES</CODE
> list,
the base library name,
and these suffixes.
</P
></DD
><DT
><A
NAME="cv-LICENSE"
></A
><CODE
CLASS="envar"
>LICENSE</CODE
></DT
><DD
><P
>&#13;The abbreviated name of the license under which
this project is released (gpl, lpgl, bsd etc.).
See http://www.opensource.org/licenses/alphabetical
for a list of license names.
</P
></DD
><DT
><A
NAME="cv-LINK"
></A
><CODE
CLASS="envar"
>LINK</CODE
></DT
><DD
><P
>&#13;The linker.
</P
></DD
><DT
><A
NAME="cv-LINKCOM"
></A
><CODE
CLASS="envar"
>LINKCOM</CODE
></DT
><DD
><P
>&#13;The command line used to link object files into an executable.
</P
></DD
><DT
><A
NAME="cv-LINKCOMSTR"
></A
><CODE
CLASS="envar"
>LINKCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when object files
are linked into an executable.
If this is not set, then <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(LINKCOMSTR = "Linking $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-LINKFLAGS"
></A
><CODE
CLASS="envar"
>LINKFLAGS</CODE
></DT
><DD
><P
>&#13;General user options passed to the linker.
Note that this variable should
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
contain
<CODE
CLASS="option"
>-l</CODE
>
(or similar) options for linking with the libraries listed in <A
HREF="#cv-LIBS"
><CODE
CLASS="envar"
>$LIBS</CODE
></A
>,
nor
<CODE
CLASS="option"
>-L</CODE
>
(or similar) library search path options
that scons generates automatically from <A
HREF="#cv-LIBPATH"
><CODE
CLASS="envar"
>$LIBPATH</CODE
></A
>.
See
<A
HREF="#cv-_LIBFLAGS"
><CODE
CLASS="envar"
>$_LIBFLAGS</CODE
></A
>
above,
for the variable that expands to library-link options,
and
<A
HREF="#cv-_LIBDIRFLAGS"
><CODE
CLASS="envar"
>$_LIBDIRFLAGS</CODE
></A
>
above,
for the variable that expands to library search path options.
</P
></DD
><DT
><A
NAME="cv-M4"
></A
><CODE
CLASS="envar"
>M4</CODE
></DT
><DD
><P
>&#13;The M4 macro preprocessor.
</P
></DD
><DT
><A
NAME="cv-M4COM"
></A
><CODE
CLASS="envar"
>M4COM</CODE
></DT
><DD
><P
>&#13;The command line used to pass files through the M4 macro preprocessor.
</P
></DD
><DT
><A
NAME="cv-M4COMSTR"
></A
><CODE
CLASS="envar"
>M4COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when
a file is passed through the M4 macro preprocessor.
If this is not set, then <A
HREF="#cv-M4COM"
><CODE
CLASS="envar"
>$M4COM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-M4FLAGS"
></A
><CODE
CLASS="envar"
>M4FLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the M4 macro preprocessor.
</P
></DD
><DT
><A
NAME="cv-MAKEINDEX"
></A
><CODE
CLASS="envar"
>MAKEINDEX</CODE
></DT
><DD
><P
>&#13;The makeindex generator for the TeX formatter and typesetter and the
LaTeX structured formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-MAKEINDEXCOM"
></A
><CODE
CLASS="envar"
>MAKEINDEXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the makeindex generator for the
TeX formatter and typesetter and the LaTeX structured formatter and
typesetter.
</P
></DD
><DT
><A
NAME="cv-MAKEINDEXCOMSTR"
></A
><CODE
CLASS="envar"
>MAKEINDEXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when calling the makeindex generator for the
TeX formatter and typesetter
and the LaTeX structured formatter and typesetter.
If this is not set, then <A
HREF="#cv-MAKEINDEXCOM"
><CODE
CLASS="envar"
>$MAKEINDEXCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-MAKEINDEXFLAGS"
></A
><CODE
CLASS="envar"
>MAKEINDEXFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the makeindex generator for the TeX formatter
and typesetter and the LaTeX structured formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-MAXLINELENGTH"
></A
><CODE
CLASS="envar"
>MAXLINELENGTH</CODE
></DT
><DD
><P
>&#13;The maximum number of characters allowed on an external command line.
On Win32 systems,
link lines longer than this many characters
are linked via a temporary file name.
</P
></DD
><DT
><A
NAME="cv-MIDL"
></A
><CODE
CLASS="envar"
>MIDL</CODE
></DT
><DD
><P
>&#13;The Microsoft IDL compiler.
</P
></DD
><DT
><A
NAME="cv-MIDLCOM"
></A
><CODE
CLASS="envar"
>MIDLCOM</CODE
></DT
><DD
><P
>&#13;The command line used to pass files to the Microsoft IDL compiler.
</P
></DD
><DT
><A
NAME="cv-MIDLCOMSTR"
></A
><CODE
CLASS="envar"
>MIDLCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when
the Microsoft IDL copmiler is called.
If this is not set, then <A
HREF="#cv-MIDLCOM"
><CODE
CLASS="envar"
>$MIDLCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-MIDLFLAGS"
></A
><CODE
CLASS="envar"
>MIDLFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the Microsoft IDL compiler.
</P
></DD
><DT
><A
NAME="cv-MSVS"
></A
><CODE
CLASS="envar"
>MSVS</CODE
></DT
><DD
><P
>&#13;When the Microsoft Visual Studio tools are initialized, they set up
this dictionary with the following keys:</P
><P
><CODE
CLASS="envar"
>VERSION</CODE
>:
the version of MSVS being used (can be set via
MSVS_VERSION)</P
><P
><CODE
CLASS="envar"
>VERSIONS</CODE
>:
the available versions of MSVS installed</P
><P
><CODE
CLASS="envar"
>VCINSTALLDIR</CODE
>:
installed directory of Visual C++</P
><P
><CODE
CLASS="envar"
>VSINSTALLDIR</CODE
>:
installed directory of Visual Studio</P
><P
><CODE
CLASS="envar"
>FRAMEWORKDIR</CODE
>:
installed directory of the .NET framework</P
><P
><CODE
CLASS="envar"
>FRAMEWORKVERSIONS</CODE
>:
list of installed versions of the .NET framework, sorted latest to oldest.</P
><P
><CODE
CLASS="envar"
>FRAMEWORKVERSION</CODE
>:
latest installed version of the .NET framework</P
><P
><CODE
CLASS="envar"
>FRAMEWORKSDKDIR</CODE
>:
installed location of the .NET SDK.</P
><P
><CODE
CLASS="envar"
>PLATFORMSDKDIR</CODE
>:
installed location of the Platform SDK.</P
><P
><CODE
CLASS="envar"
>PLATFORMSDK_MODULES</CODE
>:
dictionary of installed Platform SDK modules,
where the dictionary keys are keywords for the various modules, and
the values are 2-tuples where the first is the release date, and the
second is the version number.</P
><P
>If a value isn't set, it wasn't available in the registry.
</P
></DD
><DT
><A
NAME="cv-MSVS_IGNORE_IDE_PATHS"
></A
><CODE
CLASS="envar"
>MSVS_IGNORE_IDE_PATHS</CODE
></DT
><DD
><P
>&#13;Tells the MS Visual Studio tools to use minimal INCLUDE, LIB, and PATH settings,
instead of the settings from the IDE.</P
><P
>For Visual Studio, SCons will (by default) automatically determine
where MSVS is installed, and use the LIB, INCLUDE, and PATH variables
set by the IDE.  You can override this behavior by setting these
variables after Environment initialization, or by setting
<CODE
CLASS="envar"
>MSVS_IGNORE_IDE_PATHS = 1</CODE
>
in the Environment initialization.
Specifying this will not leave these unset, but will set them to a
minimal set of paths needed to run the tools successfully.</P
><P
>For VS6, the mininimal set is:
</P
><PRE
CLASS="programlisting"
>&#13;   INCLUDE:'&#60;VSDir&#62;\VC98\ATL\include;&#60;VSDir&#62;\VC98\MFC\include;&#60;VSDir&#62;\VC98\include'
   LIB:'&#60;VSDir&#62;\VC98\MFC\lib;&#60;VSDir&#62;\VC98\lib'
   PATH:'&#60;VSDir&#62;\Common\MSDev98\bin;&#60;VSDir&#62;\VC98\bin'
</PRE
><P
>&#13;For VS7, it is:
</P
><PRE
CLASS="programlisting"
>&#13;   INCLUDE:'&#60;VSDir&#62;\Vc7\atlmfc\include;&#60;VSDir&#62;\Vc7\include'
   LIB:'&#60;VSDir&#62;\Vc7\atlmfc\lib;&#60;VSDir&#62;\Vc7\lib'
   PATH:'&#60;VSDir&#62;\Common7\Tools\bin;&#60;VSDir&#62;\Common7\Tools;&#60;VSDir&#62;\Vc7\bin'
</PRE
><P
>&#13;Where '&#60;VSDir&#62;' is the installed location of Visual Studio.
</P
></DD
><DT
><A
NAME="cv-MSVS_PROJECT_BASE_PATH"
></A
><CODE
CLASS="envar"
>MSVS_PROJECT_BASE_PATH</CODE
></DT
><DD
><P
>&#13;The string
placed in a generated Microsoft Visual Studio solution file
as the value of the
<TT
CLASS="literal"
>SccProjectFilePathRelativizedFromConnection0</TT
>
and
<TT
CLASS="literal"
>SccProjectFilePathRelativizedFromConnection1</TT
>
attributes of the
<TT
CLASS="literal"
>GlobalSection(SourceCodeControl)</TT
>
section.
There is no default value.
</P
></DD
><DT
><A
NAME="cv-MSVS_PROJECT_GUID"
></A
><CODE
CLASS="envar"
>MSVS_PROJECT_GUID</CODE
></DT
><DD
><P
>&#13;The string
placed in a generated Microsoft Visual Studio project file
as the value of the
<TT
CLASS="literal"
>ProjectGUID</TT
>
attribute.
The string is also placed in the
<TT
CLASS="literal"
>SolutionUniqueID</TT
>
attribute of the
<TT
CLASS="literal"
>GlobalSection(SourceCodeControl)</TT
>
section of the Microsoft Visual Studio solution file.
There is no default value.
</P
></DD
><DT
><A
NAME="cv-MSVS_SCC_AUX_PATH"
></A
><CODE
CLASS="envar"
>MSVS_SCC_AUX_PATH</CODE
></DT
><DD
><P
>&#13;The path name
placed in a generated Microsoft Visual Studio project file
as the value of the
<TT
CLASS="literal"
>SccAuxPath</TT
>
attribute
if the
<CODE
CLASS="envar"
>MSVS_SCC_PROVIDER</CODE
>
construction variable is also set.
There is no default value.
</P
></DD
><DT
><A
NAME="cv-MSVS_SCC_LOCAL_PATH"
></A
><CODE
CLASS="envar"
>MSVS_SCC_LOCAL_PATH</CODE
></DT
><DD
><P
>&#13;The path name
placed in a generated Microsoft Visual Studio project file
as the value of the
<TT
CLASS="literal"
>SccLocalPath</TT
>
attribute
if the
<CODE
CLASS="envar"
>MSVS_SCC_PROVIDER</CODE
>
construction variable is also set.
The path name is also placed in the
<TT
CLASS="literal"
>SccLocalPath0</TT
>
and
<TT
CLASS="literal"
>SccLocalPath1</TT
>
attributes of the
<TT
CLASS="literal"
>GlobalSection(SourceCodeControl)</TT
>
section of the Microsoft Visual Studio solution file.
There is no default value.
</P
></DD
><DT
><A
NAME="cv-MSVS_SCC_PROJECT_NAME"
></A
><CODE
CLASS="envar"
>MSVS_SCC_PROJECT_NAME</CODE
></DT
><DD
><P
>&#13;The project name
placed in a generated Microsoft Visual Studio project file
as the value of the
<TT
CLASS="literal"
>SccProjectName</TT
>
attribute.
There is no default value.
</P
></DD
><DT
><A
NAME="cv-MSVS_SCC_PROVIDER"
></A
><CODE
CLASS="envar"
>MSVS_SCC_PROVIDER</CODE
></DT
><DD
><P
>&#13;The string
placed in a generated Microsoft Visual Studio project file
as the value of the
<TT
CLASS="literal"
>SccProvider</TT
>
attribute.
The string is also placed in the
<TT
CLASS="literal"
>SccProvider1</TT
>
attribute of the
<TT
CLASS="literal"
>GlobalSection(SourceCodeControl)</TT
>
section of the Microsoft Visual Studio solution file.
There is no default value.
</P
></DD
><DT
><A
NAME="cv-MSVS_USE_MFC_DIRS"
></A
><CODE
CLASS="envar"
>MSVS_USE_MFC_DIRS</CODE
></DT
><DD
><P
>&#13;Tells the MS Visual Studio tool(s) to use
the MFC directories in its default paths
for compiling and linking.
The <CODE
CLASS="envar"
>$MSVS_USE_MFC_DIRS</CODE
> variable has no effect if the
<CODE
CLASS="envar"
>INCLUDE</CODE
>
or
<CODE
CLASS="envar"
>LIB</CODE
>
environment variables are set explictly.</P
><P
>Under Visual Studio version 6,
setting
<CODE
CLASS="envar"
>$MSVS_USE_MFC_DIRS</CODE
>
to a non-zero value
adds the
<TT
CLASS="filename"
>ATL\include</TT
>
and
<TT
CLASS="filename"
>MFC\include</TT
>
directories to
the default
<CODE
CLASS="envar"
>INCLUDE</CODE
>
external environment variable,
and adds the
<TT
CLASS="filename"
>MFC\lib</TT
>
directory to
the default
<CODE
CLASS="envar"
>LIB</CODE
>
external environment variable.</P
><P
>Under Visual Studio version 7,
setting
<CODE
CLASS="envar"
>$MSVS_USE_MFC_DIRS</CODE
>
to a non-zero value
adds the
<TT
CLASS="filename"
>atlmfc\include</TT
>
directory to the default
<CODE
CLASS="envar"
>INCLUDE</CODE
>
external environment variable,
and adds the
<TT
CLASS="filename"
>atlmfc\lib</TT
>
directory to the default
<CODE
CLASS="envar"
>LIB</CODE
>
external environment variable.</P
><P
>Under Visual Studio version 8,
setting
<CODE
CLASS="envar"
>$MSVS_USE_MFC_DIRS</CODE
>
to a non-zero value will,
by default,
add the
<TT
CLASS="filename"
>atlmfc\include</TT
>
directory to the default
<CODE
CLASS="envar"
>INCLUDE</CODE
>
external environment variable,
and the
<TT
CLASS="filename"
>atlmfc\lib</TT
>
directory to the default
<CODE
CLASS="envar"
>LIB</CODE
>
external environment variable.
If, however, the
<CODE
CLASS="envar"
>['MSVS']['PLATFORMSDKDIR']</CODE
>
variable is set,
then the
<TT
CLASS="filename"
>mfc</TT
>
and the
<TT
CLASS="filename"
>atl</TT
>
subdirectories of the
<CODE
CLASS="envar"
>PLATFORMSDKDIR</CODE
>
are added to the default value of the
<CODE
CLASS="envar"
>INCLUDE</CODE
>
external environment variable,
and the default value of the
<CODE
CLASS="envar"
>LIB</CODE
>
external environment variable is left untouched.
</P
></DD
><DT
><A
NAME="cv-MSVS_VERSION"
></A
><CODE
CLASS="envar"
>MSVS_VERSION</CODE
></DT
><DD
><P
>&#13;Sets the preferred version of MSVS to use.</P
><P
>SCons will (by default) select the latest version of MSVS
installed on your machine.
So, if you have version 6 and version 7 (MSVS .NET) installed,
it will prefer version 7.
You can override this by
specifying the
<CODE
CLASS="envar"
>MSVS_VERSION</CODE
>
variable in the Environment initialization, setting it to the
appropriate version ('6.0' or '7.0', for example).
If the given version isn't installed, tool initialization will fail.
</P
></DD
><DT
><A
NAME="cv-MSVSBUILDCOM"
></A
><CODE
CLASS="envar"
>MSVSBUILDCOM</CODE
></DT
><DD
><P
>&#13;The build command line placed in
a generated Microsoft Visual Studio project file.
The default is to have Visual Studio invoke SCons with any specified
build targets.
</P
></DD
><DT
><A
NAME="cv-MSVSCLEANCOM"
></A
><CODE
CLASS="envar"
>MSVSCLEANCOM</CODE
></DT
><DD
><P
>&#13;The clean command line placed in
a generated Microsoft Visual Studio project file.
The default is to have Visual Studio invoke SCons with the -c option
to remove any specified targets.
</P
></DD
><DT
><A
NAME="cv-MSVSENCODING"
></A
><CODE
CLASS="envar"
>MSVSENCODING</CODE
></DT
><DD
><P
>&#13;The encoding string placed in
a generated Microsoft Visual Studio project file.
The default is encoding
<TT
CLASS="literal"
>Windows-1252</TT
>.
</P
></DD
><DT
><A
NAME="cv-MSVSPROJECTCOM"
></A
><CODE
CLASS="envar"
>MSVSPROJECTCOM</CODE
></DT
><DD
><P
>&#13;The action used to generate Microsoft Visual Studio project files.
</P
></DD
><DT
><A
NAME="cv-MSVSPROJECTSUFFIX"
></A
><CODE
CLASS="envar"
>MSVSPROJECTSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for Microsoft Visual Studio project (DSP) files.
The default value is
<TT
CLASS="filename"
>.vcproj</TT
>
when using Visual Studio version 7.x (.NET)
or later version,
and
<TT
CLASS="filename"
>.dsp</TT
>
when using earlier versions of Visual Studio.
</P
></DD
><DT
><A
NAME="cv-MSVSREBUILDCOM"
></A
><CODE
CLASS="envar"
>MSVSREBUILDCOM</CODE
></DT
><DD
><P
>&#13;The rebuild command line placed in
a generated Microsoft Visual Studio project file.
The default is to have Visual Studio invoke SCons with any specified
rebuild targets.
</P
></DD
><DT
><A
NAME="cv-MSVSSCONS"
></A
><CODE
CLASS="envar"
>MSVSSCONS</CODE
></DT
><DD
><P
>&#13;The SCons used in generated Microsoft Visual Studio project files.
The default is the version of SCons being
used to generate the project file.
</P
></DD
><DT
><A
NAME="cv-MSVSSCONSCOM"
></A
><CODE
CLASS="envar"
>MSVSSCONSCOM</CODE
></DT
><DD
><P
>&#13;The default SCons command used in generated Microsoft Visual Studio
project files.
</P
></DD
><DT
><A
NAME="cv-MSVSSCONSCRIPT"
></A
><CODE
CLASS="envar"
>MSVSSCONSCRIPT</CODE
></DT
><DD
><P
>&#13;The sconscript file
(that is,
<TT
CLASS="filename"
>SConstruct</TT
>
or
<TT
CLASS="filename"
>SConscript</TT
>
file)
that will be invoked by Visual Studio
project files
(through the
<A
HREF="#cv-MSVSSCONSCOM"
><CODE
CLASS="envar"
>$MSVSSCONSCOM</CODE
></A
>
variable).
The default is the same sconscript file
that contains the call to
<CODE
CLASS="function"
>MSVSProject</CODE
>
to build the project file.
</P
></DD
><DT
><A
NAME="cv-MSVSSCONSFLAGS"
></A
><CODE
CLASS="envar"
>MSVSSCONSFLAGS</CODE
></DT
><DD
><P
>&#13;The SCons flags used in generated Microsoft Visual Studio
project files.
</P
></DD
><DT
><A
NAME="cv-MSVSSOLUTIONCOM"
></A
><CODE
CLASS="envar"
>MSVSSOLUTIONCOM</CODE
></DT
><DD
><P
>&#13;The action used to generate Microsoft Visual Studio solution files.
</P
></DD
><DT
><A
NAME="cv-MSVSSOLUTIONSUFFIX"
></A
><CODE
CLASS="envar"
>MSVSSOLUTIONSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for Microsoft Visual Studio solution (DSW) files.
The default value is
<TT
CLASS="filename"
>.sln</TT
>
when using Visual Studio version 7.x (.NET),
and
<TT
CLASS="filename"
>.dsw</TT
>
when using earlier versions of Visual Studio.
</P
></DD
><DT
><A
NAME="cv-MWCW_VERSION"
></A
><CODE
CLASS="envar"
>MWCW_VERSION</CODE
></DT
><DD
><P
>&#13;The version number of the MetroWerks CodeWarrior C compiler
to be used.
</P
></DD
><DT
><A
NAME="cv-MWCW_VERSIONS"
></A
><CODE
CLASS="envar"
>MWCW_VERSIONS</CODE
></DT
><DD
><P
>&#13;A list of installed versions of the MetroWerks CodeWarrior C compiler
on this system.
</P
></DD
><DT
><A
NAME="cv-NAME"
></A
><CODE
CLASS="envar"
>NAME</CODE
></DT
><DD
><P
>&#13;Specfies the name of the project to package.
</P
></DD
><DT
><A
NAME="cv-no_import_lib"
></A
><CODE
CLASS="envar"
>no_import_lib</CODE
></DT
><DD
><P
>&#13;When set to non-zero,
suppresses creation of a corresponding Windows static import lib by the
<TT
CLASS="literal"
>SharedLibrary</TT
>
builder when used with
MinGW, Microsoft Visual Studio or Metrowerks.
This also suppresses creation
of an export (.exp) file
when using Microsoft Visual Studio.
</P
></DD
><DT
><A
NAME="cv-OBJPREFIX"
></A
><CODE
CLASS="envar"
>OBJPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for (static) object file names.
</P
></DD
><DT
><A
NAME="cv-OBJSUFFIX"
></A
><CODE
CLASS="envar"
>OBJSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for (static) object file names.
</P
></DD
><DT
><A
NAME="cv-P4"
></A
><CODE
CLASS="envar"
>P4</CODE
></DT
><DD
><P
>&#13;The Perforce executable.
</P
></DD
><DT
><A
NAME="cv-P4COM"
></A
><CODE
CLASS="envar"
>P4COM</CODE
></DT
><DD
><P
>&#13;The command line used to
fetch source files from Perforce.
</P
></DD
><DT
><A
NAME="cv-P4COMSTR"
></A
><CODE
CLASS="envar"
>P4COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when
fetching a source file from Perforce.
If this is not set, then <A
HREF="#cv-P4COM"
><CODE
CLASS="envar"
>$P4COM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-P4FLAGS"
></A
><CODE
CLASS="envar"
>P4FLAGS</CODE
></DT
><DD
><P
>&#13;General options that are passed to Perforce.
</P
></DD
><DT
><A
NAME="cv-PACKAGEROOT"
></A
><CODE
CLASS="envar"
>PACKAGEROOT</CODE
></DT
><DD
><P
>&#13;Specifies the directory where all files in resulting archive will be
placed if applicable.  The default value is "$NAME-$VERSION".
</P
></DD
><DT
><A
NAME="cv-PACKAGETYPE"
></A
><CODE
CLASS="envar"
>PACKAGETYPE</CODE
></DT
><DD
><P
>&#13;Selects the package type to build.  Currently these are available:</P
><P
> * msi - Microsoft Installer
 * rpm - Redhat Package Manger
 * ipkg - Itsy Package Management System
 * tarbz2 - compressed tar
 * targz - compressed tar
 * zip - zip file
 * src_tarbz2 - compressed tar source
 * src_targz - compressed tar source
 * src_zip - zip file source</P
><P
>This may be overridden with the "package_type" command line option.
</P
></DD
><DT
><A
NAME="cv-PACKAGEVERSION"
></A
><CODE
CLASS="envar"
>PACKAGEVERSION</CODE
></DT
><DD
><P
>&#13;The version of the package (not the underlying project).
This is currently only used by the rpm packager
and should reflect changes in the packaging,
not the underlying project code itself.
</P
></DD
><DT
><A
NAME="cv-PCH"
></A
><CODE
CLASS="envar"
>PCH</CODE
></DT
><DD
><P
>&#13;The Microsoft Visual C++ precompiled header that will be used when compiling
object files. This variable is ignored by tools other than Microsoft Visual C++.
When this variable is
defined SCons will add options to the compiler command line to
cause it to use the precompiled header, and will also set up the
dependencies for the PCH file.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env['PCH'] = 'StdAfx.pch'
</PRE
></DD
><DT
><A
NAME="cv-PCHCOM"
></A
><CODE
CLASS="envar"
>PCHCOM</CODE
></DT
><DD
><P
>&#13;The command line used by the
<CODE
CLASS="function"
>PCH</CODE
>
builder to generated a precompiled header.
</P
></DD
><DT
><A
NAME="cv-PCHCOMSTR"
></A
><CODE
CLASS="envar"
>PCHCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when generating a precompiled header.
If this is not set, then <A
HREF="#cv-PCHCOM"
><CODE
CLASS="envar"
>$PCHCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-PCHPDBFLAGS"
></A
><CODE
CLASS="envar"
>PCHPDBFLAGS</CODE
></DT
><DD
><P
>&#13;A construction variable that, when expanded,
adds the <TT
CLASS="literal"
>/yD</TT
> flag to the command line
only if the <CODE
CLASS="envar"
>$PDB</CODE
> construction variable is set.
</P
></DD
><DT
><A
NAME="cv-PCHSTOP"
></A
><CODE
CLASS="envar"
>PCHSTOP</CODE
></DT
><DD
><P
>&#13;This variable specifies how much of a source file is precompiled. This
variable is ignored by tools other than Microsoft Visual C++, or when
the PCH variable is not being used. When this variable is define it
must be a string that is the name of the header that
is included at the end of the precompiled portion of the source files, or
the empty string if the "#pragma hrdstop" construct is being used:
</P
><PRE
CLASS="programlisting"
>&#13;env['PCHSTOP'] = 'StdAfx.h'
</PRE
></DD
><DT
><A
NAME="cv-PDB"
></A
><CODE
CLASS="envar"
>PDB</CODE
></DT
><DD
><P
>&#13;The Microsoft Visual C++ PDB file that will store debugging information for
object files, shared libraries, and programs. This variable is ignored by
tools other than Microsoft Visual C++.
When this variable is
defined SCons will add options to the compiler and linker command line to
cause them to generate external debugging information, and will also set up the
dependencies for the PDB file.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env['PDB'] = 'hello.pdb'
</PRE
><P
>&#13;The Visual C++ compiler switch that SCons uses by default
to generate PDB information is <CODE
CLASS="option"
>/Z7</CODE
>.
This works correctly with parallel (<CODE
CLASS="option"
>-j</CODE
>) builds
because it embeds the debug information in the intermediate object files,
as opposed to sharing a single PDB file between multiple object files.
This is also the only way to get debug information
embedded into a static library.
Using the <CODE
CLASS="option"
>/Zi</CODE
> instead may yield improved
link-time performance,
although parallel builds will no longer work.
You can generate PDB files with the <CODE
CLASS="option"
>/Zi</CODE
>
switch by overriding the default <A
HREF="#cv-CCPDBFLAGS"
><CODE
CLASS="envar"
>$CCPDBFLAGS</CODE
></A
> variable;
see the entry for that variable for specific examples.
</P
></DD
><DT
><A
NAME="cv-PDFCOM"
></A
><CODE
CLASS="envar"
>PDFCOM</CODE
></DT
><DD
><P
>&#13;A deprecated synonym for <A
HREF="#cv-DVIPDFCOM"
><CODE
CLASS="envar"
>$DVIPDFCOM</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-PDFLATEX"
></A
><CODE
CLASS="envar"
>PDFLATEX</CODE
></DT
><DD
><P
>&#13;The <SPAN
CLASS="application"
>pdflatex</SPAN
> utility.
</P
></DD
><DT
><A
NAME="cv-PDFLATEXCOM"
></A
><CODE
CLASS="envar"
>PDFLATEXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the <SPAN
CLASS="application"
>pdflatex</SPAN
> utility.
</P
></DD
><DT
><A
NAME="cv-PDFLATEXCOMSTR"
></A
><CODE
CLASS="envar"
>PDFLATEXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when calling the <SPAN
CLASS="application"
>pdflatex</SPAN
> utility.
If this is not set, then <A
HREF="#cv-PDFLATEXCOM"
><CODE
CLASS="envar"
>$PDFLATEXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(PDFLATEX;COMSTR = "Building $TARGET from LaTeX input $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-PDFLATEXFLAGS"
></A
><CODE
CLASS="envar"
>PDFLATEXFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the <SPAN
CLASS="application"
>pdflatex</SPAN
> utility.
</P
></DD
><DT
><A
NAME="cv-PDFPREFIX"
></A
><CODE
CLASS="envar"
>PDFPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for PDF file names.
</P
></DD
><DT
><A
NAME="cv-PDFSUFFIX"
></A
><CODE
CLASS="envar"
>PDFSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for PDF file names.
</P
></DD
><DT
><A
NAME="cv-PDFTEX"
></A
><CODE
CLASS="envar"
>PDFTEX</CODE
></DT
><DD
><P
>&#13;The <SPAN
CLASS="application"
>pdftex</SPAN
> utility.
</P
></DD
><DT
><A
NAME="cv-PDFTEXCOM"
></A
><CODE
CLASS="envar"
>PDFTEXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the <SPAN
CLASS="application"
>pdftex</SPAN
> utility.
</P
></DD
><DT
><A
NAME="cv-PDFTEXCOMSTR"
></A
><CODE
CLASS="envar"
>PDFTEXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when calling the <SPAN
CLASS="application"
>pdftex</SPAN
> utility.
If this is not set, then <A
HREF="#cv-PDFTEXCOM"
><CODE
CLASS="envar"
>$PDFTEXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(PDFTEXCOMSTR = "Building $TARGET from TeX input $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-PDFTEXFLAGS"
></A
><CODE
CLASS="envar"
>PDFTEXFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the <SPAN
CLASS="application"
>pdftex</SPAN
> utility.
</P
></DD
><DT
><A
NAME="cv-PKGCHK"
></A
><CODE
CLASS="envar"
>PKGCHK</CODE
></DT
><DD
><P
>&#13;On Solaris systems,
the package-checking program that will
be used (along with <CODE
CLASS="envar"
>$PKGINFO</CODE
>)
to look for installed versions of
the Sun PRO C++ compiler.
The default is
<TT
CLASS="filename"
>/usr/sbin/pgkchk</TT
>.
</P
></DD
><DT
><A
NAME="cv-PKGINFO"
></A
><CODE
CLASS="envar"
>PKGINFO</CODE
></DT
><DD
><P
>&#13;On Solaris systems,
the package information program that will
be used (along with <CODE
CLASS="envar"
>$PKGCHK</CODE
>)
to look for installed versions of
the Sun PRO C++ compiler.
The default is
<TT
CLASS="filename"
>pkginfo</TT
>.
</P
></DD
><DT
><A
NAME="cv-PLATFORM"
></A
><CODE
CLASS="envar"
>PLATFORM</CODE
></DT
><DD
><P
>&#13;The name of the platform used to create the Environment.  If no platform is
specified when the Environment is created,
<SPAN
CLASS="application"
>scons</SPAN
>
autodetects the platform.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(tools = [])
if env['PLATFORM'] == 'cygwin':
    Tool('mingw')(env)
else:
    Tool('msvc')(env)
</PRE
></DD
><DT
><A
NAME="cv-PRINT_CMD_LINE_FUNC"
></A
><CODE
CLASS="envar"
>PRINT_CMD_LINE_FUNC</CODE
></DT
><DD
><P
>&#13;A Python function used to print the command lines as they are executed
(assuming command printing is not disabled by the
<CODE
CLASS="option"
>-q</CODE
>
or
<CODE
CLASS="option"
>-s</CODE
>
options or their equivalents).
The function should take four arguments:
<CODE
CLASS="varname"
>s</CODE
>,
the command being executed (a string),
<CODE
CLASS="varname"
>target</CODE
>,
the target being built (file node, list, or string name(s)),
<CODE
CLASS="varname"
>source</CODE
>,
the source(s) used (file node, list, or string name(s)), and
<CODE
CLASS="varname"
>env</CODE
>,
the environment being used.</P
><P
>The function must do the printing itself.  The default implementation,
used if this variable is not set or is None, is:
</P
><PRE
CLASS="programlisting"
>&#13;def print_cmd_line(s, target, source, env):
  sys.stdout.write(s + "\n")
</PRE
><P
>&#13;Here's an example of a more interesting function:
</P
><PRE
CLASS="programlisting"
>&#13;def print_cmd_line(s, target, source, env):
   sys.stdout.write("Building %s -&#62; %s...\n" %
    (' and '.join([str(x) for x in source]),
     ' and '.join([str(x) for x in target])))
env=Environment(PRINT_CMD_LINE_FUNC=print_cmd_line)
env.Program('foo', 'foo.c')
</PRE
><P
>&#13;This just prints "Building <CODE
CLASS="varname"
>targetname</CODE
> from <CODE
CLASS="varname"
>sourcename</CODE
>..." instead
of the actual commands.
Such a function could also log the actual commands to a log file,
for example.
</P
></DD
><DT
><A
NAME="cv-PROGPREFIX"
></A
><CODE
CLASS="envar"
>PROGPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for executable file names.
</P
></DD
><DT
><A
NAME="cv-PROGSUFFIX"
></A
><CODE
CLASS="envar"
>PROGSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for executable file names.
</P
></DD
><DT
><A
NAME="cv-PSCOM"
></A
><CODE
CLASS="envar"
>PSCOM</CODE
></DT
><DD
><P
>&#13;The command line used to convert TeX DVI files into a PostScript file.
</P
></DD
><DT
><A
NAME="cv-PSCOMSTR"
></A
><CODE
CLASS="envar"
>PSCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a TeX DVI file
is converted into a PostScript file.
If this is not set, then <A
HREF="#cv-PSCOM"
><CODE
CLASS="envar"
>$PSCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-PSPREFIX"
></A
><CODE
CLASS="envar"
>PSPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for PostScript file names.
</P
></DD
><DT
><A
NAME="cv-PSSUFFIX"
></A
><CODE
CLASS="envar"
>PSSUFFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for PostScript file names.
</P
></DD
><DT
><A
NAME="cv-QT_AUTOSCAN"
></A
><CODE
CLASS="envar"
>QT_AUTOSCAN</CODE
></DT
><DD
><P
>&#13;Turn off scanning for mocable files. Use the Moc Builder to explicitely
specify files to run moc on.
</P
></DD
><DT
><A
NAME="cv-QT_BINPATH"
></A
><CODE
CLASS="envar"
>QT_BINPATH</CODE
></DT
><DD
><P
>&#13;The path where the qt binaries are installed.
The default value is '<A
HREF="#cv-QTDIR"
><CODE
CLASS="envar"
>$QTDIR</CODE
></A
>/bin'.
</P
></DD
><DT
><A
NAME="cv-QT_CPPPATH"
></A
><CODE
CLASS="envar"
>QT_CPPPATH</CODE
></DT
><DD
><P
>&#13;The path where the qt header files are installed.
The default value is '<A
HREF="#cv-QTDIR"
><CODE
CLASS="envar"
>$QTDIR</CODE
></A
>/include'.
Note: If you set this variable to None,
the tool won't change the <A
HREF="#cv-CPPPATH"
><CODE
CLASS="envar"
>$CPPPATH</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-QT_DEBUG"
></A
><CODE
CLASS="envar"
>QT_DEBUG</CODE
></DT
><DD
><P
>&#13;Prints lots of debugging information while scanning for moc files.
</P
></DD
><DT
><A
NAME="cv-QT_LIB"
></A
><CODE
CLASS="envar"
>QT_LIB</CODE
></DT
><DD
><P
>&#13;Default value is 'qt'. You may want to set this to 'qt-mt'. Note: If you set
this variable to None, the tool won't change the <A
HREF="#cv-LIBS"
><CODE
CLASS="envar"
>$LIBS</CODE
></A
> variable.
</P
></DD
><DT
><A
NAME="cv-QT_LIBPATH"
></A
><CODE
CLASS="envar"
>QT_LIBPATH</CODE
></DT
><DD
><P
>&#13;The path where the qt libraries are installed.
The default value is '<A
HREF="#cv-QTDIR"
><CODE
CLASS="envar"
>$QTDIR</CODE
></A
>/lib'.
Note: If you set this variable to None,
the tool won't change the <A
HREF="#cv-LIBPATH"
><CODE
CLASS="envar"
>$LIBPATH</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-QT_MOC"
></A
><CODE
CLASS="envar"
>QT_MOC</CODE
></DT
><DD
><P
>&#13;Default value is '<A
HREF="#cv-QT_BINPATH"
><CODE
CLASS="envar"
>$QT_BINPATH</CODE
></A
>/moc'.
</P
></DD
><DT
><A
NAME="cv-QT_MOCCXXPREFIX"
></A
><CODE
CLASS="envar"
>QT_MOCCXXPREFIX</CODE
></DT
><DD
><P
>&#13;Default value is ''. Prefix for moc output files, when source is a cxx file.
</P
></DD
><DT
><A
NAME="cv-QT_MOCCXXSUFFIX"
></A
><CODE
CLASS="envar"
>QT_MOCCXXSUFFIX</CODE
></DT
><DD
><P
>&#13;Default value is '.moc'. Suffix for moc output files, when source is a cxx
file.
</P
></DD
><DT
><A
NAME="cv-QT_MOCFROMCXXCOM"
></A
><CODE
CLASS="envar"
>QT_MOCFROMCXXCOM</CODE
></DT
><DD
><P
>&#13;Command to generate a moc file from a cpp file.
</P
></DD
><DT
><A
NAME="cv-QT_MOCFROMCXXCOMSTR"
></A
><CODE
CLASS="envar"
>QT_MOCFROMCXXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when generating a moc file from a cpp file.
If this is not set, then <A
HREF="#cv-QT_MOCFROMCXXCOM"
><CODE
CLASS="envar"
>$QT_MOCFROMCXXCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-QT_MOCFROMCXXFLAGS"
></A
><CODE
CLASS="envar"
>QT_MOCFROMCXXFLAGS</CODE
></DT
><DD
><P
>&#13;Default value is '-i'. These flags are passed to moc, when moccing a
C++ file.
</P
></DD
><DT
><A
NAME="cv-QT_MOCFROMHCOM"
></A
><CODE
CLASS="envar"
>QT_MOCFROMHCOM</CODE
></DT
><DD
><P
>&#13;Command to generate a moc file from a header.
</P
></DD
><DT
><A
NAME="cv-QT_MOCFROMHCOMSTR"
></A
><CODE
CLASS="envar"
>QT_MOCFROMHCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when generating a moc file from a cpp file.
If this is not set, then <A
HREF="#cv-QT_MOCFROMHCOM"
><CODE
CLASS="envar"
>$QT_MOCFROMHCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-QT_MOCFROMHFLAGS"
></A
><CODE
CLASS="envar"
>QT_MOCFROMHFLAGS</CODE
></DT
><DD
><P
>&#13;Default value is ''. These flags are passed to moc, when moccing a header
file.
</P
></DD
><DT
><A
NAME="cv-QT_MOCHPREFIX"
></A
><CODE
CLASS="envar"
>QT_MOCHPREFIX</CODE
></DT
><DD
><P
>&#13;Default value is 'moc_'. Prefix for moc output files, when source is a header.
</P
></DD
><DT
><A
NAME="cv-QT_MOCHSUFFIX"
></A
><CODE
CLASS="envar"
>QT_MOCHSUFFIX</CODE
></DT
><DD
><P
>&#13;Default value is '<A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
>'. Suffix for moc output files, when source is
a header.
</P
></DD
><DT
><A
NAME="cv-QT_UIC"
></A
><CODE
CLASS="envar"
>QT_UIC</CODE
></DT
><DD
><P
>&#13;Default value is '<A
HREF="#cv-QT_BINPATH"
><CODE
CLASS="envar"
>$QT_BINPATH</CODE
></A
>/uic'.
</P
></DD
><DT
><A
NAME="cv-QT_UICCOM"
></A
><CODE
CLASS="envar"
>QT_UICCOM</CODE
></DT
><DD
><P
>&#13;Command to generate header files from .ui files.
</P
></DD
><DT
><A
NAME="cv-QT_UICCOMSTR"
></A
><CODE
CLASS="envar"
>QT_UICCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when generating header files from .ui files.
If this is not set, then <A
HREF="#cv-QT_UICCOM"
><CODE
CLASS="envar"
>$QT_UICCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-QT_UICDECLFLAGS"
></A
><CODE
CLASS="envar"
>QT_UICDECLFLAGS</CODE
></DT
><DD
><P
>&#13;Default value is ''. These flags are passed to uic, when creating a a h
file from a .ui file.
</P
></DD
><DT
><A
NAME="cv-QT_UICDECLPREFIX"
></A
><CODE
CLASS="envar"
>QT_UICDECLPREFIX</CODE
></DT
><DD
><P
>&#13;Default value is ''. Prefix for uic generated header files.
</P
></DD
><DT
><A
NAME="cv-QT_UICDECLSUFFIX"
></A
><CODE
CLASS="envar"
>QT_UICDECLSUFFIX</CODE
></DT
><DD
><P
>&#13;Default value is '.h'. Suffix for uic generated header files.
</P
></DD
><DT
><A
NAME="cv-QT_UICIMPLFLAGS"
></A
><CODE
CLASS="envar"
>QT_UICIMPLFLAGS</CODE
></DT
><DD
><P
>&#13;Default value is ''. These flags are passed to uic, when creating a cxx
file from a .ui file.
</P
></DD
><DT
><A
NAME="cv-QT_UICIMPLPREFIX"
></A
><CODE
CLASS="envar"
>QT_UICIMPLPREFIX</CODE
></DT
><DD
><P
>&#13;Default value is 'uic_'. Prefix for uic generated implementation files.
</P
></DD
><DT
><A
NAME="cv-QT_UICIMPLSUFFIX"
></A
><CODE
CLASS="envar"
>QT_UICIMPLSUFFIX</CODE
></DT
><DD
><P
>&#13;Default value is '<A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
>'. Suffix for uic generated implementation
files.
</P
></DD
><DT
><A
NAME="cv-QT_UISUFFIX"
></A
><CODE
CLASS="envar"
>QT_UISUFFIX</CODE
></DT
><DD
><P
>&#13;Default value is '.ui'. Suffix of designer input files.
</P
></DD
><DT
><A
NAME="cv-QTDIR"
></A
><CODE
CLASS="envar"
>QTDIR</CODE
></DT
><DD
><P
>&#13;The qt tool tries to take this from os.environ.
It also initializes all QT_*
construction variables listed below.
(Note that all paths are constructed
with python's os.path.join() method,
but are listed here with the '/' separator
for easier reading.)
In addition, the construction environment
variables <A
HREF="#cv-CPPPATH"
><CODE
CLASS="envar"
>$CPPPATH</CODE
></A
>,
<A
HREF="#cv-LIBPATH"
><CODE
CLASS="envar"
>$LIBPATH</CODE
></A
> and
<A
HREF="#cv-LIBS"
><CODE
CLASS="envar"
>$LIBS</CODE
></A
> may be modified
and the variables
PROGEMITTER, SHLIBEMITTER and LIBEMITTER
are modified. Because the build-performance is affected when using this tool,
you have to explicitly specify it at Environment creation:
</P
><PRE
CLASS="programlisting"
>&#13;Environment(tools=['default','qt'])
</PRE
><P
>&#13;The qt tool supports the following operations:</P
><P
><SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>Automatic moc file generation from header files.</I
></SPAN
>
You do not have to specify moc files explicitly, the tool does it for you.
However, there are a few preconditions to do so: Your header file must have
the same filebase as your implementation file and must stay in the same
directory. It must have one of the suffixes .h, .hpp, .H, .hxx, .hh. You
can turn off automatic moc file generation by setting QT_AUTOSCAN to 0.
See also the corresponding builder method
.B Moc()</P
><P
><SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>Automatic moc file generation from cxx files.</I
></SPAN
>
As stated in the qt documentation, include the moc file at the end of
the cxx file. Note that you have to include the file, which is generated
by the transformation ${QT_MOCCXXPREFIX}&#60;basename&#62;${QT_MOCCXXSUFFIX}, by default
&#60;basename&#62;.moc. A warning is generated after building the moc file, if you
do not include the correct file. If you are using VariantDir, you may
need to specify duplicate=1. You can turn off automatic moc file generation
by setting QT_AUTOSCAN to 0. See also the corresponding
<CODE
CLASS="function"
>Moc</CODE
>
builder method.</P
><P
><SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>Automatic handling of .ui files.</I
></SPAN
>
The implementation files generated from .ui files are handled much the same
as yacc or lex files. Each .ui file given as a source of Program, Library or
SharedLibrary will generate three files, the declaration file, the
implementation file and a moc file. Because there are also generated headers,
you may need to specify duplicate=1 in calls to VariantDir.
See also the corresponding
<CODE
CLASS="function"
>Uic</CODE
>
builder method.
</P
></DD
><DT
><A
NAME="cv-RANLIB"
></A
><CODE
CLASS="envar"
>RANLIB</CODE
></DT
><DD
><P
>&#13;The archive indexer.
</P
></DD
><DT
><A
NAME="cv-RANLIBCOM"
></A
><CODE
CLASS="envar"
>RANLIBCOM</CODE
></DT
><DD
><P
>&#13;The command line used to index a static library archive.
</P
></DD
><DT
><A
NAME="cv-RANLIBCOMSTR"
></A
><CODE
CLASS="envar"
>RANLIBCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a static library archive is indexed.
If this is not set, then <A
HREF="#cv-RANLIBCOM"
><CODE
CLASS="envar"
>$RANLIBCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(RANLIBCOMSTR = "Indexing $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-RANLIBFLAGS"
></A
><CODE
CLASS="envar"
>RANLIBFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the archive indexer.
</P
></DD
><DT
><A
NAME="cv-RC"
></A
><CODE
CLASS="envar"
>RC</CODE
></DT
><DD
><P
>&#13;The resource compiler used to build
a Microsoft Visual C++ resource file.
</P
></DD
><DT
><A
NAME="cv-RCCOM"
></A
><CODE
CLASS="envar"
>RCCOM</CODE
></DT
><DD
><P
>&#13;The command line used to build
a Microsoft Visual C++ resource file.
</P
></DD
><DT
><A
NAME="cv-RCCOMSTR"
></A
><CODE
CLASS="envar"
>RCCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when invoking the resource compiler
to build a Microsoft Visual C++ resource file.
If this is not set, then <A
HREF="#cv-RCCOM"
><CODE
CLASS="envar"
>$RCCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-RCFLAGS"
></A
><CODE
CLASS="envar"
>RCFLAGS</CODE
></DT
><DD
><P
>&#13;The flags passed to the resource compiler by the RES builder.
</P
></DD
><DT
><A
NAME="cv-RCINCFLAGS"
></A
><CODE
CLASS="envar"
>RCINCFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the command-line options
for specifying directories to be searched
by the resource compiler.
The value of <CODE
CLASS="envar"
>$RCINCFLAGS</CODE
> is created
by appending <CODE
CLASS="envar"
>$RCINCPREFIX</CODE
> and <CODE
CLASS="envar"
>$RCINCSUFFIX</CODE
>
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$CPPPATH</CODE
>.
</P
></DD
><DT
><A
NAME="cv-RCINCPREFIX"
></A
><CODE
CLASS="envar"
>RCINCPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix (flag) used to specify an include directory
on the resource compiler command line.
This will be appended to the beginning of each directory
in the <CODE
CLASS="envar"
>$CPPPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$RCINCFLAGS</CODE
> variable is expanded.
</P
></DD
><DT
><A
NAME="cv-RCINCSUFFIX"
></A
><CODE
CLASS="envar"
>RCINCSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify an include directory
on the resource compiler command line.
This will be appended to the end of each directory
in the <CODE
CLASS="envar"
>$CPPPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$RCINCFLAGS</CODE
> variable is expanded.
</P
></DD
><DT
><A
NAME="cv-RCS"
></A
><CODE
CLASS="envar"
>RCS</CODE
></DT
><DD
><P
>&#13;The RCS executable.
Note that this variable is not actually used
for the command to fetch source files from RCS;
see the
<A
HREF="#cv-RCS_CO"
><CODE
CLASS="envar"
>$RCS_CO</CODE
></A
>
construction variable, below.
</P
></DD
><DT
><A
NAME="cv-RCS_CO"
></A
><CODE
CLASS="envar"
>RCS_CO</CODE
></DT
><DD
><P
>&#13;The RCS "checkout" executable,
used to fetch source files from RCS.
</P
></DD
><DT
><A
NAME="cv-RCS_COCOM"
></A
><CODE
CLASS="envar"
>RCS_COCOM</CODE
></DT
><DD
&