scons/scons-user.html

45103 lines
772 KiB
HTML

<!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
><P
>&#13;The command line used to
fetch (checkout) source files from RCS.
</P
></DD
><DT
><A
NAME="cv-RCS_COCOMSTR"
></A
><CODE
CLASS="envar"
>RCS_COCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when fetching
a source file from RCS.
If this is not set, then <A
HREF="#cv-RCS_COCOM"
><CODE
CLASS="envar"
>$RCS_COCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-RCS_COFLAGS"
></A
><CODE
CLASS="envar"
>RCS_COFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the <A
HREF="#cv-RCS_CO"
><CODE
CLASS="envar"
>$RCS_CO</CODE
></A
> command.
</P
></DD
><DT
><A
NAME="cv-RDirs"
></A
><CODE
CLASS="envar"
>RDirs</CODE
></DT
><DD
><P
>&#13;A function that converts a string into a list of Dir instances by
searching the repositories.
</P
></DD
><DT
><A
NAME="cv-REGSVR"
></A
><CODE
CLASS="envar"
>REGSVR</CODE
></DT
><DD
><P
>&#13;The program used on Windows systems
to register a newly-built DLL library
whenever the <CODE
CLASS="function"
>SharedLibrary</CODE
> builder
is passed a keyword argument of <TT
CLASS="literal"
>register=1</TT
>.
</P
></DD
><DT
><A
NAME="cv-REGSVRCOM"
></A
><CODE
CLASS="envar"
>REGSVRCOM</CODE
></DT
><DD
><P
>&#13;The command line used on Windows systems
to register a newly-built DLL library
whenever the <CODE
CLASS="function"
>SharedLibrary</CODE
> builder
is passed a keyword argument of <TT
CLASS="literal"
>register=1</TT
>.
</P
></DD
><DT
><A
NAME="cv-REGSVRCOMSTR"
></A
><CODE
CLASS="envar"
>REGSVRCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when registering a newly-built DLL file.
If this is not set, then <A
HREF="#cv-REGSVRCOM"
><CODE
CLASS="envar"
>$REGSVRCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-REGSVRFLAGS"
></A
><CODE
CLASS="envar"
>REGSVRFLAGS</CODE
></DT
><DD
><P
>&#13;Flags passed to the DLL registration program
on Windows systems when a newly-built DLL library is registered.
By default,
this includes the <CODE
CLASS="option"
>/s</CODE
>
that prevents dialog boxes from popping up
and requiring user attention.
</P
></DD
><DT
><A
NAME="cv-RMIC"
></A
><CODE
CLASS="envar"
>RMIC</CODE
></DT
><DD
><P
>&#13;The Java RMI stub compiler.
</P
></DD
><DT
><A
NAME="cv-RMICCOM"
></A
><CODE
CLASS="envar"
>RMICCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile stub
and skeleton class files
from Java classes that contain RMI implementations.
Any options specified in the <A
HREF="#cv-RMICFLAGS"
><CODE
CLASS="envar"
>$RMICFLAGS</CODE
></A
> construction variable
are included on this command line.
</P
></DD
><DT
><A
NAME="cv-RMICCOMSTR"
></A
><CODE
CLASS="envar"
>RMICCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when compiling
stub and skeleton class files
from Java classes that contain RMI implementations.
If this is not set, then <A
HREF="#cv-RMICCOM"
><CODE
CLASS="envar"
>$RMICCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(RMICCOMSTR = "Generating stub/skeleton class files $TARGETS from $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-RMICFLAGS"
></A
><CODE
CLASS="envar"
>RMICFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the Java RMI stub compiler.
</P
></DD
><DT
><A
NAME="cv-_RPATH"
></A
><CODE
CLASS="envar"
>_RPATH</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the rpath flags to be used when linking
a program with shared libraries.
The value of <CODE
CLASS="envar"
>$_RPATH</CODE
> is created
by appending <CODE
CLASS="envar"
>$RPATHPREFIX</CODE
> and <CODE
CLASS="envar"
>$RPATHSUFFIX</CODE
>
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$RPATH</CODE
>.
</P
></DD
><DT
><A
NAME="cv-RPATH"
></A
><CODE
CLASS="envar"
>RPATH</CODE
></DT
><DD
><P
>&#13;A list of paths to search for shared libraries when running programs.
Currently only used in the GNU (gnulink),
IRIX (sgilink) and Sun (sunlink) linkers.
Ignored on platforms and toolchains that don't support it.
Note that the paths added to RPATH
are not transformed by
<SPAN
CLASS="application"
>scons</SPAN
>
in any way: if you want an absolute
path, you must make it absolute yourself.
</P
></DD
><DT
><A
NAME="cv-RPATHPREFIX"
></A
><CODE
CLASS="envar"
>RPATHPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used to specify a directory to be searched for
shared libraries when running programs.
This will be appended to the beginning of each directory
in the <CODE
CLASS="envar"
>$RPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_RPATH</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-RPATHSUFFIX"
></A
><CODE
CLASS="envar"
>RPATHSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify a directory to be searched for
shared libraries when running programs.
This will be appended to the end of each directory
in the <CODE
CLASS="envar"
>$RPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_RPATH</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-RPCGEN"
></A
><CODE
CLASS="envar"
>RPCGEN</CODE
></DT
><DD
><P
>&#13;The RPC protocol compiler.
</P
></DD
><DT
><A
NAME="cv-RPCGENCLIENTFLAGS"
></A
><CODE
CLASS="envar"
>RPCGENCLIENTFLAGS</CODE
></DT
><DD
><P
>&#13;Options passed to the RPC protocol compiler
when generating client side stubs.
These are in addition to any flags specified in the
<A
HREF="#cv-RPCGENFLAGS"
><CODE
CLASS="envar"
>$RPCGENFLAGS</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-RPCGENFLAGS"
></A
><CODE
CLASS="envar"
>RPCGENFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the RPC protocol compiler.
</P
></DD
><DT
><A
NAME="cv-RPCGENHEADERFLAGS"
></A
><CODE
CLASS="envar"
>RPCGENHEADERFLAGS</CODE
></DT
><DD
><P
>&#13;Options passed to the RPC protocol compiler
when generating a header file.
These are in addition to any flags specified in the
<A
HREF="#cv-RPCGENFLAGS"
><CODE
CLASS="envar"
>$RPCGENFLAGS</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-RPCGENSERVICEFLAGS"
></A
><CODE
CLASS="envar"
>RPCGENSERVICEFLAGS</CODE
></DT
><DD
><P
>&#13;Options passed to the RPC protocol compiler
when generating server side stubs.
These are in addition to any flags specified in the
<A
HREF="#cv-RPCGENFLAGS"
><CODE
CLASS="envar"
>$RPCGENFLAGS</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-RPCGENXDRFLAGS"
></A
><CODE
CLASS="envar"
>RPCGENXDRFLAGS</CODE
></DT
><DD
><P
>&#13;Options passed to the RPC protocol compiler
when generating XDR routines.
These are in addition to any flags specified in the
<A
HREF="#cv-RPCGENFLAGS"
><CODE
CLASS="envar"
>$RPCGENFLAGS</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-SCANNERS"
></A
><CODE
CLASS="envar"
>SCANNERS</CODE
></DT
><DD
><P
>&#13;A list of the available implicit dependency scanners.
New file scanners may be added by
appending to this list,
although the more flexible approach
is to associate scanners
with a specific Builder.
See the sections "Builder Objects"
and "Scanner Objects,"
below, for more information.
</P
></DD
><DT
><A
NAME="cv-SCCS"
></A
><CODE
CLASS="envar"
>SCCS</CODE
></DT
><DD
><P
>&#13;The SCCS executable.
</P
></DD
><DT
><A
NAME="cv-SCCSCOM"
></A
><CODE
CLASS="envar"
>SCCSCOM</CODE
></DT
><DD
><P
>&#13;The command line used to
fetch source files from SCCS.
</P
></DD
><DT
><A
NAME="cv-SCCSCOMSTR"
></A
><CODE
CLASS="envar"
>SCCSCOMSTR</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-SCCSCOM"
><CODE
CLASS="envar"
>$SCCSCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SCCSFLAGS"
></A
><CODE
CLASS="envar"
>SCCSFLAGS</CODE
></DT
><DD
><P
>&#13;General options that are passed to SCCS.
</P
></DD
><DT
><A
NAME="cv-SCCSGETFLAGS"
></A
><CODE
CLASS="envar"
>SCCSGETFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed specifically to the SCCS "get" subcommand.
This can be set, for example, to
<CODE
CLASS="option"
>-e</CODE
>
to check out editable files from SCCS.
</P
></DD
><DT
><A
NAME="cv-SCONS_HOME"
></A
><CODE
CLASS="envar"
>SCONS_HOME</CODE
></DT
><DD
><P
>&#13;The (optional) path to the SCons library directory,
initialized from the external environment.
If set, this is used to construct a shorter and more
efficient search path in the
<A
HREF="#cv-MSVSSCONS"
><CODE
CLASS="envar"
>$MSVSSCONS</CODE
></A
>
command line executed
from Microsoft Visual Studio project files.
</P
></DD
><DT
><A
NAME="cv-SHCC"
></A
><CODE
CLASS="envar"
>SHCC</CODE
></DT
><DD
><P
>&#13;The C compiler used for generating shared-library objects.
</P
></DD
><DT
><A
NAME="cv-SHCCCOM"
></A
><CODE
CLASS="envar"
>SHCCCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a C source file
to a shared-library object file.
Any options specified in the <A
HREF="#cv-SHCFLAGS"
><CODE
CLASS="envar"
>$SHCFLAGS</CODE
></A
>,
<A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</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-SHCCCOMSTR"
></A
><CODE
CLASS="envar"
>SHCCCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a C source file
is compiled to a shared object file.
If this is not set, then <A
HREF="#cv-SHCCCOM"
><CODE
CLASS="envar"
>$SHCCCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(SHCCCOMSTR = "Compiling shared object $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-SHCCFLAGS"
></A
><CODE
CLASS="envar"
>SHCCFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the C and C++ compilers
to generate shared-library objects.
</P
></DD
><DT
><A
NAME="cv-SHCFLAGS"
></A
><CODE
CLASS="envar"
>SHCFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the C compiler (only; not C++)
to generate shared-library objects.
</P
></DD
><DT
><A
NAME="cv-SHCXX"
></A
><CODE
CLASS="envar"
>SHCXX</CODE
></DT
><DD
><P
>&#13;The C++ compiler used for generating shared-library objects.
</P
></DD
><DT
><A
NAME="cv-SHCXXCOM"
></A
><CODE
CLASS="envar"
>SHCXXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a C++ source file
to a shared-library object file.
Any options specified in the <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</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-SHCXXCOMSTR"
></A
><CODE
CLASS="envar"
>SHCXXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a C++ source file
is compiled to a shared object file.
If this is not set, then <A
HREF="#cv-SHCXXCOM"
><CODE
CLASS="envar"
>$SHCXXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(SHCXXCOMSTR = "Compiling shared object $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-SHCXXFLAGS"
></A
><CODE
CLASS="envar"
>SHCXXFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the C++ compiler
to generate shared-library objects.
</P
></DD
><DT
><A
NAME="cv-SHELL"
></A
><CODE
CLASS="envar"
>SHELL</CODE
></DT
><DD
><P
>&#13;A string naming the shell program that will be passed to the
<CODE
CLASS="envar"
>$SPAWN</CODE
>
function.
See the
<CODE
CLASS="envar"
>$SPAWN</CODE
>
construction variable for more information.
</P
></DD
><DT
><A
NAME="cv-SHF77"
></A
><CODE
CLASS="envar"
>SHF77</CODE
></DT
><DD
><P
>&#13;The Fortran 77 compiler used for generating shared-library objects.
You should normally set the <A
HREF="#cv-SHFORTRAN"
><CODE
CLASS="envar"
>$SHFORTRAN</CODE
></A
> variable,
which specifies the default Fortran compiler
for all Fortran versions.
You only need to set <A
HREF="#cv-SHF77"
><CODE
CLASS="envar"
>$SHF77</CODE
></A
> if you need to use a specific compiler
or compiler version for Fortran 77 files.
</P
></DD
><DT
><A
NAME="cv-SHF77COM"
></A
><CODE
CLASS="envar"
>SHF77COM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 77 source file
to a shared-library object file.
You only need to set <A
HREF="#cv-SHF77COM"
><CODE
CLASS="envar"
>$SHF77COM</CODE
></A
> if you need to use a specific
command line for Fortran 77 files.
You should normally set the <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
> variable,
which specifies the default command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-SHF77COMSTR"
></A
><CODE
CLASS="envar"
>SHF77COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 77 source file
is compiled to a shared-library object file.
If this is not set, then <A
HREF="#cv-SHF77COM"
><CODE
CLASS="envar"
>$SHF77COM</CODE
></A
> or <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHF77FLAGS"
></A
><CODE
CLASS="envar"
>SHF77FLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the Fortran 77 compiler
to generated shared-library objects.
You only need to set <A
HREF="#cv-SHF77FLAGS"
><CODE
CLASS="envar"
>$SHF77FLAGS</CODE
></A
> if you need to define specific
user options for Fortran 77 files.
You should normally set the <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</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-SHF77PPCOM"
></A
><CODE
CLASS="envar"
>SHF77PPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 77 source file to a
shared-library object file
after first running the file through the C preprocessor.
Any options specified in the <A
HREF="#cv-SHF77FLAGS"
><CODE
CLASS="envar"
>$SHF77FLAGS</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-SHF77PPCOM"
><CODE
CLASS="envar"
>$SHF77PPCOM</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-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
> variable,
which specifies the default C-preprocessor command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-SHF77PPCOMSTR"
></A
><CODE
CLASS="envar"
>SHF77PPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 77 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
If this is not set, then <A
HREF="#cv-SHF77PPCOM"
><CODE
CLASS="envar"
>$SHF77PPCOM</CODE
></A
> or <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHF90"
></A
><CODE
CLASS="envar"
>SHF90</CODE
></DT
><DD
><P
>&#13;The Fortran 90 compiler used for generating shared-library objects.
You should normally set the <A
HREF="#cv-SHFORTRAN"
><CODE
CLASS="envar"
>$SHFORTRAN</CODE
></A
> variable,
which specifies the default Fortran compiler
for all Fortran versions.
You only need to set <A
HREF="#cv-SHF90"
><CODE
CLASS="envar"
>$SHF90</CODE
></A
> if you need to use a specific compiler
or compiler version for Fortran 90 files.
</P
></DD
><DT
><A
NAME="cv-SHF90COM"
></A
><CODE
CLASS="envar"
>SHF90COM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 90 source file
to a shared-library object file.
You only need to set <A
HREF="#cv-SHF90COM"
><CODE
CLASS="envar"
>$SHF90COM</CODE
></A
> if you need to use a specific
command line for Fortran 90 files.
You should normally set the <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
> variable,
which specifies the default command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-SHF90COMSTR"
></A
><CODE
CLASS="envar"
>SHF90COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 90 source file
is compiled to a shared-library object file.
If this is not set, then <A
HREF="#cv-SHF90COM"
><CODE
CLASS="envar"
>$SHF90COM</CODE
></A
> or <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHF90FLAGS"
></A
><CODE
CLASS="envar"
>SHF90FLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the Fortran 90 compiler
to generated shared-library objects.
You only need to set <A
HREF="#cv-SHF90FLAGS"
><CODE
CLASS="envar"
>$SHF90FLAGS</CODE
></A
> if you need to define specific
user options for Fortran 90 files.
You should normally set the <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</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-SHF90PPCOM"
></A
><CODE
CLASS="envar"
>SHF90PPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 90 source file to a
shared-library object file
after first running the file through the C preprocessor.
Any options specified in the <A
HREF="#cv-SHF90FLAGS"
><CODE
CLASS="envar"
>$SHF90FLAGS</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-SHF90PPCOM"
><CODE
CLASS="envar"
>$SHF90PPCOM</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-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
> variable,
which specifies the default C-preprocessor command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-SHF90PPCOMSTR"
></A
><CODE
CLASS="envar"
>SHF90PPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 90 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
If this is not set, then <A
HREF="#cv-SHF90PPCOM"
><CODE
CLASS="envar"
>$SHF90PPCOM</CODE
></A
> or <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHF95"
></A
><CODE
CLASS="envar"
>SHF95</CODE
></DT
><DD
><P
>&#13;The Fortran 95 compiler used for generating shared-library objects.
You should normally set the <A
HREF="#cv-SHFORTRAN"
><CODE
CLASS="envar"
>$SHFORTRAN</CODE
></A
> variable,
which specifies the default Fortran compiler
for all Fortran versions.
You only need to set <A
HREF="#cv-SHF95"
><CODE
CLASS="envar"
>$SHF95</CODE
></A
> if you need to use a specific compiler
or compiler version for Fortran 95 files.
</P
></DD
><DT
><A
NAME="cv-SHF95COM"
></A
><CODE
CLASS="envar"
>SHF95COM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 95 source file
to a shared-library object file.
You only need to set <A
HREF="#cv-SHF95COM"
><CODE
CLASS="envar"
>$SHF95COM</CODE
></A
> if you need to use a specific
command line for Fortran 95 files.
You should normally set the <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
> variable,
which specifies the default command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-SHF95COMSTR"
></A
><CODE
CLASS="envar"
>SHF95COMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 95 source file
is compiled to a shared-library object file.
If this is not set, then <A
HREF="#cv-SHF95COM"
><CODE
CLASS="envar"
>$SHF95COM</CODE
></A
> or <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHF95FLAGS"
></A
><CODE
CLASS="envar"
>SHF95FLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the Fortran 95 compiler
to generated shared-library objects.
You only need to set <A
HREF="#cv-SHF95FLAGS"
><CODE
CLASS="envar"
>$SHF95FLAGS</CODE
></A
> if you need to define specific
user options for Fortran 95 files.
You should normally set the <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</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-SHF95PPCOM"
></A
><CODE
CLASS="envar"
>SHF95PPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran 95 source file to a
shared-library object file
after first running the file through the C preprocessor.
Any options specified in the <A
HREF="#cv-SHF95FLAGS"
><CODE
CLASS="envar"
>$SHF95FLAGS</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-SHF95PPCOM"
><CODE
CLASS="envar"
>$SHF95PPCOM</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-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
> variable,
which specifies the default C-preprocessor command line
for all Fortran versions.
</P
></DD
><DT
><A
NAME="cv-SHF95PPCOMSTR"
></A
><CODE
CLASS="envar"
>SHF95PPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran 95 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
If this is not set, then <A
HREF="#cv-SHF95PPCOM"
><CODE
CLASS="envar"
>$SHF95PPCOM</CODE
></A
> or <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHFORTRAN"
></A
><CODE
CLASS="envar"
>SHFORTRAN</CODE
></DT
><DD
><P
>&#13;The default Fortran compiler used for generating shared-library objects.
</P
></DD
><DT
><A
NAME="cv-SHFORTRANCOM"
></A
><CODE
CLASS="envar"
>SHFORTRANCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran source file
to a shared-library object file.
</P
></DD
><DT
><A
NAME="cv-SHFORTRANCOMSTR"
></A
><CODE
CLASS="envar"
>SHFORTRANCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran source file
is compiled to a shared-library object file.
If this is not set, then <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHFORTRANFLAGS"
></A
><CODE
CLASS="envar"
>SHFORTRANFLAGS</CODE
></DT
><DD
><P
>&#13;Options that are passed to the Fortran compiler
to generate shared-library objects.
</P
></DD
><DT
><A
NAME="cv-SHFORTRANPPCOM"
></A
><CODE
CLASS="envar"
>SHFORTRANPPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to compile a Fortran source file to a
shared-library object file
after first running the file through the C preprocessor.
Any options specified
in the <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</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-SHFORTRANPPCOMSTR"
></A
><CODE
CLASS="envar"
>SHFORTRANPPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when a Fortran source file
is compiled to a shared-library object file
after first running the file throught the C preprocessor.
If this is not set, then <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>
(the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SHLIBPREFIX"
></A
><CODE
CLASS="envar"
>SHLIBPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for shared library file names.
</P
></DD
><DT
><A
NAME="cv-SHLIBSUFFIX"
></A
><CODE
CLASS="envar"
>SHLIBSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for shared library file names.
</P
></DD
><DT
><A
NAME="cv-SHLINK"
></A
><CODE
CLASS="envar"
>SHLINK</CODE
></DT
><DD
><P
>&#13;The linker for programs that use shared libraries.
</P
></DD
><DT
><A
NAME="cv-SHLINKCOM"
></A
><CODE
CLASS="envar"
>SHLINKCOM</CODE
></DT
><DD
><P
>&#13;The command line used to link programs using shared libaries.
</P
></DD
><DT
><A
NAME="cv-SHLINKCOMSTR"
></A
><CODE
CLASS="envar"
>SHLINKCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when programs using shared libraries are linked.
If this is not set, then <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(SHLINKCOMSTR = "Linking shared $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-SHLINKFLAGS"
></A
><CODE
CLASS="envar"
>SHLINKFLAGS</CODE
></DT
><DD
><P
>&#13;General user options passed to the linker for programs using shared libraries.
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) include 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-SHOBJPREFIX"
></A
><CODE
CLASS="envar"
>SHOBJPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for shared object file names.
</P
></DD
><DT
><A
NAME="cv-SHOBJSUFFIX"
></A
><CODE
CLASS="envar"
>SHOBJSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for shared object file names.
</P
></DD
><DT
><A
NAME="cv-SOURCE"
></A
><CODE
CLASS="envar"
>SOURCE</CODE
></DT
><DD
><P
>&#13;A reserved variable name
that may not be set or used in a construction environment.
(See "Variable Substitution," below.)
</P
></DD
><DT
><A
NAME="cv-SOURCE_URL"
></A
><CODE
CLASS="envar"
>SOURCE_URL</CODE
></DT
><DD
><P
>&#13;The URL
(web address)
of the location from which the project was retrieved.
This is used to fill in the
<TT
CLASS="literal"
>Source:</TT
>
field in the controlling information for Ipkg and RPM packages.
</P
></DD
><DT
><A
NAME="cv-SOURCES"
></A
><CODE
CLASS="envar"
>SOURCES</CODE
></DT
><DD
><P
>&#13;A reserved variable name
that may not be set or used in a construction environment.
(See "Variable Substitution," below.)
</P
></DD
><DT
><A
NAME="cv-SPAWN"
></A
><CODE
CLASS="envar"
>SPAWN</CODE
></DT
><DD
><P
>&#13;A command interpreter function that will be called to execute command line
strings. The function must expect the following arguments:
</P
><PRE
CLASS="programlisting"
>&#13;def spawn(shell, escape, cmd, args, env):
</PRE
><P
>&#13;<CODE
CLASS="varname"
>sh</CODE
>
is a string naming the shell program to use.
<CODE
CLASS="varname"
>escape</CODE
>
is a function that can be called to escape shell special characters in
the command line.
<CODE
CLASS="varname"
>cmd</CODE
>
is the path to the command to be executed.
<CODE
CLASS="varname"
>args</CODE
>
is the arguments to the command.
<CODE
CLASS="varname"
>env</CODE
>
is a dictionary of the environment variables
in which the command should be executed.
</P
></DD
><DT
><A
NAME="cv-SUMMARY"
></A
><CODE
CLASS="envar"
>SUMMARY</CODE
></DT
><DD
><P
>&#13;A short summary of what the project is about.
This is used to fill in the
<TT
CLASS="literal"
>Summary:</TT
>
field in the controlling information for Ipkg and RPM packages,
and as the
<TT
CLASS="literal"
>Description:</TT
>
field in MSI packages.
</P
></DD
><DT
><A
NAME="cv-SWIG"
></A
><CODE
CLASS="envar"
>SWIG</CODE
></DT
><DD
><P
>&#13;The scripting language wrapper and interface generator.
</P
></DD
><DT
><A
NAME="cv-SWIGCFILESUFFIX"
></A
><CODE
CLASS="envar"
>SWIGCFILESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix that will be used for intermediate C
source files generated by
the scripting language wrapper and interface generator.
The default value is
<TT
CLASS="filename"
>_wrap</TT
><A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
>.
By default, this value is used whenever the
<CODE
CLASS="option"
>-c++</CODE
>
option is
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>not</I
></SPAN
>
specified as part of the
<A
HREF="#cv-SWIGFLAGS"
><CODE
CLASS="envar"
>$SWIGFLAGS</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-SWIGCOM"
></A
><CODE
CLASS="envar"
>SWIGCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call
the scripting language wrapper and interface generator.
</P
></DD
><DT
><A
NAME="cv-SWIGCOMSTR"
></A
><CODE
CLASS="envar"
>SWIGCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when calling
the scripting language wrapper and interface generator.
If this is not set, then <A
HREF="#cv-SWIGCOM"
><CODE
CLASS="envar"
>$SWIGCOM</CODE
></A
> (the command line) is displayed.
</P
></DD
><DT
><A
NAME="cv-SWIGCXXFILESUFFIX"
></A
><CODE
CLASS="envar"
>SWIGCXXFILESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix that will be used for intermediate C++
source files generated by
the scripting language wrapper and interface generator.
The default value is
<TT
CLASS="filename"
>_wrap</TT
><A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
>.
By default, this value is used whenever the
<TT
CLASS="filename"
>-c++</TT
>
option is specified as part of the
<A
HREF="#cv-SWIGFLAGS"
><CODE
CLASS="envar"
>$SWIGFLAGS</CODE
></A
>
construction variable.
</P
></DD
><DT
><A
NAME="cv-SWIGFLAGS"
></A
><CODE
CLASS="envar"
>SWIGFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to
the scripting language wrapper and interface generator.
This is where you should set
<CODE
CLASS="option"
>-python</CODE
>,
<CODE
CLASS="option"
>-perl5</CODE
>,
<CODE
CLASS="option"
>-tcl</CODE
>,
or whatever other options you want to specify to SWIG.
If you set the
<CODE
CLASS="option"
>-c++</CODE
>
option in this variable,
<SPAN
CLASS="application"
>scons</SPAN
>
will, by default,
generate a C++ intermediate source file
with the extension that is specified as the
<A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
>
variable.
</P
></DD
><DT
><A
NAME="cv-_SWIGINCFLAGS"
></A
><CODE
CLASS="envar"
>_SWIGINCFLAGS</CODE
></DT
><DD
><P
>&#13;An automatically-generated construction variable
containing the SWIG command-line options
for specifying directories to be searched for included files.
The value of <CODE
CLASS="envar"
>$_SWIGINCFLAGS</CODE
> is created
by appending <CODE
CLASS="envar"
>$SWIGINCPREFIX</CODE
> and <CODE
CLASS="envar"
>$SWIGINCSUFFIX</CODE
>
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$SWIGPATH</CODE
>.
</P
></DD
><DT
><A
NAME="cv-SWIGINCPREFIX"
></A
><CODE
CLASS="envar"
>SWIGINCPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used to specify an include directory on the SWIG command line.
This will be appended to the beginning of each directory
in the <CODE
CLASS="envar"
>$SWIGPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_SWIGINCFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-SWIGINCSUFFIX"
></A
><CODE
CLASS="envar"
>SWIGINCSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used to specify an include directory on the SWIG command line.
This will be appended to the end of each directory
in the <CODE
CLASS="envar"
>$SWIGPATH</CODE
> construction variable
when the <CODE
CLASS="envar"
>$_SWIGINCFLAGS</CODE
> variable is automatically generated.
</P
></DD
><DT
><A
NAME="cv-SWIGOUTDIR"
></A
><CODE
CLASS="envar"
>SWIGOUTDIR</CODE
></DT
><DD
><P
>&#13;Specifies the output directory in which
the scripting language wrapper and interface generator
should place generated language-specific files.
This will be used by SCons to identify
the files that will be generated by the <SPAN
CLASS="application"
>swig</SPAN
> call,
and translated into the
<TT
CLASS="literal"
>swig -outdir</TT
> option on the command line.
</P
></DD
><DT
><A
NAME="cv-SWIGPATH"
></A
><CODE
CLASS="envar"
>SWIGPATH</CODE
></DT
><DD
><P
>&#13;The list of directories that the scripting language wrapper
and interface generate will search for included files.
The SWIG implicit dependency scanner will search these
directories for include files.
The default is to use the same path
specified as <CODE
CLASS="envar"
>$CPPPATH</CODE
>.</P
><P
>Don't explicitly put include directory
arguments in SWIGFLAGS;
the result will be non-portable
and the directories will not be searched by the dependency scanner.
Note: directory names in SWIGPATH 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(SWIGPATH='#/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(SWIGPATH=include)
</PRE
><P
>&#13;The directory list will be added to command lines
through the automatically-generated
<CODE
CLASS="envar"
>$_SWIGINCFLAGS</CODE
>
construction variable,
which is constructed by
appending the values of the
<CODE
CLASS="envar"
>$SWIGINCPREFIX</CODE
> and <CODE
CLASS="envar"
>$SWIGINCSUFFIX</CODE
>
construction variables
to the beginning and end
of each directory in <CODE
CLASS="envar"
>$SWIGPATH</CODE
>.
Any command lines you define that need
the SWIGPATH directory list should
include <CODE
CLASS="envar"
>$_SWIGINCFLAGS</CODE
>:
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SORUCES")
</PRE
></DD
><DT
><A
NAME="cv-TAR"
></A
><CODE
CLASS="envar"
>TAR</CODE
></DT
><DD
><P
>&#13;The tar archiver.
</P
></DD
><DT
><A
NAME="cv-TARCOM"
></A
><CODE
CLASS="envar"
>TARCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the tar archiver.
</P
></DD
><DT
><A
NAME="cv-TARCOMSTR"
></A
><CODE
CLASS="envar"
>TARCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when archiving files
using the tar archiver.
If this is not set, then <A
HREF="#cv-TARCOM"
><CODE
CLASS="envar"
>$TARCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(TARCOMSTR = "Archiving $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-TARFLAGS"
></A
><CODE
CLASS="envar"
>TARFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the tar archiver.
</P
></DD
><DT
><A
NAME="cv-TARGET"
></A
><CODE
CLASS="envar"
>TARGET</CODE
></DT
><DD
><P
>&#13;A reserved variable name
that may not be set or used in a construction environment.
(See "Variable Substitution," below.)
</P
></DD
><DT
><A
NAME="cv-TARGETS"
></A
><CODE
CLASS="envar"
>TARGETS</CODE
></DT
><DD
><P
>&#13;A reserved variable name
that may not be set or used in a construction environment.
(See "Variable Substitution," below.)
</P
></DD
><DT
><A
NAME="cv-TARSUFFIX"
></A
><CODE
CLASS="envar"
>TARSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for tar file names.
</P
></DD
><DT
><A
NAME="cv-TEMPFILEPREFIX"
></A
><CODE
CLASS="envar"
>TEMPFILEPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix for a temporary file used
to execute lines longer than $MAXLINELENGTH.
The default is '@'.
This may be set for toolchains that use other values,
such as '-@' for the diab compiler
or '-via' for ARM toolchain.
</P
></DD
><DT
><A
NAME="cv-TEX"
></A
><CODE
CLASS="envar"
>TEX</CODE
></DT
><DD
><P
>&#13;The TeX formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-TEXCOM"
></A
><CODE
CLASS="envar"
>TEXCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the TeX formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-TEXCOMSTR"
></A
><CODE
CLASS="envar"
>TEXCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when calling
the TeX formatter and typesetter.
If this is not set, then <A
HREF="#cv-TEXCOM"
><CODE
CLASS="envar"
>$TEXCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(TEXCOMSTR = "Building $TARGET from TeX input $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-TEXFLAGS"
></A
><CODE
CLASS="envar"
>TEXFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the TeX formatter and typesetter.
</P
></DD
><DT
><A
NAME="cv-TEXINPUTS"
></A
><CODE
CLASS="envar"
>TEXINPUTS</CODE
></DT
><DD
><P
>&#13;List of directories that the LaTeX programm will search
for include directories.
The LaTeX implicit dependency scanner will search these
directories for \include and \import files.
</P
></DD
><DT
><A
NAME="cv-TOOLS"
></A
><CODE
CLASS="envar"
>TOOLS</CODE
></DT
><DD
><P
>&#13;A list of the names of the Tool specifications
that are part of this construction environment.
</P
></DD
><DT
><A
NAME="cv-VENDOR"
></A
><CODE
CLASS="envar"
>VENDOR</CODE
></DT
><DD
><P
>&#13;The person or organization who supply the packaged software.
This is used to fill in the
<TT
CLASS="literal"
>Vendor:</TT
>
field in the controlling information for RPM packages,
and the
<TT
CLASS="literal"
>Manufacturer:</TT
>
field in the controlling information for MSI packages.
</P
></DD
><DT
><A
NAME="cv-VERSION"
></A
><CODE
CLASS="envar"
>VERSION</CODE
></DT
><DD
><P
>&#13;The version of the project, specified as a string.
</P
></DD
><DT
><A
NAME="cv-WIN32_INSERT_DEF"
></A
><CODE
CLASS="envar"
>WIN32_INSERT_DEF</CODE
></DT
><DD
><P
>&#13;A deprecated synonym for <A
HREF="#cv-WINDOWS_INSERT_DEF"
><CODE
CLASS="envar"
>$WINDOWS_INSERT_DEF</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-WIN32DEFPREFIX"
></A
><CODE
CLASS="envar"
>WIN32DEFPREFIX</CODE
></DT
><DD
><P
>&#13;A deprecated synonym for <A
HREF="#cv-WINDOWSDEFPREFIX"
><CODE
CLASS="envar"
>$WINDOWSDEFPREFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-WIN32DEFSUFFIX"
></A
><CODE
CLASS="envar"
>WIN32DEFSUFFIX</CODE
></DT
><DD
><P
>&#13;A deprecated synonym for <A
HREF="#cv-WINDOWSDEFSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSDEFSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-WIN32EXPPREFIX"
></A
><CODE
CLASS="envar"
>WIN32EXPPREFIX</CODE
></DT
><DD
><P
>&#13;A deprecated synonym for <A
HREF="#cv-WINDOWSEXPSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSEXPSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-WIN32EXPSUFFIX"
></A
><CODE
CLASS="envar"
>WIN32EXPSUFFIX</CODE
></DT
><DD
><P
>&#13;A deprecated synonym for <A
HREF="#cv-WINDOWSEXPSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSEXPSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="cv-WINDOWS_INSERT_DEF"
></A
><CODE
CLASS="envar"
>WINDOWS_INSERT_DEF</CODE
></DT
><DD
><P
>&#13;When this is set to true,
a library build of a Windows shared library
(<TT
CLASS="filename"
>.dll</TT
>file)
will also build a corresponding <TT
CLASS="filename"
>.def</TT
> file
at the same time,
if a <TT
CLASS="filename"
>.def</TT
> file
is not already listed as a build target.
The default is 0 (do not build a <TT
CLASS="filename"
>.def</TT
> file).
</P
></DD
><DT
><A
NAME="cv-WINDOWS_INSERT_MANIFEST"
></A
><CODE
CLASS="envar"
>WINDOWS_INSERT_MANIFEST</CODE
></DT
><DD
><P
>&#13;When this is set to true,
<SPAN
CLASS="application"
>scons</SPAN
>
will be aware of the
<TT
CLASS="filename"
>.manifest</TT
>
files generated by Microsoft Visua C/C++ 8.
</P
></DD
><DT
><A
NAME="cv-WINDOWSDEFPREFIX"
></A
><CODE
CLASS="envar"
>WINDOWSDEFPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for Windows <TT
CLASS="filename"
>.def</TT
>file names.
</P
></DD
><DT
><A
NAME="cv-WINDOWSDEFSUFFIX"
></A
><CODE
CLASS="envar"
>WINDOWSDEFSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for Windows <TT
CLASS="filename"
>.def</TT
> file names.
</P
></DD
><DT
><A
NAME="cv-WINDOWSEXPPREFIX"
></A
><CODE
CLASS="envar"
>WINDOWSEXPPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for Windows <TT
CLASS="filename"
>.exp</TT
> file names.
</P
></DD
><DT
><A
NAME="cv-WINDOWSEXPSUFFIX"
></A
><CODE
CLASS="envar"
>WINDOWSEXPSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for Windows <TT
CLASS="filename"
>.exp</TT
> file names.
</P
></DD
><DT
><A
NAME="cv-WINDOWSPROGMANIFESTPREFIX"
></A
><CODE
CLASS="envar"
>WINDOWSPROGMANIFESTPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for executable program <TT
CLASS="filename"
>.manifest</TT
> files
generated by Microsoft Visual C/C++.
</P
></DD
><DT
><A
NAME="cv-WINDOWSPROGMANIFESTSUFFIX"
></A
><CODE
CLASS="envar"
>WINDOWSPROGMANIFESTSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for executable program <TT
CLASS="filename"
>.manifest</TT
> files
generated by Microsoft Visual C/C++.
</P
></DD
><DT
><A
NAME="cv-WINDOWSSHLIBMANIFESTPREFIX"
></A
><CODE
CLASS="envar"
>WINDOWSSHLIBMANIFESTPREFIX</CODE
></DT
><DD
><P
>&#13;The prefix used for shared library <TT
CLASS="filename"
>.manifest</TT
> files
generated by Microsoft Visual C/C++.
</P
></DD
><DT
><A
NAME="cv-WINDOWSSHLIBMANIFESTSUFFIX"
></A
><CODE
CLASS="envar"
>WINDOWSSHLIBMANIFESTSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for shared library <TT
CLASS="filename"
>.manifest</TT
> files
generated by Microsoft Visual C/C++.
</P
></DD
><DT
><A
NAME="cv-X_IPK_DEPENDS"
></A
><CODE
CLASS="envar"
>X_IPK_DEPENDS</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Depends:</TT
>
field in the controlling information for Ipkg packages.
</P
></DD
><DT
><A
NAME="cv-X_IPK_DESCRIPTION"
></A
><CODE
CLASS="envar"
>X_IPK_DESCRIPTION</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Description:</TT
>
field in the controlling information for Ipkg packages.
The default value is
<TT
CLASS="literal"
>$SUMMARY\n$DESCRIPTION</TT
>
</P
></DD
><DT
><A
NAME="cv-X_IPK_MAINTAINER"
></A
><CODE
CLASS="envar"
>X_IPK_MAINTAINER</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Maintainer:</TT
>
field in the controlling information for Ipkg packages.
</P
></DD
><DT
><A
NAME="cv-X_IPK_PRIORITY"
></A
><CODE
CLASS="envar"
>X_IPK_PRIORITY</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Priority:</TT
>
field in the controlling information for Ipkg packages.
</P
></DD
><DT
><A
NAME="cv-X_IPK_SECTION"
></A
><CODE
CLASS="envar"
>X_IPK_SECTION</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Section:</TT
>
field in the controlling information for Ipkg packages.
</P
></DD
><DT
><A
NAME="cv-X_MSI_LANGUAGE"
></A
><CODE
CLASS="envar"
>X_MSI_LANGUAGE</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Language:</TT
>
attribute in the controlling information for MSI packages.
</P
></DD
><DT
><A
NAME="cv-X_MSI_LICENSE_TEXT"
></A
><CODE
CLASS="envar"
>X_MSI_LICENSE_TEXT</CODE
></DT
><DD
><P
>&#13;The text of the software license in RTF format.
Carriage return characters will be
replaced with the RTF equivalent \\par.
</P
></DD
><DT
><A
NAME="cv-X_MSI_UPGRADE_CODE"
></A
><CODE
CLASS="envar"
>X_MSI_UPGRADE_CODE</CODE
></DT
><DD
><P
>&#13;TODO
</P
></DD
><DT
><A
NAME="cv-X_RPM_AUTOREQPROV"
></A
><CODE
CLASS="envar"
>X_RPM_AUTOREQPROV</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>AutoReqProv:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_BUILD"
></A
><CODE
CLASS="envar"
>X_RPM_BUILD</CODE
></DT
><DD
><P
>&#13;internal, but overridable
</P
></DD
><DT
><A
NAME="cv-X_RPM_BUILDREQUIRES"
></A
><CODE
CLASS="envar"
>X_RPM_BUILDREQUIRES</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>BuildRequires:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_BUILDROOT"
></A
><CODE
CLASS="envar"
>X_RPM_BUILDROOT</CODE
></DT
><DD
><P
>&#13;internal, but overridable
</P
></DD
><DT
><A
NAME="cv-X_RPM_CLEAN"
></A
><CODE
CLASS="envar"
>X_RPM_CLEAN</CODE
></DT
><DD
><P
>&#13;internal, but overridable
</P
></DD
><DT
><A
NAME="cv-X_RPM_CONFLICTS"
></A
><CODE
CLASS="envar"
>X_RPM_CONFLICTS</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Conflicts:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_DEFATTR"
></A
><CODE
CLASS="envar"
>X_RPM_DEFATTR</CODE
></DT
><DD
><P
>&#13;This value is used as the default attributes
for the files in the RPM package.
The default value is
<TT
CLASS="literal"
>(-,root,root)</TT
>.
</P
></DD
><DT
><A
NAME="cv-X_RPM_DISTRIBUTION"
></A
><CODE
CLASS="envar"
>X_RPM_DISTRIBUTION</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Distribution:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_EPOCH"
></A
><CODE
CLASS="envar"
>X_RPM_EPOCH</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Epoch:</TT
>
field in the controlling information for RPM packages.
</P
></DD
><DT
><A
NAME="cv-X_RPM_EXCLUDEARCH"
></A
><CODE
CLASS="envar"
>X_RPM_EXCLUDEARCH</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>ExcludeArch:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_EXLUSIVEARCH"
></A
><CODE
CLASS="envar"
>X_RPM_EXLUSIVEARCH</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>ExclusiveArch:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_GROUP"
></A
><CODE
CLASS="envar"
>X_RPM_GROUP</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Group:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_GROUP_lang"
></A
><CODE
CLASS="envar"
>X_RPM_GROUP_lang</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Group(lang):</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
Note that
<CODE
CLASS="varname"
>lang</CODE
>
is not literal
and should be replaced by
the appropriate language code.
</P
></DD
><DT
><A
NAME="cv-X_RPM_ICON"
></A
><CODE
CLASS="envar"
>X_RPM_ICON</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Icon:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_INSTALL"
></A
><CODE
CLASS="envar"
>X_RPM_INSTALL</CODE
></DT
><DD
><P
>&#13;internal, but overridable
</P
></DD
><DT
><A
NAME="cv-X_RPM_PACKAGER"
></A
><CODE
CLASS="envar"
>X_RPM_PACKAGER</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Packager:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_POSTINSTALL"
></A
><CODE
CLASS="envar"
>X_RPM_POSTINSTALL</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>%post:</TT
>
section in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_POSTUNINSTALL"
></A
><CODE
CLASS="envar"
>X_RPM_POSTUNINSTALL</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>%postun:</TT
>
section in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_PREFIX"
></A
><CODE
CLASS="envar"
>X_RPM_PREFIX</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Prefix:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_PREINSTALL"
></A
><CODE
CLASS="envar"
>X_RPM_PREINSTALL</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>%pre:</TT
>
section in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_PREP"
></A
><CODE
CLASS="envar"
>X_RPM_PREP</CODE
></DT
><DD
><P
>&#13;internal, but overridable
</P
></DD
><DT
><A
NAME="cv-X_RPM_PREUNINSTALL"
></A
><CODE
CLASS="envar"
>X_RPM_PREUNINSTALL</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>%preun:</TT
>
section in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_PROVIDES"
></A
><CODE
CLASS="envar"
>X_RPM_PROVIDES</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Provides:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_REQUIRES"
></A
><CODE
CLASS="envar"
>X_RPM_REQUIRES</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Requires:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_SERIAL"
></A
><CODE
CLASS="envar"
>X_RPM_SERIAL</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Serial:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-X_RPM_URL"
></A
><CODE
CLASS="envar"
>X_RPM_URL</CODE
></DT
><DD
><P
>&#13;This is used to fill in the
<TT
CLASS="literal"
>Url:</TT
>
field in the RPM
<TT
CLASS="filename"
>.spec</TT
> file.
</P
></DD
><DT
><A
NAME="cv-YACC"
></A
><CODE
CLASS="envar"
>YACC</CODE
></DT
><DD
><P
>&#13;The parser generator.
</P
></DD
><DT
><A
NAME="cv-YACCCOM"
></A
><CODE
CLASS="envar"
>YACCCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the parser generator
to generate a source file.
</P
></DD
><DT
><A
NAME="cv-YACCCOMSTR"
></A
><CODE
CLASS="envar"
>YACCCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when generating a source file
using the parser generator.
If this is not set, then <A
HREF="#cv-YACCCOM"
><CODE
CLASS="envar"
>$YACCCOM</CODE
></A
> (the command line) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(YACCCOMSTR = "Yacc'ing $TARGET from $SOURCES")
</PRE
></DD
><DT
><A
NAME="cv-YACCFLAGS"
></A
><CODE
CLASS="envar"
>YACCFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the parser generator.
If <A
HREF="#cv-YACCFLAGS"
><CODE
CLASS="envar"
>$YACCFLAGS</CODE
></A
> contains a <CODE
CLASS="option"
>-d</CODE
> option,
SCons assumes that the call will also create a .h file
(if the yacc source file ends in a .y suffix)
or a .hpp file
(if the yacc source file ends in a .yy suffix)
</P
></DD
><DT
><A
NAME="cv-YACCHFILESUFFIX"
></A
><CODE
CLASS="envar"
>YACCHFILESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix of the C
header file generated by the parser generator
when the
<CODE
CLASS="option"
>-d</CODE
>
option is used.
Note that setting this variable does not cause
the parser generator to generate a header
file with the specified suffix,
it exists to allow you to specify
what suffix the parser generator will use of its own accord.
The default value is
<TT
CLASS="filename"
>.h</TT
>.
</P
></DD
><DT
><A
NAME="cv-YACCHXXFILESUFFIX"
></A
><CODE
CLASS="envar"
>YACCHXXFILESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix of the C++
header file generated by the parser generator
when the
<CODE
CLASS="option"
>-d</CODE
>
option is used.
Note that setting this variable does not cause
the parser generator to generate a header
file with the specified suffix,
it exists to allow you to specify
what suffix the parser generator will use of its own accord.
The default value is
<TT
CLASS="filename"
>.hpp</TT
>,
except on Mac OS X,
where the default is
<TT
CLASS="filename"
>${TARGET.suffix}.h</TT
>.
because the default <SPAN
CLASS="application"
>bison</SPAN
> parser generator just
appends <TT
CLASS="filename"
>.h</TT
>
to the name of the generated C++ file.
</P
></DD
><DT
><A
NAME="cv-YACCVCGFILESUFFIX"
></A
><CODE
CLASS="envar"
>YACCVCGFILESUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix of the file
containing the VCG grammar automaton definition
when the
<CODE
CLASS="option"
>--graph=</CODE
>
option is used.
Note that setting this variable does not cause
the parser generator to generate a VCG
file with the specified suffix,
it exists to allow you to specify
what suffix the parser generator will use of its own accord.
The default value is
<TT
CLASS="filename"
>.vcg</TT
>.
</P
></DD
><DT
><A
NAME="cv-ZIP"
></A
><CODE
CLASS="envar"
>ZIP</CODE
></DT
><DD
><P
>&#13;The zip compression and file packaging utility.
</P
></DD
><DT
><A
NAME="cv-ZIPCOM"
></A
><CODE
CLASS="envar"
>ZIPCOM</CODE
></DT
><DD
><P
>&#13;The command line used to call the zip utility,
or the internal Python function used to create a
zip archive.
</P
></DD
><DT
><A
NAME="cv-ZIPCOMPRESSION"
></A
><CODE
CLASS="envar"
>ZIPCOMPRESSION</CODE
></DT
><DD
><P
>&#13;The
<CODE
CLASS="varname"
>compression</CODE
>
flag
from the Python
<TT
CLASS="filename"
>zipfile</TT
>
module used by the internal Python function
to control whether the zip archive
is compressed or not.
The default value is
<TT
CLASS="literal"
>zipfile.ZIP_DEFLATED</TT
>,
which creates a compressed zip archive.
This value has no effect when using Python 1.5.2
or if the
<TT
CLASS="literal"
>zipfile</TT
>
module is otherwise unavailable.
</P
></DD
><DT
><A
NAME="cv-ZIPCOMSTR"
></A
><CODE
CLASS="envar"
>ZIPCOMSTR</CODE
></DT
><DD
><P
>&#13;The string displayed when archiving files
using the zip utility.
If this is not set, then <A
HREF="#cv-ZIPCOM"
><CODE
CLASS="envar"
>$ZIPCOM</CODE
></A
>
(the command line or internal Python function) is displayed.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(ZIPCOMSTR = "Zipping $TARGET")
</PRE
></DD
><DT
><A
NAME="cv-ZIPFLAGS"
></A
><CODE
CLASS="envar"
>ZIPFLAGS</CODE
></DT
><DD
><P
>&#13;General options passed to the zip utility.
</P
></DD
><DT
><A
NAME="cv-ZIPSUFFIX"
></A
><CODE
CLASS="envar"
>ZIPSUFFIX</CODE
></DT
><DD
><P
>&#13;The suffix used for zip file names.
</P
></DD
></DL
></DIV
></DIV
><DIV
CLASS="appendix"
><HR><H1
><A
NAME="app-builders"
></A
>Appendix B. Builders</H1
><P
>&#13;
This appendix contains descriptions of all of the
Builders that are <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>potentially</I
></SPAN
>
available "out of the box" in this version of SCons.
</P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
><A
NAME="b-CFile"
></A
><CODE
CLASS="function"
>CFile()</CODE
>, <CODE
CLASS="function"
>env.CFile()</CODE
></DT
><DD
><P
>&#13;Builds a C source file given a lex (<TT
CLASS="filename"
>.l</TT
>)
or yacc (<TT
CLASS="filename"
>.y</TT
>) input file.
The suffix specified by the <A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
> construction variable
(<TT
CLASS="filename"
>.c</TT
> by default)
is automatically added to the target
if it is not already present.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;# builds foo.c
env.CFile(target = 'foo.c', source = 'foo.l')
# builds bar.c
env.CFile(target = 'bar', source = 'bar.y')
</PRE
></DD
><DT
><A
NAME="b-CXXFile"
></A
><CODE
CLASS="function"
>CXXFile()</CODE
>, <CODE
CLASS="function"
>env.CXXFile()</CODE
></DT
><DD
><P
>&#13;Builds a C++ source file given a lex (<TT
CLASS="filename"
>.ll</TT
>)
or yacc (<TT
CLASS="filename"
>.yy</TT
>)
input file.
The suffix specified by the <A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
> construction variable
(<TT
CLASS="filename"
>.cc</TT
> by default)
is automatically added to the target
if it is not already present.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;# builds foo.cc
env.CXXFile(target = 'foo.cc', source = 'foo.ll')
# builds bar.cc
env.CXXFile(target = 'bar', source = 'bar.yy')
</PRE
></DD
><DT
><A
NAME="b-DVI"
></A
><CODE
CLASS="function"
>DVI()</CODE
>, <CODE
CLASS="function"
>env.DVI()</CODE
></DT
><DD
><P
>&#13;Builds a <TT
CLASS="filename"
>.dvi</TT
> file
from a <TT
CLASS="filename"
>.tex</TT
>,
<TT
CLASS="filename"
>.ltx</TT
> or <TT
CLASS="filename"
>.latex</TT
> input file.
If the source file suffix is <TT
CLASS="filename"
>.tex</TT
>,
<SPAN
CLASS="application"
>scons</SPAN
>
will examine the contents of the file;
if the string
<TT
CLASS="literal"
>\documentclass</TT
>
or
<TT
CLASS="literal"
>\documentstyle</TT
>
is found, the file is assumed to be a LaTeX file and
the target is built by invoking the <A
HREF="#cv-LATEXCOM"
><CODE
CLASS="envar"
>$LATEXCOM</CODE
></A
> command line;
otherwise, the <A
HREF="#cv-TEXCOM"
><CODE
CLASS="envar"
>$TEXCOM</CODE
></A
> command line is used.
If the file is a LaTeX file,
the
<CODE
CLASS="function"
>DVI</CODE
>
builder method will also examine the contents
of the
<TT
CLASS="filename"
>.aux</TT
>
file and invoke the <A
HREF="#cv-BIBTEX"
><CODE
CLASS="envar"
>$BIBTEX</CODE
></A
> command line
if the string
<TT
CLASS="literal"
>bibdata</TT
>
is found,
start <A
HREF="#cv-MAKEINDEX"
><CODE
CLASS="envar"
>$MAKEINDEX</CODE
></A
> to generate an index if a
<TT
CLASS="filename"
>.ind</TT
>
file is found
and will examine the contents
<TT
CLASS="filename"
>.log</TT
>
file and re-run the <A
HREF="#cv-LATEXCOM"
><CODE
CLASS="envar"
>$LATEXCOM</CODE
></A
> command
if the log file says it is necessary.</P
><P
>The suffix <TT
CLASS="filename"
>.dvi</TT
>
(hard-coded within TeX itself)
is automatically added to the target
if it is not already present.
Examples:
</P
><PRE
CLASS="programlisting"
>&#13;# builds from aaa.tex
env.DVI(target = 'aaa.dvi', source = 'aaa.tex')
# builds bbb.dvi
env.DVI(target = 'bbb', source = 'bbb.ltx')
# builds from ccc.latex
env.DVI(target = 'ccc.dvi', source = 'ccc.latex')
</PRE
></DD
><DT
><A
NAME="b-Install"
></A
><CODE
CLASS="function"
>Install()</CODE
>, <CODE
CLASS="function"
>env.Install()</CODE
></DT
><DD
><P
>&#13;Installs one or more source files or directories
in the specified target,
which must be a directory.
The names of the specified source files or directories
remain the same within the destination directory.
</P
><PRE
CLASS="programlisting"
>&#13;env.Install('/usr/local/bin', source = ['foo', 'bar'])
</PRE
></DD
><DT
><A
NAME="b-InstallAs"
></A
><CODE
CLASS="function"
>InstallAs()</CODE
>, <CODE
CLASS="function"
>env.InstallAs()</CODE
></DT
><DD
><P
>&#13;Installs one or more source files or directories
to specific names,
allowing changing a file or directory name
as part of the installation.
It is an error if the
target
and
source
arguments list different numbers of files or directories.
</P
><PRE
CLASS="programlisting"
>&#13;env.InstallAs(target = '/usr/local/bin/foo',
source = 'foo_debug')
env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'],
source = ['libFOO.a', 'libBAR.a'])
</PRE
></DD
><DT
><A
NAME="b-Jar"
></A
><CODE
CLASS="function"
>Jar()</CODE
>, <CODE
CLASS="function"
>env.Jar()</CODE
></DT
><DD
><P
>&#13;Builds a Java archive (<TT
CLASS="filename"
>.jar</TT
>) file
from the specified list of sources.
Any directories in the source list
will be searched for <TT
CLASS="filename"
>.class</TT
> files).
Any <TT
CLASS="filename"
>.java</TT
> files in the source list
will be compiled to <TT
CLASS="filename"
>.class</TT
> files
by calling the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> Builder.</P
><P
>If the <A
HREF="#cv-JARCHDIR"
><CODE
CLASS="envar"
>$JARCHDIR</CODE
></A
> value is set, the
<SPAN
CLASS="application"
>jar</SPAN
>
command will change to the specified directory using the
<CODE
CLASS="option"
>-C</CODE
>
option.
If <CODE
CLASS="envar"
>$JARCHDIR</CODE
> is not set explicitly,
<SPAN
CLASS="application"
>SCons</SPAN
> will use the top of any subdirectory tree
in which Java <TT
CLASS="filename"
>.class</TT
>
were built by the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> Builder.</P
><P
>If the contents any of the source files begin with the string
<TT
CLASS="literal"
>Manifest-Version</TT
>,
the file is assumed to be a manifest
and is passed to the
<SPAN
CLASS="application"
>jar</SPAN
>
command with the
<CODE
CLASS="option"
>m</CODE
>
option set.
</P
><PRE
CLASS="programlisting"
>&#13;env.Jar(target = 'foo.jar', source = 'classes')
env.Jar(target = 'bar.jar',
source = ['bar1.java', 'bar2.java'])
</PRE
></DD
><DT
><A
NAME="b-Java"
></A
><CODE
CLASS="function"
>Java()</CODE
>, <CODE
CLASS="function"
>env.Java()</CODE
></DT
><DD
><P
>&#13;Builds one or more Java class files.
The sources may be any combination of explicit
<TT
CLASS="filename"
>.java</TT
> files,
or directory trees which will be scanned
for <TT
CLASS="filename"
>.java</TT
> files.</P
><P
>SCons will parse each source <TT
CLASS="filename"
>.java</TT
> file
to find the classes
(including inner classes)
defined within that file,
and from that figure out the
target <TT
CLASS="filename"
>.class</TT
> files that will be created.
The class files will be placed underneath
the specified target directory.</P
><P
>SCons will also search each Java file
for the Java package name,
which it assumes can be found on a line
beginning with the string
<TT
CLASS="literal"
>package</TT
>
in the first column;
the resulting <TT
CLASS="filename"
>.class</TT
> files
will be placed in a directory reflecting
the specified package name.
For example,
the file
<TT
CLASS="filename"
>Foo.java</TT
>
defining a single public
<CODE
CLASS="classname"
>Foo</CODE
>
class and
containing a package name of
<CODE
CLASS="classname"
>sub.dir</CODE
>
will generate a corresponding
<TT
CLASS="filename"
>sub/dir/Foo.class</TT
>
class file.</P
><P
>Examples:
</P
><PRE
CLASS="programlisting"
>&#13;env.Java(target = 'classes', source = 'src')
env.Java(target = 'classes', source = ['src1', 'src2'])
env.Java(target = 'classes', source = ['File1.java', 'File2.java'])
</PRE
><P
>&#13;Java source files can use the native encoding for the underlying OS.
Since SCons compiles in simple ASCII mode by default,
the compiler will generate warnings about unmappable characters,
which may lead to errors as the file is processed further.
In this case, the user must specify the <TT
CLASS="literal"
>LANG</TT
>
environment variable to tell the compiler what encoding is uesd.
For portibility, it's best if the encoding is hard-coded
so that the compile will work if it is done on a system
with a different encoding.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment()
env['ENV']['LANG'] = 'en_GB.UTF-8'
</PRE
></DD
><DT
><A
NAME="b-JavaH"
></A
><CODE
CLASS="function"
>JavaH()</CODE
>, <CODE
CLASS="function"
>env.JavaH()</CODE
></DT
><DD
><P
>&#13;Builds C header and source files for
implementing Java native methods.
The target can be either a directory
in which the header files will be written,
or a header file name which
will contain all of the definitions.
The source can be the names of <TT
CLASS="filename"
>.class</TT
> files,
the names of <TT
CLASS="filename"
>.java</TT
> files
to be compiled into <TT
CLASS="filename"
>.class</TT
> files
by calling the <A
HREF="#b-Java"
><CODE
CLASS="function"
>Java</CODE
></A
> builder method,
or the objects returned from the
<CODE
CLASS="function"
>Java</CODE
>
builder method.</P
><P
>If the construction variable
<A
HREF="#cv-JAVACLASSDIR"
><CODE
CLASS="envar"
>$JAVACLASSDIR</CODE
></A
>
is set, either in the environment
or in the call to the
<CODE
CLASS="function"
>JavaH</CODE
>
builder method itself,
then the value of the variable
will be stripped from the
beginning of any <TT
CLASS="filename"
>.class</TT
> file names.</P
><P
>Examples:
</P
><PRE
CLASS="programlisting"
>&#13;# builds java_native.h
classes = env.Java(target = 'classdir', source = 'src')
env.JavaH(target = 'java_native.h', source = classes)
# builds include/package_foo.h and include/package_bar.h
env.JavaH(target = 'include',
source = ['package/foo.class', 'package/bar.class'])
# builds export/foo.h and export/bar.h
env.JavaH(target = 'export',
source = ['classes/foo.class', 'classes/bar.class'],
JAVACLASSDIR = 'classes')
</PRE
></DD
><DT
><A
NAME="b-Library"
></A
><CODE
CLASS="function"
>Library()</CODE
>, <CODE
CLASS="function"
>env.Library()</CODE
></DT
><DD
><P
>&#13;A synonym for the
<CODE
CLASS="function"
>StaticLibrary</CODE
>
builder method.
</P
></DD
><DT
><A
NAME="b-LoadableModule"
></A
><CODE
CLASS="function"
>LoadableModule()</CODE
>, <CODE
CLASS="function"
>env.LoadableModule()</CODE
></DT
><DD
><P
>&#13;On most systems,
this is the same as
<CODE
CLASS="function"
>SharedLibrary</CODE
>.
On Mac OS X (Darwin) platforms,
this creates a loadable module bundle.
</P
></DD
><DT
><A
NAME="b-M4"
></A
><CODE
CLASS="function"
>M4()</CODE
>, <CODE
CLASS="function"
>env.M4()</CODE
></DT
><DD
><P
>&#13;Builds an output file from an M4 input file.
This uses a default <A
HREF="#cv-M4FLAGS"
><CODE
CLASS="envar"
>$M4FLAGS</CODE
></A
> value of
<CODE
CLASS="option"
>-E</CODE
>,
which considers all warnings to be fatal
and stops on the first warning
when using the GNU version of m4.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env.M4(target = 'foo.c', source = 'foo.c.m4')
</PRE
></DD
><DT
><A
NAME="b-Moc"
></A
><CODE
CLASS="function"
>Moc()</CODE
>, <CODE
CLASS="function"
>env.Moc()</CODE
></DT
><DD
><P
>&#13;Builds an output file from a moc input file. Moc input files are either
header files or cxx files. This builder is only available after using the
tool 'qt'. See the <A
HREF="#cv-QTDIR"
><CODE
CLASS="envar"
>$QTDIR</CODE
></A
> variable for more information.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env.Moc('foo.h') # generates moc_foo.cc
env.Moc('foo.cpp') # generates foo.moc
</PRE
></DD
><DT
><A
NAME="b-MSVSProject"
></A
><CODE
CLASS="function"
>MSVSProject()</CODE
>, <CODE
CLASS="function"
>env.MSVSProject()</CODE
></DT
><DD
><P
>&#13;Builds a Microsoft Visual Studio project file,
and by default builds a solution file as well.</P
><P
>This builds a Visual Studio project file, based on the version of
Visual Studio that is configured (either the latest installed version,
or the version specified by
<A
HREF="#cv-MSVS_VERSION"
><CODE
CLASS="envar"
>$MSVS_VERSION</CODE
></A
>
in the Environment constructor).
For Visual Studio 6, it will generate a
<TT
CLASS="filename"
>.dsp</TT
>
file.
For Visual Studio 7 (.NET) and later versions, it will generate a
<TT
CLASS="filename"
>.vcproj</TT
>
file.</P
><P
>By default,
this also generates a solution file
for the specified project,
a
<TT
CLASS="filename"
>.dsw</TT
>
file for Visual Studio 6
or a
<TT
CLASS="filename"
>.sln</TT
>
file for Visual Studio 7 (.NET).
This behavior may be disabled by specifying
<TT
CLASS="literal"
>auto_build_solution=0</TT
>
when you call
<CODE
CLASS="function"
>MSVSProject</CODE
>,
in which case you presumably want to
build the solution file(s)
by calling the
<CODE
CLASS="function"
>MSVSSolution</CODE
>
Builder (see below).</P
><P
>The <CODE
CLASS="function"
>MSVSProject</CODE
> builder
takes several lists of filenames
to be placed into the project file.
These are currently limited to
<TT
CLASS="literal"
>srcs</TT
>,
<TT
CLASS="literal"
>incs</TT
>,
<TT
CLASS="literal"
>localincs</TT
>,
<TT
CLASS="literal"
>resources</TT
>,
and
<TT
CLASS="literal"
>misc</TT
>.
These are pretty self-explanatory, but it should be noted that these
lists are added to the <A
HREF="#cv-SOURCES"
><CODE
CLASS="envar"
>$SOURCES</CODE
></A
> construction variable as strings,
NOT as SCons File Nodes. This is because they represent file
names to be added to the project file, not the source files used to
build the project file.</P
><P
>The above filename lists are all optional,
although at least one must be specified
for the resulting project file to be non-empty.</P
><P
>In addition to the above lists of values,
the following values may be specified:</P
><P
><TT
CLASS="literal"
>target</TT
>:
The name of the target
<TT
CLASS="filename"
>.dsp</TT
>
or
<TT
CLASS="filename"
>.vcproj</TT
>
file.
The correct
suffix for the version of Visual Studio must be used,
but the
<A
HREF="#cv-MSVSPROJECTSUFFIX"
><CODE
CLASS="envar"
>$MSVSPROJECTSUFFIX</CODE
></A
>
construction variable
will be defined to the correct value (see example below).</P
><P
><TT
CLASS="literal"
>variant</TT
>:
The name of this particular variant.
For Visual Studio 7 projects,
this can also be a list of variant names.
These are typically things like "Debug" or "Release", but really
can be anything you want.
For Visual Studio 7 projects,
they may also specify a target platform
separated from the variant name by a
<TT
CLASS="literal"
>|</TT
>
(vertical pipe)
character:
<TT
CLASS="literal"
>Debug|Xbox</TT
>.
The default target platform is Win32.
Multiple calls to
<CODE
CLASS="function"
>MSVSProject</CODE
>
with different variants are allowed;
all variants will be added to the project file with their appropriate
build targets and sources.</P
><P
><TT
CLASS="literal"
>buildtarget</TT
>:
An optional string, node, or list of strings or nodes
(one per build variant), to tell the Visual Studio debugger
what output target to use in what build variant.
The number of
<TT
CLASS="literal"
>buildtarget</TT
>
entries must match the number of
<TT
CLASS="literal"
>variant</TT
>
entries.</P
><P
><TT
CLASS="literal"
>runfile</TT
>:
The name of the file that Visual Studio 7 and later
will run and debug.
This appears as the value of the
<TT
CLASS="literal"
>Output</TT
>
field in the resutling Visual Studio project file.
If this is not specified,
the default is the same as the specified
<TT
CLASS="literal"
>buildtarget</TT
>
value.</P
><P
>Note that because <SPAN
CLASS="application"
>SCons</SPAN
> always executes its build commands
from the directory in which the <TT
CLASS="filename"
>SConstruct</TT
> file is located,
if you generate a project file in a different directory
than the <TT
CLASS="filename"
>SConstruct</TT
> directory,
users will not be able to double-click
on the file name in compilation error messages
displayed in the Visual Studio console output window.
This can be remedied by adding the
Visual C/C++
.B /FC
compiler option to the <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
> variable
so that the compiler will print
the full path name of any
files that cause compilation errors.</P
><P
>Example usage:
</P
><PRE
CLASS="programlisting"
>&#13;barsrcs = ['bar.cpp'],
barincs = ['bar.h'],
barlocalincs = ['StdAfx.h']
barresources = ['bar.rc','resource.h']
barmisc = ['bar_readme.txt']
dll = env.SharedLibrary(target = 'bar.dll',
source = barsrcs)
env.MSVSProject(target = 'Bar' + env['MSVSPROJECTSUFFIX'],
srcs = barsrcs,
incs = barincs,
localincs = barlocalincs,
resources = barresources,
misc = barmisc,
buildtarget = dll,
variant = 'Release')
</PRE
></DD
><DT
><A
NAME="b-MSVSSolution"
></A
><CODE
CLASS="function"
>MSVSSolution()</CODE
>, <CODE
CLASS="function"
>env.MSVSSolution()</CODE
></DT
><DD
><P
>&#13;Builds a Microsoft Visual Studio solution file.</P
><P
>This builds a Visual Studio solution file,
based on the version of Visual Studio that is configured
(either the latest installed version,
or the version specified by
<A
HREF="#cv-MSVS_VERSION"
><CODE
CLASS="envar"
>$MSVS_VERSION</CODE
></A
>
in the construction environment).
For Visual Studio 6, it will generate a
<TT
CLASS="filename"
>.dsw</TT
>
file.
For Visual Studio 7 (.NET), it will
generate a
<TT
CLASS="filename"
>.sln</TT
>
file.</P
><P
>The following values must be specified:</P
><P
><TT
CLASS="literal"
>target</TT
>:
The name of the target .dsw or .sln file. The correct
suffix for the version of Visual Studio must be used, but the value
<A
HREF="#cv-MSVSSOLUTIONSUFFIX"
><CODE
CLASS="envar"
>$MSVSSOLUTIONSUFFIX</CODE
></A
>
will be defined to the correct value (see example below).</P
><P
><TT
CLASS="literal"
>variant</TT
>:
The name of this particular variant, or a list of variant
names (the latter is only supported for MSVS 7 solutions). These are
typically things like "Debug" or "Release", but really can be anything
you want. For MSVS 7 they may also specify target platform, like this
"Debug|Xbox". Default platform is Win32.</P
><P
><TT
CLASS="literal"
>projects</TT
>:
A list of project file names, or Project nodes returned by calls to the
<CODE
CLASS="function"
>MSVSProject</CODE
>
Builder,
to be placed into the solution file.
It should be noted that these file names are NOT added to the $SOURCES
environment variable in form of files, but rather as strings. This
is because they represent file names to be added to the solution file,
not the source files used to build the solution file.</P
><P
>(NOTE: Currently only one project is supported per solution.)</P
><P
>Example Usage:
</P
><PRE
CLASS="programlisting"
>&#13;env.MSVSSolution(target = 'Bar' + env['MSVSSOLUTIONSUFFIX'],
projects = ['bar' + env['MSVSPROJECTSUFFIX']],
variant = 'Release')
</PRE
></DD
><DT
><A
NAME="b-Object"
></A
><CODE
CLASS="function"
>Object()</CODE
>, <CODE
CLASS="function"
>env.Object()</CODE
></DT
><DD
><P
>&#13;A synonym for the
<CODE
CLASS="function"
>StaticObject</CODE
>
builder method.
</P
></DD
><DT
><A
NAME="b-Package"
></A
><CODE
CLASS="function"
>Package()</CODE
>, <CODE
CLASS="function"
>env.Package()</CODE
></DT
><DD
><P
>&#13;Builds software distribution packages.
Packages consist of files to install and packaging information.
The former may be specified with the <CODE
CLASS="varname"
>source</CODE
> parameter and may be left out,
in which case the <CODE
CLASS="function"
>FindInstalledFiles</CODE
> function will collect
all files that have an <CODE
CLASS="function"
>Install</CODE
> or <CODE
CLASS="function"
>InstallAs</CODE
> Builder attached.
If the <CODE
CLASS="varname"
>target</CODE
> is not specified
it will be deduced from additional information given to this Builder.</P
><P
>The packaging information is specified
with the help of construction variables documented below.
This information is called a tag to stress that
some of them can also be attached to files with the <CODE
CLASS="function"
>Tag</CODE
> function.
The mandatory ones will complain if they were not specified.
They vary depending on chosen target packager.</P
><P
>The target packager may be selected with the "PACKAGETYPE" command line
option or with the <CODE
CLASS="envar"
>$PACKAGETYPE</CODE
> construction variable. Currently
the following packagers 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
>An updated list is always available under the "package_type" option when
running "scons --help" on a project that has packaging activated.
</P
><PRE
CLASS="programlisting"
>&#13;env = Environment(tools=['default', 'packaging'])
env.Install('/bin/', 'my_program')
env.Package( NAME = 'foo',
VERSION = '1.2.3',
PACKAGEVERSION = 0,
PACKAGETYPE = 'rpm',
LICENSE = 'gpl',
SUMMARY = 'balalalalal',
DESCRIPTION = 'this should be really really long',
X_RPM_GROUP = 'Application/fu',
SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz'
)
</PRE
></DD
><DT
><A
NAME="b-PCH"
></A
><CODE
CLASS="function"
>PCH()</CODE
>, <CODE
CLASS="function"
>env.PCH()</CODE
></DT
><DD
><P
>&#13;Builds a Microsoft Visual C++ precompiled header.
Calling this builder method
returns a list of two targets: the PCH as the first element, and the object
file as the second element. Normally the object file is ignored.
This builder method is only
provided when Microsoft Visual C++ is being used as the compiler.
The PCH builder method is generally used in
conjuction with the PCH construction variable to force object files to use
the precompiled header:
</P
><PRE
CLASS="programlisting"
>&#13;env['PCH'] = env.PCH('StdAfx.cpp')[0]
</PRE
></DD
><DT
><A
NAME="b-PDF"
></A
><CODE
CLASS="function"
>PDF()</CODE
>, <CODE
CLASS="function"
>env.PDF()</CODE
></DT
><DD
><P
>&#13;Builds a <TT
CLASS="filename"
>.pdf</TT
> file
from a <TT
CLASS="filename"
>.dvi</TT
> input file
(or, by extension, a <TT
CLASS="filename"
>.tex</TT
>,
<TT
CLASS="filename"
>.ltx</TT
>,
or
<TT
CLASS="filename"
>.latex</TT
> input file).
The suffix specified by the <A
HREF="#cv-PDFSUFFIX"
><CODE
CLASS="envar"
>$PDFSUFFIX</CODE
></A
> construction variable
(<TT
CLASS="filename"
>.pdf</TT
> by default)
is added automatically to the target
if it is not already present. Example:
</P
><PRE
CLASS="programlisting"
>&#13;# builds from aaa.tex
env.PDF(target = 'aaa.pdf', source = 'aaa.tex')
# builds bbb.pdf from bbb.dvi
env.PDF(target = 'bbb', source = 'bbb.dvi')
</PRE
></DD
><DT
><A
NAME="b-PostScript"
></A
><CODE
CLASS="function"
>PostScript()</CODE
>, <CODE
CLASS="function"
>env.PostScript()</CODE
></DT
><DD
><P
>&#13;Builds a <TT
CLASS="filename"
>.ps</TT
> file
from a <TT
CLASS="filename"
>.dvi</TT
> input file
(or, by extension, a <TT
CLASS="filename"
>.tex</TT
>,
<TT
CLASS="filename"
>.ltx</TT
>,
or
<TT
CLASS="filename"
>.latex</TT
> input file).
The suffix specified by the <A
HREF="#cv-PSSUFFIX"
><CODE
CLASS="envar"
>$PSSUFFIX</CODE
></A
> construction variable
(<TT
CLASS="filename"
>.ps</TT
> by default)
is added automatically to the target
if it is not already present. Example:
</P
><PRE
CLASS="programlisting"
>&#13;# builds from aaa.tex
env.PostScript(target = 'aaa.ps', source = 'aaa.tex')
# builds bbb.ps from bbb.dvi
env.PostScript(target = 'bbb', source = 'bbb.dvi')
</PRE
></DD
><DT
><A
NAME="b-Program"
></A
><CODE
CLASS="function"
>Program()</CODE
>, <CODE
CLASS="function"
>env.Program()</CODE
></DT
><DD
><P
>&#13;Builds an executable given one or more object files
or C, C++, D, or Fortran source files.
If any C, C++, D or Fortran source files are specified,
then they will be automatically
compiled to object files using the
<CODE
CLASS="function"
>Object</CODE
>
builder method;
see that builder method's description for
a list of legal source file suffixes
and how they are interpreted.
The target executable file prefix
(specified by the <A
HREF="#cv-PROGPREFIX"
><CODE
CLASS="envar"
>$PROGPREFIX</CODE
></A
> construction variable; nothing by default)
and suffix
(specified by the <A
HREF="#cv-PROGSUFFIX"
><CODE
CLASS="envar"
>$PROGSUFFIX</CODE
></A
> construction variable;
by default, <TT
CLASS="filename"
>.exe</TT
> on Windows systems,
nothing on POSIX systems)
are automatically added to the target if not already present.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env.Program(target = 'foo', source = ['foo.o', 'bar.c', 'baz.f'])
</PRE
></DD
><DT
><A
NAME="b-RES"
></A
><CODE
CLASS="function"
>RES()</CODE
>, <CODE
CLASS="function"
>env.RES()</CODE
></DT
><DD
><P
>&#13;Builds a Microsoft Visual C++ resource file.
This builder method is only provided
when Microsoft Visual C++ or MinGW is being used as the compiler. The
<TT
CLASS="filename"
>.res</TT
>
(or
<TT
CLASS="filename"
>.o</TT
>
for MinGW) suffix is added to the target name if no other suffix is given.
The source
file is scanned for implicit dependencies as though it were a C file.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env.RES('resource.rc')
</PRE
></DD
><DT
><A
NAME="b-RMIC"
></A
><CODE
CLASS="function"
>RMIC()</CODE
>, <CODE
CLASS="function"
>env.RMIC()</CODE
></DT
><DD
><P
>&#13;Builds stub and skeleton class files
for remote objects
from Java <TT
CLASS="filename"
>.class</TT
> files.
The target is a directory
relative to which the stub
and skeleton class files will be written.
The source can be the names of <TT
CLASS="filename"
>.class</TT
> files,
or the objects return from the
<CODE
CLASS="function"
>Java</CODE
>
builder method.</P
><P
>If the construction variable
<A
HREF="#cv-JAVACLASSDIR"
><CODE
CLASS="envar"
>$JAVACLASSDIR</CODE
></A
>
is set, either in the environment
or in the call to the
<CODE
CLASS="function"
>RMIC</CODE
>
builder method itself,
then the value of the variable
will be stripped from the
beginning of any <TT
CLASS="filename"
>.class </TT
>
file names.
</P
><PRE
CLASS="programlisting"
>&#13;classes = env.Java(target = 'classdir', source = 'src')
env.RMIC(target = 'outdir1', source = classes)
env.RMIC(target = 'outdir2',
source = ['package/foo.class', 'package/bar.class'])
env.RMIC(target = 'outdir3',
source = ['classes/foo.class', 'classes/bar.class'],
JAVACLASSDIR = 'classes')
</PRE
></DD
><DT
><A
NAME="b-RPCGenClient"
></A
><CODE
CLASS="function"
>RPCGenClient()</CODE
>, <CODE
CLASS="function"
>env.RPCGenClient()</CODE
></DT
><DD
><P
>&#13;Generates an RPC client stub (<TT
CLASS="filename"
>_clnt.c</TT
>) file
from a specified RPC (<TT
CLASS="filename"
>.x</TT
>) source file.
Because rpcgen only builds output files
in the local directory,
the command will be executed
in the source file's directory by default.
</P
><PRE
CLASS="programlisting"
>&#13;# Builds src/rpcif_clnt.c
env.RPCGenClient('src/rpcif.x')
</PRE
></DD
><DT
><A
NAME="b-RPCGenHeader"
></A
><CODE
CLASS="function"
>RPCGenHeader()</CODE
>, <CODE
CLASS="function"
>env.RPCGenHeader()</CODE
></DT
><DD
><P
>&#13;Generates an RPC header (<TT
CLASS="filename"
>.h</TT
>) file
from a specified RPC (<TT
CLASS="filename"
>.x</TT
>) source file.
Because rpcgen only builds output files
in the local directory,
the command will be executed
in the source file's directory by default.
</P
><PRE
CLASS="programlisting"
>&#13;# Builds src/rpcif.h
env.RPCGenHeader('src/rpcif.x')
</PRE
></DD
><DT
><A
NAME="b-RPCGenService"
></A
><CODE
CLASS="function"
>RPCGenService()</CODE
>, <CODE
CLASS="function"
>env.RPCGenService()</CODE
></DT
><DD
><P
>&#13;Generates an RPC server-skeleton (<TT
CLASS="filename"
>_svc.c</TT
>) file
from a specified RPC (<TT
CLASS="filename"
>.x</TT
>) source file.
Because rpcgen only builds output files
in the local directory,
the command will be executed
in the source file's directory by default.
</P
><PRE
CLASS="programlisting"
>&#13;# Builds src/rpcif_svc.c
env.RPCGenClient('src/rpcif.x')
</PRE
></DD
><DT
><A
NAME="b-RPCGenXDR"
></A
><CODE
CLASS="function"
>RPCGenXDR()</CODE
>, <CODE
CLASS="function"
>env.RPCGenXDR()</CODE
></DT
><DD
><P
>&#13;Generates an RPC XDR routine (<TT
CLASS="filename"
>_xdr.c</TT
>) file
from a specified RPC (<TT
CLASS="filename"
>.x</TT
>) source file.
Because rpcgen only builds output files
in the local directory,
the command will be executed
in the source file's directory by default.
</P
><PRE
CLASS="programlisting"
>&#13;# Builds src/rpcif_xdr.c
env.RPCGenClient('src/rpcif.x')
</PRE
></DD
><DT
><A
NAME="b-SharedLibrary"
></A
><CODE
CLASS="function"
>SharedLibrary()</CODE
>, <CODE
CLASS="function"
>env.SharedLibrary()</CODE
></DT
><DD
><P
>&#13;Builds a shared library
(<TT
CLASS="filename"
>.so</TT
> on a POSIX system,
<TT
CLASS="filename"
>.dll</TT
> on Windows)
given one or more object files
or C, C++, D or Fortran source files.
If any source files are given,
then they will be automatically
compiled to object files.
The static library prefix and suffix (if any)
are automatically added to the target.
The target library file prefix
(specified by the <A
HREF="#cv-SHLIBPREFIX"
><CODE
CLASS="envar"
>$SHLIBPREFIX</CODE
></A
> construction variable;
by default, <TT
CLASS="filename"
>lib</TT
> on POSIX systems,
nothing on Windows systems)
and suffix
(specified by the <A
HREF="#cv-SHLIBSUFFIX"
><CODE
CLASS="envar"
>$SHLIBSUFFIX</CODE
></A
> construction variable;
by default, <TT
CLASS="filename"
>.dll</TT
> on Windows systems,
<TT
CLASS="filename"
>.so</TT
> on POSIX systems)
are automatically added to the target if not already present.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env.SharedLibrary(target = 'bar', source = ['bar.c', 'foo.o'])
</PRE
><P
>&#13;On Windows systems, the
<CODE
CLASS="function"
>SharedLibrary</CODE
>
builder method will always build an import
(<TT
CLASS="filename"
>.lib</TT
>) library
in addition to the shared (<TT
CLASS="filename"
>.dll</TT
>) library,
adding a <TT
CLASS="filename"
>.lib</TT
> library with the same basename
if there is not already a <TT
CLASS="filename"
>.lib</TT
> file explicitly
listed in the targets.</P
><P
>Any object files listed in the
<TT
CLASS="literal"
>source</TT
>
must have been built for a shared library
(that is, using the
<CODE
CLASS="function"
>SharedObject</CODE
>
builder method).
<SPAN
CLASS="application"
>scons</SPAN
>
will raise an error if there is any mismatch.</P
><P
>On Windows systems, specifying
<TT
CLASS="literal"
>register=1</TT
>
will cause the <TT
CLASS="filename"
>.dll</TT
> to be
registered after it is built using REGSVR32.
The command that is run
("regsvr32" by default) is determined by <A
HREF="#cv-REGSVR"
><CODE
CLASS="envar"
>$REGSVR</CODE
></A
> construction
variable, and the flags passed are determined by <A
HREF="#cv-REGSVRFLAGS"
><CODE
CLASS="envar"
>$REGSVRFLAGS</CODE
></A
>. By
default, <A
HREF="#cv-REGSVRFLAGS"
><CODE
CLASS="envar"
>$REGSVRFLAGS</CODE
></A
> includes the <CODE
CLASS="option"
>/s</CODE
> option,
to prevent dialogs from popping
up and requiring user attention when it is run. If you change
<A
HREF="#cv-REGSVRFLAGS"
><CODE
CLASS="envar"
>$REGSVRFLAGS</CODE
></A
>, be sure to include the <CODE
CLASS="option"
>/s</CODE
> option.
For example,
</P
><PRE
CLASS="programlisting"
>&#13;env.SharedLibrary(target = 'bar',
source = ['bar.cxx', 'foo.obj'],
register=1)
</PRE
><P
>&#13;will register <TT
CLASS="filename"
>bar.dll</TT
> as a COM object
when it is done linking it.
</P
></DD
><DT
><A
NAME="b-SharedObject"
></A
><CODE
CLASS="function"
>SharedObject()</CODE
>, <CODE
CLASS="function"
>env.SharedObject()</CODE
></DT
><DD
><P
>&#13;Builds an object file for
inclusion in a shared library.
Source files must have one of the same set of extensions
specified above for the
<CODE
CLASS="function"
>StaticObject</CODE
>
builder method.
On some platforms building a shared object requires additional
compiler option
(e.g. <CODE
CLASS="option"
>-fPIC</CODE
> for gcc)
in addition to those needed to build a
normal (static) object, but on some platforms there is no difference between a
shared object and a normal (static) one. When there is a difference, SCons
will only allow shared objects to be linked into a shared library, and will
use a different suffix for shared objects. On platforms where there is no
difference, SCons will allow both normal (static)
and shared objects to be linked into a
shared library, and will use the same suffix for shared and normal
(static) objects.
The target object file prefix
(specified by the <A
HREF="#cv-SHOBJPREFIX"
><CODE
CLASS="envar"
>$SHOBJPREFIX</CODE
></A
> construction variable;
by default, the same as <A
HREF="#cv-OBJPREFIX"
><CODE
CLASS="envar"
>$OBJPREFIX</CODE
></A
>)
and suffix
(specified by the <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
> construction variable)
are automatically added to the target if not already present.
Examples:
</P
><PRE
CLASS="programlisting"
>&#13;env.SharedObject(target = 'ddd', source = 'ddd.c')
env.SharedObject(target = 'eee.o', source = 'eee.cpp')
env.SharedObject(target = 'fff.obj', source = 'fff.for')
</PRE
><P
>&#13;Note that the source files will be scanned
according to the suffix mappings in the
<TT
CLASS="literal"
>SourceFileScanner</TT
>
object.
See the section "Scanner Objects,"
below, for a more information.
</P
></DD
><DT
><A
NAME="b-StaticLibrary"
></A
><CODE
CLASS="function"
>StaticLibrary()</CODE
>, <CODE
CLASS="function"
>env.StaticLibrary()</CODE
></DT
><DD
><P
>&#13;Builds a static library given one or more object files
or C, C++, D or Fortran source files.
If any source files are given,
then they will be automatically
compiled to object files.
The static library prefix and suffix (if any)
are automatically added to the target.
The target library file prefix
(specified by the <A
HREF="#cv-LIBPREFIX"
><CODE
CLASS="envar"
>$LIBPREFIX</CODE
></A
> construction variable;
by default, <TT
CLASS="filename"
>lib</TT
> on POSIX systems,
nothing on Windows systems)
and suffix
(specified by the <A
HREF="#cv-LIBSUFFIX"
><CODE
CLASS="envar"
>$LIBSUFFIX</CODE
></A
> construction variable;
by default, <TT
CLASS="filename"
>.lib</TT
> on Windows systems,
<TT
CLASS="filename"
>.a</TT
> on POSIX systems)
are automatically added to the target if not already present.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env.StaticLibrary(target = 'bar', source = ['bar.c', 'foo.o'])
</PRE
><P
>&#13;Any object files listed in the
<TT
CLASS="literal"
>source</TT
>
must have been built for a static library
(that is, using the
<CODE
CLASS="function"
>StaticObject</CODE
>
builder method).
<SPAN
CLASS="application"
>scons</SPAN
>
will raise an error if there is any mismatch.
</P
></DD
><DT
><A
NAME="b-StaticObject"
></A
><CODE
CLASS="function"
>StaticObject()</CODE
>, <CODE
CLASS="function"
>env.StaticObject()</CODE
></DT
><DD
><P
>&#13;Builds a static object file
from one or more C, C++, D, or Fortran source files.
Source files must have one of the following extensions:
</P
><PRE
CLASS="programlisting"
>&#13; .asm assembly language file
.ASM assembly language file
.c C file
.C Windows: C file
POSIX: C++ file
.cc C++ file
.cpp C++ file
.cxx C++ file
.cxx C++ file
.c++ C++ file
.C++ C++ file
.d D file
.f Fortran file
.F Windows: Fortran file
POSIX: Fortran file + C pre-processor
.for Fortran file
.FOR Fortran file
.fpp Fortran file + C pre-processor
.FPP Fortran file + C pre-processor
.m Object C file
.mm Object C++ file
.s assembly language file
.S Windows: assembly language file
POSIX: assembly language file + C pre-processor
.spp assembly language file + C pre-processor
.SPP assembly language file + C pre-processor
</PRE
><P
>&#13;The target object file prefix
(specified by the <A
HREF="#cv-OBJPREFIX"
><CODE
CLASS="envar"
>$OBJPREFIX</CODE
></A
> construction variable; nothing by default)
and suffix
(specified by the <A
HREF="#cv-OBJSUFFIX"
><CODE
CLASS="envar"
>$OBJSUFFIX</CODE
></A
> construction variable;
<TT
CLASS="filename"
>.obj</TT
> on Windows systems,
<TT
CLASS="filename"
>.o</TT
> on POSIX systems)
are automatically added to the target if not already present.
Examples:
</P
><PRE
CLASS="programlisting"
>&#13;env.StaticObject(target = 'aaa', source = 'aaa.c')
env.StaticObject(target = 'bbb.o', source = 'bbb.c++')
env.StaticObject(target = 'ccc.obj', source = 'ccc.f')
</PRE
><P
>&#13;Note that the source files will be scanned
according to the suffix mappings in
<TT
CLASS="literal"
>SourceFileScanner</TT
>
object.
See the section "Scanner Objects,"
below, for a more information.
</P
></DD
><DT
><A
NAME="b-Tar"
></A
><CODE
CLASS="function"
>Tar()</CODE
>, <CODE
CLASS="function"
>env.Tar()</CODE
></DT
><DD
><P
>&#13;Builds a tar archive of the specified files
and/or directories.
Unlike most builder methods,
the
<CODE
CLASS="function"
>Tar</CODE
>
builder method may be called multiple times
for a given target;
each additional call
adds to the list of entries
that will be built into the archive.
Any source directories will
be scanned for changes to
any on-disk files,
regardless of whether or not
<SPAN
CLASS="application"
>scons</SPAN
>
knows about them from other Builder or function calls.
</P
><PRE
CLASS="programlisting"
>&#13;env.Tar('src.tar', 'src')
# Create the stuff.tar file.
env.Tar('stuff', ['subdir1', 'subdir2'])
# Also add "another" to the stuff.tar file.
env.Tar('stuff', 'another')
# Set TARFLAGS to create a gzip-filtered archive.
env = Environment(TARFLAGS = '-c -z')
env.Tar('foo.tar.gz', 'foo')
# Also set the suffix to .tgz.
env = Environment(TARFLAGS = '-c -z',
TARSUFFIX = '.tgz')
env.Tar('foo')
</PRE
></DD
><DT
><A
NAME="b-TypeLibrary"
></A
><CODE
CLASS="function"
>TypeLibrary()</CODE
>, <CODE
CLASS="function"
>env.TypeLibrary()</CODE
></DT
><DD
><P
>&#13;Builds a Windows type library (<TT
CLASS="filename"
>.tlb</TT
>)
file from an input IDL file (<TT
CLASS="filename"
>.idl</TT
>).
In addition, it will build the associated inteface stub and
proxy source files,
naming them according to the base name of the <TT
CLASS="filename"
>.idl</TT
> file.
For example,
</P
><PRE
CLASS="programlisting"
>&#13;env.TypeLibrary(source="foo.idl")
</PRE
><P
>&#13;Will create <TT
CLASS="filename"
>foo.tlb</TT
>,
<TT
CLASS="filename"
>foo.h</TT
>,
<TT
CLASS="filename"
>foo_i.c</TT
>,
<TT
CLASS="filename"
>foo_p.c</TT
>
and
<TT
CLASS="filename"
>foo_data.c</TT
>
files.
</P
></DD
><DT
><A
NAME="b-Uic"
></A
><CODE
CLASS="function"
>Uic()</CODE
>, <CODE
CLASS="function"
>env.Uic()</CODE
></DT
><DD
><P
>&#13;Builds a header file, an implementation file and a moc file from an ui file.
and returns the corresponding nodes in the above order.
This builder is only available after using the tool 'qt'. Note: you can
specify <TT
CLASS="filename"
>.ui</TT
> files directly as source
files to the <CODE
CLASS="function"
>Program</CODE
>,
<CODE
CLASS="function"
>Library</CODE
> and <CODE
CLASS="function"
>SharedLibrary</CODE
> builders
without using this builder. Using this builder lets you override the standard
naming conventions (be careful: prefixes are always prepended to names of
built files; if you don't want prefixes, you may set them to ``).
See the <A
HREF="#cv-QTDIR"
><CODE
CLASS="envar"
>$QTDIR</CODE
></A
> variable for more information.
Example:
</P
><PRE
CLASS="programlisting"
>&#13;env.Uic('foo.ui') # -&#62; ['foo.h', 'uic_foo.cc', 'moc_foo.cc']
env.Uic(target = Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'),
source = 'foo.ui') # -&#62; ['include/foo.h', 'gen/uicfoo.cc', 'gen/mocfoo.cc']
</PRE
></DD
><DT
><A
NAME="b-Zip"
></A
><CODE
CLASS="function"
>Zip()</CODE
>, <CODE
CLASS="function"
>env.Zip()</CODE
></DT
><DD
><P
>&#13;Builds a zip archive of the specified files
and/or directories.
Unlike most builder methods,
the
<CODE
CLASS="function"
>Zip</CODE
>
builder method may be called multiple times
for a given target;
each additional call
adds to the list of entries
that will be built into the archive.
Any source directories will
be scanned for changes to
any on-disk files,
regardless of whether or not
<SPAN
CLASS="application"
>scons</SPAN
>
knows about them from other Builder or function calls.
</P
><PRE
CLASS="programlisting"
>&#13;env.Zip('src.zip', 'src')
# Create the stuff.zip file.
env.Zip('stuff', ['subdir1', 'subdir2'])
# Also add "another" to the stuff.tar file.
env.Zip('stuff', 'another')
</PRE
></DD
></DL
></DIV
></DIV
><DIV
CLASS="appendix"
><HR><H1
><A
NAME="app-tools"
></A
>Appendix C. Tools</H1
><P
>&#13;
This appendix contains descriptions of all of the
Tools modules that are
available "out of the box" in this version of SCons.
</P
><P
></P
><DIV
CLASS="variablelist"
><DL
><DT
><A
NAME="t-386asm"
></A
><TT
CLASS="literal"
>386asm</TT
></DT
><DD
><P
>&#13;Sets construction variables for the 386ASM assembler
for the Phar Lap ETS embedded operating system.
</P
><P
>&#13;Sets: <A
HREF="#cv-AS"
><CODE
CLASS="envar"
>$AS</CODE
></A
>, <A
HREF="#cv-ASCOM"
><CODE
CLASS="envar"
>$ASCOM</CODE
></A
>, <A
HREF="#cv-ASFLAGS"
><CODE
CLASS="envar"
>$ASFLAGS</CODE
></A
>, <A
HREF="#cv-ASPPCOM"
><CODE
CLASS="envar"
>$ASPPCOM</CODE
></A
>, <A
HREF="#cv-ASPPFLAGS"
><CODE
CLASS="envar"
>$ASPPFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</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-_CPPINCFLAGS"
><CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-aixcXX"
></A
><TT
CLASS="literal"
>aixc++</TT
></DT
><DD
><P
>&#13;Sets construction variables for the IMB xlc / Visual Age C++ compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXVERSION"
><CODE
CLASS="envar"
>$CXXVERSION</CODE
></A
>, <A
HREF="#cv-SHCXX"
><CODE
CLASS="envar"
>$SHCXX</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-aixcc"
></A
><TT
CLASS="literal"
>aixcc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the IBM xlc / Visual Age C compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CCVERSION"
><CODE
CLASS="envar"
>$CCVERSION</CODE
></A
>, <A
HREF="#cv-SHCC"
><CODE
CLASS="envar"
>$SHCC</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-aixf77"
></A
><TT
CLASS="literal"
>aixf77</TT
></DT
><DD
><P
>&#13;Sets construction variables for the IBM Visual Age f77 Fortran compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-F77"
><CODE
CLASS="envar"
>$F77</CODE
></A
>, <A
HREF="#cv-SHF77"
><CODE
CLASS="envar"
>$SHF77</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-aixlink"
></A
><TT
CLASS="literal"
>aixlink</TT
></DT
><DD
><P
>&#13;Sets construction variables for the IBM Visual Age linker.
</P
><P
>&#13;Sets: <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
>, <A
HREF="#cv-SHLIBSUFFIX"
><CODE
CLASS="envar"
>$SHLIBSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-applelink"
></A
><TT
CLASS="literal"
>applelink</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Apple linker
(similar to the GNU linker).
</P
><P
>&#13;Sets: <A
HREF="#cv-FRAMEWORKPATHPREFIX"
><CODE
CLASS="envar"
>$FRAMEWORKPATHPREFIX</CODE
></A
>, <A
HREF="#cv-LDMODULECOM"
><CODE
CLASS="envar"
>$LDMODULECOM</CODE
></A
>, <A
HREF="#cv-LDMODULEFLAGS"
><CODE
CLASS="envar"
>$LDMODULEFLAGS</CODE
></A
>, <A
HREF="#cv-LDMODULEPREFIX"
><CODE
CLASS="envar"
>$LDMODULEPREFIX</CODE
></A
>, <A
HREF="#cv-LDMODULESUFFIX"
><CODE
CLASS="envar"
>$LDMODULESUFFIX</CODE
></A
>, <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>, <A
HREF="#cv-_FRAMEWORKPATH"
><CODE
CLASS="envar"
>$_FRAMEWORKPATH</CODE
></A
>, <A
HREF="#cv-_FRAMEWORKS"
><CODE
CLASS="envar"
>$_FRAMEWORKS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-FRAMEWORKSFLAGS"
><CODE
CLASS="envar"
>$FRAMEWORKSFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-ar"
></A
><TT
CLASS="literal"
>ar</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>ar</SPAN
> library archiver.
</P
><P
>&#13;Sets: <A
HREF="#cv-AR"
><CODE
CLASS="envar"
>$AR</CODE
></A
>, <A
HREF="#cv-ARCOM"
><CODE
CLASS="envar"
>$ARCOM</CODE
></A
>, <A
HREF="#cv-ARFLAGS"
><CODE
CLASS="envar"
>$ARFLAGS</CODE
></A
>, <A
HREF="#cv-LIBPREFIX"
><CODE
CLASS="envar"
>$LIBPREFIX</CODE
></A
>, <A
HREF="#cv-LIBSUFFIX"
><CODE
CLASS="envar"
>$LIBSUFFIX</CODE
></A
>, <A
HREF="#cv-RANLIB"
><CODE
CLASS="envar"
>$RANLIB</CODE
></A
>, <A
HREF="#cv-RANLIBCOM"
><CODE
CLASS="envar"
>$RANLIBCOM</CODE
></A
>, <A
HREF="#cv-RANLIBFLAGS"
><CODE
CLASS="envar"
>$RANLIBFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-as"
></A
><TT
CLASS="literal"
>as</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>as</SPAN
> assembler.
</P
><P
>&#13;Sets: <A
HREF="#cv-AS"
><CODE
CLASS="envar"
>$AS</CODE
></A
>, <A
HREF="#cv-ASCOM"
><CODE
CLASS="envar"
>$ASCOM</CODE
></A
>, <A
HREF="#cv-ASFLAGS"
><CODE
CLASS="envar"
>$ASFLAGS</CODE
></A
>, <A
HREF="#cv-ASPPCOM"
><CODE
CLASS="envar"
>$ASPPCOM</CODE
></A
>, <A
HREF="#cv-ASPPFLAGS"
><CODE
CLASS="envar"
>$ASPPFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</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-_CPPINCFLAGS"
><CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-bcc32"
></A
><TT
CLASS="literal"
>bcc32</TT
></DT
><DD
><P
>&#13;Sets construction variables for the bcc32 compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
>, <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>, <A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
>, <A
HREF="#cv-CFLAGS"
><CODE
CLASS="envar"
>$CFLAGS</CODE
></A
>, <A
HREF="#cv-CPPDEFPREFIX"
><CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFSUFFIX"
><CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
></A
>, <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
>, <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>, <A
HREF="#cv-SHCC"
><CODE
CLASS="envar"
>$SHCC</CODE
></A
>, <A
HREF="#cv-SHCCCOM"
><CODE
CLASS="envar"
>$SHCCCOM</CODE
></A
>, <A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCFLAGS"
><CODE
CLASS="envar"
>$SHCFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-_CPPDEFFLAGS"
><CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
></A
>, <A
HREF="#cv-_CPPINCFLAGS"
><CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-BitKeeper"
></A
><TT
CLASS="literal"
>BitKeeper</TT
></DT
><DD
><P
>&#13;Sets construction variables for the BitKeeper
source code control system.
</P
><P
>&#13;Sets: <A
HREF="#cv-BITKEEPER"
><CODE
CLASS="envar"
>$BITKEEPER</CODE
></A
>, <A
HREF="#cv-BITKEEPERCOM"
><CODE
CLASS="envar"
>$BITKEEPERCOM</CODE
></A
>, <A
HREF="#cv-BITKEEPERGET"
><CODE
CLASS="envar"
>$BITKEEPERGET</CODE
></A
>, <A
HREF="#cv-BITKEEPERGETFLAGS"
><CODE
CLASS="envar"
>$BITKEEPERGETFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-BITKEEPERCOMSTR"
><CODE
CLASS="envar"
>$BITKEEPERCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-cc"
></A
><TT
CLASS="literal"
>cc</TT
></DT
><DD
><P
>&#13;Sets construction variables for generic POSIX C copmilers.
</P
><P
>&#13;Sets: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
>, <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>, <A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
>, <A
HREF="#cv-CFLAGS"
><CODE
CLASS="envar"
>$CFLAGS</CODE
></A
>, <A
HREF="#cv-CPPDEFPREFIX"
><CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFSUFFIX"
><CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
></A
>, <A
HREF="#cv-FRAMEWORKPATH"
><CODE
CLASS="envar"
>$FRAMEWORKPATH</CODE
></A
>, <A
HREF="#cv-FRAMEWORKS"
><CODE
CLASS="envar"
>$FRAMEWORKS</CODE
></A
>, <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
>, <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>, <A
HREF="#cv-SHCC"
><CODE
CLASS="envar"
>$SHCC</CODE
></A
>, <A
HREF="#cv-SHCCCOM"
><CODE
CLASS="envar"
>$SHCCCOM</CODE
></A
>, <A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCFLAGS"
><CODE
CLASS="envar"
>$SHCFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-PLATFORM"
><CODE
CLASS="envar"
>$PLATFORM</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-cvf"
></A
><TT
CLASS="literal"
>cvf</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Compaq Visual Fortran compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
>, <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>, <A
HREF="#cv-FORTRANMODDIR"
><CODE
CLASS="envar"
>$FORTRANMODDIR</CODE
></A
>, <A
HREF="#cv-FORTRANMODDIRPREFIX"
><CODE
CLASS="envar"
>$FORTRANMODDIRPREFIX</CODE
></A
>, <A
HREF="#cv-FORTRANMODDIRSUFFIX"
><CODE
CLASS="envar"
>$FORTRANMODDIRSUFFIX</CODE
></A
>, <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
>, <A
HREF="#cv-OBJSUFFIX"
><CODE
CLASS="envar"
>$OBJSUFFIX</CODE
></A
>, <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>, <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
>, <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
>, <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</CODE
></A
>, <A
HREF="#cv-_CPPDEFFLAGS"
><CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
></A
>, <A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
>, <A
HREF="#cv-_FORTRANMODFLAG"
><CODE
CLASS="envar"
>$_FORTRANMODFLAG</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-CVS"
></A
><TT
CLASS="literal"
>CVS</TT
></DT
><DD
><P
>&#13;Sets construction variables for the CVS source code
management system.
</P
><P
>&#13;Sets: <A
HREF="#cv-CVS"
><CODE
CLASS="envar"
>$CVS</CODE
></A
>, <A
HREF="#cv-CVSCOFLAGS"
><CODE
CLASS="envar"
>$CVSCOFLAGS</CODE
></A
>, <A
HREF="#cv-CVSCOM"
><CODE
CLASS="envar"
>$CVSCOM</CODE
></A
>, <A
HREF="#cv-CVSFLAGS"
><CODE
CLASS="envar"
>$CVSFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CVSCOMSTR"
><CODE
CLASS="envar"
>$CVSCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-cXX"
></A
><TT
CLASS="literal"
>cXX</TT
></DT
><DD
><P
>&#13;Sets construction variables for generic POSIX C++ compilers.
</P
><P
>&#13;Sets: <A
HREF="#cv-CPPDEFPREFIX"
><CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFSUFFIX"
><CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
></A
>, <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXCOM"
><CODE
CLASS="envar"
>$CXXCOM</CODE
></A
>, <A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
>, <A
HREF="#cv-CXXFLAGS"
><CODE
CLASS="envar"
>$CXXFLAGS</CODE
></A
>, <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
>, <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>, <A
HREF="#cv-OBJSUFFIX"
><CODE
CLASS="envar"
>$OBJSUFFIX</CODE
></A
>, <A
HREF="#cv-SHCXX"
><CODE
CLASS="envar"
>$SHCXX</CODE
></A
>, <A
HREF="#cv-SHCXXCOM"
><CODE
CLASS="envar"
>$SHCXXCOM</CODE
></A
>, <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CXXCOMSTR"
><CODE
CLASS="envar"
>$CXXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-default"
></A
><TT
CLASS="literal"
>default</TT
></DT
><DD
><P
>&#13;Sets variables by calling a default list of Tool modules
for the platform on which SCons is running.
</P
></DD
><DT
><A
NAME="t-dmd"
></A
><TT
CLASS="literal"
>dmd</TT
></DT
><DD
><P
>&#13;Sets construction variables for D language compilers
(the Digital Mars D compiler, or GDC).
</P
></DD
><DT
><A
NAME="t-dvi"
></A
><TT
CLASS="literal"
>dvi</TT
></DT
><DD
><P
>&#13;Attaches the <CODE
CLASS="function"
>DVI</CODE
> builder to the
construction environment.
</P
></DD
><DT
><A
NAME="t-dvipdf"
></A
><TT
CLASS="literal"
>dvipdf</TT
></DT
><DD
><P
>&#13;Sets construction variables for the dvipdf utility.
</P
><P
>&#13;Sets: <A
HREF="#cv-DVIPDF"
><CODE
CLASS="envar"
>$DVIPDF</CODE
></A
>, <A
HREF="#cv-DVIPDFCOM"
><CODE
CLASS="envar"
>$DVIPDFCOM</CODE
></A
>, <A
HREF="#cv-DVIPDFFLAGS"
><CODE
CLASS="envar"
>$DVIPDFFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-DVIPDFCOMSTR"
><CODE
CLASS="envar"
>$DVIPDFCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-dvips"
></A
><TT
CLASS="literal"
>dvips</TT
></DT
><DD
><P
>&#13;Sets construction variables for the dvips utility.
</P
><P
>&#13;Sets: <A
HREF="#cv-DVIPS"
><CODE
CLASS="envar"
>$DVIPS</CODE
></A
>, <A
HREF="#cv-DVIPSFLAGS"
><CODE
CLASS="envar"
>$DVIPSFLAGS</CODE
></A
>, <A
HREF="#cv-PSCOM"
><CODE
CLASS="envar"
>$PSCOM</CODE
></A
>, <A
HREF="#cv-PSPREFIX"
><CODE
CLASS="envar"
>$PSPREFIX</CODE
></A
>, <A
HREF="#cv-PSSUFFIX"
><CODE
CLASS="envar"
>$PSSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-PSCOMSTR"
><CODE
CLASS="envar"
>$PSCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-f77"
></A
><TT
CLASS="literal"
>f77</TT
></DT
><DD
><P
>&#13;Set construction variables for generic POSIX Fortran 77 compilers.
</P
><P
>&#13;Sets: <A
HREF="#cv-F77"
><CODE
CLASS="envar"
>$F77</CODE
></A
>, <A
HREF="#cv-F77COM"
><CODE
CLASS="envar"
>$F77COM</CODE
></A
>, <A
HREF="#cv-F77FILESUFFIXES"
><CODE
CLASS="envar"
>$F77FILESUFFIXES</CODE
></A
>, <A
HREF="#cv-F77FLAGS"
><CODE
CLASS="envar"
>$F77FLAGS</CODE
></A
>, <A
HREF="#cv-F77PPCOM"
><CODE
CLASS="envar"
>$F77PPCOM</CODE
></A
>, <A
HREF="#cv-F77PPFILESUFFIXES"
><CODE
CLASS="envar"
>$F77PPFILESUFFIXES</CODE
></A
>, <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
>, <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>, <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
>, <A
HREF="#cv-SHF77"
><CODE
CLASS="envar"
>$SHF77</CODE
></A
>, <A
HREF="#cv-SHF77COM"
><CODE
CLASS="envar"
>$SHF77COM</CODE
></A
>, <A
HREF="#cv-SHF77FLAGS"
><CODE
CLASS="envar"
>$SHF77FLAGS</CODE
></A
>, <A
HREF="#cv-SHF77PPCOM"
><CODE
CLASS="envar"
>$SHF77PPCOM</CODE
></A
>, <A
HREF="#cv-SHFORTRAN"
><CODE
CLASS="envar"
>$SHFORTRAN</CODE
></A
>, <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>, <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</CODE
></A
>, <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>, <A
HREF="#cv-_F77INCFLAGS"
><CODE
CLASS="envar"
>$_F77INCFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-F77COMSTR"
><CODE
CLASS="envar"
>$F77COMSTR</CODE
></A
>, <A
HREF="#cv-F77PPCOMSTR"
><CODE
CLASS="envar"
>$F77PPCOMSTR</CODE
></A
>, <A
HREF="#cv-FORTRANCOMSTR"
><CODE
CLASS="envar"
>$FORTRANCOMSTR</CODE
></A
>, <A
HREF="#cv-FORTRANPPCOMSTR"
><CODE
CLASS="envar"
>$FORTRANPPCOMSTR</CODE
></A
>, <A
HREF="#cv-SHF77COMSTR"
><CODE
CLASS="envar"
>$SHF77COMSTR</CODE
></A
>, <A
HREF="#cv-SHF77PPCOMSTR"
><CODE
CLASS="envar"
>$SHF77PPCOMSTR</CODE
></A
>, <A
HREF="#cv-SHFORTRANCOMSTR"
><CODE
CLASS="envar"
>$SHFORTRANCOMSTR</CODE
></A
>, <A
HREF="#cv-SHFORTRANPPCOMSTR"
><CODE
CLASS="envar"
>$SHFORTRANPPCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-f90"
></A
><TT
CLASS="literal"
>f90</TT
></DT
><DD
><P
>&#13;Set construction variables for generic POSIX Fortran 90 compilers.
</P
><P
>&#13;Sets: <A
HREF="#cv-F90"
><CODE
CLASS="envar"
>$F90</CODE
></A
>, <A
HREF="#cv-F90COM"
><CODE
CLASS="envar"
>$F90COM</CODE
></A
>, <A
HREF="#cv-F90FLAGS"
><CODE
CLASS="envar"
>$F90FLAGS</CODE
></A
>, <A
HREF="#cv-F90PPCOM"
><CODE
CLASS="envar"
>$F90PPCOM</CODE
></A
>, <A
HREF="#cv-SHF90"
><CODE
CLASS="envar"
>$SHF90</CODE
></A
>, <A
HREF="#cv-SHF90COM"
><CODE
CLASS="envar"
>$SHF90COM</CODE
></A
>, <A
HREF="#cv-SHF90FLAGS"
><CODE
CLASS="envar"
>$SHF90FLAGS</CODE
></A
>, <A
HREF="#cv-SHF90PPCOM"
><CODE
CLASS="envar"
>$SHF90PPCOM</CODE
></A
>, <A
HREF="#cv-_F90INCFLAGS"
><CODE
CLASS="envar"
>$_F90INCFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-F90COMSTR"
><CODE
CLASS="envar"
>$F90COMSTR</CODE
></A
>, <A
HREF="#cv-F90PPCOMSTR"
><CODE
CLASS="envar"
>$F90PPCOMSTR</CODE
></A
>, <A
HREF="#cv-SHF90COMSTR"
><CODE
CLASS="envar"
>$SHF90COMSTR</CODE
></A
>, <A
HREF="#cv-SHF90PPCOMSTR"
><CODE
CLASS="envar"
>$SHF90PPCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-f95"
></A
><TT
CLASS="literal"
>f95</TT
></DT
><DD
><P
>&#13;Set construction variables for generic POSIX Fortran 95 compilers.
</P
><P
>&#13;Sets: <A
HREF="#cv-F95"
><CODE
CLASS="envar"
>$F95</CODE
></A
>, <A
HREF="#cv-F95COM"
><CODE
CLASS="envar"
>$F95COM</CODE
></A
>, <A
HREF="#cv-F95FLAGS"
><CODE
CLASS="envar"
>$F95FLAGS</CODE
></A
>, <A
HREF="#cv-F95PPCOM"
><CODE
CLASS="envar"
>$F95PPCOM</CODE
></A
>, <A
HREF="#cv-SHF95"
><CODE
CLASS="envar"
>$SHF95</CODE
></A
>, <A
HREF="#cv-SHF95COM"
><CODE
CLASS="envar"
>$SHF95COM</CODE
></A
>, <A
HREF="#cv-SHF95FLAGS"
><CODE
CLASS="envar"
>$SHF95FLAGS</CODE
></A
>, <A
HREF="#cv-SHF95PPCOM"
><CODE
CLASS="envar"
>$SHF95PPCOM</CODE
></A
>, <A
HREF="#cv-_F95INCFLAGS"
><CODE
CLASS="envar"
>$_F95INCFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-F95COMSTR"
><CODE
CLASS="envar"
>$F95COMSTR</CODE
></A
>, <A
HREF="#cv-F95PPCOMSTR"
><CODE
CLASS="envar"
>$F95PPCOMSTR</CODE
></A
>, <A
HREF="#cv-SHF95COMSTR"
><CODE
CLASS="envar"
>$SHF95COMSTR</CODE
></A
>, <A
HREF="#cv-SHF95PPCOMSTR"
><CODE
CLASS="envar"
>$SHF95PPCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-fortran"
></A
><TT
CLASS="literal"
>fortran</TT
></DT
><DD
><P
>&#13;Set construction variables for generic POSIX Fortran compilers.
</P
><P
>&#13;Sets: <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
>, <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>, <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
>, <A
HREF="#cv-SHFORTRAN"
><CODE
CLASS="envar"
>$SHFORTRAN</CODE
></A
>, <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>, <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</CODE
></A
>, <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-FORTRANCOMSTR"
><CODE
CLASS="envar"
>$FORTRANCOMSTR</CODE
></A
>, <A
HREF="#cv-FORTRANPPCOMSTR"
><CODE
CLASS="envar"
>$FORTRANPPCOMSTR</CODE
></A
>, <A
HREF="#cv-SHFORTRANCOMSTR"
><CODE
CLASS="envar"
>$SHFORTRANCOMSTR</CODE
></A
>, <A
HREF="#cv-SHFORTRANPPCOMSTR"
><CODE
CLASS="envar"
>$SHFORTRANPPCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-gXX"
></A
><TT
CLASS="literal"
>g++</TT
></DT
><DD
><P
>&#13;Set construction variables for the <SPAN
CLASS="application"
>gXX</SPAN
> C++ compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXVERSION"
><CODE
CLASS="envar"
>$CXXVERSION</CODE
></A
>, <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-g77"
></A
><TT
CLASS="literal"
>g77</TT
></DT
><DD
><P
>&#13;Set construction variables for the <SPAN
CLASS="application"
>g77</SPAN
> Fortran compiler.
Calls the <TT
CLASS="literal"
>f77</TT
> Tool module
to set variables.
</P
></DD
><DT
><A
NAME="t-gas"
></A
><TT
CLASS="literal"
>gas</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>gas</SPAN
> assembler.
Calls the <TT
CLASS="literal"
>as</TT
> module.
</P
><P
>&#13;Sets: <A
HREF="#cv-AS"
><CODE
CLASS="envar"
>$AS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-gcc"
></A
><TT
CLASS="literal"
>gcc</TT
></DT
><DD
><P
>&#13;Set construction variables for the <SPAN
CLASS="application"
>gcc</SPAN
> C compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CCVERSION"
><CODE
CLASS="envar"
>$CCVERSION</CODE
></A
>, <A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-gnulink"
></A
><TT
CLASS="literal"
>gnulink</TT
></DT
><DD
><P
>&#13;Set construction variables for GNU linker/loader.
</P
><P
>&#13;Sets: <A
HREF="#cv-RPATHPREFIX"
><CODE
CLASS="envar"
>$RPATHPREFIX</CODE
></A
>, <A
HREF="#cv-RPATHSUFFIX"
><CODE
CLASS="envar"
>$RPATHSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-gs"
></A
><TT
CLASS="literal"
>gs</TT
></DT
><DD
><P
>&#13;Set construction variables for Ghostscript.
</P
><P
>&#13;Sets: <A
HREF="#cv-GS"
><CODE
CLASS="envar"
>$GS</CODE
></A
>, <A
HREF="#cv-GSCOM"
><CODE
CLASS="envar"
>$GSCOM</CODE
></A
>, <A
HREF="#cv-GSFLAGS"
><CODE
CLASS="envar"
>$GSFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-GSCOMSTR"
><CODE
CLASS="envar"
>$GSCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-hpcXX"
></A
><TT
CLASS="literal"
>hpc++</TT
></DT
><DD
><P
>&#13;Set construction variables for the compilers aCC on HP/UX systems.
</P
></DD
><DT
><A
NAME="t-hpcc"
></A
><TT
CLASS="literal"
>hpcc</TT
></DT
><DD
><P
>&#13;Set construction variables for the
<SPAN
CLASS="application"
>aCC</SPAN
> on HP/UX systems.
Calls the <TT
CLASS="literal"
>cXX</TT
> tool for additional variables.
</P
><P
>&#13;Sets: <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXVERSION"
><CODE
CLASS="envar"
>$CXXVERSION</CODE
></A
>, <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-hplink"
></A
><TT
CLASS="literal"
>hplink</TT
></DT
><DD
><P
>&#13;Sets construction variables for the linker on HP/UX systems.
</P
><P
>&#13;Sets: <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
>, <A
HREF="#cv-SHLIBSUFFIX"
><CODE
CLASS="envar"
>$SHLIBSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-icc"
></A
><TT
CLASS="literal"
>icc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the
<SPAN
CLASS="application"
>icc</SPAN
> compiler on OS/2 systems.
</P
><P
>&#13;Sets: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
>, <A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFPREFIX"
><CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFSUFFIX"
><CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
></A
>, <A
HREF="#cv-CXXCOM"
><CODE
CLASS="envar"
>$CXXCOM</CODE
></A
>, <A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
>, <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
>, <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>, <A
HREF="#cv-CFLAGS"
><CODE
CLASS="envar"
>$CFLAGS</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-_CPPINCFLAGS"
><CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-icl"
></A
><TT
CLASS="literal"
>icl</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Intel C/C++ compiler.
Calls the <TT
CLASS="literal"
>intelc</TT
> Tool module to set its variables.
</P
></DD
><DT
><A
NAME="t-ifl"
></A
><TT
CLASS="literal"
>ifl</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Intel Fortran compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
>, <A
HREF="#cv-FORTRANCOM"
><CODE
CLASS="envar"
>$FORTRANCOM</CODE
></A
>, <A
HREF="#cv-FORTRANPPCOM"
><CODE
CLASS="envar"
>$FORTRANPPCOM</CODE
></A
>, <A
HREF="#cv-SHFORTRANCOM"
><CODE
CLASS="envar"
>$SHFORTRANCOM</CODE
></A
>, <A
HREF="#cv-SHFORTRANPPCOM"
><CODE
CLASS="envar"
>$SHFORTRANPPCOM</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CPPFLAGS"
><CODE
CLASS="envar"
>$CPPFLAGS</CODE
></A
>, <A
HREF="#cv-FORTRANFLAGS"
><CODE
CLASS="envar"
>$FORTRANFLAGS</CODE
></A
>, <A
HREF="#cv-_CPPDEFFLAGS"
><CODE
CLASS="envar"
>$_CPPDEFFLAGS</CODE
></A
>, <A
HREF="#cv-_FORTRANINCFLAGS"
><CODE
CLASS="envar"
>$_FORTRANINCFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-ifort"
></A
><TT
CLASS="literal"
>ifort</TT
></DT
><DD
><P
>&#13;Sets construction variables for newer versions
of the Intel Fortran compiler for Linux.
</P
><P
>&#13;Sets: <A
HREF="#cv-F77"
><CODE
CLASS="envar"
>$F77</CODE
></A
>, <A
HREF="#cv-F90"
><CODE
CLASS="envar"
>$F90</CODE
></A
>, <A
HREF="#cv-F95"
><CODE
CLASS="envar"
>$F95</CODE
></A
>, <A
HREF="#cv-FORTRAN"
><CODE
CLASS="envar"
>$FORTRAN</CODE
></A
>, <A
HREF="#cv-SHF77"
><CODE
CLASS="envar"
>$SHF77</CODE
></A
>, <A
HREF="#cv-SHF77FLAGS"
><CODE
CLASS="envar"
>$SHF77FLAGS</CODE
></A
>, <A
HREF="#cv-SHF90"
><CODE
CLASS="envar"
>$SHF90</CODE
></A
>, <A
HREF="#cv-SHF90FLAGS"
><CODE
CLASS="envar"
>$SHF90FLAGS</CODE
></A
>, <A
HREF="#cv-SHF95"
><CODE
CLASS="envar"
>$SHF95</CODE
></A
>, <A
HREF="#cv-SHF95FLAGS"
><CODE
CLASS="envar"
>$SHF95FLAGS</CODE
></A
>, <A
HREF="#cv-SHFORTRAN"
><CODE
CLASS="envar"
>$SHFORTRAN</CODE
></A
>, <A
HREF="#cv-SHFORTRANFLAGS"
><CODE
CLASS="envar"
>$SHFORTRANFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-ilink"
></A
><TT
CLASS="literal"
>ilink</TT
></DT
><DD
><P
>&#13;Sets construction variables for the
<SPAN
CLASS="application"
>ilink</SPAN
> linker on OS/2 systems.
</P
><P
>&#13;Sets: <A
HREF="#cv-LIBDIRPREFIX"
><CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRSUFFIX"
><CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKPREFIX"
><CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKSUFFIX"
><CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
></A
>, <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>, <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
>, <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-ilink32"
></A
><TT
CLASS="literal"
>ilink32</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Borland
<SPAN
CLASS="application"
>ilink32</SPAN
> linker.
</P
><P
>&#13;Sets: <A
HREF="#cv-LIBDIRPREFIX"
><CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRSUFFIX"
><CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKPREFIX"
><CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKSUFFIX"
><CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
></A
>, <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>, <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
>, <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-install"
></A
><TT
CLASS="literal"
>install</TT
></DT
><DD
><P
>&#13;Sets construction variables for file
and directory installation.
</P
><P
>&#13;Sets: <A
HREF="#cv-INSTALL"
><CODE
CLASS="envar"
>$INSTALL</CODE
></A
>, <A
HREF="#cv-INSTALLSTR"
><CODE
CLASS="envar"
>$INSTALLSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-intelc"
></A
><TT
CLASS="literal"
>intelc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Intel C/C++ compiler
(Linux and Windows, version 7 and later).
Calls the <TT
CLASS="literal"
>gcc</TT
> or <TT
CLASS="literal"
>msvc</TT
>
(on Linux and Windows, respectively)
to set underlying variables.
</P
><P
>&#13;Sets: <A
HREF="#cv-AR"
><CODE
CLASS="envar"
>$AR</CODE
></A
>, <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-INTEL_C_COMPILER_VERSION"
><CODE
CLASS="envar"
>$INTEL_C_COMPILER_VERSION</CODE
></A
>, <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-jar"
></A
><TT
CLASS="literal"
>jar</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>jar</SPAN
> utility.
</P
><P
>&#13;Sets: <A
HREF="#cv-JAR"
><CODE
CLASS="envar"
>$JAR</CODE
></A
>, <A
HREF="#cv-JARCOM"
><CODE
CLASS="envar"
>$JARCOM</CODE
></A
>, <A
HREF="#cv-JARFLAGS"
><CODE
CLASS="envar"
>$JARFLAGS</CODE
></A
>, <A
HREF="#cv-JARSUFFIX"
><CODE
CLASS="envar"
>$JARSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-JARCOMSTR"
><CODE
CLASS="envar"
>$JARCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-javac"
></A
><TT
CLASS="literal"
>javac</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>javac</SPAN
> compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-JAVABOOTCLASSPATH"
><CODE
CLASS="envar"
>$JAVABOOTCLASSPATH</CODE
></A
>, <A
HREF="#cv-JAVAC"
><CODE
CLASS="envar"
>$JAVAC</CODE
></A
>, <A
HREF="#cv-JAVACCOM"
><CODE
CLASS="envar"
>$JAVACCOM</CODE
></A
>, <A
HREF="#cv-JAVACFLAGS"
><CODE
CLASS="envar"
>$JAVACFLAGS</CODE
></A
>, <A
HREF="#cv-JAVACLASSPATH"
><CODE
CLASS="envar"
>$JAVACLASSPATH</CODE
></A
>, <A
HREF="#cv-JAVACLASSSUFFIX"
><CODE
CLASS="envar"
>$JAVACLASSSUFFIX</CODE
></A
>, <A
HREF="#cv-JAVASOURCEPATH"
><CODE
CLASS="envar"
>$JAVASOURCEPATH</CODE
></A
>, <A
HREF="#cv-JAVASUFFIX"
><CODE
CLASS="envar"
>$JAVASUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-JAVACCOMSTR"
><CODE
CLASS="envar"
>$JAVACCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-javah"
></A
><TT
CLASS="literal"
>javah</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>javah</SPAN
> tool.
</P
><P
>&#13;Sets: <A
HREF="#cv-JAVACLASSSUFFIX"
><CODE
CLASS="envar"
>$JAVACLASSSUFFIX</CODE
></A
>, <A
HREF="#cv-JAVAH"
><CODE
CLASS="envar"
>$JAVAH</CODE
></A
>, <A
HREF="#cv-JAVAHCOM"
><CODE
CLASS="envar"
>$JAVAHCOM</CODE
></A
>, <A
HREF="#cv-JAVAHFLAGS"
><CODE
CLASS="envar"
>$JAVAHFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-JAVACLASSPATH"
><CODE
CLASS="envar"
>$JAVACLASSPATH</CODE
></A
>, <A
HREF="#cv-JAVAHCOMSTR"
><CODE
CLASS="envar"
>$JAVAHCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-latex"
></A
><TT
CLASS="literal"
>latex</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>latex</SPAN
> utility.
</P
><P
>&#13;Sets: <A
HREF="#cv-LATEX"
><CODE
CLASS="envar"
>$LATEX</CODE
></A
>, <A
HREF="#cv-LATEXCOM"
><CODE
CLASS="envar"
>$LATEXCOM</CODE
></A
>, <A
HREF="#cv-LATEXFLAGS"
><CODE
CLASS="envar"
>$LATEXFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-LATEXCOMSTR"
><CODE
CLASS="envar"
>$LATEXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-lex"
></A
><TT
CLASS="literal"
>lex</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>lex</SPAN
> lexical analyser.
</P
><P
>&#13;Sets: <A
HREF="#cv-LEX"
><CODE
CLASS="envar"
>$LEX</CODE
></A
>, <A
HREF="#cv-LEXCOM"
><CODE
CLASS="envar"
>$LEXCOM</CODE
></A
>, <A
HREF="#cv-LEXFLAGS"
><CODE
CLASS="envar"
>$LEXFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-LEXCOMSTR"
><CODE
CLASS="envar"
>$LEXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-link"
></A
><TT
CLASS="literal"
>link</TT
></DT
><DD
><P
>&#13;Sets construction variables for generic POSIX linkers.
</P
><P
>&#13;Sets: <A
HREF="#cv-LDMODULE"
><CODE
CLASS="envar"
>$LDMODULE</CODE
></A
>, <A
HREF="#cv-LDMODULECOM"
><CODE
CLASS="envar"
>$LDMODULECOM</CODE
></A
>, <A
HREF="#cv-LDMODULEFLAGS"
><CODE
CLASS="envar"
>$LDMODULEFLAGS</CODE
></A
>, <A
HREF="#cv-LDMODULEPREFIX"
><CODE
CLASS="envar"
>$LDMODULEPREFIX</CODE
></A
>, <A
HREF="#cv-LDMODULESUFFIX"
><CODE
CLASS="envar"
>$LDMODULESUFFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRPREFIX"
><CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRSUFFIX"
><CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKPREFIX"
><CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKSUFFIX"
><CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
></A
>, <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>, <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
>, <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
>, <A
HREF="#cv-SHLIBSUFFIX"
><CODE
CLASS="envar"
>$SHLIBSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>, <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-LDMODULECOMSTR"
><CODE
CLASS="envar"
>$LDMODULECOMSTR</CODE
></A
>, <A
HREF="#cv-LINKCOMSTR"
><CODE
CLASS="envar"
>$LINKCOMSTR</CODE
></A
>, <A
HREF="#cv-SHLINKCOMSTR"
><CODE
CLASS="envar"
>$SHLINKCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-linkloc"
></A
><TT
CLASS="literal"
>linkloc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the
<SPAN
CLASS="application"
>LinkLoc</SPAN
>
linker for the Phar Lap ETS embedded operating system.
</P
><P
>&#13;Sets: <A
HREF="#cv-LIBDIRPREFIX"
><CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRSUFFIX"
><CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKPREFIX"
><CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKSUFFIX"
><CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
></A
>, <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>, <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
>, <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
>, <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>, <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-LINKCOMSTR"
><CODE
CLASS="envar"
>$LINKCOMSTR</CODE
></A
>, <A
HREF="#cv-SHLINKCOMSTR"
><CODE
CLASS="envar"
>$SHLINKCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-m4"
></A
><TT
CLASS="literal"
>m4</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>m4</SPAN
> macro processor.
</P
><P
>&#13;Sets: <A
HREF="#cv-M4"
><CODE
CLASS="envar"
>$M4</CODE
></A
>, <A
HREF="#cv-M4COM"
><CODE
CLASS="envar"
>$M4COM</CODE
></A
>, <A
HREF="#cv-M4FLAGS"
><CODE
CLASS="envar"
>$M4FLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-M4COMSTR"
><CODE
CLASS="envar"
>$M4COMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-masm"
></A
><TT
CLASS="literal"
>masm</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Microsoft assembler.
</P
><P
>&#13;Sets: <A
HREF="#cv-AS"
><CODE
CLASS="envar"
>$AS</CODE
></A
>, <A
HREF="#cv-ASCOM"
><CODE
CLASS="envar"
>$ASCOM</CODE
></A
>, <A
HREF="#cv-ASFLAGS"
><CODE
CLASS="envar"
>$ASFLAGS</CODE
></A
>, <A
HREF="#cv-ASPPCOM"
><CODE
CLASS="envar"
>$ASPPCOM</CODE
></A
>, <A
HREF="#cv-ASPPFLAGS"
><CODE
CLASS="envar"
>$ASPPFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-ASCOMSTR"
><CODE
CLASS="envar"
>$ASCOMSTR</CODE
></A
>, <A
HREF="#cv-ASPPCOMSTR"
><CODE
CLASS="envar"
>$ASPPCOMSTR</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-_CPPINCFLAGS"
><CODE
CLASS="envar"
>$_CPPINCFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-midl"
></A
><TT
CLASS="literal"
>midl</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Microsoft IDL compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-MIDL"
><CODE
CLASS="envar"
>$MIDL</CODE
></A
>, <A
HREF="#cv-MIDLCOM"
><CODE
CLASS="envar"
>$MIDLCOM</CODE
></A
>, <A
HREF="#cv-MIDLFLAGS"
><CODE
CLASS="envar"
>$MIDLFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-MIDLCOMSTR"
><CODE
CLASS="envar"
>$MIDLCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-mingw"
></A
><TT
CLASS="literal"
>mingw</TT
></DT
><DD
><P
>&#13;Sets construction variables for MinGW (Minimal Gnu on Windows).
</P
><P
>&#13;Sets: <A
HREF="#cv-AS"
><CODE
CLASS="envar"
>$AS</CODE
></A
>, <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-LDMODULECOM"
><CODE
CLASS="envar"
>$LDMODULECOM</CODE
></A
>, <A
HREF="#cv-LIBPREFIX"
><CODE
CLASS="envar"
>$LIBPREFIX</CODE
></A
>, <A
HREF="#cv-LIBSUFFIX"
><CODE
CLASS="envar"
>$LIBSUFFIX</CODE
></A
>, <A
HREF="#cv-OBJSUFFIX"
><CODE
CLASS="envar"
>$OBJSUFFIX</CODE
></A
>, <A
HREF="#cv-RC"
><CODE
CLASS="envar"
>$RC</CODE
></A
>, <A
HREF="#cv-RCCOM"
><CODE
CLASS="envar"
>$RCCOM</CODE
></A
>, <A
HREF="#cv-RCFLAGS"
><CODE
CLASS="envar"
>$RCFLAGS</CODE
></A
>, <A
HREF="#cv-RCINCFLAGS"
><CODE
CLASS="envar"
>$RCINCFLAGS</CODE
></A
>, <A
HREF="#cv-RCINCPREFIX"
><CODE
CLASS="envar"
>$RCINCPREFIX</CODE
></A
>, <A
HREF="#cv-RCINCSUFFIX"
><CODE
CLASS="envar"
>$RCINCSUFFIX</CODE
></A
>, <A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</CODE
></A
>, <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSDEFPREFIX"
><CODE
CLASS="envar"
>$WINDOWSDEFPREFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSDEFSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSDEFSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-RCCOMSTR"
><CODE
CLASS="envar"
>$RCCOMSTR</CODE
></A
>, <A
HREF="#cv-SHLINKCOMSTR"
><CODE
CLASS="envar"
>$SHLINKCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-mslib"
></A
><TT
CLASS="literal"
>mslib</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Microsoft
<SPAN
CLASS="application"
>mslib</SPAN
>
library archiver.
</P
><P
>&#13;Sets: <A
HREF="#cv-AR"
><CODE
CLASS="envar"
>$AR</CODE
></A
>, <A
HREF="#cv-ARCOM"
><CODE
CLASS="envar"
>$ARCOM</CODE
></A
>, <A
HREF="#cv-ARFLAGS"
><CODE
CLASS="envar"
>$ARFLAGS</CODE
></A
>, <A
HREF="#cv-LIBPREFIX"
><CODE
CLASS="envar"
>$LIBPREFIX</CODE
></A
>, <A
HREF="#cv-LIBSUFFIX"
><CODE
CLASS="envar"
>$LIBSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-ARCOMSTR"
><CODE
CLASS="envar"
>$ARCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-mslink"
></A
><TT
CLASS="literal"
>mslink</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Microsoft linker.
</P
><P
>&#13;Sets: <A
HREF="#cv-LDMODULE"
><CODE
CLASS="envar"
>$LDMODULE</CODE
></A
>, <A
HREF="#cv-LDMODULECOM"
><CODE
CLASS="envar"
>$LDMODULECOM</CODE
></A
>, <A
HREF="#cv-LDMODULEFLAGS"
><CODE
CLASS="envar"
>$LDMODULEFLAGS</CODE
></A
>, <A
HREF="#cv-LDMODULEPREFIX"
><CODE
CLASS="envar"
>$LDMODULEPREFIX</CODE
></A
>, <A
HREF="#cv-LDMODULESUFFIX"
><CODE
CLASS="envar"
>$LDMODULESUFFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRPREFIX"
><CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRSUFFIX"
><CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKPREFIX"
><CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKSUFFIX"
><CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
></A
>, <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>, <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
>, <A
HREF="#cv-LINKFLAGS"
><CODE
CLASS="envar"
>$LINKFLAGS</CODE
></A
>, <A
HREF="#cv-REGSVR"
><CODE
CLASS="envar"
>$REGSVR</CODE
></A
>, <A
HREF="#cv-REGSVRCOM"
><CODE
CLASS="envar"
>$REGSVRCOM</CODE
></A
>, <A
HREF="#cv-REGSVRFLAGS"
><CODE
CLASS="envar"
>$REGSVRFLAGS</CODE
></A
>, <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>, <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>, <A
HREF="#cv-WIN32DEFPREFIX"
><CODE
CLASS="envar"
>$WIN32DEFPREFIX</CODE
></A
>, <A
HREF="#cv-WIN32DEFSUFFIX"
><CODE
CLASS="envar"
>$WIN32DEFSUFFIX</CODE
></A
>, <A
HREF="#cv-WIN32EXPPREFIX"
><CODE
CLASS="envar"
>$WIN32EXPPREFIX</CODE
></A
>, <A
HREF="#cv-WIN32EXPSUFFIX"
><CODE
CLASS="envar"
>$WIN32EXPSUFFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSDEFPREFIX"
><CODE
CLASS="envar"
>$WINDOWSDEFPREFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSDEFSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSDEFSUFFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSEXPPREFIX"
><CODE
CLASS="envar"
>$WINDOWSEXPPREFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSEXPSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSEXPSUFFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSPROGMANIFESTPREFIX"
><CODE
CLASS="envar"
>$WINDOWSPROGMANIFESTPREFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSPROGMANIFESTSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSPROGMANIFESTSUFFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSSHLIBMANIFESTPREFIX"
><CODE
CLASS="envar"
>$WINDOWSSHLIBMANIFESTPREFIX</CODE
></A
>, <A
HREF="#cv-WINDOWSSHLIBMANIFESTSUFFIX"
><CODE
CLASS="envar"
>$WINDOWSSHLIBMANIFESTSUFFIX</CODE
></A
>, <A
HREF="#cv-WINDOWS_INSERT_DEF"
><CODE
CLASS="envar"
>$WINDOWS_INSERT_DEF</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-LDMODULECOMSTR"
><CODE
CLASS="envar"
>$LDMODULECOMSTR</CODE
></A
>, <A
HREF="#cv-LINKCOMSTR"
><CODE
CLASS="envar"
>$LINKCOMSTR</CODE
></A
>, <A
HREF="#cv-MSVS_IGNORE_IDE_PATHS"
><CODE
CLASS="envar"
>$MSVS_IGNORE_IDE_PATHS</CODE
></A
>, <A
HREF="#cv-REGSVRCOMSTR"
><CODE
CLASS="envar"
>$REGSVRCOMSTR</CODE
></A
>, <A
HREF="#cv-SHLINKCOMSTR"
><CODE
CLASS="envar"
>$SHLINKCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-msvc"
></A
><TT
CLASS="literal"
>msvc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Microsoft Visual C/C++ compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-BUILDERS"
><CODE
CLASS="envar"
>$BUILDERS</CODE
></A
>, <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
>, <A
HREF="#cv-CCFLAGS"
><CODE
CLASS="envar"
>$CCFLAGS</CODE
></A
>, <A
HREF="#cv-CCPCHFLAGS"
><CODE
CLASS="envar"
>$CCPCHFLAGS</CODE
></A
>, <A
HREF="#cv-CCPDBFLAGS"
><CODE
CLASS="envar"
>$CCPDBFLAGS</CODE
></A
>, <A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
>, <A
HREF="#cv-CFLAGS"
><CODE
CLASS="envar"
>$CFLAGS</CODE
></A
>, <A
HREF="#cv-CPPDEFPREFIX"
><CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFSUFFIX"
><CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
></A
>, <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXCOM"
><CODE
CLASS="envar"
>$CXXCOM</CODE
></A
>, <A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
>, <A
HREF="#cv-CXXFLAGS"
><CODE
CLASS="envar"
>$CXXFLAGS</CODE
></A
>, <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
>, <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>, <A
HREF="#cv-OBJPREFIX"
><CODE
CLASS="envar"
>$OBJPREFIX</CODE
></A
>, <A
HREF="#cv-OBJSUFFIX"
><CODE
CLASS="envar"
>$OBJSUFFIX</CODE
></A
>, <A
HREF="#cv-PCHCOM"
><CODE
CLASS="envar"
>$PCHCOM</CODE
></A
>, <A
HREF="#cv-PCHPDBFLAGS"
><CODE
CLASS="envar"
>$PCHPDBFLAGS</CODE
></A
>, <A
HREF="#cv-RC"
><CODE
CLASS="envar"
>$RC</CODE
></A
>, <A
HREF="#cv-RCCOM"
><CODE
CLASS="envar"
>$RCCOM</CODE
></A
>, <A
HREF="#cv-RCFLAGS"
><CODE
CLASS="envar"
>$RCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCC"
><CODE
CLASS="envar"
>$SHCC</CODE
></A
>, <A
HREF="#cv-SHCCCOM"
><CODE
CLASS="envar"
>$SHCCCOM</CODE
></A
>, <A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCFLAGS"
><CODE
CLASS="envar"
>$SHCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCXX"
><CODE
CLASS="envar"
>$SHCXX</CODE
></A
>, <A
HREF="#cv-SHCXXCOM"
><CODE
CLASS="envar"
>$SHCXXCOM</CODE
></A
>, <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJPREFIX"
><CODE
CLASS="envar"
>$SHOBJPREFIX</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CCCOMSTR"
><CODE
CLASS="envar"
>$CCCOMSTR</CODE
></A
>, <A
HREF="#cv-CXXCOMSTR"
><CODE
CLASS="envar"
>$CXXCOMSTR</CODE
></A
>, <A
HREF="#cv-SHCCCOMSTR"
><CODE
CLASS="envar"
>$SHCCCOMSTR</CODE
></A
>, <A
HREF="#cv-SHCXXCOMSTR"
><CODE
CLASS="envar"
>$SHCXXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-msvs"
></A
><TT
CLASS="literal"
>msvs</TT
></DT
><DD
><P
>&#13;Sets construction variables for Microsoft Visual Studio.
</P
><P
>&#13;Sets: <A
HREF="#cv-MSVSBUILDCOM"
><CODE
CLASS="envar"
>$MSVSBUILDCOM</CODE
></A
>, <A
HREF="#cv-MSVSCLEANCOM"
><CODE
CLASS="envar"
>$MSVSCLEANCOM</CODE
></A
>, <A
HREF="#cv-MSVSENCODING"
><CODE
CLASS="envar"
>$MSVSENCODING</CODE
></A
>, <A
HREF="#cv-MSVSPROJECTCOM"
><CODE
CLASS="envar"
>$MSVSPROJECTCOM</CODE
></A
>, <A
HREF="#cv-MSVSREBUILDCOM"
><CODE
CLASS="envar"
>$MSVSREBUILDCOM</CODE
></A
>, <A
HREF="#cv-MSVSSCONS"
><CODE
CLASS="envar"
>$MSVSSCONS</CODE
></A
>, <A
HREF="#cv-MSVSSCONSCOM"
><CODE
CLASS="envar"
>$MSVSSCONSCOM</CODE
></A
>, <A
HREF="#cv-MSVSSCONSCRIPT"
><CODE
CLASS="envar"
>$MSVSSCONSCRIPT</CODE
></A
>, <A
HREF="#cv-MSVSSCONSFLAGS"
><CODE
CLASS="envar"
>$MSVSSCONSFLAGS</CODE
></A
>, <A
HREF="#cv-MSVSSOLUTIONCOM"
><CODE
CLASS="envar"
>$MSVSSOLUTIONCOM</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-mwcc"
></A
><TT
CLASS="literal"
>mwcc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Metrowerks CodeWarrior compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CC"
><CODE
CLASS="envar"
>$CC</CODE
></A
>, <A
HREF="#cv-CCCOM"
><CODE
CLASS="envar"
>$CCCOM</CODE
></A
>, <A
HREF="#cv-CFILESUFFIX"
><CODE
CLASS="envar"
>$CFILESUFFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFPREFIX"
><CODE
CLASS="envar"
>$CPPDEFPREFIX</CODE
></A
>, <A
HREF="#cv-CPPDEFSUFFIX"
><CODE
CLASS="envar"
>$CPPDEFSUFFIX</CODE
></A
>, <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXCOM"
><CODE
CLASS="envar"
>$CXXCOM</CODE
></A
>, <A
HREF="#cv-CXXFILESUFFIX"
><CODE
CLASS="envar"
>$CXXFILESUFFIX</CODE
></A
>, <A
HREF="#cv-INCPREFIX"
><CODE
CLASS="envar"
>$INCPREFIX</CODE
></A
>, <A
HREF="#cv-INCSUFFIX"
><CODE
CLASS="envar"
>$INCSUFFIX</CODE
></A
>, <A
HREF="#cv-MWCW_VERSION"
><CODE
CLASS="envar"
>$MWCW_VERSION</CODE
></A
>, <A
HREF="#cv-MWCW_VERSIONS"
><CODE
CLASS="envar"
>$MWCW_VERSIONS</CODE
></A
>, <A
HREF="#cv-SHCC"
><CODE
CLASS="envar"
>$SHCC</CODE
></A
>, <A
HREF="#cv-SHCCCOM"
><CODE
CLASS="envar"
>$SHCCCOM</CODE
></A
>, <A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCFLAGS"
><CODE
CLASS="envar"
>$SHCFLAGS</CODE
></A
>, <A
HREF="#cv-SHCXX"
><CODE
CLASS="envar"
>$SHCXX</CODE
></A
>, <A
HREF="#cv-SHCXXCOM"
><CODE
CLASS="envar"
>$SHCXXCOM</CODE
></A
>, <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-CCCOMSTR"
><CODE
CLASS="envar"
>$CCCOMSTR</CODE
></A
>, <A
HREF="#cv-CXXCOMSTR"
><CODE
CLASS="envar"
>$CXXCOMSTR</CODE
></A
>, <A
HREF="#cv-SHCCCOMSTR"
><CODE
CLASS="envar"
>$SHCCCOMSTR</CODE
></A
>, <A
HREF="#cv-SHCXXCOMSTR"
><CODE
CLASS="envar"
>$SHCXXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-mwld"
></A
><TT
CLASS="literal"
>mwld</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Metrowerks CodeWarrior linker.
</P
><P
>&#13;Sets: <A
HREF="#cv-AR"
><CODE
CLASS="envar"
>$AR</CODE
></A
>, <A
HREF="#cv-ARCOM"
><CODE
CLASS="envar"
>$ARCOM</CODE
></A
>, <A
HREF="#cv-LIBDIRPREFIX"
><CODE
CLASS="envar"
>$LIBDIRPREFIX</CODE
></A
>, <A
HREF="#cv-LIBDIRSUFFIX"
><CODE
CLASS="envar"
>$LIBDIRSUFFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKPREFIX"
><CODE
CLASS="envar"
>$LIBLINKPREFIX</CODE
></A
>, <A
HREF="#cv-LIBLINKSUFFIX"
><CODE
CLASS="envar"
>$LIBLINKSUFFIX</CODE
></A
>, <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>, <A
HREF="#cv-LINKCOM"
><CODE
CLASS="envar"
>$LINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>, <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-nasm"
></A
><TT
CLASS="literal"
>nasm</TT
></DT
><DD
><P
>&#13;Sets construction variables for the
<SPAN
CLASS="application"
>nasm</SPAN
> Netwide Assembler.
</P
><P
>&#13;Sets: <A
HREF="#cv-AS"
><CODE
CLASS="envar"
>$AS</CODE
></A
>, <A
HREF="#cv-ASCOM"
><CODE
CLASS="envar"
>$ASCOM</CODE
></A
>, <A
HREF="#cv-ASFLAGS"
><CODE
CLASS="envar"
>$ASFLAGS</CODE
></A
>, <A
HREF="#cv-ASPPCOM"
><CODE
CLASS="envar"
>$ASPPCOM</CODE
></A
>, <A
HREF="#cv-ASPPFLAGS"
><CODE
CLASS="envar"
>$ASPPFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-ASCOMSTR"
><CODE
CLASS="envar"
>$ASCOMSTR</CODE
></A
>, <A
HREF="#cv-ASPPCOMSTR"
><CODE
CLASS="envar"
>$ASPPCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-packaging"
></A
><TT
CLASS="literal"
>packaging</TT
></DT
><DD
><P
>&#13;A framework for building binary and source packages.
</P
></DD
><DT
><A
NAME="t-Packaging"
></A
><TT
CLASS="literal"
>Packaging</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <CODE
CLASS="function"
>Package</CODE
> Builder.
</P
></DD
><DT
><A
NAME="t-pdf"
></A
><TT
CLASS="literal"
>pdf</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Portable Document Format builder.
</P
><P
>&#13;Sets: <A
HREF="#cv-PDFPREFIX"
><CODE
CLASS="envar"
>$PDFPREFIX</CODE
></A
>, <A
HREF="#cv-PDFSUFFIX"
><CODE
CLASS="envar"
>$PDFSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-pdflatex"
></A
><TT
CLASS="literal"
>pdflatex</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>pdflatex</SPAN
> utility.
</P
><P
>&#13;Sets: <A
HREF="#cv-LATEXRETRIES"
><CODE
CLASS="envar"
>$LATEXRETRIES</CODE
></A
>, <A
HREF="#cv-PDFLATEX"
><CODE
CLASS="envar"
>$PDFLATEX</CODE
></A
>, <A
HREF="#cv-PDFLATEXCOM"
><CODE
CLASS="envar"
>$PDFLATEXCOM</CODE
></A
>, <A
HREF="#cv-PDFLATEXFLAGS"
><CODE
CLASS="envar"
>$PDFLATEXFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-PDFLATEXCOMSTR"
><CODE
CLASS="envar"
>$PDFLATEXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-pdftex"
></A
><TT
CLASS="literal"
>pdftex</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>pdftex</SPAN
> utility.
</P
><P
>&#13;Sets: <A
HREF="#cv-LATEXRETRIES"
><CODE
CLASS="envar"
>$LATEXRETRIES</CODE
></A
>, <A
HREF="#cv-PDFLATEX"
><CODE
CLASS="envar"
>$PDFLATEX</CODE
></A
>, <A
HREF="#cv-PDFLATEXCOM"
><CODE
CLASS="envar"
>$PDFLATEXCOM</CODE
></A
>, <A
HREF="#cv-PDFLATEXFLAGS"
><CODE
CLASS="envar"
>$PDFLATEXFLAGS</CODE
></A
>, <A
HREF="#cv-PDFTEX"
><CODE
CLASS="envar"
>$PDFTEX</CODE
></A
>, <A
HREF="#cv-PDFTEXCOM"
><CODE
CLASS="envar"
>$PDFTEXCOM</CODE
></A
>, <A
HREF="#cv-PDFTEXFLAGS"
><CODE
CLASS="envar"
>$PDFTEXFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-PDFLATEXCOMSTR"
><CODE
CLASS="envar"
>$PDFLATEXCOMSTR</CODE
></A
>, <A
HREF="#cv-PDFTEXCOMSTR"
><CODE
CLASS="envar"
>$PDFTEXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-Perforce"
></A
><TT
CLASS="literal"
>Perforce</TT
></DT
><DD
><P
>&#13;Sets construction variables for interacting with the
Perforce source code management system.
</P
><P
>&#13;Sets: <A
HREF="#cv-P4"
><CODE
CLASS="envar"
>$P4</CODE
></A
>, <A
HREF="#cv-P4COM"
><CODE
CLASS="envar"
>$P4COM</CODE
></A
>, <A
HREF="#cv-P4FLAGS"
><CODE
CLASS="envar"
>$P4FLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-P4COMSTR"
><CODE
CLASS="envar"
>$P4COMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-qt"
></A
><TT
CLASS="literal"
>qt</TT
></DT
><DD
><P
>&#13;Sets construction variables for building Qt applications.
</P
><P
>&#13;Sets: <A
HREF="#cv-QTDIR"
><CODE
CLASS="envar"
>$QTDIR</CODE
></A
>, <A
HREF="#cv-QT_AUTOSCAN"
><CODE
CLASS="envar"
>$QT_AUTOSCAN</CODE
></A
>, <A
HREF="#cv-QT_BINPATH"
><CODE
CLASS="envar"
>$QT_BINPATH</CODE
></A
>, <A
HREF="#cv-QT_CPPPATH"
><CODE
CLASS="envar"
>$QT_CPPPATH</CODE
></A
>, <A
HREF="#cv-QT_LIB"
><CODE
CLASS="envar"
>$QT_LIB</CODE
></A
>, <A
HREF="#cv-QT_LIBPATH"
><CODE
CLASS="envar"
>$QT_LIBPATH</CODE
></A
>, <A
HREF="#cv-QT_MOC"
><CODE
CLASS="envar"
>$QT_MOC</CODE
></A
>, <A
HREF="#cv-QT_MOCCXXPREFIX"
><CODE
CLASS="envar"
>$QT_MOCCXXPREFIX</CODE
></A
>, <A
HREF="#cv-QT_MOCCXXSUFFIX"
><CODE
CLASS="envar"
>$QT_MOCCXXSUFFIX</CODE
></A
>, <A
HREF="#cv-QT_MOCFROMCXXCOM"
><CODE
CLASS="envar"
>$QT_MOCFROMCXXCOM</CODE
></A
>, <A
HREF="#cv-QT_MOCFROMCXXFLAGS"
><CODE
CLASS="envar"
>$QT_MOCFROMCXXFLAGS</CODE
></A
>, <A
HREF="#cv-QT_MOCFROMHCOM"
><CODE
CLASS="envar"
>$QT_MOCFROMHCOM</CODE
></A
>, <A
HREF="#cv-QT_MOCFROMHFLAGS"
><CODE
CLASS="envar"
>$QT_MOCFROMHFLAGS</CODE
></A
>, <A
HREF="#cv-QT_MOCHPREFIX"
><CODE
CLASS="envar"
>$QT_MOCHPREFIX</CODE
></A
>, <A
HREF="#cv-QT_MOCHSUFFIX"
><CODE
CLASS="envar"
>$QT_MOCHSUFFIX</CODE
></A
>, <A
HREF="#cv-QT_UIC"
><CODE
CLASS="envar"
>$QT_UIC</CODE
></A
>, <A
HREF="#cv-QT_UICCOM"
><CODE
CLASS="envar"
>$QT_UICCOM</CODE
></A
>, <A
HREF="#cv-QT_UICDECLFLAGS"
><CODE
CLASS="envar"
>$QT_UICDECLFLAGS</CODE
></A
>, <A
HREF="#cv-QT_UICDECLPREFIX"
><CODE
CLASS="envar"
>$QT_UICDECLPREFIX</CODE
></A
>, <A
HREF="#cv-QT_UICDECLSUFFIX"
><CODE
CLASS="envar"
>$QT_UICDECLSUFFIX</CODE
></A
>, <A
HREF="#cv-QT_UICIMPLFLAGS"
><CODE
CLASS="envar"
>$QT_UICIMPLFLAGS</CODE
></A
>, <A
HREF="#cv-QT_UICIMPLPREFIX"
><CODE
CLASS="envar"
>$QT_UICIMPLPREFIX</CODE
></A
>, <A
HREF="#cv-QT_UICIMPLSUFFIX"
><CODE
CLASS="envar"
>$QT_UICIMPLSUFFIX</CODE
></A
>, <A
HREF="#cv-QT_UISUFFIX"
><CODE
CLASS="envar"
>$QT_UISUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-RCS"
></A
><TT
CLASS="literal"
>RCS</TT
></DT
><DD
><P
>&#13;Sets construction variables for the interaction
with the Revision Control System.
</P
><P
>&#13;Sets: <A
HREF="#cv-RCS"
><CODE
CLASS="envar"
>$RCS</CODE
></A
>, <A
HREF="#cv-RCS_CO"
><CODE
CLASS="envar"
>$RCS_CO</CODE
></A
>, <A
HREF="#cv-RCS_COCOM"
><CODE
CLASS="envar"
>$RCS_COCOM</CODE
></A
>, <A
HREF="#cv-RCS_COFLAGS"
><CODE
CLASS="envar"
>$RCS_COFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-RCS_COCOMSTR"
><CODE
CLASS="envar"
>$RCS_COCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-rmic"
></A
><TT
CLASS="literal"
>rmic</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>rmic</SPAN
> utility.
</P
><P
>&#13;Sets: <A
HREF="#cv-JAVACLASSSUFFIX"
><CODE
CLASS="envar"
>$JAVACLASSSUFFIX</CODE
></A
>, <A
HREF="#cv-RMIC"
><CODE
CLASS="envar"
>$RMIC</CODE
></A
>, <A
HREF="#cv-RMICCOM"
><CODE
CLASS="envar"
>$RMICCOM</CODE
></A
>, <A
HREF="#cv-RMICFLAGS"
><CODE
CLASS="envar"
>$RMICFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-RMICCOMSTR"
><CODE
CLASS="envar"
>$RMICCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-rpcgen"
></A
><TT
CLASS="literal"
>rpcgen</TT
></DT
><DD
><P
>&#13;Sets construction variables for building with RPCGEN.
</P
><P
>&#13;Sets: <A
HREF="#cv-RPCGEN"
><CODE
CLASS="envar"
>$RPCGEN</CODE
></A
>, <A
HREF="#cv-RPCGENCLIENTFLAGS"
><CODE
CLASS="envar"
>$RPCGENCLIENTFLAGS</CODE
></A
>, <A
HREF="#cv-RPCGENFLAGS"
><CODE
CLASS="envar"
>$RPCGENFLAGS</CODE
></A
>, <A
HREF="#cv-RPCGENHEADERFLAGS"
><CODE
CLASS="envar"
>$RPCGENHEADERFLAGS</CODE
></A
>, <A
HREF="#cv-RPCGENSERVICEFLAGS"
><CODE
CLASS="envar"
>$RPCGENSERVICEFLAGS</CODE
></A
>, <A
HREF="#cv-RPCGENXDRFLAGS"
><CODE
CLASS="envar"
>$RPCGENXDRFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-SCCS"
></A
><TT
CLASS="literal"
>SCCS</TT
></DT
><DD
><P
>&#13;Sets construction variables for interacting with the
Source Code Control System.
</P
><P
>&#13;Sets: <A
HREF="#cv-SCCS"
><CODE
CLASS="envar"
>$SCCS</CODE
></A
>, <A
HREF="#cv-SCCSCOM"
><CODE
CLASS="envar"
>$SCCSCOM</CODE
></A
>, <A
HREF="#cv-SCCSFLAGS"
><CODE
CLASS="envar"
>$SCCSFLAGS</CODE
></A
>, <A
HREF="#cv-SCCSGETFLAGS"
><CODE
CLASS="envar"
>$SCCSGETFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-SCCSCOMSTR"
><CODE
CLASS="envar"
>$SCCSCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-sgiar"
></A
><TT
CLASS="literal"
>sgiar</TT
></DT
><DD
><P
>&#13;Sets construction variables for the SGI library archiver.
</P
><P
>&#13;Sets: <A
HREF="#cv-AR"
><CODE
CLASS="envar"
>$AR</CODE
></A
>, <A
HREF="#cv-ARCOMSTR"
><CODE
CLASS="envar"
>$ARCOMSTR</CODE
></A
>, <A
HREF="#cv-ARFLAGS"
><CODE
CLASS="envar"
>$ARFLAGS</CODE
></A
>, <A
HREF="#cv-LIBPREFIX"
><CODE
CLASS="envar"
>$LIBPREFIX</CODE
></A
>, <A
HREF="#cv-LIBSUFFIX"
><CODE
CLASS="envar"
>$LIBSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-ARCOMSTR"
><CODE
CLASS="envar"
>$ARCOMSTR</CODE
></A
>, <A
HREF="#cv-SHLINKCOMSTR"
><CODE
CLASS="envar"
>$SHLINKCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-sgicXX"
></A
><TT
CLASS="literal"
>sgic++</TT
></DT
><DD
><P
>&#13;Sets construction variables for the SGI C++ compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXFLAGS"
><CODE
CLASS="envar"
>$CXXFLAGS</CODE
></A
>, <A
HREF="#cv-SHCXX"
><CODE
CLASS="envar"
>$SHCXX</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-sgicc"
></A
><TT
CLASS="literal"
>sgicc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the SGI C compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-sgilink"
></A
><TT
CLASS="literal"
>sgilink</TT
></DT
><DD
><P
>&#13;Sets construction variables for the SGI linker.
</P
><P
>&#13;Sets: <A
HREF="#cv-LINK"
><CODE
CLASS="envar"
>$LINK</CODE
></A
>, <A
HREF="#cv-RPATHPREFIX"
><CODE
CLASS="envar"
>$RPATHPREFIX</CODE
></A
>, <A
HREF="#cv-RPATHSUFFIX"
><CODE
CLASS="envar"
>$RPATHSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-sunar"
></A
><TT
CLASS="literal"
>sunar</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Sun library archiver.
</P
><P
>&#13;Sets: <A
HREF="#cv-AR"
><CODE
CLASS="envar"
>$AR</CODE
></A
>, <A
HREF="#cv-ARCOM"
><CODE
CLASS="envar"
>$ARCOM</CODE
></A
>, <A
HREF="#cv-ARFLAGS"
><CODE
CLASS="envar"
>$ARFLAGS</CODE
></A
>, <A
HREF="#cv-LIBPREFIX"
><CODE
CLASS="envar"
>$LIBPREFIX</CODE
></A
>, <A
HREF="#cv-LIBSUFFIX"
><CODE
CLASS="envar"
>$LIBSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINK"
><CODE
CLASS="envar"
>$SHLINK</CODE
></A
>, <A
HREF="#cv-SHLINKCOM"
><CODE
CLASS="envar"
>$SHLINKCOM</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-ARCOMSTR"
><CODE
CLASS="envar"
>$ARCOMSTR</CODE
></A
>, <A
HREF="#cv-SHLINKCOMSTR"
><CODE
CLASS="envar"
>$SHLINKCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-suncXX"
></A
><TT
CLASS="literal"
>sunc++</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Sun C++ compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-CXXVERSION"
><CODE
CLASS="envar"
>$CXXVERSION</CODE
></A
>, <A
HREF="#cv-SHCXX"
><CODE
CLASS="envar"
>$SHCXX</CODE
></A
>, <A
HREF="#cv-SHCXXFLAGS"
><CODE
CLASS="envar"
>$SHCXXFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJPREFIX"
><CODE
CLASS="envar"
>$SHOBJPREFIX</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-suncc"
></A
><TT
CLASS="literal"
>suncc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Sun C compiler.
</P
><P
>&#13;Sets: <A
HREF="#cv-CXX"
><CODE
CLASS="envar"
>$CXX</CODE
></A
>, <A
HREF="#cv-SHCCFLAGS"
><CODE
CLASS="envar"
>$SHCCFLAGS</CODE
></A
>, <A
HREF="#cv-SHOBJPREFIX"
><CODE
CLASS="envar"
>$SHOBJPREFIX</CODE
></A
>, <A
HREF="#cv-SHOBJSUFFIX"
><CODE
CLASS="envar"
>$SHOBJSUFFIX</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-sunlink"
></A
><TT
CLASS="literal"
>sunlink</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Sun linker.
</P
><P
>&#13;Sets: <A
HREF="#cv-RPATHPREFIX"
><CODE
CLASS="envar"
>$RPATHPREFIX</CODE
></A
>, <A
HREF="#cv-RPATHSUFFIX"
><CODE
CLASS="envar"
>$RPATHSUFFIX</CODE
></A
>, <A
HREF="#cv-SHLINKFLAGS"
><CODE
CLASS="envar"
>$SHLINKFLAGS</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-swig"
></A
><TT
CLASS="literal"
>swig</TT
></DT
><DD
><P
>&#13;Sets construction variables for the SWIG interface generator.
</P
><P
>&#13;Sets: <A
HREF="#cv-SWIG"
><CODE
CLASS="envar"
>$SWIG</CODE
></A
>, <A
HREF="#cv-SWIGCFILESUFFIX"
><CODE
CLASS="envar"
>$SWIGCFILESUFFIX</CODE
></A
>, <A
HREF="#cv-SWIGCOM"
><CODE
CLASS="envar"
>$SWIGCOM</CODE
></A
>, <A
HREF="#cv-SWIGCXXFILESUFFIX"
><CODE
CLASS="envar"
>$SWIGCXXFILESUFFIX</CODE
></A
>, <A
HREF="#cv-SWIGFLAGS"
><CODE
CLASS="envar"
>$SWIGFLAGS</CODE
></A
>, <A
HREF="#cv-SWIGINCPREFIX"
><CODE
CLASS="envar"
>$SWIGINCPREFIX</CODE
></A
>, <A
HREF="#cv-SWIGINCSUFFIX"
><CODE
CLASS="envar"
>$SWIGINCSUFFIX</CODE
></A
>, <A
HREF="#cv-SWIGPATH"
><CODE
CLASS="envar"
>$SWIGPATH</CODE
></A
>, <A
HREF="#cv-_SWIGINCFLAGS"
><CODE
CLASS="envar"
>$_SWIGINCFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-SWIGCOMSTR"
><CODE
CLASS="envar"
>$SWIGCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-tar"
></A
><TT
CLASS="literal"
>tar</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>tar</SPAN
> archiver.
</P
><P
>&#13;Sets: <A
HREF="#cv-TAR"
><CODE
CLASS="envar"
>$TAR</CODE
></A
>, <A
HREF="#cv-TARCOM"
><CODE
CLASS="envar"
>$TARCOM</CODE
></A
>, <A
HREF="#cv-TARFLAGS"
><CODE
CLASS="envar"
>$TARFLAGS</CODE
></A
>, <A
HREF="#cv-TARSUFFIX"
><CODE
CLASS="envar"
>$TARSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-TARCOMSTR"
><CODE
CLASS="envar"
>$TARCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-tex"
></A
><TT
CLASS="literal"
>tex</TT
></DT
><DD
><P
>&#13;Sets construction variables for the TeX formatter and typesetter.
</P
><P
>&#13;Sets: <A
HREF="#cv-BIBTEX"
><CODE
CLASS="envar"
>$BIBTEX</CODE
></A
>, <A
HREF="#cv-BIBTEXCOM"
><CODE
CLASS="envar"
>$BIBTEXCOM</CODE
></A
>, <A
HREF="#cv-BIBTEXFLAGS"
><CODE
CLASS="envar"
>$BIBTEXFLAGS</CODE
></A
>, <A
HREF="#cv-LATEX"
><CODE
CLASS="envar"
>$LATEX</CODE
></A
>, <A
HREF="#cv-LATEXCOM"
><CODE
CLASS="envar"
>$LATEXCOM</CODE
></A
>, <A
HREF="#cv-LATEXFLAGS"
><CODE
CLASS="envar"
>$LATEXFLAGS</CODE
></A
>, <A
HREF="#cv-MAKEINDEX"
><CODE
CLASS="envar"
>$MAKEINDEX</CODE
></A
>, <A
HREF="#cv-MAKEINDEXCOM"
><CODE
CLASS="envar"
>$MAKEINDEXCOM</CODE
></A
>, <A
HREF="#cv-MAKEINDEXFLAGS"
><CODE
CLASS="envar"
>$MAKEINDEXFLAGS</CODE
></A
>, <A
HREF="#cv-TEX"
><CODE
CLASS="envar"
>$TEX</CODE
></A
>, <A
HREF="#cv-TEXCOM"
><CODE
CLASS="envar"
>$TEXCOM</CODE
></A
>, <A
HREF="#cv-TEXFLAGS"
><CODE
CLASS="envar"
>$TEXFLAGS</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-BIBTEXCOMSTR"
><CODE
CLASS="envar"
>$BIBTEXCOMSTR</CODE
></A
>, <A
HREF="#cv-LATEXCOMSTR"
><CODE
CLASS="envar"
>$LATEXCOMSTR</CODE
></A
>, <A
HREF="#cv-MAKEINDEXCOMSTR"
><CODE
CLASS="envar"
>$MAKEINDEXCOMSTR</CODE
></A
>, <A
HREF="#cv-TEXCOMSTR"
><CODE
CLASS="envar"
>$TEXCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-tlib"
></A
><TT
CLASS="literal"
>tlib</TT
></DT
><DD
><P
>&#13;Sets construction variables for the Borlan
<SPAN
CLASS="application"
>tib</SPAN
> library archiver.
</P
><P
>&#13;Sets: <A
HREF="#cv-AR"
><CODE
CLASS="envar"
>$AR</CODE
></A
>, <A
HREF="#cv-ARCOM"
><CODE
CLASS="envar"
>$ARCOM</CODE
></A
>, <A
HREF="#cv-ARFLAGS"
><CODE
CLASS="envar"
>$ARFLAGS</CODE
></A
>, <A
HREF="#cv-LIBPREFIX"
><CODE
CLASS="envar"
>$LIBPREFIX</CODE
></A
>, <A
HREF="#cv-LIBSUFFIX"
><CODE
CLASS="envar"
>$LIBSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-ARCOMSTR"
><CODE
CLASS="envar"
>$ARCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-yacc"
></A
><TT
CLASS="literal"
>yacc</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>yacc</SPAN
> parse generator.
</P
><P
>&#13;Sets: <A
HREF="#cv-YACC"
><CODE
CLASS="envar"
>$YACC</CODE
></A
>, <A
HREF="#cv-YACCCOM"
><CODE
CLASS="envar"
>$YACCCOM</CODE
></A
>, <A
HREF="#cv-YACCFLAGS"
><CODE
CLASS="envar"
>$YACCFLAGS</CODE
></A
>, <A
HREF="#cv-YACCHFILESUFFIX"
><CODE
CLASS="envar"
>$YACCHFILESUFFIX</CODE
></A
>, <A
HREF="#cv-YACCHXXFILESUFFIX"
><CODE
CLASS="envar"
>$YACCHXXFILESUFFIX</CODE
></A
>, <A
HREF="#cv-YACCVCGFILESUFFIX"
><CODE
CLASS="envar"
>$YACCVCGFILESUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-YACCCOMSTR"
><CODE
CLASS="envar"
>$YACCCOMSTR</CODE
></A
>.
</P
></DD
><DT
><A
NAME="t-zip"
></A
><TT
CLASS="literal"
>zip</TT
></DT
><DD
><P
>&#13;Sets construction variables for the <SPAN
CLASS="application"
>zip</SPAN
> archiver.
</P
><P
>&#13;Sets: <A
HREF="#cv-ZIP"
><CODE
CLASS="envar"
>$ZIP</CODE
></A
>, <A
HREF="#cv-ZIPCOM"
><CODE
CLASS="envar"
>$ZIPCOM</CODE
></A
>, <A
HREF="#cv-ZIPCOMPRESSION"
><CODE
CLASS="envar"
>$ZIPCOMPRESSION</CODE
></A
>, <A
HREF="#cv-ZIPFLAGS"
><CODE
CLASS="envar"
>$ZIPFLAGS</CODE
></A
>, <A
HREF="#cv-ZIPSUFFIX"
><CODE
CLASS="envar"
>$ZIPSUFFIX</CODE
></A
>.
</P
><P
>&#13;Uses: <A
HREF="#cv-ZIPCOMSTR"
><CODE
CLASS="envar"
>$ZIPCOMSTR</CODE
></A
>.
</P
></DD
></DL
></DIV
></DIV
><DIV
CLASS="appendix"
><HR><H1
><A
NAME="app-tasks"
></A
>Appendix D. Handling Common Tasks</H1
><P
>&#13;There is a common set of simple tasks that many build configurations rely
on as they become more complex. Most build tools have special
purpose constructs for performing these tasks, but since <TT
CLASS="filename"
>SConscript</TT
>
files are <SPAN
CLASS="application"
>Python</SPAN
> scripts, you can use more flexible built-in <SPAN
CLASS="application"
>Python</SPAN
>
services to perform these tasks. This appendix lists a number of these
tasks and how to implement them in <SPAN
CLASS="application"
>Python</SPAN
>.
</P
><DIV
CLASS="example"
><A
NAME="AEN10745"
></A
><P
><B
>Example D-1. Wildcard globbing to create a list of filenames</B
></P
><PRE
CLASS="programlisting"
>&#13;import glob
files = glob.glob(wildcard)
</PRE
></DIV
><DIV
CLASS="example"
><A
NAME="AEN10748"
></A
><P
><B
>Example D-2. Filename extension substitution</B
></P
><PRE
CLASS="programlisting"
>&#13;import os.path
filename = os.path.splitext(filename)[0]+extension
</PRE
></DIV
><DIV
CLASS="example"
><A
NAME="AEN10751"
></A
><P
><B
>Example D-3. Appending a path prefix to a list of filenames</B
></P
><PRE
CLASS="programlisting"
>&#13;import os.path
filenames = [os.path.join(prefix, x) for x in filenames]
</PRE
><P
>or in Python 1.5.2:</P
><PRE
CLASS="programlisting"
>&#13;import os.path
new_filenames = []
for x in filenames:
new_filenames.append(os.path.join(prefix, x))
</PRE
></DIV
><DIV
CLASS="example"
><A
NAME="AEN10756"
></A
><P
><B
>Example D-4. Substituting a path prefix with another one</B
></P
><PRE
CLASS="programlisting"
>&#13;if filename.find(old_prefix) == 0:
filename = filename.replace(old_prefix, new_prefix)
</PRE
><P
>or in Python 1.5.2:</P
><PRE
CLASS="programlisting"
>&#13;import string
if string.find(filename, old_prefix) == 0:
filename = string.replace(filename, old_prefix, new_prefix)
</PRE
></DIV
><DIV
CLASS="example"
><A
NAME="AEN10761"
></A
><P
><B
>Example D-5. Filtering a filename list to exclude/retain only a specific set
of extensions</B
></P
><PRE
CLASS="programlisting"
>&#13;import os.path
filenames = [x for x in filenames if os.path.splitext(x)[1] in extensions]
</PRE
><P
>or in Python 1.5.2:</P
><PRE
CLASS="programlisting"
>&#13;import os.path
new_filenames = []
for x in filenames:
if os.path.splitext(x)[1] in extensions:
new_filenames.append(x)
</PRE
></DIV
><DIV
CLASS="example"
><A
NAME="AEN10766"
></A
><P
><B
>Example D-6. The "backtick function": run a shell command and capture the
output</B
></P
><PRE
CLASS="programlisting"
>import os
output = os.popen(command).read()
</PRE
></DIV
></DIV
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN380"
HREF="#AEN380"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>In programming parlance,
the <TT
CLASS="filename"
>SConstruct</TT
> file is
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>declarative</I
></SPAN
>,
meaning you tell <SPAN
CLASS="application"
>SCons</SPAN
> what you want done
and let it figure out the order in which to do it,
rather than strictly <SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>imperative</I
></SPAN
>,
where you specify explicitly the order in
which to do things.
</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN1019"
HREF="#AEN1019"
><SPAN
CLASS="footnote"
>[2]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>&#13; This easily-overlooked distinction between
how <SPAN
CLASS="application"
>SCons</SPAN
> decides if the target itself must be rebuilt
and how the target is then used to decide if a different
target must be rebuilt is one of the confusing
things that has led to the <CODE
CLASS="function"
>TargetSignatures</CODE
>
and <CODE
CLASS="function"
>SourceSignatures</CODE
> functions being
replaced by the simpler <CODE
CLASS="function"
>Decider</CODE
> function.
</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN2335"
HREF="#AEN2335"
><SPAN
CLASS="footnote"
>[3]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>&#13; The <CODE
CLASS="function"
>AddOption</CODE
> function is,
in fact, implemented using a subclass
of the <CODE
CLASS="classname"
>optparse.OptionParser</CODE
>.
</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN2910"
HREF="#AEN2910"
><SPAN
CLASS="footnote"
>[4]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>&#13; Unfortunately, in the early days of SCons design,
we used the name <CODE
CLASS="function"
>Copy</CODE
> for the function that
returns a copy of the environment,
otherwise that would be the logical choice for
a Builder that copies a file or directory tree
to a target location.
</P
></TD
></TR
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN4110"
HREF="#AEN4110"
><SPAN
CLASS="footnote"
>[5]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
>&#13; Actually, the MD5 signature is used as the name of the file
in the shared cache directory in which the contents are stored.
</P
></TD
></TR
></TABLE
></BODY
></HTML
>