Changeset 52

Show
Ignore:
Timestamp:
03/01/08 11:07:11 (4 years ago)
Author:
Derek Parnell
Message:

Pre release of version 3.5

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Source/Makefile.dos

    r48 r52  
    11DMD=dmd 
    2 DFLAGS=-op -release -inline 
     2DFLAGS=-op -release -inline -version=BuildVerbose 
    33SOURCES=$(SOURCES) build.d 
    4 SOURCES=$(SOURCES) util/pathex_bn.d 
    5 SOURCES=$(SOURCES) util/pathex.d 
     4SOURCES=$(SOURCES) opts.d 
     5SOURCES=$(SOURCES) util\pathex_bn.d 
     6SOURCES=$(SOURCES) util\pathex.d 
    67SOURCES=$(SOURCES) source_bn.d 
    7 SOURCES=$(SOURCES) util/str.d 
     8SOURCES=$(SOURCES) util\str.d 
    89SOURCES=$(SOURCES) build_bn.d 
    9 SOURCES=$(SOURCES) util/fdt_bn.d 
    10 SOURCES=$(SOURCES) util/str_bn.d 
     10SOURCES=$(SOURCES) util\fdt_bn.d 
     11SOURCES=$(SOURCES) util\str_bn.d 
    1112SOURCES=$(SOURCES) source.d 
    12 SOURCES=$(SOURCES) util/fdt.d 
    13 SOURCES=$(SOURCES) util/fileex.d 
    14 SOURCES=$(SOURCES) util/fileex_bn.d 
    15 SOURCES=$(SOURCES) util/linetoken.d 
    16 SOURCES=$(SOURCES) util/linetoken_bn.d 
    17 SOURCES=$(SOURCES) util/macro.d 
    18 SOURCES=$(SOURCES) util/booltype.d 
    19 SOURCES=$(SOURCES) util/file2.d 
     13SOURCES=$(SOURCES) util\fdt.d 
     14SOURCES=$(SOURCES) util\fileex.d 
     15SOURCES=$(SOURCES) util\fileex_bn.d 
     16SOURCES=$(SOURCES) util\linetoken.d 
     17SOURCES=$(SOURCES) util\linetoken_bn.d 
     18SOURCES=$(SOURCES) util\macro.d 
     19SOURCES=$(SOURCES) util\booltype.d 
     20SOURCES=$(SOURCES) util\file2.d 
    2021 
    2122 
     
    2324 
    2425build: $(SOURCES) 
    25     $(DMD) $(DFLAGS) -of$@ $(SOURCES) 
     26    $(DMD) $(DFLAGS) -ofbud $(SOURCES) 
    2627 
    2728clean: 
  • trunk/Source/Makefile.gdc

    r48 r52  
    11DMD=gdmd 
    2 DFLAGS=-op -release -inline 
    3 SOURCES=build.d util/pathex_bn.d util/pathex.d source_bn.d util/str.d build_bn.d util/booltype.d util/fdt_bn.d util/str_bn.d source.d util/fdt.d util/fileex.d util/fileex_bn.d util/linetoken.d util/linetoken_bn.d util/macro.d util/file2.d 
     2DFLAGS=-op -release -inline -version=BuildVerbose 
     3SOURCES=build.d opts.d util/pathex_bn.d util/pathex.d source_bn.d util/str.d build_bn.d util/booltype.d util/fdt_bn.d util/str_bn.d source.d util/fdt.d util/fileex.d util/fileex_bn.d util/linetoken.d util/linetoken_bn.d util/macro.d util/file2.d 
    44 
    55all: build 
    66 
    77build: $(SOURCES) 
    8     $(DMD) $(DFLAGS) -of$@ $(SOURCES) 
     8    $(DMD) $(DFLAGS) -ofbud $(SOURCES) 
    99 
    1010clean: 
  • trunk/Source/Makefile.unix

    r48 r52  
    11DMD=dmd 
    2 DFLAGS=-op -release -inline 
    3 SOURCES=build.d util/pathex_bn.d util/pathex.d source_bn.d util/str.d build_bn.d util/booltype.d util/fdt_bn.d util/str_bn.d source.d util/fdt.d util/fileex.d util/fileex_bn.d util/linetoken.d util/linetoken_bn.d util/macro.d util/file2.d 
     2DFLAGS=-op -release -inline -version=BuildVerbose 
     3SOURCES=build.d opts.d util/pathex_bn.d util/pathex.d source_bn.d util/str.d build_bn.d util/booltype.d util/fdt_bn.d util/str_bn.d source.d util/fdt.d util/fileex.d util/fileex_bn.d util/linetoken.d util/linetoken_bn.d util/macro.d util/file2.d 
    44 
    55all: build 
    66 
    77build: $(SOURCES) 
    8     $(DMD) $(DFLAGS) -of$@ $(SOURCES) 
     8    $(DMD) $(DFLAGS) -ofbud $(SOURCES) 
    99 
    1010clean: 
  • trunk/Source/build.d

    r50 r52  
    11/* ******************************************************* 
    2    Build is a tool to assist building applications and libraries written 
     2   This is a tool to assist building applications and libraries written 
    33   using the D programming language. 
    44 
     
    66 Authors: Derek Parnell, Melbourne 
    77 Initial Creation: January 2005 
    8  Version: 3.04 
    9  Date: October 2006 
     8 Version: 3.05 
     9 Date: September 2007 
    1010 License: 
    1111        This software is provided 'as-is', without any express or implied 
     
    3030private import build_bn;    // This module's build number 
    3131 
     32alias char[] text; 
     33 
     34version(D_Version2) 
     35{ 
     36    mixin("alias invariant(dchar)   dcharc;"); 
     37    mixin("alias invariant(wchar)   wcharc;"); 
     38    mixin("alias invariant(char)    charc;"); 
     39} 
     40else 
     41{ 
     42    alias char[] string; 
     43    alias wchar[] wstring; 
     44    alias dchar[] dstring; 
     45    alias wchar   wcharc; 
     46    alias dchar   dcharc; 
     47    alias char    charc; 
     48} 
     49 
     50 
    3251version(unix)   version = Unix; 
    3352version(Unix)   version = Posix; 
    3453version(linux)  version = Posix; 
    3554version(darwin) version = Posix; 
    36 version(DigitalMars) version(Windows) version = UseResponseFile; 
     55 
     56const vMyVersion = "3.05"; 
     57version(build) pragma(todo, "Single file compilation"); 
     58version(build) pragma(todo, "Output Paths"); 
    3759 
    3860version(build) 
     
    4062    version(Windows) { 
    4163        // OptLink Definition File 
    42         pragma (build_def, "VERSION 3.04"); 
    43     } 
    44 
    45  
     64        pragma (build_def, "VERSION 3.05"); 
     65    } 
     66
    4667 
    4768private{ 
    48     alias char[] string; 
    4969    // --------- imports ---------------- 
    5070    static import source;          // Source File class 
     71    static import opts;            // Run time options 
    5172 
    5273    static import util.str;        // non-standard string routines. 
     
    5475    static import util.pathex;     // Extended Path routines. 
    5576    static import util.fileex;     // Extended File routines. 
    56     static import util.macro;      // Macro processing routines. 
     77    static import util.macroex;      // Macro processing routines. 
    5778    static import util.booltype;   // definition of True and False 
    5879    alias util.booltype.True True; 
     
    7293        static import std.c.windows.windows; 
    7394    } 
    74  
    7595    else version(linux) 
    7696    { 
     
    93113        this(string pMsg) 
    94114        { 
    95             super (vAppName ~ ":" ~ pMsg); 
     115            super (vMyName ~ ":" ~ pMsg); 
    96116        } 
    97117    } 
     
    100120    enum LibOpt {Implicit, Build, DontBuild} 
    101121 
    102     // --------- internal strings ---------------- 
    103     version(Windows) { 
    104         string vExeExtension=`exe`; 
    105         string vLibExtension=`lib`; 
    106         string vObjExtension=`obj`; 
    107         string vShrLibExtension=`dll`; 
    108         string vLinkerStdOut = ">nul"; 
    109     } 
    110  
    111     version(Posix) { 
    112         string vExeExtension=``; 
    113         string vLibExtension=`a`; 
    114         string vObjExtension=`o`; 
    115         string vShrLibExtension=`so`; 
    116         string vLinkerStdOut = ">/dev/null"; 
    117     } 
    118     string vSrcExtension=`d`; 
    119     string vSrcDInterfaceExt = `di`; 
    120     string vMacroExtension=`mac`; 
    121     string vDdocExtension=`ddoc`; 
    122122 
    123123    // ---------- Module scoped globals ----------- 
    124     version(DigitalMars) { 
    125         version(Windows) { 
    126             string vCompilerExe=`dmd.exe`; 
    127             string vCompileOnly = `-c`; 
    128             string vLinkerExe=`link.exe`; 
    129             bool   vPostSwitches = true; 
    130             bool   vAppendLinkSwitches = true; 
    131             string vArgDelim = ","; 
    132             string vArgFileDelim = "+"; 
    133             string vConfigFile=`sc.ini`; 
    134             string vCompilerPath=``; 
    135             string vLinkerPath=``; 
    136             string vLinkerDefs=`/noi/map`; 
    137             string vConfigPath=``; 
    138             string vLibPaths = ``; 
    139             string vConfigSep = ";"; 
    140             string vLibrarian = `lib.exe`; 
    141             string vLibrarianOpts = `-c -p256`; 
    142             string vHomePathId = "HOME"; 
    143             string vEtcPath    = ""; 
    144             string vSymInfoSwitch = "/co"; 
    145             string vOutFileSwitch = "-of"; 
    146             string vLinkLibSwitch = ""; 
    147         } 
    148  
    149         version(Posix) { 
    150             string vCompilerExe=`dmd`; 
    151             string vCompileOnly= `-c`; 
    152             string vLinkerExe=`gcc`; 
    153             bool   vPostSwitches = false; 
    154             bool   vAppendLinkSwitches = false; 
    155             string vArgDelim = " "; 
    156             string vArgFileDelim = " "; 
    157             string vConfigFile=`dmd.conf`; 
    158             string vCompilerPath=``; 
    159             string vLinkerPath=``; 
    160             string vLinkerDefs=``; 
    161             string vConfigPath=`/etc/`; 
    162             string vLibPaths = ``; 
    163             string vConfigSep = ":"; 
    164             string vLibrarian = `ar`; 
    165             string vLibrarianOpts = `-r`; 
    166             string vHomePathId = "HOME"; 
    167             string vEtcPath    = "/etc/"; 
    168             string vSymInfoSwitch = "-g"; 
    169             string vOutFileSwitch = "-o "; 
    170             string vLinkLibSwitch = "-l"; 
    171         } 
    172  
    173         string     vVersionSwitch = "-version"; 
    174         string     vDebugSwitch = "-debug"; 
    175         string[]   vCompilerDefs; 
    176         string     vImportPath = "-I"; 
    177         bool       vUseModBaseName = false; 
    178     } 
    179  
    180     version(GNU) { 
    181         version(Windows) { 
    182             string vCompilerExe=`gdc.exe`; 
    183             string vCompileOnly= `-c`; 
    184             string vLinkerExe=`gdc.exe`; 
    185             bool   vPostSwitches = false; 
    186             bool   vAppendLinkSwitches = false; 
    187             string vArgDelim = " "; 
    188             string vArgFileDelim = " "; 
    189             string vConfigFile=null; 
    190             string vCompilerPath=``; 
    191             string vLinkerPath=``; 
    192             string vLinkerDefs=``; 
    193             string vConfigPath=null; 
    194             string vLibPaths = ``; 
    195             string vConfigSep = ";"; 
    196             string vLibrarian = `ar.exe`; 
    197             string vLibrarianOpts = `-c`; 
    198             string vLinkLibSwitch = "-l"; 
    199             string vHomePathId = "HOME"; 
    200             string vEtcPath    = ""; 
    201         } 
    202  
    203         version(Posix) { 
    204             string vCompilerExe=`gdc`; 
    205             string vCompileOnly= `-c`; 
    206             string vLinkerExe=`gdc`; 
    207             bool   vPostSwitches = false; 
    208             bool   vAppendLinkSwitches = false; 
    209             string vArgDelim = " "; 
    210             string vArgFileDelim = " "; 
    211             string vConfigFile=null; 
    212             string vCompilerPath=``; 
    213             string vLinkerPath=``; 
    214             string vLinkerDefs=``; 
    215             string vConfigPath=null; 
    216             string vLibPaths = ``; 
    217             string vConfigSep = ":"; 
    218             string vLibrarian = `ar`; 
    219             string vLibrarianOpts = `-r`; 
    220             string vLinkLibSwitch = "-l"; 
    221             string vHomePathId = "HOME"; 
    222             string vEtcPath    = "/etc/"; 
    223         } 
    224         string     vVersionSwitch = "-fversion"; 
    225         string     vDebugSwitch = "-fdebug"; 
    226         string     vOutFileSwitch = "-o "; 
    227         string[]   vCompilerDefs; 
    228         string     vImportPath = "-I "; 
    229         string     vSymInfoSwitch = "-g"; 
    230         /* GDC places object files in the directory from which it is called */ 
    231         bool       vUseModBaseName = true; 
    232     } 
    233  
    234     string       vCFGPath = ``; 
    235     string       vOverrideConfigPath = ""; 
    236     string       vBuildImportPath = "-I"; 
    237     string       vImportPathDelim = ";"; 
    238     string       vOutputPath = "-od"; 
    239     string       vRunSwitch = "-exec"; 
    240     string       vLibrarianPath = ""; 
    241     string*      vDelayedValue = null; 
    242     string       vTemporaryPath = ""; 
    243     string       vLibPathSwitch = "-L"; 
    244     string       vMapSwitch = "-M"; 
    245     string       vGenDebugInfo = "-g"; 
    246     string       vResponseExt = "brf"; 
    247     string       vDefResponseFile = "build.brf"; 
    248     string       vDefMacroDefFile = "build.mdf"; 
    249     string       vUtilsConfigFile = "build.cfg"; 
    250     string       vPathId = "PATH";   // Used to locate the environment symbol 
    251  
    252     string       vModOutPrefix = "MODULES = \n"; 
    253     string       vModOutSuffix = ""; 
    254     string       vModOutBody   = "    $(MODULE {mod})\n"; 
    255     string       vModOutDelim  = ""; 
    256     string       vModOutFile   = "_modules.ddoc"; 
    257  
    258     string[]     vFinalProc; 
    259  
    260     Bool         vTestRun; 
    261     Bool         vExplicit; 
     124 
     125    string*        vDelayedValue = null; 
     126    string         vTemporaryPath; 
     127 
     128 
     129    string[]       vFinalProc; 
     130    string[]       vFailureProc; 
     131 
    262132    Bool         vScanImports; 
    263133    Bool         vNoLink; 
    264     Bool         vForceCompile; 
    265134    Bool         vSilent; 
    266135    Bool         vSymbols; 
    267136    Bool         vCleanup; 
    268     version(BuildVerbose) Bool         vVerbose; 
    269137    Bool         vMacroInput; 
    270138    Bool         vCollectUses; 
     
    274142    Bool         vAutoImports; 
    275143    Bool         vExecuteProgram; 
    276     Bool         vUseResponseFile; 
    277144    Bool         vConsoleApp; 
    278145    Bool         vUseFinal; 
    279146    Bool         vEmptyArgs; 
     147    Bool         vCleanDummy; 
    280148 
    281149    string       vUsesOutput; 
     
    283151    string       vRunParms; 
    284152    string       vTargetExe; 
    285     string[]     vImportRoots; 
    286     string[]     vModulesToIgnore; 
    287     string[]     vModulesToNotice; 
    288     string[]     vBuildDef; 
    289     string[]     vDefaultLibs; 
    290     LibOpt       vLibraryAction = LibOpt.Implicit; 
    291     string       vAppPath; 
    292     string       vAppName; 
    293     string       vAppVersion = "3.04"; 
     153    string[]   vImportRoots; 
     154    string[]   vBuildDef; 
     155    LibOpt     vLibraryAction = LibOpt.Implicit; 
     156    string     vMyPath; 
     157    string     vMyName; 
     158    string     vMyDir; 
    294159    string       vTargetName;           // Output name from first file name. 
    295160    string       vPragmaTargetName;     // Output name from pragma. 
    296161    string       vCommandTargetName;    // Output name from switches. 
    297162    string[]     vCmdLineSourceFiles;   // List of source files from command line 
    298     bool[string] vLinkFiles;            // List of non-source files from command line 
     163    string[]    vLinkFiles;            // List of non-source files from command line 
    299164    string[]     vCombinedArgs;         // All the args are gathered here prior to processing. 
    300165    string[]     vBuildArgs;            // Arguments passed to build 
    301166    string[]     vCompilerArgs;         // Arguments passed to compiler 
    302     string[]     vSourceScanList;       // The list of places to find source files. 
     167    string[]   vSourceScanList;       // The list of places to find source files. 
    303168    bool[string] vResourceFileTypes; 
    304     string[]     vUDResTypes; 
    305169 
    306170 
    307171    version(Windows) 
    308172    { 
    309         string       vWinVer = ""
    310         ubyte        vWinVerNum; 
    311         bool         vAutoWinLibs = true; 
     173        string     vWinVer
     174        ubyte      vWinVerNum; 
     175        bool       vAutoWinLibs = true; 
    312176    } 
    313177 
     
    324188    vSourceScanList ~= "." ~ std.path.sep; 
    325189    vNoLink = False; 
    326     vTestRun = False; 
    327     vExplicit = False; 
    328190    vScanImports = False; 
    329191    vUseFinal = True; 
    330192    vEmptyArgs = True; 
    331     vForceCompile = False; 
    332193    vSilent = False; 
    333194    vCleanup = False; 
    334     version(BuildVerbose) vVerbose = False; 
    335195    vMacroInput = True; 
    336196    vCollectUses = False; 
     
    340200    vAutoImports = True; 
    341201    vExecuteProgram = False; 
    342     vUseResponseFile = False; 
    343202    vSymbols = False; 
    344203    vConsoleApp = True; 
     204    vCleanDummy = False; 
    345205 
    346206    version(Posix) 
    347207    { 
    348         vCompilerDefs ~= vVersionSwitch ~ "=Posix"; // Until such time as this is standard in dmd. 
     208        opts.CompilerDefs ~= opts.VersionSwitch ~ "=Posix"; // Until such time as this is standard in dmd. 
    349209    } 
    350210 
     
    354214     } 
    355215 
    356     vUseResponseFile = False; 
    357     version(UseResponseFile) vUseResponseFile = True; 
    358  
    359     util.str.SetEnv("@P", std.path.getDirName(vConfigPath)); 
    360     util.str.SetEnv("@D", std.path.getDirName(vCompilerPath)); 
    361  
    362     source.Source.UseModBaseName(vUseModBaseName); 
     216 
     217    util.str.SetEnv("@P", std.path.getDirName(opts.ConfigPath)); 
     218    util.str.SetEnv("@D", std.path.getDirName(opts.CompilerPath)); 
    363219 
    364220} 
     
    371227    std.stdio.writefln( 
    372228        "Path and Version : %s v%s(%d)\n  built on %s" 
    373             ,vAppPath, vAppVersion, build_bn.auto_build_number, 
     229            ,vMyPath, vMyVersion, build_bn.auto_build_number, 
    374230            __TIMESTAMP__); 
    375231    if (pFull == false) 
     
    379235    std.stdio.writefln( 
    380236        "Usage: %s sourcefile [options objectfiles libraries]" 
    381             , vAppName); 
     237            , vMyName); 
    382238    std.stdio.writefln("  sourcefile D source file"); 
    383239    std.stdio.writefln("  -v         Verbose (passed through to D)"); 
     
    388244    std.stdio.writefln("             PATH list. Used if you are testing an alternate"); 
    389245    std.stdio.writefln("             version of the compiler."); 
    390     std.stdio.writefln("  -CFPATH<path> <path> is where the D config file has been installed."); 
    391     std.stdio.writefln("  -BCFPATH<path> <path> is where the Build config file has been installed."); 
     246    std.stdio.writefln("  -CFPATH<path> <path> is where the compiler config file has been installed."); 
     247    std.stdio.writefln("  -BCFPATH<path> <path> is where the config file has been installed."); 
    392248    std.stdio.writefln("  -full      Causes all source files, except ignored modules,"); 
    393249    std.stdio.writefln("              to be compiled."); 
     
    467323    std.stdio.writefln("  -noautoimport Turns off the automatic addition of source paths"); 
    468324    std.stdio.writefln("              to the list of Import Roots."); 
    469     std.stdio.writefln("  -info      Displays the version and path of the Build application."); 
     325    std.stdio.writefln("  -info      Displays the version and path of this application."); 
    470326    std.stdio.writefln("  -nodef    Prevents a Module Definition File from being created."); 
    471327    std.stdio.writefln("  -UMB=<Yes/No> If 'Yes' this forces the utility to expect"); 
     
    516372            version(BuildVerbose) 
    517373            { 
    518                 if(vVerbose == True) { 
     374                if(opts.Verbose == True) { 
    519375                    std.stdio.writefln("source file[%d] %s", i, 
    520                             util.pathex.AbbreviateFileName(lSource.FileName)); 
     376                            source.ReducePathName(lSource.FileName)); 
    521377                } 
    522378                else if(vNames == True) { 
    523                     std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lSource.FileName)); 
     379                    std.stdio.writefln(" [ %s ]", source.ReducePathName(lSource.FileName)); 
    524380                } 
    525381            } else { 
    526382                if(vNames == True) { 
    527                     std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lSource.FileName)); 
     383                    std.stdio.writefln(" [ %s ]", source.ReducePathName(lSource.FileName)); 
    528384                } 
    529385            } 
     
    533389                version(BuildVerbose) 
    534390                { 
    535                     if(vVerbose == True) 
     391                    if(opts.Verbose == True) 
    536392                        std.stdio.writefln("Newer time: from %s to %s", 
    537393                                    lModsTime.toString(), 
     
    548404 
    549405    // Examine any link file dependancies too. 
    550     foreach(int idx, string lFileName; vLinkFiles.keys
     406    foreach(int idx, string lFileName; vLinkFiles
    551407    { 
    552408        util.fdt.FileDateTime lLinkTime = new util.fdt.FileDateTime(lFileName); 
     
    554410        version(BuildVerbose) 
    555411        { 
    556             if(vVerbose == True) { 
     412            if(opts.Verbose == True) { 
    557413                std.stdio.writefln("link file[%d] %s %s", idx, 
    558                         util.pathex.AbbreviateFileName(lFileName), lLinkTime.toString()); 
     414                        source.ReducePathName(lFileName), lLinkTime.toString()); 
    559415            } 
    560416            else if(vNames == True) { 
    561                 std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName)); 
     417                std.stdio.writefln(" [ %s ]", source.ReducePathName(lFileName)); 
    562418            } 
    563419        } else { 
    564420            if(vNames == True) { 
    565                 std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName)); 
     421                std.stdio.writefln(" [ %s ]", source.ReducePathName(lFileName)); 
    566422            } 
    567423        } 
     
    570426            version(BuildVerbose) 
    571427            { 
    572                 if(vVerbose == True) 
     428                if(opts.Verbose == True) 
    573429                    std.stdio.writefln("Newer time: from %s to %s", 
    574430                                lModsTime.toString(), 
     
    584440} 
    585441 
    586  
    587 /* Build the target.  Return an error code if there 
     442//------------------------------------------------------- 
     443int RunCallBack(int pReason, string pCommand, int pRC) 
     444//------------------------------------------------------- 
     445
     446    if (pReason == 1) 
     447    { 
     448      if (opts.TestRun == True) 
     449      { 
     450          std.stdio.writefln("Generated command: '%s'",pCommand); 
     451          return 1; // Don't run the command 
     452      } 
     453      else 
     454      { 
     455          version(BuildVerbose) 
     456          { 
     457              if(opts.Verbose == True) 
     458                  std.stdio.writefln("Running '%s'",pCommand); 
     459          } 
     460          return 0; // Continue with the command. 
     461      } 
     462    } 
     463 
     464    if (pReason == 2) 
     465    { 
     466      version(BuildVerbose) 
     467      { 
     468          if(opts.Verbose == True) { 
     469              if (pRC == 0) 
     470              { 
     471                  std.stdio.writefln("Successful"); 
     472              } else { 
     473                  std.stdio.writefln("Failed. Return code: %04x",pRC); 
     474              } 
     475          } 
     476      } 
     477 
     478    } 
     479    return 0;  // Continue with command processing. 
     480
     481 
     482/* Create the target.  Return an error code if there 
    588483    was a problem, else return zero. 
    589484*/ 
    590485//------------------------------------------------------- 
    591 int Build() 
     486int MakeItSo() 
    592487//------------------------------------------------------- 
    593488{ 
     
    614509    string[]    lLibraryFiles; 
    615510 
    616  
    617511    lCompiling = False; 
    618512    lLinking = False; 
     
    622516    foreach( string lFile; vCmdLineSourceFiles) 
    623517    { 
    624         lFile = GetFullPathname(lFile, vSourceScanList); 
    625         if (std.path.getExt(lFile) == vMacroExtension) 
     518        string lFullFile; 
     519        lFullFile = GetFullPathname(lFile, vSourceScanList); 
     520        if (std.path.getExt(lFullFile) == opts.MacroExtension) 
    626521        { 
    627522            version(BuildVerbose) 
    628523            { 
    629                 if (vVerbose == True) 
    630                     std.stdio.writefln("Macro file '%s' being processed.", lFile); 
    631             } 
    632  
    633             string lAltFile = std.path.addExt( lFile, vSrcExtension); // Make it a D source file. 
    634             if (util.macro.ConvertFile(lFile, "build", lAltFile)) 
    635                 lFile = lAltFile; 
     524                if (opts.Verbose == True) 
     525                    std.stdio.writefln("Macro file '%s' being processed.", lFullFile); 
     526            } 
     527 
     528            string lAltFile = util.pathex.ReplaceExtension( lFullFile, opts.SrcExtension); // Make it a D source file. 
     529            if (util.macroex.ConvertFile(lFile, "build", lAltFile)) 
     530                lFullFile = lAltFile; 
    636531            else 
    637532            { 
    638533                version(BuildVerbose) 
    639534                { 
    640                     if ((vSilent != True) || (vVerbose == True)) 
    641                         std.stdio.writefln("Macro file '%s' failed to generate output", lFile); 
     535                    if ((vSilent != True) || (opts.Verbose == True)) 
     536                        std.stdio.writefln("Macro file '%s' failed to generate output", lFullFile); 
    642537                } else { 
    643538                    if (vSilent != True) 
    644                         std.stdio.writefln("Macro file '%s' failed to generate output", lFile); 
    645                 } 
    646                 lFile.length = 0; 
    647             } 
    648         } 
    649  
    650         if (lFile.length > 0) 
    651         { 
    652             new source.Source(lFile); 
     539                        std.stdio.writefln("Macro file '%s' failed to generate output", lFullFile); 
     540                } 
     541                lFullFile.length = 0; 
     542            } 
     543        } 
     544 
     545        if (lFullFile.length > 0) 
     546        { 
     547            new source.Source(lFullFile); 
    653548        } 
    654549    } 
     
    657552    // found, and I was not explicitly told not to link. 
    658553    lLinking =  (vLibraryAction == LibOpt.Build) || 
    659                 (source.Source.WasMainFound == false) || 
     554                (source.Source.WasMainFound == False) || 
    660555                (vNoLink == True) 
    661556               ? False : True; 
     
    665560    // If not explictly known, set the library action 
    666561    // based on whether or not 'main' was found in the sources. 
    667     if (vLibraryAction == LibOpt.Implicit) { 
    668         if (source.Source.WasMainFound){ 
     562    if (vLibraryAction == LibOpt.Implicit) 
     563    { 
     564        if (source.Source.WasMainFound == True) 
     565        { 
    669566            vLibraryAction = LibOpt.DontBuild; 
    670567        } 
    671         else { 
     568        else 
     569        { 
    672570            vLibraryAction = LibOpt.Build; 
    673571        } 
    674572    } 
     573 
     574    if (vLibraryAction == LibOpt.DontBuild && 
     575        source.Source.WasMainFound == False && 
     576        opts.UnitTesting == True) 
     577    { 
     578        /* Auto creation of a dummy main() to trigger unittesting to happen. */ 
     579        util.fileex.CreateTextFile(opts.DummyMain, 
     580                    [ 
     581                     "int main(string[] pArgs)", 
     582                     "{", 
     583                     "    return 1;", 
     584                     "}" 
     585                     ]); 
     586        new source.Source(opts.DummyMain); 
     587        lLinking = True; 
     588        vCleanDummy = True; 
     589    } 
     590 
    675591 
    676592    // I'm either creating a library, an executable or neither. 
     
    683599        version(BuildVerbose) 
    684600        { 
    685             if(vVerbose == True) 
     601            if(opts.Verbose == True) 
    686602                std.stdio.writefln("Pragma target override is '%s'", std.path.getName(vTargetName)); 
    687603        } 
     
    697613        version(BuildVerbose) 
    698614        { 
    699             if(vVerbose == True) 
     615            if(opts.Verbose == True) 
    700616                std.stdio.writefln("Cmdline target override is '%s'", vTargetName); 
    701617        } 
    702618    } 
     619 
     620    vTargetName = source.ExpandPathName(vTargetName, False); 
    703621 
    704622    // Ensure that the path to the target's location will exist. 
     
    708626    if (vLibraryAction == LibOpt.Build) 
    709627        // Target is a library. 
    710         lTargetName = util.pathex.ReplaceExtension(vTargetName, vLibExtension); 
     628        lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.LibExtension); 
    711629 
    712630    else if (vNoLink == False) 
    713631    { 
    714         if (source.Source.WasMainFound
     632        if (source.Source.WasMainFound == True
    715633            if (source.Source.WasMainDLL) 
    716634                // Target is a shared library. 
    717                 lTargetName = util.pathex.ReplaceExtension(vTargetName, vShrLibExtension); 
     635                lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.ShrLibExtension); 
    718636            else 
    719637            { 
    720638                // Target is an executable 
    721                 lTargetName = util.pathex.ReplaceExtension(vTargetName, vExeExtension); 
     639                lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.ExeExtension); 
    722640                vTargetExe = lTargetName; 
    723641            } 
     
    727645            // so assume they know what they are doing and also assume an 
    728646            // executable is required. 
    729             lTargetName = util.pathex.ReplaceExtension(vTargetName, vExeExtension); 
     647            lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.ExeExtension); 
    730648            vTargetExe = lTargetName; 
    731649        } 
     
    733651    else 
    734652        // Not linking and not archiving, so no target is required. 
    735         lTargetName = ""
     653        lTargetName.length = 0
    736654 
    737655    if (lTargetName.length > 0) 
    738656    { 
    739657        // Get the full name of the target's location. 
    740         lTargetName = util.pathex.CanonicalPath(lTargetName, false); 
     658        lTargetName = source.ExpandPathName(lTargetName, False); 
    741659        lTargetDir = std.path.getDirName(lTargetName); 
    742660 
     
    744662        version(BuildVerbose) 
    745663        { 
    746             if((vVerbose == True) || (vNames == True) ) 
     664            if((opts.Verbose == True) || (vNames == True) ) 
    747665                std.stdio.writefln("\nBuilding target '%s'", lTargetName); 
    748666        } 
    749667 
    750668        // Shorten the target name for future usages. 
    751         lTargetName = util.pathex.AbbreviateFileName(lTargetName); 
     669        lTargetName = source.ReducePathName(lTargetName); 
    752670 
    753671 
     
    758676        version(BuildVerbose) 
    759677        { 
    760             if(vVerbose == True) { 
     678            if(opts.Verbose == True) { 
    761679                std.stdio.writefln("Time %s for %s (target)", lTargetTime.toString(), lTargetName); 
    762680                std.stdio.writefln("Time %s (most recent)", lMostRecentTime.toString()); 
     
    772690        version(BuildVerbose) 
    773691        { 
    774             if((vVerbose == True) || (vNames == True) ) 
     692            if((opts.Verbose == True) || (vNames == True) ) 
    775693                std.stdio.writefln("\nCompiling only. No target will be built."); 
    776694        } else { 
     
    789707        // No files to compile, just link files, so collect 
    790708        // all the object files to link in. 
    791         foreach( string lFileName; vLinkFiles.keys
     709        foreach( string lFileName; vLinkFiles
    792710        { 
    793711            // Only include OBJECT files. 
    794             if (util.str.ends(lFileName , vObjExtension) == True) 
     712            if (util.str.ends(lFileName , opts.ObjExtension) == True) 
    795713                lFilesToLink ~= lFileName; 
    796714        } 
     
    823741                string lFileType; 
    824742 
    825                 lNeedsCompiling = vForceCompile; 
     743                lNeedsCompiling = opts.ForceCompile; 
    826744 
    827745                if (lCurrentSource.Ignore) 
    828746                    return 0; 
    829747 
    830                 lShortFileName = util.pathex.AbbreviateFileName(lCurrentSource.FileName); 
     748                lShortFileName = source.ReducePathName(lCurrentSource.FileName); 
    831749                lFileType = std.path.getExt(lShortFileName); 
    832                 if (lFileType != vSrcExtension && lFileType != vDdocExtension) 
     750                if (lFileType != opts.SrcExtension && lFileType != opts.DdocExtension) 
    833751                    return 0; 
    834752 
    835753                // Only source files are examined from here on. 
    836                 if (lCurrentSource.NoLink || lFileType == vDdocExtension) 
     754                if (lCurrentSource.NoLink || lFileType == opts.DdocExtension) 
    837755                { 
    838756                    lNonLinkingSources ~= lCurrentSource; 
     
    843761                    version(BuildVerbose) 
    844762                    { 
    845                         if (vVerbose == True) 
     763                        if (opts.Verbose == True) 
    846764                            std.stdio.writefln("%s newer than its object file", lShortFileName); 
    847765                    } 
     
    852770                    version(BuildVerbose) 
    853771                    { 
    854                         if (vVerbose == True) 
     772                        if (opts.Verbose == True) 
    855773                            std.stdio.writefln("%s has newer dependants than its object file.", 
    856774                                        lShortFileName); 
     
    870788                    // Check to see if I'm allowed to link this file. 
    871789                    if (lCurrentSource.NoLink == false) 
    872                         lFilesToLink ~= util.pathex.AbbreviateFileName(lCurrentSource.ObjectName); 
    873  
    874                     if (vTestRun == False) 
     790                        lFilesToLink ~= source.ReducePathName(lCurrentSource.ObjectName); 
     791 
     792                    if (opts.TestRun == False) 
    875793                    { 
    876794                        if (lCurrentSource.IncrementBuildNumber()) 
     
    878796                            version(BuildVerbose) 
    879797                            { 
    880                                 if (vVerbose == True) 
     798                                if (opts.Verbose == True) 
    881799                                    std.stdio.writefln("New build number %d for %s", 
    882800                                               lCurrentSource.BuildNumber, 
     
    888806                else if (lCurrentSource.NoLink == false) 
    889807                { 
    890                     lFilesToLink ~= util.pathex.AbbreviateFileName(lCurrentSource.ObjectName); 
     808                    lFilesToLink ~= source.ReducePathName(lCurrentSource.ObjectName); 
    891809                } 
    892810 
     
    919837            if (vAutoWinLibs == true) 
    920838            { 
    921                 vDefaultLibs ~= "gdi32.lib"; 
    922                 vDefaultLibs ~= "advapi32.lib"; 
    923                 vDefaultLibs ~= "COMCTL32.LIB"; 
    924                 vDefaultLibs ~= "comdlg32.lib"; 
    925                 vDefaultLibs ~= "CTL3D32.LIB"; 
    926                 vDefaultLibs ~= "kernel32.lib"; 
    927                 vDefaultLibs ~= "ODBC32.LIB"; 
    928                 vDefaultLibs ~= "ole32.lib"; 
    929                 vDefaultLibs ~= "OLEAUT32.LIB"; 
    930                 vDefaultLibs ~= "shell32.lib"; 
    931                 vDefaultLibs ~= "user32.lib"; 
    932                 vDefaultLibs ~= "uuid.lib"; 
    933                 vDefaultLibs ~= "winmm.lib"; 
    934                 vDefaultLibs ~= "winspool.lib"; 
    935                 vDefaultLibs ~= "wsock32.lib"; 
     839                foreach(string lAutoLib; opts.AutoLibs) 
     840                { 
     841                    opts.DefaultLibs ~= lAutoLib; 
     842                } 
    936843            } 
    937844        } 
     
    957864                lDefName = vTemporaryPath ~ std.path.getBaseName(lDefName); 
    958865            } 
    959             lDefName = util.pathex.AbbreviateFileName(lDefName); 
     866            lDefName = source.ReducePathName(lDefName); 
    960867            util.fileex.CreateTextFile(lDefName, vBuildDef); 
    961868 
     
    965872    // Add any library and any external object files required. 
    966873    lLibraryFiles.length = 0; 
    967     foreach (string lFileName; vLinkFiles.keys
     874    foreach (string lFileName; vLinkFiles
    968875    { 
    969876        string lCmdItem; 
     
    972879        { 
    973880            lCmdItem = lFileName; 
    974             if ( util.str.ends(lCmdItem, "." ~ vLibExtension) == True) 
     881            if ( util.str.ends(lCmdItem, "." ~ opts.LibExtension) == True) 
    975882            { 
    976883                // Cut off extension. 
    977                 lCmdItem.length = lCmdItem.length - vLibExtension.length - 1; 
     884                lCmdItem.length = lCmdItem.length - opts.LibExtension.length - 1; 
    978885                lLibraryFiles ~= lCmdItem; 
    979886            } 
     
    995902            lCommandLine = GatherCompilerArgs(lLinking) ~ lSourcesToCompile; 
    996903 
    997             if (vUseResponseFile == True) 
     904            if (opts.UseResponseFile == True) 
    998905            { 
    999906                lDResponseFileName = util.pathex.ReplaceExtension(lTargetName, "rsp"); 
     
    1002909                    lDResponseFileName = vTemporaryPath ~ std.path.getBaseName(lDResponseFileName); 
    1003910                } 
    1004                 lDResponseFileName = util.pathex.AbbreviateFileName(lDResponseFileName); 
     911                lDResponseFileName = source.ReducePathName(lDResponseFileName); 
    1005912                util.fileex.CreateTextFile(lDResponseFileName,lCommandLine); 
    1006                 lCommand = vCompileOnly ~ " @" ~ lDResponseFileName
     913                lCommand = opts.CompileOnly ~ " " ~ util.str.enquote("@" ~ lDResponseFileName)
    1007914            } 
    1008915            else 
    1009916            {   // using commandline; may run into limits 
    1010917                lCommandLine=std.string.replace(lCommandLine, "\n", " "); 
    1011                 lCommand = vCompileOnly ~ " " ~ lCommandLine; 
     918                lCommand = opts.CompileOnly ~ " " ~ lCommandLine; 
    1012919            } 
    1013920 
    1014921            version(BuildVerbose) 
    1015922            { 
    1016                 if (vVerbose == True) 
     923                if (opts.Verbose == True) 
    1017924                    std.stdio.writefln("Compiling with ..........\n%s\n", lCommandLine); 
    1018925            } 
    1019926 
    1020927            // Run Compiler to compile the source files that need it. 
    1021             lRunResult = util.fileex.RunCommand(vCompilerPath ~ vCompilerExe, lCommand); 
     928            lRunResult = util.fileex.RunCommand(opts.CompilerPath ~ opts.CompilerExe, lCommand, &RunCallBack); 
    1022929            if (lRunResult != 0) 
    1023930                vExecuteProgram = False; 
     
    1034941            if (vResourceFileTypes.length == 0) 
    1035942            { 
    1036                 if (vUDResTypes.length == 0) 
    1037                 { 
    1038                     vUDResTypes ~= "res"; 
    1039                 } 
    1040                 foreach( string lResType; vUDResTypes) 
     943                foreach( string lResType; opts.UDResTypes) 
    1041944                { 
    1042945                    vResourceFileTypes[lResType] = true; 
     
    1044947            } 
    1045948 
    1046             // Build the command line for the linker. 
    1047             lCommandLine = ""
     949            // Construct the command line for the linker. 
     950            lCommandLine.length = 0
    1048951            version(Windows) 
    1049952            { 
     
    1053956                    if (util.str.begins(lCompileArg, "-L") == True) 
    1054957                    { 
    1055                         lLinkerSwitches ~= lCompileArg[2..$] ~ vArgDelim; 
    1056                     } 
    1057                 } 
    1058                 foreach( string lSwitch; std.string.split(vLinkerDefs ~ lLinkerSwitches, "/")) 
     958                        lLinkerSwitches ~= lCompileArg[2..$] ~ opts.ArgDelim; 
     959                    } 
     960                } 
     961                foreach( string lSwitch; std.string.split(opts.LinkerDefs ~ lLinkerSwitches, "/")) 
    1059962                { 
    1060963                    if (lSwitch == "nomap") 
     
    1074977                    { 
    1075978                        // Only include OBJECT files. 
    1076                         if (std.path.getExt(lFile) == vObjExtension) 
     979                        if (std.path.getExt(lFile) == opts.ObjExtension) 
    1077980                        { 
    1078981                            if (lCnt > 0) 
    1079                                 lCommandLine ~= vArgFileDelim; 
    1080                             lCommandLine ~= lFile; 
     982                                lCommandLine ~= opts.ArgFileDelim; 
     983                            lCommandLine ~= source.ReducePathName( 
     984                                                 source.ExpandPathName(lFile, False)); 
    1081985                            lCnt++; 
    1082986                        } 
     
    1086990 
    1087991                // (2) Set the output file name 
    1088                 lCommandLine ~= util.str.enquote(util.pathex.AbbreviateFileName(lTargetName)) ~ "\n"; 
     992                lCommandLine ~= source.ReducePathName(lTargetName) ~ "\n"; 
    1089993 
    1090994                // (3) Set the map name 
    1091995                if (IsMapping == True) 
    1092                     lCommandLine ~= util.pathex.ReplaceExtension(lTargetName, "map"); 
     996                    lCommandLine ~= source.ReducePathName(util.pathex.ReplaceExtension(lTargetName, "map")); 
    1093997 
    1094998                lCommandLine ~= "\n"; 
     
    10961000                // (4) Gather the libraries names. 
    10971001                // Include the default libraries first. 
    1098                 lLibraryFiles = vDefaultLibs ~ lLibraryFiles; 
     1002                lLibraryFiles = opts.DefaultLibs ~ lLibraryFiles; 
    10991003                if (lLibraryFiles.length > 0) 
    11001004                { 
    11011005                    foreach( int i, string lLib; lLibraryFiles) 
    11021006                    { 
    1103                         lLib =  std.path.addExt(lLib, vLibExtension); 
     1007                        string lLibFile; 
     1008                        lLibFile =  util.pathex.EnsureExtension(lLib, opts.LibExtension); 
    11041009                        if (i > 0) 
    1105                             lCommandLine ~= vArgFileDelim; 
    1106                         lCommandLine ~= vLinkLibSwitch ~ 
    1107                                         util.str.enquote(lLib); 
     1010                            lCommandLine ~= opts.ArgFileDelim; 
     1011                        lCommandLine ~= opts.LinkLibSwitch ~ 
     1012                                        source.ReducePathName( 
     1013                                           source.ExpandPathName(lLibFile, False)); 
    11081014                    } 
    11091015                } 
     
    11111017 
    11121018                // Include the explictly named libraries. 
    1113                 if (vLibPaths.length > 1) 
    1114                 { 
    1115                     if (vLibPaths[0..1] == vConfigSep) 
    1116                         vLibPaths = vLibPaths[1..$]; 
    1117  
     1019                if (opts.LibPaths.length > 0) 
     1020                { 
    11181021                    // Include the paths to the libraries. 
    11191022                    version(BuildVerbose) 
    11201023                    { 
    1121                         if (vVerbose == True) 
    1122                             std.stdio.writefln("Setting LIB=%s", vLibPaths); 
    1123                     } 
    1124                     util.str.SetEnv("LIB",vLibPaths[1..$]); 
     1024                        if (opts.Verbose == True) 
     1025                            std.stdio.writefln("Setting LIB=%s", opts.LibPaths); 
     1026                    } 
     1027                    util.str.SetEnv("LIB",opts.LibPaths); 
    11251028                } 
    11261029 
    11271030                // (5) Set the 'def' file name 
    11281031                if (lDefName.length > 0) 
    1129                     lCommandLine ~= util.str.enquote(lDefName) ~ "\n"; 
     1032                    lCommandLine ~= source.ReducePathName(source.ExpandPathName(lDefName, False)) ~ "\n"; 
    11301033                else 
    11311034                    lCommandLine ~= "\n"; 
     
    11441047                        { 
    11451048                            if (lCnt > 0) 
    1146                                 lCommandLine ~= vArgFileDelim; 
    1147                             lCommandLine ~= lFile; 
     1049                                lCommandLine ~= opts.ArgFileDelim; 
     1050                            lCommandLine ~= source.ReducePathName( 
     1051                                               source.ExpandPathName(lFile, False)); 
    11481052                            lCnt++; 
    11491053                        } 
     
    11531057 
    11541058                // (7) Gather then switches 
    1155                 lLinkerSwitches = util.str.strip(vLinkerDefs ~ lLinkerSwitches); 
     1059                lLinkerSwitches = util.str.strip(opts.LinkerDefs ~ lLinkerSwitches); 
    11561060            } 
    11571061 
     
    11631067                    if (util.str.begins(lCompileArg, "-L") == True) 
    11641068                    { 
    1165                         lLinkerSwitches ~= lCompileArg[2..$] ~ vArgDelim; 
     1069                        lLinkerSwitches ~= lCompileArg[2..$] ~ opts.ArgDelim; 
    11661070                    } 
    11671071                } 
     
    11741078 
    11751079                // (2) Set the output file name 
    1176                 lCommandLine ~= vOutFileSwitch ~ util.str.enquote(util.pathex.AbbreviateFileName(lTargetName)) ~ "\n"; 
     1080                lCommandLine ~= opts.OutFileSwitch ~ util.str.enquote(source.ReducePathName(lTargetName)) ~ "\n"; 
    11771081 
    11781082                // (3) Set the map name 
    11791083                if (IsMapping == True) 
    1180                     lLinkerSwitches ~= vMapSwitch ~ vArgDelim; 
     1084                    lLinkerSwitches ~= opts.MapSwitch ~ opts.ArgDelim; 
    11811085 
    11821086                // (4) Gather the libraries names. 
    11831087                // Include the default libraries first. 
    1184                 foreach( string lLib; vDefaultLibs ~ lLibraryFiles) 
    1185                 { 
    1186                     lCommandLine ~= vLinkLibSwitch ~ util.str.enquote(lLib) ~ "\n"; 
    1187                 } 
    1188  
    1189                 if (vLibPaths.length > 1) 
    1190                 { 
    1191                     if (vLibPaths[0..1] == vConfigSep) 
    1192                         vLibPaths = vLibPaths[1..$]; 
    1193  
     1088                foreach( string lLib; opts.DefaultLibs ~ lLibraryFiles) 
     1089                { 
     1090                    lCommandLine ~= opts.LinkLibSwitch ~ 
     1091                                    util.str.enquote(lLib) ~ 
     1092                                    "\n"; 
     1093                } 
     1094 
     1095                if (opts.LibPaths.length > 0) 
     1096                { 
    11941097                    // Include the paths to the libraries. 
    11951098                    version(BuildVerbose) 
    11961099                    { 
    1197                         if (vVerbose == True) 
    1198                             std.stdio.writefln("Setting LIB=%s", vLibPaths); 
     1100                        if (opts.Verbose == True) 
     1101                            std.stdio.writefln("Using library paths=%s", opts.LibPaths); 
    11991102                    } 
    12001103 
    12011104                    string[] lLibPaths; 
    1202                     lLibPaths = std.string.split(vLibPaths, vConfigSep); 
     1105                    lLibPaths = std.string.split(opts.LibPaths, opts.ConfigSep); 
    12031106                    foreach(string lLib; lLibPaths) 
    12041107                    { 
    12051108                        if (lLib.length > 0) 
    1206                             lCommandLine ~= vLibPathSwitch ~ util.str.enquote(lLib) ~ "\n"; 
     1109                            lCommandLine ~= opts.LibPathSwitch ~ 
     1110                                            util.str.enquote(lLib) ~ 
     1111                                            "\n"; 
    12071112                    } 
    12081113                } 
    12091114 
    12101115                // (5) Gather then switches 
    1211                 lLinkerSwitches = util.str.strip(vLinkerDefs ~ lLinkerSwitches); 
    1212             } 
    1213  
    1214             if (vUseResponseFile == True) 
     1116                lLinkerSwitches = util.str.strip(opts.LinkerDefs ~ lLinkerSwitches); 
     1117            } 
     1118 
     1119            if (opts.UseResponseFile == True) 
    12151120            { 
    12161121                lLinkResponseFileName = util.pathex.ReplaceExtension(lTargetName, "ksp"); 
     
    12191124                    lLinkResponseFileName = vTemporaryPath ~ std.path.getBaseName(lLinkResponseFileName); 
    12201125                } 
    1221                 lLinkResponseFileName = util.pathex.AbbreviateFileName(lLinkResponseFileName); 
    1222  
    1223                 if (vPostSwitches) 
    1224                 { 
    1225                     if (vAppendLinkSwitches) 
     1126                lLinkResponseFileName = source.ReducePathName(lLinkResponseFileName); 
     1127 
     1128                if (opts.PostSwitches) 
     1129                { 
     1130                    if (opts.AppendLinkSwitches) 
    12261131                    { 
    12271132                        lCommandLine = util.str.stripr(lCommandLine); 
     
    12321137                    lCommandLine = lLinkerSwitches ~ "\n" ~ lCommandLine; 
    12331138                util.fileex.CreateTextFile(lLinkResponseFileName,lCommandLine); 
    1234                 lCommand = "@" ~ lLinkResponseFileName; 
     1139                lCommand = util.str.enquote("@" ~ 
     1140                             source.ReducePathName( 
     1141                                 source.ExpandPathName(lLinkResponseFileName, False))); 
    12351142            } 
    12361143            else 
    12371144            {   // using commandline; may run into limits 
    1238                 if (vPostSwitches) 
     1145                if (opts.PostSwitches) 
    12391146                    lCommandLine ~= lLinkerSwitches ~ "\n"; 
    12401147                else 
    12411148                    lCommandLine = lLinkerSwitches ~ "\n" ~ lCommandLine; 
    12421149 
    1243                 lCommandLine=std.string.replace(lCommandLine, "\n", vArgDelim); 
     1150                lCommandLine=std.string.replace(lCommandLine, "\n", opts.ArgDelim); 
    12441151                // Locate switches and change delim from a comma to a blank, 
    12451152                // then remove any trailing comma too. 
     
    12481155                    int lPos = std.string.find(lCommandLine, lLinkerSwitches[0]); 
    12491156                    if (lPos > 0) 
    1250                         lCommandLine[lPos-1] = ' '
    1251                 } 
    1252  
    1253                 if (util.str.ends(lCommandLine,vArgDelim) == True) 
    1254                     lCommandLine.length = lCommandLine.length - vArgDelim.length; 
     1157                        lCommandLine = lCommandLine[0..lPos] ~ " " ~ lCommandLine[lPos+1..$]
     1158                } 
     1159 
     1160                if (util.str.ends(lCommandLine,opts.ArgDelim) == True) 
     1161                    lCommandLine.length = lCommandLine.length - opts.ArgDelim.length; 
    12551162                lCommand = lCommandLine; 
    12561163            } 
     
    12581165            version(BuildVerbose) 
    12591166            { 
    1260                 if (vVerbose == True) 
     1167                if (opts.Verbose == True) 
    12611168                    std.stdio.writefln("Linking with ..........\n%s\n", lCommandLine); 
    12621169            } 
     
    12651172            if (vSilent == True) 
    12661173            { 
    1267                 lCommand ~= " " ~ vLinkerStdOut; 
    1268             } 
    1269  
    1270             lRunResult = util.fileex.RunCommand(vLinkerPath ~ vLinkerExe, lCommand); 
     1174                lCommand ~= " " ~ opts.LinkerStdOut; 
     1175            } 
     1176 
     1177            lRunResult = util.fileex.RunCommand(opts.LinkerPath ~ opts.LinkerExe, lCommand, &RunCallBack); 
    12711178            if (lRunResult != 0) 
    12721179                vExecuteProgram = False; 
     
    12841191    if ( (source.Source.WasMainDLL)  && (lRunResult == 0) ) 
    12851192    { 
    1286         string lTargetFileName; 
    1287         string lImpLibPath; 
    1288         string lImpLibArgs; 
     1193        string   lTargetFileName; 
     1194        string   lImpLibPath; 
     1195        string   lImpLibArgs; 
    12891196        ulong[] lImpManf; 
    12901197 
    12911198        vExecuteProgram = False; 
    12921199 
    1293         lImpLibPath = util.pathex.LocateFile("implib.exe", util.str.GetEnv(vPathId)); 
     1200        lImpLibPath = util.pathex.LocateFile("implib.exe", util.str.GetEnv(opts.PathId)); 
    12941201        if (util.file2.FileExists(lImpLibPath)) 
    12951202        { 
     
    13021209            lTargetFileName = std.path.getBaseName(lTargetName); 
    13031210            lRunResult = util.fileex.RunCommand(lImpLibPath, lImpLibArgs ~ 
    1304                                        " " ~ std.path.addExt(lTargetFileName, "lib") ~ 
    1305                                        " " ~ std.path.addExt(lTargetFileName, "dll") ); 
     1211                                       " " ~ util.pathex.ReplaceExtension(lTargetFileName, "lib") ~ 
     1212                                       " " ~ util.pathex.ReplaceExtension(lTargetFileName, "dll"), &RunCallBack ); 
    13061213        } 
    13071214    } 
     
    13121219        vExecuteProgram = False; 
    13131220 
    1314         lOutText = vLibrarianOpts ~ std.path.linesep; 
     1221        lOutText = opts.LibrarianOpts ~ std.path.linesep; 
    13151222        lOutText ~= lTargetName ~  std.path.linesep;  // Create a new library 
    13161223 
     
    13181225        { 
    13191226            string lFileDir; 
     1227            string lFullFileName; 
     1228 
    13201229 
    13211230            lFileDir = std.path.getDirName(lFileName); 
     1231            lFullFileName = lFileName; 
    13221232            if ((vAllObjects == True) || lFileDir == "" || lFileDir == lTargetDir) 
    13231233            { 
    1324                 if (lFileName.length > 1 + vSrcExtension.length) 
    1325                 { 
    1326                     if (lFileName[$-vSrcExtension.length .. $] == vSrcExtension) 
    1327                     { 
    1328                         lFileName = lFileName[0..$-vSrcExtension.length] ~ vObjExtension; 
     1234                if (lFullFileName.length > 1 + opts.SrcExtension.length) 
     1235                { 
     1236                    if (lFullFileName[$-opts.SrcExtension.length .. $] == opts.SrcExtension) 
     1237                    { 
     1238                        lFullFileName = lFullFileName[0..$-opts.SrcExtension.length] ~ opts.ObjExtension; 
    13291239                    } 
    13301240                } 
    13311241                lFileCount++; 
    1332                 lOutText ~= lFileName ~ std.path.linesep; 
     1242                lOutText ~= lFullFileName ~ std.path.linesep; 
    13331243            } 
    13341244        } 
     
    13361246        if (lFileCount > 0) 
    13371247        { 
    1338             if (vUseResponseFile == True) { 
     1248            if (opts.UseResponseFile == True) { 
    13391249                lLResponseFileName = util.pathex.ReplaceExtension(lTargetName, "lsp"); 
    13401250                if (vTemporaryPath.length != 0) 
     
    13521262            version(BuildVerbose) 
    13531263            { 
    1354                 if (vVerbose == True) 
     1264                if (opts.Verbose == True) 
    13551265                    std.stdio.writefln("Librarian with ..........\n%s\n", lOutText); 
    13561266            } 
    13571267 
    1358             lRunResult = util.fileex.RunCommand(vLibrarianPath ~ vLibrarian, lCommand); 
     1268            lRunResult = util.fileex.RunCommand(opts.LibrarianPath ~ opts.Librarian, lCommand, &RunCallBack); 
    13591269        } 
    13601270    } 
     
    13671277        version(BuildVerbose) 
    13681278        { 
    1369             if (vVerbose == True) 
     1279            if (opts.Verbose == True) 
    13701280                std.stdio.writefln("Cleaning up ..."); 
    13711281        } 
     
    13841294            } 
    13851295        ); 
    1386         // Build's own temprary files. 
     1296        // The utilities's own temprary files. 
    13871297        lHitList ~= lDResponseFileName; 
    13881298        lHitList ~= lLinkResponseFileName; 
     
    13951305        lHitList ~= util.pathex.ReplaceExtension(lTargetName, "lst"); 
    13961306 
     1307 
    13971308        foreach(string lFilename; lHitList) 
    13981309        { 
     
    14031314                    version(BuildVerbose) 
    14041315                    { 
    1405                         if (vVerbose == True) 
     1316                        if (opts.Verbose == True) 
    14061317                            std.stdio.writefln("  removing %s", lFilename); 
    14071318                    } 
     
    14131324    } 
    14141325 
    1415     if (lRunResult == 0 && (vUseFinal == True)) 
    1416     { 
    1417         foreach(string lFinal; vFinalProc) 
    1418         { 
    1419             string lCommandLine; 
    1420             lCommandLine = util.str.Expand(lFinal, "Target=" ~ lTargetName ~ 
    1421                                                    ",TargetPath=" ~ std.path.getDirName(lTargetName) ~ 
    1422                                                    ",TargetBase=" ~ std.path.getBaseName(lTargetName) 
    1423                              ); 
    1424             if (lCommandLine.length > 0) 
    1425             { 
    1426                 lRunResult = util.fileex.RunCommand(lCommandLine); 
    1427                 if (lRunResult != 0) 
    1428                     break; 
    1429             } 
    1430         } 
    1431     } 
     1326    if (vUseFinal == True) 
     1327    { 
     1328        if (lRunResult == 0) 
     1329        { 
     1330            foreach(string lFinal; vFinalProc) 
     1331            { 
     1332                string lCommandLine; 
     1333                lCommandLine = util.str.Expand(lFinal, "Target=" ~ util.str.enquote(lTargetName) ~ 
     1334                                                       ",TargetPath=" ~ util.str.enquote(std.path.getDirName(lTargetName)) ~ 
     1335                                                       ",TargetBase=" ~ std.path.getBaseName(lTargetName) 
     1336                                 ); 
     1337                if (lCommandLine.length > 0) 
     1338                { 
     1339                    lRunResult = util.fileex.RunCommand(lCommandLine, &RunCallBack); 
     1340                    if (lRunResult != 0) 
     1341                        break; 
     1342                } 
     1343            } 
     1344        } 
     1345        else 
     1346        { 
     1347            foreach(string lFinal; vFailureProc) 
     1348            { 
     1349                string lCommandLine; 
     1350                lCommandLine = util.str.Expand(lFinal, "Target=" ~ util.str.enquote(lTargetName) ~ 
     1351                                                       ",TargetPath=" ~ util.str.enquote(std.path.getDirName(lTargetName)) ~ 
     1352                                                       ",TargetBase=" ~ std.path.getBaseName(lTargetName) 
     1353                                 ); 
     1354                if (lCommandLine.length > 0) 
     1355                { 
     1356                    lRunResult = util.fileex.RunCommand(lCommandLine, &RunCallBack); 
     1357                    if (lRunResult != 0) 
     1358                        break; 
     1359                } 
     1360            } 
     1361        } 
     1362    } 
     1363 
    14321364 
    14331365    return lRunResult; 
     
    14361368 
    14371369// ------------------------------------------- 
    1438 char [] GatherCompilerArgs(Bool pLinking) 
     1370string GatherCompilerArgs(Bool pLinking) 
    14391371// ------------------------------------------- 
    14401372{ 
    14411373    string lOutText; 
    14421374 
    1443     foreach(char [] lRoot; vImportRoots) 
    1444     { 
    1445         version(Posix) 
    1446             AddCompilerArg( vImportPath ~ "\"" ~ lRoot ~ "\"" ); 
    1447         version(Windows) 
    1448             AddCompilerArg( vImportPath ~ lRoot ); 
    1449     } 
    1450  
    1451     // Build command files for compilation. 
     1375    foreach(string lRoot; vImportRoots) 
     1376    { 
     1377        AddCompilerArg( opts.ImportPath ~ util.str.enquote(lRoot) ); 
     1378    } 
     1379 
     1380    // Construct command files for compilation. 
    14521381    foreach (string lCompileArg; vCompilerArgs) 
    14531382    { 
     
    14621391                    // Strip off any trailing shell escape lead-in character. 
    14631392                    if (lCompileArg[$-1] == '\\') 
    1464                         lCompileArg.length = lCompileArg.length - 1; 
    1465                     lOutText ~= std.string.format(`"%s"`, lCompileArg); 
     1393                        lOutText ~= std.string.format(`"%s"`, lCompileArg[0..$-1]); 
     1394                    else 
     1395                        lOutText ~= std.string.format(`"%s"`, lCompileArg); 
    14661396                } 
    14671397                else 
     
    14771407    if (pLinking == False) 
    14781408    { // No linking allowed. 
    1479         if (vCompileOnly.length > 0) 
    1480         { 
    1481             if (std.string.find(vCompileOnly, " ") != -1) 
    1482                 lOutText ~= std.string.format(`"%s"`,vCompileOnly); 
     1409        if (opts.CompileOnly.length > 0) 
     1410        { 
     1411            if (std.string.find(opts.CompileOnly, " ") != -1) 
     1412                lOutText ~= std.string.format(`"%s"`,opts.CompileOnly); 
    14831413            else 
    1484                 lOutText ~= vCompileOnly; 
     1414                lOutText ~= opts.CompileOnly; 
    14851415            // Terminate with a newline char. 
    14861416            lOutText ~= "\n"; 
    14871417 
    1488             AddCompilerArg( vCompileOnly ); 
     1418            AddCompilerArg( opts.CompileOnly ); 
    14891419        } 
    14901420    } 
     
    14981428// ------------------------------------------- 
    14991429{ 
    1500     return vModulesToIgnore; 
     1430    return opts.ModulesToIgnore; 
    15011431} 
    15021432 
     
    15061436// ------------------------------------------- 
    15071437{ 
    1508     if (pPath.length == 0) 
    1509         return; 
    1510     if ((pPath in vLinkFiles) is null) 
    1511         vLinkFiles[pPath] = true; 
     1438    static bool [string] lLinkHash; 
     1439    string lFullName; 
     1440    string lSearchName; 
     1441 
     1442    if(pPath.length == 0) 
     1443        return pPath; 
     1444 
     1445    lFullName = source.ExpandPathName(pPath, False /* Never a directory */ ); 
     1446    version(Windows) lSearchName = std.string.tolower(lFullName); 
     1447    version(Posix)   lSearchName = lFullName; 
     1448    if( !(lSearchName in lLinkHash) ) 
     1449    { 
     1450        vLinkFiles ~= lFullName; 
     1451        lLinkHash[lSearchName] = true; 
     1452    } 
     1453 
    15121454} 
    15131455 
     
    15271469            if (vPragmaTargetName != pPath) 
    15281470            { 
    1529                 if (vVerbose == True) 
     1471                if (opts.Verbose == True) 
    15301472                    std.stdio.writefln("Multiple pragma(target,...) detected. '%s' will be used and '%s' rejected.", 
    15311473                                    vPragmaTargetName, pPath ); 
     
    15601502    } 
    15611503    else { 
    1562         vBuildDef ~= pText; 
     1504        vBuildDef ~= pText;  
     1505         
    15631506        lElementIdx[ lLowerText ] = vBuildDef.length-1; 
    15641507    } 
     
    15771520        { 
    15781521            if (pArg[0..3] == `+v+`) 
    1579                 pArg = vVersionSwitch ~ "=" ~ pArg[3..$]; 
     1522                pArg = opts.VersionSwitch ~ "=" ~ pArg[3..$]; 
    15801523        } 
    15811524 
     
    16051548        return pRootName; 
    16061549 
    1607     lFullName = util.pathex.CanonicalPath(pRootName); 
     1550    lFullName = source.ExpandPathName(pRootName, True /* Always a path */ ); 
    16081551    version(Windows) lSearchName = std.string.tolower(lFullName); 
    16091552    version(Posix)   lSearchName = lFullName; 
     
    16361579    string[] lRoots; 
    16371580    string[] lArgs; 
    1638     int      lArg; 
    1639     bool     lInArg; 
    1640     char     lQuote; 
    1641  
    1642     lInArg = false; 
    1643     lArg = -1; 
    1644     lQuote = 0; 
    1645     foreach (char lArgChar; pText) 
    1646     { 
    1647         if ( (lArgChar == '"') || (lArgChar == '\'') ) 
    1648         { 
    1649             if (lQuote == lArgChar) 
    1650             { 
    1651                 lQuote = 0; 
    1652                 continue; 
    1653             } 
    1654  
    1655             if (lQuote == 0) 
    1656             { 
    1657                 lQuote = lArgChar; 
    1658                 continue; 
    1659             } 
    1660         } 
    1661  
    1662         if (lArgChar == ' ') 
    1663         { 
    1664             if (lQuote == 0) 
    1665             { 
    1666                 lInArg = false; 
    1667                 continue; 
    1668             } 
    1669         } 
    1670  
    1671         if (lInArg == false) 
    1672         { 
    1673             lArg++; 
    1674             lArgs.length = lArg+1; 
    1675             lInArg = true; 
    1676         } 
    1677         lArgs[lArg] ~= lArgChar; 
    1678  
    1679     } 
     1581 
     1582    lArgs = util.str.substrings(pText); 
    16801583 
    16811584    foreach(string lSwitch; lArgs) 
    16821585    { 
    1683         if ((lSwitch.length > 0) && (lSwitch[0] == '-')) 
    1684         { 
    1685             if (vDelayedValue != null) 
    1686             { 
    1687                 // Used when an switch needs the subsequent arg to 
    1688                 // be its value. 
    1689                 *vDelayedValue = lSwitch; 
    1690                 vDelayedValue = null; 
    1691                 vReceivedArgs[$-1].ArgText ~= " " ~ lSwitch; 
    1692                 continue; 
    1693             } 
    1694  
    1695             vReceivedArgs.length = vReceivedArgs.length + 1; 
    1696             vReceivedArgs[$-1].ArgText = lSwitch.dup; 
    1697             vReceivedArgs[$-1].CompilerArg = False; 
    1698             vReceivedArgs[$-1].DFlag = True; 
    1699  
    1700             if (lSwitch[1] == 'I') 
    1701             { 
    1702                 lRoots = std.string.split(lSwitch[2..length], vConfigSep); 
    1703                 foreach(string lRoot; lRoots) 
    1704                 { 
    1705                     lRootName = AddRoot(lRoot); 
    1706                     version(BuildVerbose) 
    1707                     { 
    1708                         if(vVerbose == True && lRootName.length > 0) 
    1709                                 std.stdio.writefln(" added root from config file %s", lRootName); 
    1710                     } 
    1711                 } 
    1712             } 
    1713             else 
    1714             { 
    1715                 version(DigitalMars) 
    1716                 { 
    1717                     if (util.str.IsLike(lSwitch,  (vOutFileSwitch ~ "*")) == True) 
    1718                     { 
    1719                         // Target name (eg. -oftestapp) 
    1720                         vCommandTargetName = lSwitch[vOutFileSwitch.length .. $]; 
    1721                         continue; 
    1722                     } 
    1723                 } 
    1724  
    1725                 version(GNU) 
    1726                 { 
    1727                     if (lSwitch == vOutFileSwitch) 
    1728                     { 
    1729                         // Target name (eg. -o testapp) 
    1730                         vDelayedValue = &vCommandTargetName; 
    1731                         continue; 
    1732                     } 
    1733                 } 
    1734  
    1735                 if (util.str.IsLike(lSwitch,  vOutputPath ~ "*") == True) 
    1736                 { 
    1737                     string lbRoot; 
    1738  
    1739                     vTemporaryPath = lSwitch[vOutputPath.length .. $]; 
    1740  
    1741                     if (vTemporaryPath.length == 0) 
    1742                     { 
    1743                         vTemporaryPath = std.path.curdir; 
    1744                     } 
    1745                     if (util.str.ends(vTemporaryPath, std.path.sep) == False) 
    1746                         vTemporaryPath ~= std.path.sep; 
    1747  
    1748                     vTemporaryPath = AddRoot(vTemporaryPath); 
    1749                     // The path was added to the list of import roots. 
    1750                     version(BuildVerbose) 
    1751                     { 
    1752                         if(vVerbose == True) 
    1753                             std.stdio.writefln("Added root from config file Object Write Path = %s",vTemporaryPath); 
    1754                     } 
    1755                     util.pathex.MakePath(vTemporaryPath); 
    1756  
    1757                     // This one actually *is* passed thru. 
    1758                     version(DigitalMars) 
    1759                     { 
    1760                         // Ensure we don't have both -op and -od when using dmd. 
    1761                         RemoveRecdArg("-op"); 
    1762                     } 
    1763                 } 
    1764                 vReceivedArgs[$-1].CompilerArg = True; 
    1765             } 
    1766         } 
     1586        GatherOneArg( lSwitch, vCombinedArgs ); 
    17671587    } 
    17681588} 
    17691589 
    17701590// ------------------------------------------- 
    1771 void ReadEnviron() 
     1591void GetEnvironSwitches() 
    17721592// ------------------------------------------- 
    17731593{ 
     
    17801600        version(BuildVerbose) 
    17811601        { 
    1782             if (vVerbose == True) 
     1602            if (opts.Verbose == True) 
    17831603                std.stdio.writefln("Analyzing environment symbol DFLAGS=%s", lSymValue); 
    17841604        } 
     
    17921612// ------------------------------------------- 
    17931613{ 
     1614    string[] lPotentialPaths; 
    17941615    string   lConfigPath; 
    17951616    string[] lTextLines; 
    17961617    int      lPos; 
    17971618 
    1798     if (vConfigFile.length == 0) 
     1619    if (opts.ConfigFile.length == 0) 
    17991620    { 
    18001621        // There is no configuration file to process 
     
    18021623    } 
    18031624 
    1804     if (vOverrideConfigPath.length > 0) 
    1805         lConfigPath = vOverrideConfigPath ~ vConfigFile ; 
     1625 
     1626    // Current directory. 
     1627    lPotentialPaths ~= "." ~ std.path.sep; 
     1628    // Home directory 
     1629    lPotentialPaths ~= util.str.GetEnv(opts.HomePathId); 
     1630 
     1631    version(Windows) 
     1632    { 
     1633        string lTemp; 
     1634        lTemp = util.str.GetEnv("HOMEDRIVE"); 
     1635        if (lTemp.length > 0) 
     1636        { 
     1637            lPotentialPaths ~= lTemp ~ util.str.GetEnv("HOMEPATH"); 
     1638        } 
     1639    } 
     1640 
     1641    if (opts.OverrideConfigPath.length > 0) 
     1642        lPotentialPaths ~= opts.OverrideConfigPath; 
     1643 
     1644    // Where the compiler is. 
     1645    lPotentialPaths ~= opts.CompilerPath; 
     1646 
     1647    // the etc paths. 
     1648    if (opts.EtcPath.length > 0) 
     1649        lPotentialPaths ~= opts.EtcPath; 
     1650 
     1651    foreach( int lCnt, string lOnePath; lPotentialPaths) 
     1652    { 
     1653        string lPath; 
     1654        lPath = lOnePath; 
     1655        if (lPath.length > 0) 
     1656        { 
     1657            if (util.str.ends(lPath, std.path.sep) is False) 
     1658                lPath ~= std.path.sep; 
     1659            if (util.file2.FileExists(lPath ~ opts.ConfigFile) == true) 
     1660            { 
     1661                opts.ConfigPath = lPath; 
     1662                util.str.SetEnv("@P", std.path.getDirName(opts.ConfigPath)); 
     1663                break; 
     1664            } 
     1665        } 
     1666        if (lCnt+1 == lPotentialPaths.length) 
     1667        { 
     1668            // Scan all paths for config file but couldn't find one. 
     1669            throw new BuildException( std.string.format("Unable to find Config File '%s' in \n%s", 
     1670                     opts.ConfigFile, lPotentialPaths)); 
     1671        } 
     1672    } 
     1673 
     1674    if (opts.OverrideConfigPath.length > 0) 
     1675        lConfigPath = opts.OverrideConfigPath ~ opts.ConfigFile ; 
    18061676    else 
    1807         lConfigPath = vConfigPath ~ vConfigFile ; 
     1677        lConfigPath = opts.ConfigPath ~ opts.ConfigFile ; 
    18081678    version(BuildVerbose) 
    18091679    { 
    1810         if (vVerbose == True) 
     1680        if (opts.Verbose == True) 
    18111681            std.stdio.writefln("Reading from config: %s", lConfigPath); 
    18121682    } 
     
    18161686    foreach(int i, string lLine; lTextLines) 
    18171687    { 
     1688        string lText; 
     1689 
    18181690        // Strip off trailing whitespace. 
    1819         lLine = util.str.stripr(lLine); 
     1691        lText = util.str.stripr(lLine); 
    18201692 
    18211693        // Replace any environment symbols with their value. 
    18221694        version(BuildVerbose) 
    18231695        { 
    1824             if (vVerbose == True) 
    1825                 std.stdio.writefln(" Line %d: %s", i+1, lLine); 
    1826         } 
    1827  
    1828         lLine = util.str.ExpandEnvVar(lLine); 
     1696            if (opts.Verbose == True) 
     1697                std.stdio.writefln(" Line %d: %s", i+1, lText); 
     1698        } 
     1699 
     1700        lText = util.str.ExpandEnvVar(lText); 
    18291701 
    18301702        // Examine DFLAGS 
    1831         lPos = std.string.find(lLine, "DFLAGS="); 
     1703        lPos = std.string.find(lText, "DFLAGS="); 
    18321704        if(lPos == 0) 
    18331705        { 
    1834             Process_DFLAGS(lLine[lPos+7..length]); 
     1706            Process_DFLAGS(lText[lPos+7..length]); 
    18351707        } // end of DFLAGS processing. 
    18361708 
    18371709        // Examine LIB 
    1838         lPos = std.string.find(lLine, "LIB="); 
     1710        lPos = std.string.find(lText, "LIB="); 
    18391711        if(lPos == 0) 
    18401712        { 
    18411713            string[] lPaths; 
    1842             lLine = lLine[lPos+4 .. length]; 
     1714            lText = lText[lPos+4 .. length]; 
    18431715            lPaths.length = 1; 
    1844             foreach(char lChar; lLine
     1716            foreach(char lChar; lText
    18451717            { 
    18461718                if (lChar == '"') {} 
     
    18621734                if (lPath.length > 0) 
    18631735                { 
    1864                     if (lPath[0] == '"' && lPath[length-1] == '"') { 
    1865                         lPath = lPath[1..length-1]; 
    1866                     } 
    1867                     vLibPaths ~= vConfigSep ~ `"` ~ util.pathex.CanonicalPath(lPath) ~ `"`; 
    1868                 } 
    1869             } 
     1736                    if (opts.LibPaths.length > 0) 
     1737                        opts.LibPaths ~= opts.ConfigSep; 
     1738 
     1739                    // Strip off any enclosing quotation marks. 
     1740                    opts.LibPaths ~= util.str.enquote(source.ExpandPathName( 
     1741                            (lPath[0] == '"' && lPath[$-1] == '"') ? lPath[1..$-1] : lPath, 
     1742                            True)); 
     1743                } 
     1744            } 
     1745 
    18701746            version(BuildVerbose) 
    18711747            { 
    1872                 if(vVerbose == True) 
    1873                     std.stdio.writefln(" use %s",vLibPaths); 
     1748                if(opts.Verbose == True) 
     1749                    std.stdio.writefln(" use library paths %s",opts.LibPaths); 
    18741750            } 
    18751751            continue; 
     
    18801756        if(lPos == 0) 
    18811757        { 
    1882             SetFileLocation(lLine[8..$], vLinkerPath, vLinkerExe, "linker"); 
     1758            SetFileLocation(lLine[8..$], opts.LinkerPath, opts.LinkerExe, "linker"); 
    18831759            continue; 
    18841760        } 
     
    18861762        lPos = std.string.find(lLine, "LIBCMD="); 
    18871763        if(lPos == 0) { 
    1888             SetFileLocation(lLine[7..$], vLibrarianPath, vLibrarian, "librarian"); 
     1764            SetFileLocation(lLine[7..$], opts.LibrarianPath, opts.Librarian, "librarian"); 
    18891765            continue; 
    18901766        } 
     
    18921768    } 
    18931769 
    1894     if (vLinkerPath.length == 0) 
    1895         SetFileLocation(vLinkerExe.dup, vLinkerPath, vLinkerExe, "linker"); 
    1896  
    1897     if (vLibrarianPath.length == 0) 
    1898         SetFileLocation(vLibrarian.dup, vLibrarianPath, vLibrarian, "librarian"); 
     1770    if (opts.LinkerPath.length == 0) 
     1771        SetFileLocation(opts.LinkerExe, opts.LinkerPath, opts.LinkerExe, "linker"); 
     1772 
     1773    if (opts.LibrarianPath.length == 0) 
     1774        SetFileLocation(opts.Librarian, opts.LibrarianPath, opts.Librarian, "librarian"); 
    18991775} 
    19001776 
     
    19051781    int lPos; 
    19061782 
    1907     lCmdValue = pCmdValue.dup
     1783    lCmdValue = util.str.ExpandEnvVar(pCmdValue)
    19081784 
    19091785    // Strip out any quotes 
     
    19131789    } 
    19141790 
    1915     if (vExeExtension.length > 0) 
     1791    if (opts.ExeExtension.length > 0) 
    19161792    { 
    19171793        if (std.path.getExt(lCmdValue).length == 0) 
    1918             lCmdValue ~= "." ~ vExeExtension; 
     1794            lCmdValue ~= "." ~ opts.ExeExtension; 
    19191795    } 
    19201796 
    19211797    if (util.pathex.IsRelativePath(lCmdValue) == True) 
    19221798    { 
    1923         pFilePath = util.pathex.FindFileInPathList(vPathId,lCmdValue); 
     1799        pFilePath = util.pathex.FindFileInPathList(opts.PathId,lCmdValue); 
    19241800        if (util.str.ends(pFilePath, std.path.sep) == False) 
    19251801            pFilePath ~= std.path.sep; 
    19261802 
    1927         pFilePath = util.pathex.CanonicalPath(pFilePath ~ lCmdValue, false); 
     1803        pFilePath = source.ExpandPathName(pFilePath ~ lCmdValue, False); 
    19281804    } 
    19291805    else 
    19301806    { 
    1931         pFilePath = util.pathex.CanonicalPath(lCmdValue, false); 
    1932     } 
    1933     pFileExe = std.path.getBaseName(pFilePath).dup
     1807        pFilePath = source.ExpandPathName(lCmdValue, False); 
     1808    } 
     1809    pFileExe = std.path.getBaseName(pFilePath)
    19341810    pFilePath = std.path.getDirName(pFilePath) ~ std.path.sep; 
    19351811 
    19361812    version(BuildVerbose) 
    19371813    { 
    1938         if(vVerbose == True) 
     1814        if(opts.Verbose == True) 
    19391815        { 
    19401816            std.stdio.writefln(" %s path '%s'",pType, pFilePath); 
     
    19461822// Display each entry in the supplied list. 
    19471823// ------------------------------------------- 
    1948 void DisplayItems(string[] pList, string pTitle = "") 
     1824void DisplayItems(string[] pList, in string pTitle = "") 
    19491825// ------------------------------------------- 
    19501826{ 
     
    19601836 
    19611837// ------------------------------------------- 
    1962 void DisplayItems(source.ExternRef[] pList, string pTitle = "") 
     1838void DisplayItems(source.ExternRef[] pList, in string pTitle = "") 
    19631839// ------------------------------------------- 
    19641840{ 
     
    20041880string GetAppPath() 
    20051881{ 
    2006     return vAppPath.dup
     1882    return vMyPath
    20071883} 
    20081884 
     
    20271903 
    20281904    lFileExtList ~= std.file.getExt(pFileName); 
    2029     if (lFileExtList[0] == vSrcExtension) 
    2030     { 
    2031         lFileExtList ~= vSrcExtension; 
    2032         lFileExtList[0] = vSrcDInterfaceExt; 
     1905    if (lFileExtList[0] == opts.SrcExtension) 
     1906    { 
     1907        lFileExtList ~= opts.SrcExtension; 
     1908        lFileExtList[0] = opts.SrcDInterfaceExt; 
    20331909    } 
    20341910    lFileBase = std.path.getName(pFileName); 
     
    20441920                lPossiblePath = ( lNextRoot ~ lTestFileName ); 
    20451921                if(util.file2.FileExists(lPossiblePath)) { 
    2046                     return util.pathex.AbbreviateFileName(lPossiblePath); 
     1922                    return source.ReducePathName(lPossiblePath); 
    20471923                } 
    20481924            } 
     
    20521928 
    20531929        // Look for file in current folder first. 
    2054         lLocalPath = util.pathex.CanonicalPath(lTestFileName, false); 
     1930        lLocalPath = source.ExpandPathName(lTestFileName, False); 
    20551931        if(util.file2.FileExists(lLocalPath)) 
    20561932        { 
    2057             return util.pathex.AbbreviateFileName(lLocalPath); 
     1933            return source.ReducePathName(lLocalPath); 
    20581934        } 
    20591935 
     
    20641940            if(util.file2.FileExists(lPossiblePath)) 
    20651941            { 
    2066                 return util.pathex.AbbreviateFileName(lPossiblePath); 
    2067             } 
    2068         } 
    2069  
    2070     } 
    2071     return util.pathex.AbbreviateFileName(lLocalPath); 
     1942                return source.ReducePathName(lPossiblePath); 
     1943            } 
     1944        } 
     1945 
     1946    } 
     1947    return source.ReducePathName(lLocalPath); 
    20721948} 
    20731949 
     
    20811957            if (util.str.begins(vReceivedArgs[i].ArgText, pArg[0..$-1]) == True) 
    20821958            { 
    2083                 vReceivedArgs[i].ArgText = ""
     1959                vReceivedArgs[i].ArgText.length = 0
    20841960                vReceivedArgs[i].CompilerArg = False; 
    20851961            } 
     
    20871963        else if (vReceivedArgs[i].ArgText == pArg) 
    20881964        { 
    2089             vReceivedArgs[i].ArgText = ""
     1965            vReceivedArgs[i].ArgText.length = 0
    20901966            vReceivedArgs[i].CompilerArg = False; 
    20911967        } 
     
    21111987                    if (util.str.begins(pArgGroup[i], lArg[0..$-1]) == True) 
    21121988                    { 
    2113                         pArgGroup[i] = ""
     1989                        pArgGroup[i].length = 0
    21141990                        break; 
    21151991                    } 
     
    21171993                else if (pArgGroup[i] == lArg) 
    21181994                { 
    2119                     pArgGroup[i] = ""
     1995                    pArgGroup[i].length = 0
    21201996                    break; 
    21211997                } 
    21221998            } 
    2123             pArgGroup[j] = ""
     1999            pArgGroup[j]= string.init
    21242000        } 
    21252001    } 
     
    21462022    int lBuildResult; 
    21472023    string lCompPath; 
    2148     bool lSetPath = false; 
     2024 
     2025    version(BuildVerbose) bool lSetPath = false; 
    21492026 
    21502027    /* Set routine addresses in the Source module. This allows 
     
    21632040    source.AddCompilerArg   = &AddCompilerArg; 
    21642041    source.GetAppPath       = &GetAppPath; 
    2165     source.vPathId          = vPathId; 
    2166     util.fileex.vPathId     = vPathId; 
    2167     util.fileex.vExeExtension = vExeExtension; 
    21682042 
    21692043    // Strip off application's path from arglist. 
    2170     vAppPath = pArgs[0]; 
    2171     vAppName = std.path.getBaseName(vAppPath); 
    2172     version (Windows) 
    2173     { 
    2174         int DotPos; 
    2175         DotPos = std.string.rfind(vAppName, '.'); 
    2176         if (DotPos != -1) 
    2177         { 
    2178             vAppName.length = DotPos; 
    2179         } 
    2180     } 
    2181     util.str.SetEnv("@S", std.path.getDirName(vAppPath)); 
     2044    vMyPath = pArgs[0]; 
     2045    vMyName = std.path.getBaseName(vMyPath); 
     2046    vMyDir  = std.path.getDirName(vMyPath); 
     2047    util.str.SetEnv("@S", vMyDir); 
    21822048 
    21832049    pArgs=pArgs[1..pArgs.length]; 
    2184     if (pArgs.length == 0) { 
    2185         if (util.file2.FileExists(vDefResponseFile) == false) 
     2050 
     2051    version(BuildVerbose) CheckVerbose(pArgs); 
     2052 
     2053    { 
     2054        string lTempPath = util.str.GetEnv("BCFPATH"); 
     2055        if (lTempPath.length > 0) 
     2056            opts.CFGPath = lTempPath; 
     2057    } 
     2058 
     2059    ReadBuildConfigFile(); 
     2060 
     2061    if (util.str.ends(vMyName, "." ~ opts.ExeExtension) == True) 
     2062    { 
     2063        vMyName.length = vMyName.length - opts.ExeExtension.length - 1; 
     2064    } 
     2065 
     2066    if (pArgs.length == 0) 
     2067    { 
     2068        if (util.file2.FileExists(opts.DefResponseFile) == false) 
    21862069        { 
    21872070            // No other arguments so show usage message. 
     
    21912074        else 
    21922075        { 
    2193             pArgs ~= "@" ~ vDefResponseFile; 
    2194         } 
    2195     } 
    2196  
    2197  
    2198     vCFGPath = util.str.GetEnv("BCFPATH"); 
    2199     GatherArgs( pArgs ); 
    2200     version(BuildVerbose) 
    2201     { 
    2202         source.vVerboseMode = vVerbose; 
    2203  
    2204         util.fileex.vVerbose = vVerbose; 
    2205  
    2206         if (vVerbose == True) 
    2207             std.stdio.writefln("*** build v%s (build %d)***", vAppVersion, build_bn.auto_build_number); 
    2208     } 
    2209  
    2210     ExamineArgs( vCombinedArgs ); 
    2211  
    2212     // Scan the PATH env symbol to locate the D compiler. 
    2213     if (vExeExtension.length > 0 && std.path.getExt(vCompilerExe).length == 0) 
    2214     { 
    2215         vCompilerExe = std.path.addExt(vCompilerExe, vExeExtension); 
    2216     } 
    2217     lCompPath = util.pathex.FindFileInPathList(vPathId, vCompilerExe); 
    2218     if (lCompPath.length > 0){ 
     2076            pArgs ~= "@" ~ opts.DefResponseFile; 
     2077        } 
     2078    } 
     2079 
     2080 
     2081    // --- Scan the PATH env symbol to locate the D compiler. --- 
     2082    // Ensure that the complier command has the right extention on it. 
     2083    if (opts.ExeExtension.length > 0 && std.path.getExt(opts.CompilerExe).length == 0) 
     2084    { 
     2085        opts.CompilerExe = util.pathex.ReplaceExtension(opts.CompilerExe, opts.ExeExtension); 
     2086    } 
     2087    // Scan the PATH symbol directories. 
     2088    lCompPath = util.pathex.FindFileInPathList(opts.PathId, opts.CompilerExe); 
     2089 
     2090    if (lCompPath.length > 0) 
     2091    { 
     2092        // Found it, so ensure it ends with a path separator. 
    22192093        if (lCompPath[length-1] != std.path.sep[0]) 
    22202094            lCompPath ~= std.path.sep; 
    2221         vCompilerPath = lCompPath.dup; 
    2222         util.str.SetEnv("@D", std.path.getDirName(vCompilerPath)); 
    2223     } 
    2224  
    2225     if (vCompilerPath.length == 0) 
    2226     { 
    2227         vCompilerPath = util.pathex.GetInitCurDir; 
    2228         util.str.SetEnv("@D", std.path.getDirName(vCompilerPath)); 
    2229         lSetPath = true; 
    2230     } 
    2231  
    2232     util.fileex.vTestRun = vTestRun; 
     2095        // Save it and set the special env symbol for it. 
     2096        opts.CompilerPath = lCompPath; 
     2097        util.str.SetEnv("@D", std.path.getDirName(opts.CompilerPath)); 
     2098    } 
     2099 
     2100    if (opts.CompilerPath.length == 0) 
     2101    { 
     2102        // Not found the compiler, so assume current directory. 
     2103        opts.CompilerPath = util.pathex.GetInitCurDir; 
     2104        util.str.SetEnv("@D", std.path.getDirName(opts.CompilerPath)); 
     2105        version(BuildVerbose) lSetPath = true; 
     2106    } 
     2107 
     2108    GatherArgs( pArgs ); 
     2109 
     2110 
     2111    ReadCompilerConfigFile(); 
     2112 
     2113    ExamineArgs( vCombinedArgs ); 
     2114 
    22332115    source.mCollectUses  = vCollectUses; 
    2234     source.vForceCompile = vForceCompile; 
    22352116    source.ObjWritePath  = vTemporaryPath; 
    2236     source.vExplicit     = vExplicit; 
    22372117 
    22382118    // Grab the external macro definitions unless otherwise told not to. 
    22392119    source.mMacroInput = vMacroInput; 
    22402120    if (vMacroInput == True) 
    2241         version(BuildVerbose) 
    2242         { 
    2243             ProcessMacroDefs(vVerbose); 
    2244         } else { 
    2245             ProcessMacroDefs(False); 
    2246         } 
     2121        ProcessMacroDefs(); 
    22472122 
    22482123    if( (vTargetName.length == 0) && (vCommandTargetName.length == 0) ){ 
     
    22522127    version(BuildVerbose) 
    22532128    { 
    2254         if ((vVerbose == True) || (vNames == True) ) 
     2129        if ((opts.Verbose == True) || (vNames == True) ) 
    22552130            std.stdio.writefln("Current Dir '%s'", util.pathex.GetInitCurDir()); 
    22562131    } else { 
     
    22592134    } 
    22602135 
    2261     if (lSetPath
    2262     { 
    2263         version(BuildVerbose
    2264         { 
    2265             if (vVerbose == True) 
     2136    version(BuildVerbose
     2137    { 
     2138        if (lSetPath
     2139        { 
     2140            if (opts.Verbose == True) 
    22662141                std.stdio.writefln("%s not found in PATH symbol, so assuming current directory", 
    2267                         vCompilerExe); 
    2268         } 
    2269     } 
    2270  
    2271     if (vCompilerPath[length-1] != std.path.sep[0]) 
    2272     { 
    2273         vCompilerPath ~= std.path.sep; 
    2274         util.str.SetEnv("@D", std.path.getDirName(vCompilerPath)); 
    2275     } 
    2276  
    2277  
    2278     if (vConfigFile.length > 0) 
    2279     { 
    2280         string[] lPotentialPaths; 
    2281  
    2282         lPotentialPaths ~= "." ~ std.path.sep; 
    2283         lPotentialPaths ~= util.str.GetEnv(vHomePathId); 
    2284         version(Windows) 
    2285         { 
    2286             string lTemp; 
    2287             lTemp = util.str.GetEnv("HOMEDRIVE"); 
    2288             if (lTemp.length > 0) 
    2289             { 
    2290                 lPotentialPaths ~= lTemp ~ util.str.GetEnv("HOMEPATH"); 
    2291             } 
    2292         } 
    2293         if (vOverrideConfigPath.length > 0) 
    2294             lPotentialPaths ~= vOverrideConfigPath; 
    2295         lPotentialPaths ~= vCompilerPath; 
    2296         if (vEtcPath.length > 0) 
    2297             lPotentialPaths ~= vEtcPath; 
    2298  
    2299         foreach( int lCnt, string p; lPotentialPaths) 
    2300         { 
    2301             if (p.length > 0) 
    2302             { 
    2303                 if (util.str.ends(p, std.path.sep) is False) 
    2304                     p ~= std.path.sep; 
    2305                 if (util.file2.FileExists(p ~ vConfigFile) == true) 
    2306                 { 
    2307                     vConfigPath = p.dup; 
    2308                     util.str.SetEnv("@P", std.path.getDirName(vConfigPath)); 
    2309                     break; 
    2310                 } 
    2311             } 
    2312             if (lCnt+1 == lPotentialPaths.length) 
    2313             { 
    2314                 // Scan all paths for config file but couldn't find one. 
    2315                 throw new BuildException( std.string.format("Unable to find Config File '%s' in \n%s", 
    2316                          vConfigFile, lPotentialPaths)); 
    2317             } 
    2318         } 
    2319     } 
    2320  
    2321     if (vExeExtension.length > 0) 
    2322     { 
    2323         if (std.path.getExt(vCompilerExe).length == 0) 
    2324             vCompilerExe ~= "." ~ vExeExtension; 
    2325     } 
    2326     if (util.file2.FileExists(vCompilerPath ~ vCompilerExe) == false) 
     2142                        opts.CompilerExe); 
     2143        } 
     2144    } 
     2145 
     2146    if (opts.CompilerPath[length-1] != std.path.sep[0]) 
     2147    { 
     2148        opts.CompilerPath ~= std.path.sep; 
     2149        util.str.SetEnv("@D", std.path.getDirName(opts.CompilerPath)); 
     2150    } 
     2151 
     2152 
     2153    if (opts.ExeExtension.length > 0) 
     2154    { 
     2155        if (std.path.getExt(opts.CompilerExe).length == 0) 
     2156            opts.CompilerExe ~= "." ~ opts.ExeExtension; 
     2157    } 
     2158    if (util.file2.FileExists(opts.CompilerPath ~ opts.CompilerExe) == false) 
    23272159    { 
    23282160        throw new BuildException(std.string.format("The compiler '%s' was not found.", 
    2329                 vCompilerPath ~ vCompilerExe)); 
     2161                opts.CompilerPath ~ opts.CompilerExe)); 
    23302162    } 
    23312163 
    23322164    version(BuildVerbose) 
    23332165    { 
    2334         if (vVerbose == True) 
    2335             std.stdio.writefln("Compiler installed in %s",vCompilerPath); 
     2166        if (opts.Verbose == True) 
     2167            std.stdio.writefln("Compiler installed in %s",opts.CompilerPath); 
    23362168    } 
    23372169 
    23382170    source.SetKnownVersions(); 
    23392171 
    2340     ReadEnviron(); 
    2341  
    2342     ReadCompilerConfigFile(); 
    2343  
    2344     version(Posix) 
    2345     { 
    2346         // Unless supplied by the config file, these are the default 
    2347         // libraries to use for linking. 
    2348         if (vDefaultLibs.length == 0) 
    2349         { 
    2350             vDefaultLibs ~= "c"; 
    2351             version(DigitalMars) 
    2352             { 
    2353                 vDefaultLibs ~= "phobos"; 
    2354             } 
    2355             version(GNU) 
    2356             { 
    2357                 vDefaultLibs ~= "gphobos"; 
    2358             } 
    2359             vDefaultLibs ~= "pthread"; 
    2360             vDefaultLibs ~= "m"; 
    2361         } 
    2362     } 
    2363  
    2364     // Assume phobos will be ignored unless user has specified another set. 
    2365     if (vModulesToIgnore.length == 0) 
    2366         vModulesToIgnore ~= "phobos"; 
     2172//    ReadCompilerConfigFile(); 
    23672173 
    23682174    // Rationalize the ignored modules list. 
    2369     foreach(string m; vModulesToNotice) { 
    2370         for (int i=0; i < vModulesToIgnore.length; i++) { 
    2371             if (vModulesToIgnore[i] == m) { 
     2175    foreach(string m; opts.ModulesToNotice) { 
     2176        for (int i=0; i < opts.ModulesToIgnore.length; i++) { 
     2177            if (opts.ModulesToIgnore[i] == m) { 
    23722178                // Must remove from ignored list. 
    2373                 vModulesToIgnore = vModulesToIgnore[0..i] ~ vModulesToIgnore[i+1..length]; 
     2179                opts.ModulesToIgnore = opts.ModulesToIgnore[0..i] ~ opts.ModulesToIgnore[i+1..length]; 
    23742180                i--; 
    23752181            } 
     
    23992205 
    24002206    // Process the files 
    2401     lBuildResult = Build(); 
     2207    lBuildResult = MakeItSo(); 
    24022208 
    24032209    // After processing analysis. 
    24042210    version(BuildVerbose) 
    24052211    { 
    2406         if(vVerbose == True) 
     2212        if(opts.Verbose == True) 
    24072213        { 
    24082214            std.stdio.writefln(""); 
     
    24122218            DisplayItems(source.Source.AllFiles, 
    24132219                                          "source files: ..............."); 
    2414             DisplayItems(vLinkFiles.keys, "link files: ..............."); 
     2220            DisplayItems(vLinkFiles, "link files: ..............."); 
    24152221            DisplayItems(source.Externals,"externally built files: ..............."); 
    24162222            DisplayItems(vImportRoots,    "import roots: ................."); 
    2417             DisplayItems(vModulesToIgnore,"ignored packages: ................."); 
    2418             DisplayItems(vModulesToNotice,"noticed package: ................."); 
     2223            DisplayItems(opts.ModulesToIgnore,"ignored packages: ................."); 
     2224            DisplayItems(opts.ModulesToNotice,"noticed package: ................."); 
    24192225        } 
    24202226    } 
     
    24392245                if (lModuleCount == 0) 
    24402246                { 
    2441                     lSymbolData ~= vModOutPrefix; 
     2247                    lSymbolData ~= opts.ModOutPrefix; 
    24422248                } 
    24432249                lModuleCount++; 
     
    24452251                if (lModuleCount > 1) 
    24462252                { 
    2447                     lSymbolData ~= vModOutDelim; 
    2448                 } 
    2449  
    2450                 lSymbolData ~= util.str.Expand(vModOutBody, "mod=" ~ lSource.ModuleName 
     2253                    lSymbolData ~= opts.ModOutDelim; 
     2254                } 
     2255 
     2256                lSymbolData ~= util.str.Expand(opts.ModOutBody, "mod=" ~ lSource.ModuleName 
    24512257                                                    ~ "," ~ "src=" ~ lSource.FileName 
    24522258                                               ); 
     
    24562262        if (lModuleCount != 0) 
    24572263        { 
    2458             lSymbolData ~= vModOutSuffix; 
     2264            lSymbolData ~= opts.ModOutSuffix; 
    24592265        } 
    24602266 
    24612267        if (vSymbolOutName.length == 0) 
    2462             vSymbolOutName = util.pathex.GetBaseName(vTargetName) ~ vModOutFile; 
    2463  
    2464         if (vTestRun == False) 
     2268            vSymbolOutName = util.pathex.GetBaseName(vTargetName) ~ opts.ModOutFile; 
     2269 
     2270        if (opts.TestRun == False) 
    24652271        { 
    24662272            // ensure requested path exists. 
     
    24882294            { 
    24892295                lFile ~= lLine ~ "\n"; 
    2490                 lPrevLine = lLine.dup
     2296                lPrevLine = lLine
    24912297            } 
    24922298        } 
     
    24992305            { 
    25002306                lFile ~= lLine ~ "\n"; 
    2501                 lPrevLine = lLine.dup
     2307                lPrevLine = lLine
    25022308            } 
    25032309        } 
     
    25062312            vUsesOutput = util.pathex.GetBaseName(vTargetName) ~ ".use"; 
    25072313 
    2508         if (vTestRun == False) 
     2314        if (opts.TestRun == False) 
    25092315        { 
    25102316            // ensure requested path exists. 
     
    25282334        std.stdio.writefln(""); 
    25292335 
    2530         util.fileex.RunCommand( util.pathex.CanonicalPath(vTargetExe, false), 
    2531                      std.string.strip(vRunParms)); 
     2336        util.fileex.RunCommand( source.ExpandPathName(vTargetExe, False), 
     2337                     std.string.strip(vRunParms), &RunCallBack); 
     2338 
     2339        if (vCleanDummy == True) 
     2340        { 
     2341            std.file.remove(source.ExpandPathName(vTargetExe, False)); 
     2342            std.file.remove(opts.DummyMain); 
     2343        } 
     2344 
    25322345    } 
    25332346 
     
    25372350} 
    25382351 
    2539 void ProcessResponseFile(string pArg, Bool pVerbose
     2352void ProcessResponseFile(string pArg
    25402353{ 
    25412354    // A response file is being used. 
     
    25462359        return; 
    25472360    if (pArg == "@") 
    2548         lRespFileName = vDefResponseFile; 
     2361        lRespFileName = opts.DefResponseFile; 
    25492362    else if (pArg[0] == '@') 
    2550         lRespFileName = pArg[1..length].dup
     2363        lRespFileName = pArg[1..length]
    25512364    else 
    25522365        lRespFileName = pArg; 
    2553  
    25542366    if (std.path.getExt(lRespFileName).length == 0) 
    25552367    { 
    2556         lRespFileName ~= "." ~ vResponseExt; 
     2368        lRespFileName ~= "." ~ opts.ResponseExt; 
    25572369    } 
    25582370 
    25592371    version(BuildVerbose) 
    25602372    { 
    2561         if (pVerbose == True) 
     2373        if (opts.Verbose == True) 
    25622374            std.stdio.writefln("Response file %s", lRespFileName); 
    25632375    } 
    25642376 
    25652377    lRespLines = util.fileex.GetTextLines(lRespFileName, util.fileex.GetOpt.Exists); 
    2566     foreach(string lArg; lRespLines) 
     2378    foreach(ref string lArg; lRespLines) 
    25672379    { 
    25682380        // Locate any comment text in the line. 
     2381        // 'Truncate' the line at the '#' character. 
    25692382        int lPos = std.string.find(lArg, "#"); 
    2570         if (lPos != -1) 
    2571         { 
    2572             // Truncate the line at the '#' character. 
    2573             lArg.length = lPos; 
    2574         } 
    2575  
    2576         lArg = std.string.strip(lArg); 
     2383        if (lPos == -1) 
     2384        { 
     2385            lPos = lArg.length; 
     2386        } 
     2387 
     2388        lArg = std.string.strip(lArg[0..lPos]); 
    25772389        if (lArg.length > 1) 
    25782390        { 
    25792391            version(BuildVerbose) 
    25802392            { 
    2581                 if (pVerbose == True) 
     2393                if (opts.Verbose == True) 
    25822394                    std.stdio.writefln("Response file arg: %s", lArg); 
    25832395            } 
     
    25982410{ 
    25992411    static string lImportSwitch; 
    2600  
     2412    static string lResponseFileRef; 
     2413 
     2414    pArg = util.str.ExpandEnvVar(pArg); 
    26012415    // Handle a version switch on the command line by 
    2602     if(util.str.begins(pArg, vVersionSwitch) == True) 
     2416    if(util.str.begins(pArg, opts.VersionSwitch) == True) 
    26032417    { 
    26042418        string lVersionString; 
    26052419 
    2606         lVersionString=pArg [vVersionSwitch.length .. $]; 
     2420        lVersionString=pArg [opts.VersionSwitch.length .. $]; 
    26072421        if (lVersionString.length > 0 && lVersionString[0] == '=') 
    26082422            lVersionString = lVersionString[1..$]; 
     
    26122426        } 
    26132427    } 
    2614     else if(pArg == vDebugSwitch) 
     2428    else if(pArg == opts.DebugSwitch) 
    26152429    { 
    26162430        source.ActivateDebug("1"); 
    26172431    } 
    2618     else if(util.str.begins(pArg, vDebugSwitch) == True) 
     2432    else if(util.str.begins(pArg, opts.DebugSwitch) == True) 
    26192433    { 
    26202434        string lDebugString; 
    26212435 
    2622         lDebugString = pArg [vDebugSwitch.length .. $]; 
     2436        lDebugString = pArg [opts.DebugSwitch.length .. $]; 
    26232437        if (lDebugString.length > 0 && lDebugString[0] == '=') 
    26242438            lDebugString = lDebugString[1..$]; 
     
    26322446    { 
    26332447        vReceivedArgs.length = vReceivedArgs.length + 1; 
    2634         vReceivedArgs[$-1].ArgText = pArg.dup
     2448        vReceivedArgs[$-1].ArgText = pArg
    26352449        vReceivedArgs[$-1].CompilerArg = False; 
    26362450        vReceivedArgs[$-1].DFlag = False; 
     
    26392453    switch(pArg) { 
    26402454        case "-full": 
    2641             vForceCompile = True; 
     2455            opts.ForceCompile = True; 
    26422456            // Not passed thru. 
    26432457            break; 
    26442458 
    26452459        case "-link": 
    2646             source.Source.WasMainFound = true; 
     2460            source.Source.WasMainFound = True; 
    26472461            // Not passed thru. 
    26482462            break; 
     
    27142528 
    27152529        case "-test": 
    2716             vTestRun = True; 
     2530            opts.TestRun = True; 
    27172531            // Not passed thru. 
    27182532            break; 
    27192533 
    27202534        case "-explicit": 
    2721             vExplicit = True; 
     2535            opts.Explicit = True; 
    27222536            // Not passed thru. 
    27232537            break; 
     
    27432557            { 
    27442558            if (pArg[0] == '-') { 
    2745                 if (pArg == vGenDebugInfo) 
     2559                if (pArg == opts.GenDebugInfo) 
    27462560                { 
    27472561                    // Requires symbolic debug info. 
    2748                     vLinkerDefs ~= vSymInfoSwitch; 
     2562                    opts.LinkerDefs ~= opts.SymInfoSwitch; 
    27492563                    vReceivedArgs[$-1].CompilerArg = True; 
    27502564                    break; 
     
    27542568                if (util.str.IsLike(pArg, "-LIBOPT*"c) == True) 
    27552569                { 
    2756                     vLibrarianOpts ~= " " ~ pArg[7..$].dup
     2570                    opts.LibrarianOpts ~= " " ~ pArg[7..$]
    27572571                    break; 
    27582572 
     
    27612575                if (util.str.begins(pArg, "-LIBPATH=") == True) 
    27622576                { 
    2763                     vLibPaths ~= vConfigSep ~ pArg[9..$].dup; 
     2577                    if (pArg.length == 9) 
     2578                    { 
     2579                        delete opts.LibPaths; 
     2580                    } 
     2581                    else 
     2582                    { 
     2583                        if (opts.LibPaths.length > 0) 
     2584                            opts.LibPaths ~= opts.ConfigSep; 
     2585                        opts.LibPaths ~= pArg[9..$]; 
     2586                    } 
    27642587                    break; 
    27652588                } 
     
    27772600                        lFile = m.match(1); 
    27782601                    } 
    2779                     version(BuildVerbose) 
    2780                     { 
    2781                         ProcessOneBuildConfig("+" ~ lSubSection, vVerbose, lFile, lLocalArgs); 
    2782                     } else { 
    2783                         ProcessOneBuildConfig("+" ~ lSubSection, False, lFile, lLocalArgs); 
    2784                     } 
     2602                    ProcessOneBuildConfig("+" ~ lSubSection, lFile, lLocalArgs); 
    27852603                    ExamineArgs(lLocalArgs); 
     2604                    break; 
     2605                } 
     2606 
     2607                if (util.str.begins(pArg, "-showtodo") == True) 
     2608                { 
     2609                    opts.ShowToDo = new Bool(util.str.YesNo(pArg, true)); 
    27862610                    break; 
    27872611                } 
     
    28102634                if (util.str.IsLike(pArg, "-DCPATH?*"c) == True) 
    28112635                { 
    2812                     string lNewPath = pArg[7..length].dup
     2636                    string lNewPath = pArg[7..length]
    28132637                    if (util.str.ends(lNewPath, std.path.sep) == False) 
    28142638                        lNewPath ~= std.path.sep; 
    28152639                    version(BuildVerbose) 
    28162640                    { 
    2817                         if (vVerbose == True) 
    2818                             std.stdio.writefln("DCPATH was %s now %s", vCompilerPath, lNewPath); 
    2819                     } 
    2820                     vCompilerPath = lNewPath; 
    2821                     util.str.SetEnv("@D", std.path.getDirName(vCompilerPath)); 
     2641                        if (opts.Verbose == True) 
     2642                            std.stdio.writefln("DCPATH was %s now %s", opts.CompilerPath, lNewPath); 
     2643                    } 
     2644                    opts.CompilerPath = lNewPath; 
     2645                    util.str.SetEnv("@D", std.path.getDirName(opts.CompilerPath)); 
    28222646                    break; 
    28232647 
     
    28262650                if (util.str.IsLike(pArg,  "-CFPATH?*"c) == True) 
    28272651                { 
    2828                     string lNewPath = pArg[7..length].dup
     2652                    string lNewPath = pArg[7..length]
    28292653                    if (util.str.ends(lNewPath, std.path.sep) == False) 
    28302654                        lNewPath ~= std.path.sep; 
    28312655                    version(BuildVerbose) 
    28322656                    { 
    2833                         if (vVerbose == True) 
    2834                             std.stdio.writefln("CFPATH was %s now %s", vConfigPath, lNewPath); 
    2835                     } 
    2836                     vOverrideConfigPath = lNewPath; 
    2837                     util.str.SetEnv("@P", std.path.getDirName(vOverrideConfigPath)); 
     2657                        if (opts.Verbose == True) 
     2658                            std.stdio.writefln("CFPATH was %s now %s", opts.ConfigPath, lNewPath); 
     2659                    } 
     2660                    opts.OverrideConfigPath = lNewPath; 
     2661                    util.str.SetEnv("@P", std.path.getDirName(opts.OverrideConfigPath)); 
    28382662                    break; 
    28392663 
     
    28422666                if (util.str.IsLike(pArg,  "-BCFPATH?*"c) == True) 
    28432667                { 
    2844                     string lNewPath = pArg[8..length].dup
     2668                    string lNewPath = pArg[8..length]
    28452669                    if (util.str.ends(lNewPath, std.path.sep) == False) 
    28462670                        lNewPath ~= std.path.sep; 
    28472671                    version(BuildVerbose) 
    28482672                    { 
    2849                         if (vVerbose == True) 
    2850                             std.stdio.writefln("BCFPATH was '%s' now '%s'", vCFGPath, lNewPath); 
    2851                     } 
    2852                     vCFGPath = lNewPath; 
     2673                        if (opts.Verbose == True) 
     2674                            std.stdio.writefln("BCFPATH was '%s' now '%s'", opts.CFGPath, lNewPath); 
     2675                    } 
     2676                    opts.CFGPath = lNewPath; 
    28532677                    break; 
    28542678 
     
    28572681                if (util.str.IsLike(pArg,  "-PP?*"c) == True) 
    28582682                { 
    2859                     string lNewPath = pArg[3..length].dup
     2683                    string lNewPath = pArg[3..length]
    28602684                    version(BuildVerbose) 
    28612685                    { 
    2862                         if (vVerbose == True) 
     2686                        if (opts.Verbose == True) 
    28632687                            std.stdio.writefln("Added %s to Source Scan List", lNewPath); 
    28642688                    } 
     
    28752699                    version(BuildVerbose) 
    28762700                    { 
    2877                         if (vVerbose == True) 
    2878                             std.stdio.writefln("RDF was %s now %s", source.vRDFName, pArg[4..$]); 
    2879                     } 
    2880  
    2881                     source.vRDFName = pArg[4..$].dup
     2701                        if (opts.Verbose == True) 
     2702                            std.stdio.writefln("RDF was %s now %s", opts.RDFName, pArg[4..$]); 
     2703                    } 
     2704 
     2705                    opts.RDFName = pArg[4..$]
    28822706                    break; 
    28832707 
     
    28882712                    version(BuildVerbose) 
    28892713                    { 
    2890                         if (vVerbose == True) 
    2891                             std.stdio.writefln("MDF was %s now %s", vDefMacroDefFile, pArg[4..$]); 
    2892                     } 
    2893  
    2894                     vDefMacroDefFile = pArg[4..$].dup
     2714                        if (opts.Verbose == True) 
     2715                            std.stdio.writefln("MDF was %s now %s", opts.DefMacroDefFile, pArg[4..$]); 
     2716                    } 
     2717 
     2718                    opts.DefMacroDefFile = pArg[4..$]
    28952719                    break; 
    28962720 
    28972721                } 
    28982722 
    2899                 if (pArg == vBuildImportPath) 
     2723                if (pArg == opts.BuildImportPath) 
    29002724                { 
    29012725                    vDelayedValue = &lImportSwitch; 
    29022726                    break; 
    29032727                } 
    2904                 else if ( util.str.begins(pArg, vBuildImportPath) == True) 
    2905                 { 
    2906                     char [] lRoot; 
    2907                     foreach(string lCmdRoot; std.string.split(pArg[vBuildImportPath.length .. $], 
    2908                                                         vImportPathDelim)) 
     2728                else if ( util.str.begins(pArg, opts.BuildImportPath) == True) 
     2729                { 
     2730                    string lRoot; 
     2731                    foreach(string lCmdRoot; std.string.split(pArg[opts.BuildImportPath.length .. $], 
     2732                                                        opts.ImportPathDelim)) 
    29092733                    { 
    29102734                        lRoot = AddRoot(lCmdRoot); 
     
    29132737                            version(BuildVerbose) 
    29142738                            { 
    2915                                 if(vVerbose == True) 
     2739                                if(opts.Verbose == True) 
    29162740                                    std.stdio.writefln("Added root from command line = %s",lRoot); 
    29172741                            } 
     
    29212745                } 
    29222746 
    2923                 if (util.str.IsLike(pArg,  vRunSwitch ~ "*") == True) 
    2924                 { 
    2925                     vRunParms ~= pArg[vRunSwitch.length .. $] ~ " "; 
     2747                if (pArg == "-f") 
     2748                { 
     2749                    vDelayedValue = &lResponseFileRef; 
     2750                    break; 
     2751                } 
     2752                else if ( util.str.begins(pArg, "-f=") == True) 
     2753                { 
     2754                    ProcessResponseFile(pArg[3..$]); 
     2755                    break; 
     2756                } 
     2757 
     2758                if (util.str.IsLike(pArg,  opts.RunSwitch ~ "*") == True) 
     2759                { 
     2760                    vRunParms ~= pArg[opts.RunSwitch.length .. $] ~ " "; 
    29262761                    vExecuteProgram = True; 
    29272762                    break; 
     
    29452780                { 
    29462781 
    2947                     vUseModBaseName = util.str.YesNo(pArg, true); 
    2948                     source.Source.UseModBaseName(vUseModBaseName); 
     2782                    util.str.YesNo(pArg, opts.UseModBaseName, True); 
    29492783                    break; 
    29502784                } 
     
    29752809 
    29762810                // Special check for Object Write Path 
    2977                 version(DigitalMars) 
    2978                 { 
    2979                 if (util.str.IsLike(pArg,  vOutputPath ~ "*") == True) 
     2811                if (util.str.IsLike(pArg,  opts.OutputPath ~ "*") == True) 
    29802812                { 
    29812813                    string lRoot; 
    29822814 
    2983                     vTemporaryPath = pArg[vOutputPath.length .. $]; 
     2815                    vTemporaryPath = pArg[opts.OutputPath.length .. $]; 
    29842816                    if (vTemporaryPath.length > 0 && vTemporaryPath[$-1..$] != std.path.sep) 
    29852817                        vTemporaryPath ~= std.path.sep; 
     
    29892821                        version(BuildVerbose) 
    29902822                        { 
    2991                             if(vVerbose == True) 
     2823                            if(opts.Verbose == True) 
    29922824                                std.stdio.writefln("Added root from Object Write Path = %s",lRoot); 
    29932825                        } 
    2994                         util.pathex.MakePath(lRoot); 
    29952826                    } 
    29962827 
    29972828 
    29982829                    // This one actually *is* passed thru. 
    2999                     version(DigitalMars) 
    3000                     { 
    3001                         // Ensure we don't have both -op and -od when using dmd. 
    3002                         RemoveRecdArg("-op"); 
    3003                     } 
    3004                 } 
    30052830                } 
    30062831 
     
    30082833                { 
    30092834                    // Modules to ignore (eg. -Xmylib) 
    3010                     vModulesToIgnore ~= pArg[2..$]; 
     2835                    opts.ModulesToIgnore ~= pArg[2..$]; 
    30112836                    break; 
    30122837                } 
     
    30152840                { 
    30162841                    // Modules to notice (eg. -Mphobos) 
    3017                     vModulesToNotice ~= pArg[2..$]; 
     2842                    opts.ModulesToNotice ~= pArg[2..$]; 
    30182843                    break; 
    30192844                } 
    30202845 
     2846 
    30212847                if (util.str.IsLike(pArg,  "-T?*"c) == True) 
    30222848                { 
    30232849                    // Target name (eg. -Ttestapp) 
    3024  
    30252850                    if (vCommandTargetName.length > 0) 
    30262851                    { 
     
    30302855                    } 
    30312856                    else 
    3032                         vCommandTargetName = pArg[2..$].dup
     2857                        vCommandTargetName = pArg[2..$]
    30332858 
    30342859                    break; 
    3035                 } 
    3036  
    3037                 version(DigitalMars) 
    3038                 { 
    3039                 if (util.str.IsLike(pArg,  (vOutFileSwitch ~ "*")) == True) 
    3040                 { 
    3041                     // Target name (eg. -oftestapp) 
    3042                     vCommandTargetName = pArg[vOutFileSwitch.length .. $]; 
    3043                     break; 
    3044                 } 
    3045                 } 
    3046  
    3047                 version(GNU) 
    3048                 { 
    3049                 if (pArg == vOutFileSwitch) 
    3050                 { 
    3051                     // Target name (eg. -o testapp) 
    3052                     vDelayedValue = &vCommandTargetName; 
    3053                     break; 
    3054                 } 
    30552860                } 
    30562861 
     
    30602865                    // Response file usage (eg. -R=Yes) 
    30612866                    if (pArg.length == 2) 
    3062                         vUseResponseFile = ~vUseResponseFile; 
     2867                        // Reverse the current meaning. 
     2868                        opts.UseResponseFile = ~opts.UseResponseFile; 
    30632869                    else 
    3064                         util.str.YesNo(pArg, vUseResponseFile, False); 
     2870                        util.str.YesNo(pArg, opts.UseResponseFile, False); 
    30652871                    break; 
    30662872                } 
     
    30962902                    if ( vDelayedValue == &lImportSwitch) 
    30972903                    { 
    3098                         char [] lRoot; 
     2904                        string lRoot; 
     2905                        vDelayedValue = null; 
    30992906                        foreach(string lCmdRoot; std.string.split(pArg, ";")) 
    31002907                        { 
     
    31032910                                version(BuildVerbose) 
    31042911                                { 
    3105                                     if(vVerbose == True) 
     2912                                    if(opts.Verbose == True) 
    31062913                                        std.stdio.writefln("Added root from command line = %s",lRoot); 
    31072914                                } 
     
    31092916                        } 
    31102917                    } 
     2918                    else if ( vDelayedValue == &lResponseFileRef) 
     2919                    { 
     2920                        vDelayedValue = null; 
     2921                        ProcessResponseFile(pArg); 
     2922                    } 
    31112923                    else 
    31122924                    { 
    31132925                        *vDelayedValue = pArg; 
     2926                        vDelayedValue = null; 
    31142927                        vReceivedArgs[$-1].ArgText ~= " " ~ pArg; 
    31152928                    } 
    3116                     vDelayedValue = null; 
     2929 
    31172930                    break; 
    31182931                } 
     
    31242937                    pArg = std.string.replace(pArg, "/", std.path.sep); 
    31252938                } 
    3126                 pArg = util.pathex.AbbreviateFileName(util.pathex.CanonicalPath(pArg, false)); 
    3127                 auto lArgExt = std.path.getExt(pArg); 
     2939                pArg = source.ReducePathName(source.ExpandPathName(pArg, False)); 
     2940                string lArgExt = std.path.getExt(pArg); 
    31282941                if (lArgExt == "") 
    31292942                { 
    3130                        pArg ~= "." ~ vSrcExtension; 
     2943                       pArg ~= "." ~ opts.SrcExtension; 
    31312944                       vCmdLineSourceFiles ~= pArg; 
    31322945                } 
    3133                 else if (lArgExt == vSrcExtension || 
    3134                            lArgExt == vMacroExtension || 
    3135                            lArgExt == vDdocExtension) 
     2946                else if (lArgExt == opts.SrcExtension || 
     2947                           lArgExt == opts.MacroExtension || 
     2948                           lArgExt == opts.DdocExtension) 
    31362949                { 
    31372950                       vCmdLineSourceFiles ~= pArg; 
    31382951                } 
    3139                 else if (lArgExt == vResponseExt) 
     2952                else if (lArgExt == opts.ResponseExt) 
    31402953                { 
    31412954                } 
     
    31462959 
    31472960                if(vTargetName is null && 
    3148                     ((std.path.getExt(pArg) == vSrcExtension) || 
    3149                      (std.path.getExt(pArg) == vMacroExtension) 
     2961                    ((std.path.getExt(pArg) == opts.SrcExtension) || 
     2962                     (std.path.getExt(pArg) == opts.MacroExtension) 
    31502963                    ) 
    31512964                  ) 
    31522965                { 
    3153                    vTargetName = std.path.getName(pArg.dup); 
     2966                   vTargetName = util.pathex.GetFileBaseName(pArg); 
    31542967                    version(BuildVerbose) 
    31552968                    { 
    3156                         if(vVerbose == True) 
     2969                        if(opts.Verbose == True) 
    31572970                            std.stdio.writefln("Default target is '%s'", vTargetName); 
    31582971                    } 
     
    31672980{ 
    31682981    static bool[string] lKnownArgs; 
     2982    static string lDelayed; 
    31692983 
    31702984    pArg = std.string.strip(pArg); 
     
    31772991    } 
    31782992 
     2993    if (lDelayed == "-f") 
     2994    { 
     2995        lDelayed.length = 0; 
     2996        ProcessResponseFile(pArg); 
     2997        return; 
     2998    } 
     2999 
    31793000    version(BuildVerbose) 
    31803001    { 
    31813002        if ((pArg == "-V") || (pArg == "-v")) 
    3182             vVerbose = True; 
     3003            opts.Verbose = True; 
    31833004    } 
    31843005 
     
    31883009        { 
    31893010            if ((pArg == "--V") || (pArg == "--v")) 
    3190                 vVerbose = False; 
     3011                opts.Verbose = False; 
    31913012        } 
    31923013        // Defer removing the earlier arg until I've examined all args. 
     
    31973018 
    31983019    if ( (pArg[0] == '@') || 
    3199               (util.str.ends(pArg, "." ~ vResponseExt) is True) 
     3020              (util.str.ends(pArg, "." ~ opts.ResponseExt) is True) 
    32003021             ) 
    32013022    { 
    3202         version(BuildVerbose) 
    3203         { 
    3204             ProcessResponseFile(pArg, vVerbose); 
    3205         } else { 
    3206             ProcessResponseFile(pArg, False); 
    3207         } 
     3023        ProcessResponseFile(pArg); 
     3024    } 
     3025    else if (pArg == "-ut") 
     3026    { 
     3027        GatherOneArg( "-unittest", vCombinedArgs ); 
     3028        GatherOneArg( "-nolib", vCombinedArgs ); 
     3029        GatherOneArg( "-exec", vCombinedArgs ); 
     3030        GatherOneArg( "-full", vCombinedArgs ); 
     3031        GatherOneArg( "-clean", vCombinedArgs ); 
     3032    } 
     3033    else if (pArg == "-f") 
     3034    { 
     3035        lDelayed = pArg; 
     3036    } 
     3037    else if (util.str.begins(pArg,"-f=") == True) 
     3038    { 
     3039        ProcessResponseFile(pArg[3..$]); 
     3040    } 
     3041    else if (util.str.begins(pArg, "INIT:") == True) 
     3042    { 
     3043        opts.SetInternalString( pArg[5..$] ); 
    32083044    } 
    32093045    else if (pArg[0] == '+') 
    3210         version(BuildVerbose) 
    3211         { 
    3212             ProcessBuildConfig(pArg, vVerbose, pArgGroup); 
    3213         } else { 
    3214             ProcessBuildConfig(pArg, False, pArgGroup); 
    3215         } 
     3046    { 
     3047        ProcessBuildConfig(pArg, pArgGroup); 
     3048    } 
    32163049    else 
    32173050    {   // Only add an argument if it is not already been added. 
     
    32203053            pArgGroup ~= pArg; 
    32213054            lKnownArgs[pArg] = true; 
     3055            if (pArg == "-unittest") 
     3056                opts.UnitTesting = True; 
    32223057        } 
    32233058    } 
     
    32313066       the contents of any response files. 
    32323067    */ 
    3233     Bool lVerbose; 
    3234     version(BuildVerbose) 
    3235     { 
    3236         lVerbose = vVerbose; 
    3237     } else { 
    3238         lVerbose = False; 
    3239     } 
    3240     // Collect from configuration file(s). 
    3241     ProcessBuildConfig("+", lVerbose, vCombinedArgs); 
    3242     version(Windows) 
    3243     { 
    3244         ProcessBuildConfig("+Windows", lVerbose, vCombinedArgs); 
    3245     } 
    3246     version(Posix) 
    3247     { 
    3248         ProcessBuildConfig("+Posix", lVerbose, vCombinedArgs); 
    3249     } 
    3250     version(DigitalMars) 
    3251     { 
    3252         ProcessBuildConfig("+DigitalMars", lVerbose, vCombinedArgs); 
    3253     } 
    3254     version(GNU) 
    3255     { 
    3256         ProcessBuildConfig("+GNU", lVerbose, vCombinedArgs); 
    3257     } 
    3258  
    3259     version(darwin) 
    3260     { 
    3261         ProcessBuildConfig("+darwin", lVerbose, vCombinedArgs); 
    3262     } 
    3263  
    3264     version(Windows) 
    3265     { 
    3266         version(DigitalMars) 
    3267         { 
    3268             ProcessBuildConfig("+Windows:DigitalMars", lVerbose, vCombinedArgs); 
    3269         } 
    3270         version(GNU) 
    3271         { 
    3272             ProcessBuildConfig("+Windows:GNU", lVerbose, vCombinedArgs); 
    3273         } 
    3274     } 
    3275     version(Posix) 
    3276     { 
    3277         version(DigitalMars) 
    3278         { 
    3279             ProcessBuildConfig("+Posix:DigitalMars", lVerbose, vCombinedArgs); 
    3280         } 
    3281         version(GNU) 
    3282         { 
    3283             ProcessBuildConfig("+Posix:GNU", lVerbose, vCombinedArgs); 
    3284         } 
    3285  
    3286     } 
    3287  
    3288     version(DigitalMars) 
    3289     { 
    3290         if (vCompilerDefs.length == 0) vCompilerDefs  ~= "-op"; 
    3291     } 
     3068 
     3069    GetEnvironSwitches(); 
    32923070 
    32933071    // Collect from original command line. 
    3294     foreach( string lArg; vCompilerDefs ~ pArgs) 
    3295     { 
    3296         string[] lSplitArgs; 
    3297  
    3298         lSplitArgs = std.string.split(lArg); 
    3299         foreach(string lOneArg; lSplitArgs) 
    3300         { 
    3301             GatherOneArg( lOneArg, vCombinedArgs ); 
    3302         } 
    3303     } 
    3304  
    3305  
    3306 
    3307  
    3308 void ProcessMacroDefs(Bool pVerbose) 
     3072    foreach( string lArg; opts.CompilerDefs ~ pArgs) 
     3073    { 
     3074         GatherOneArg( lArg, vCombinedArgs ); 
     3075    } 
     3076 
     3077 
     3078
     3079 
     3080void ProcessMacroDefs() 
    33093081{ 
    33103082    // From build.exe location 
    3311     ProcessOneMacroDef(pVerbose, std.path.getDirName(vAppPath)); 
     3083    ProcessOneMacroDef(vMyDir); 
    33123084 
    33133085    // From compiler location 
    3314     ProcessOneMacroDef(pVerbose, vCompilerPath); 
     3086    ProcessOneMacroDef(opts.CompilerPath); 
    33153087 
    33163088    // From current folder location 
    3317     ProcessOneMacroDef(pVerbose, util.pathex.GetInitCurDir()); 
    3318 } 
    3319  
    3320 void ProcessOneMacroDef(Bool pVerbose, string pPath) 
     3089    ProcessOneMacroDef(util.pathex.GetInitCurDir()); 
     3090} 
     3091 
     3092void ProcessOneMacroDef(string pPath) 
    33213093{ 
    33223094    string lMacroDefFileName; 
     
    33263098    static bool[ string ] lUsedPaths; 
    33273099 
    3328     lMacroDefFileName = pPath.dup
     3100    lMacroDefFileName = pPath
    33293101 
    33303102    if ((lMacroDefFileName.length > 0) && 
     
    33323104            lMacroDefFileName ~= std.path.sep; 
    33333105 
    3334     lMacroDefFileName ~= vDefMacroDefFile; 
     3106    lMacroDefFileName ~= opts.DefMacroDefFile; 
    33353107 
    33363108    if (lMacroDefFileName in lUsedPaths) 
     
    33403112    version(BuildVerbose) 
    33413113    { 
    3342         if ((pVerbose == True) && util.file2.FileExists(lMacroDefFileName) ) 
    3343             std.stdio.writefln("Build Macro Definition file %s", lMacroDefFileName); 
     3114        if (opts.Verbose == True) 
     3115            if (util.file2.FileExists(lMacroDefFileName)) 
     3116                std.stdio.writefln("Macro Definition file %s", lMacroDefFileName); 
    33443117    } 
    33453118 
    33463119    lMacroDefLines = util.fileex.GetTextLines(lMacroDefFileName, util.fileex.GetOpt.Always); 
    33473120 
    3348     util.macro.AddMacros( "build", lMacroDefLines, lMessages); 
     3121    util.macroex.AddMacros( "build", lMacroDefLines, lMessages); 
    33493122    version(BuildVerbose) 
    33503123    { 
    3351         if (pVerbose == True) 
     3124        if (opts.Verbose == True) 
    33523125        { 
    33533126            foreach(string lMsg; lMessages) 
     
    33603133} 
    33613134 
    3362 void ProcessBuildConfig(string pArg, Bool pVerbose, inout string[] pArgGroup) 
    3363 
    3364     // From build.exe location 
    3365     ProcessOneBuildConfig(pArg, pVerbose, std.path.getDirName(vAppPath), pArgGroup); 
     3135int ProcessBuildConfig(string pArg, inout string[] pArgGroup) 
     3136
     3137    int lCmdCnt; 
     3138    int lPos; 
     3139 
     3140    if (pArg[$-1] == ']') 
     3141    { 
     3142        lPos = std.string.find(pArg, '['); 
     3143 
     3144        if (lPos >= 0) 
     3145        { 
     3146            opts.CFGPath = pArg[lPos+1 .. $-1]; 
     3147            pArg.length = lPos; 
     3148        } 
     3149    } 
     3150 
     3151    // From my location 
     3152    lCmdCnt += ProcessOneBuildConfig(pArg, vMyDir, pArgGroup); 
     3153 
     3154    version (Posix) 
     3155    { 
     3156        lCmdCnt += ProcessOneBuildConfig(pArg, "/etc", pArgGroup); 
     3157        lCmdCnt += ProcessOneBuildConfig(pArg, vMyDir ~ "/../etc", pArgGroup); 
     3158        lCmdCnt += ProcessOneBuildConfig(pArg, util.str.GetEnv(opts.HomePathId) ~ "/.build", pArgGroup); 
     3159        if (vMyName != "build") 
     3160            lCmdCnt += ProcessOneBuildConfig(pArg, util.str.GetEnv(opts.HomePathId) ~ "/." ~ vMyName, pArgGroup); 
     3161    } 
    33663162 
    33673163    // From alternate location 
    3368     if (vCFGPath.length > 0) 
    3369         ProcessOneBuildConfig(pArg, pVerbose, vCFGPath, pArgGroup); 
     3164    if (opts.CFGPath.length > 0) 
     3165        lCmdCnt += ProcessOneBuildConfig(pArg, opts.CFGPath, pArgGroup); 
    33703166 
    33713167    // compiler path 
    3372     ProcessOneBuildConfig(pArg, pVerbose, vCompilerPath, pArgGroup); 
     3168    lCmdCnt += ProcessOneBuildConfig(pArg, opts.CompilerPath, pArgGroup); 
    33733169 
    33743170    // From current location 
    3375     ProcessOneBuildConfig(pArg, pVerbose, util.pathex.GetInitCurDir(), pArgGroup ); 
    3376  
    3377 
    3378  
    3379 void ProcessOneBuildConfig(string pArg, Bool pVerbose, string pPath, inout string[] pArgGroup) 
     3171    lCmdCnt += ProcessOneBuildConfig(pArg, util.pathex.GetInitCurDir(), pArgGroup ); 
     3172 
     3173    return lCmdCnt; 
     3174
     3175 
     3176int ProcessOneBuildConfig(string pArg, string pPath, inout string[] pArgGroup) 
    33803177{ 
    33813178    string lConfigFileName; 
    33823179    string[] lConfigLines; 
     3180    string lKey; 
    33833181    bool lFoundGroup; 
    33843182    static bool[ string ] lUsedPaths; 
    3385  
    3386     version(BuildVerbose) 
    3387     { 
    3388         if (pVerbose == True) 
    3389             std.stdio.writefln("Build Configuration file %s [%s]", pPath, pArg[1..$]); 
    3390     } 
    3391  
    3392     lConfigFileName = pPath.dup; 
     3183    int lCmdCnt; 
     3184 
     3185    lConfigFileName = pPath; 
    33933186    if (util.file2.FileExists(lConfigFileName) == false) 
    33943187    { 
     
    33983191                lConfigFileName ~= std.path.sep; 
    33993192 
    3400         lConfigFileName ~= vUtilsConfigFile; 
    3401     } 
    3402  
    3403     lConfigFileName = util.pathex.CanonicalPath(lConfigFileName, false); 
     3193        if (opts.UtilsConfigFile.length == 0) 
     3194        { 
     3195            opts.UtilsConfigFile = util.pathex.GetBaseName(vMyName) ~ ".cfg"; 
     3196        } 
     3197        lConfigFileName ~= opts.UtilsConfigFile; 
     3198    } 
     3199 
     3200    lConfigFileName = source.ExpandPathName(lConfigFileName, False); 
    34043201    if (pArg.length == 0) 
    34053202        pArg = "+"; 
    34063203 
    3407     if (lConfigFileName~pArg in lUsedPaths) 
    3408     { 
    3409         return; 
    3410     } 
    3411     lUsedPaths[lConfigFileName~pArg] = true; 
     3204    version(BuildVerbose) 
     3205    { 
     3206        if (opts.Verbose == True) 
     3207            std.stdio.writefln("Configuration file: %s[%s]", lConfigFileName, pArg[1..$]); 
     3208    } 
     3209 
     3210    version(Windows) lKey = std.string.toupper(lConfigFileName~pArg); 
     3211    version(Posix) lKey = lConfigFileName~pArg; 
     3212    if (lKey in lUsedPaths) 
     3213    { 
     3214        return 0; 
     3215    } 
     3216    lUsedPaths[lKey] = true; 
    34123217 
    34133218 
     
    34213226    } 
    34223227 
    3423     foreach(string lArg; lConfigLines) 
     3228    foreach(ref string lArg; lConfigLines) 
    34243229    { 
    34253230        if (lArg.length == 0) 
     
    34553260                version(BuildVerbose) 
    34563261                { 
    3457                     if (pVerbose == True) 
    3458                         std.stdio.writefln("Build Configuration file arg: %s", lArg); 
     3262                    if (opts.Verbose == True) 
     3263                        std.stdio.writefln("Configuration file arg: %s", lArg); 
    34593264                } 
    34603265 
     
    34693274                    int lEndPos; 
    34703275                    bool lEndFound; 
     3276 
    34713277                    lArg = std.string.strip(lArg[8..$]); 
    34723278                    lStartPos = 0; 
     
    34753281                    while(lEndPos < lArg.length) 
    34763282                    { 
    3477                         if (!lEndFound
     3283                        if (lEndFound == false
    34783284                        { 
    34793285                            if (lArg[lEndPos] == ' ') 
     
    34893295                                lStartPos = lEndPos; 
    34903296                                lEndFound = false; 
     3297                                lCmdCnt += 1; 
    34913298                            } 
    34923299                        } 
     
    34963303                    { 
    34973304                        GatherOneArg( lArg[lStartPos..lEndPos], pArgGroup ); 
     3305                        lCmdCnt += 1; 
    34983306                    } 
    34993307 
     
    35023310                { 
    35033311                    vFinalProc ~= lArg[6..$]; 
     3312                    lCmdCnt += 1; 
     3313                } 
     3314                else if (util.str.begins(lArg, "FAILURE=") == True) 
     3315                { 
     3316                    vFailureProc ~= lArg[8..$]; 
     3317                    lCmdCnt += 1; 
    35043318                } 
    35053319                else if (util.str.begins(lArg, "LIBCMD=") == True) 
    35063320                { 
    3507                     SetFileLocation(lArg[7..$], vLibrarianPath, vLibrarian, "librarian"); 
     3321                    SetFileLocation(lArg[7..$], opts.LibrarianPath, opts.Librarian, "librarian"); 
     3322                    lCmdCnt += 1; 
    35083323                } 
    35093324                else if (util.str.begins(lArg, "COMPCMD=") == True) 
    35103325                { 
    3511                     SetFileLocation(lArg[8..$], vCompilerPath, vCompilerExe, "compiler"); 
     3326                    SetFileLocation(lArg[8..$], opts.CompilerPath, opts.CompilerExe, "compiler"); 
     3327                    lCmdCnt += 1; 
    35123328                } 
    35133329                else if (util.str.begins(lArg, "LINKCMD=") == True) 
    35143330                { 
    3515                     SetFileLocation(lArg[8..$], vLinkerPath, vLinkerExe, "linker"); 
     3331                    SetFileLocation(lArg[8..$], opts.LinkerPath, opts.LinkerExe, "linker"); 
     3332                    lCmdCnt += 1; 
    35163333                } 
    35173334                else if (util.str.begins(lArg, "LINKSWITCH=") == True) 
    35183335                { 
    3519                     vLinkerDefs = lArg[11..$].dup; 
     3336                    opts.LinkerDefs = lArg[11..$]; 
     3337                    lCmdCnt += 1; 
    35203338                } 
    35213339                else if (util.str.begins(lArg, "INIT:") == True) 
    35223340                { 
    3523                     SetInternalString( lArg[5..$] ); 
     3341                    lCmdCnt += opts.SetInternalString( lArg[5..$] ); 
    35243342                } 
    35253343                else { 
    35263344                    version(BuildVerbose) 
    35273345                    { 
    3528                         if (vVerbose == True) 
     3346                        if (opts.Verbose == True) 
    35293347                            std.stdio.writefln("Bad configuration command '%s' ignored.", lArg); 
    35303348                    } 
     
    35333351        } 
    35343352    } 
    3535 
    3536  
    3537 void SetInternalString(string pCommand) 
    3538 
    3539     string lName; 
    3540     string lValue; 
    3541     int lPos; 
    3542  
    3543     lPos = std.string.find(pCommand, "="); 
    3544     if (lPos == -1) 
    3545     { 
    3546         std.stdio.writefln("Internal String Set '%s' ignored ... '=' not found.", pCommand); 
    3547         return; 
    3548     } 
    3549  
    3550     lName = std.string.strip(pCommand[0..lPos]); 
    3551     lValue = std.string.strip(pCommand[lPos+1..$]); 
    3552  
    3553     // Strip off any enclosing quotes. 
    3554     if (lValue.length >= 2 && 
    3555         std.string.find("\"'`", lValue[0]) != -1 && 
    3556         lValue[$-1] == lValue[0]) 
    3557     { 
    3558         lValue = lValue[1..$-1]; 
    3559     } 
    3560  
    3561     // Resolve any environment symbols and translate any escape sequences. 
    3562     lValue = util.str.TranslateEscapes(util.str.ExpandEnvVar(lValue)); 
    3563  
    3564     switch(lName) 
    3565     { 
    3566         case "ExeExtension"    : { vExeExtension     = lValue.dup; 
    3567                                    util.fileex.vExeExtension = vExeExtension; 
    3568                                    break; 
    3569                                  } 
    3570         case "LibExtension"    : { vLibExtension     = lValue.dup; break; } 
    3571         case "ObjExtension"    : { vObjExtension     = lValue.dup; break; } 
    3572         case "ShrLibExtension" : { vShrLibExtension  = lValue.dup; break; } 
    3573         case "SrcExtension"    : { vSrcExtension     = lValue.dup; break; } 
    3574         case "MacroExtension"  : { vMacroExtension   = lValue.dup; break; } 
    3575         case "DdocExtension"   : { vDdocExtension    = lValue.dup; break; } 
    3576         case "CompilerExe"     : { vCompilerExe      = lValue.dup; break; } 
    3577         case "CompileOnly"     : { vCompileOnly      = lValue.dup; break; } 
    3578         case "LinkerExe"       : { vLinkerExe        = lValue.dup; break; } 
    3579         case "ConfigFile"      : { vConfigFile       = lValue.dup; break; } 
    3580         case "CompilerPath"    : { vCompilerPath     = lValue.dup; 
    3581                                    if (vCompilerPath.length > 0) 
    3582                                    { 
    3583                                     if (util.str.ends(vCompilerPath, std.path.sep) == False) 
    3584                                         vCompilerPath ~= std.path.sep; 
    3585                                     util.str.SetEnv("@D", std.path.getDirName(vCompilerPath)); 
    3586                                    } 
    3587                                    break; } 
    3588         case "LinkerPath"      : { vLinkerPath       = lValue.dup; break; } 
    3589         case "LinkerDefs"      : { vLinkerDefs       = lValue.dup; break; } 
    3590         case "ConfigPath"      : { vOverrideConfigPath       = lValue.dup; 
    3591                                    if (vOverrideConfigPath.length > 0) 
    3592                                    { 
    3593                                     if (util.str.ends(vOverrideConfigPath, std.path.sep) == False) 
    3594                                         vOverrideConfigPath ~= std.path.sep; 
    3595                                     util.str.SetEnv("@P", std.path.getDirName(vOverrideConfigPath)); 
    3596                                    } 
    3597                                    break; } 
    3598         case "LibPaths"        : { vLibPaths         = lValue.dup; break; } 
    3599         case "ConfigSep"       : { vConfigSep        = lValue.dup; break; } 
    3600         case "Librarian"       : { vLibrarian        = lValue.dup; break; } 
    3601         case "LibrarianOpts"   : { vLibrarianOpts    = lValue.dup; break; } 
    3602         case "VersionSwitch"   : { vVersionSwitch    = lValue.dup; break; } 
    3603         case "DebugSwitch"     : { vDebugSwitch      = lValue.dup; break; } 
    3604         case "OutFileSwitch"   : { vOutFileSwitch    = lValue.dup; break; } 
    3605         case "ImportPath"      : { vImportPath       = lValue.dup; break; } 
    3606         case "LinkLibSwitch"   : { vLinkLibSwitch    = lValue.dup; break; } 
    3607         case "LibPathSwitch"   : { vLibPathSwitch    = lValue.dup; break; } 
    3608         case "MapSwitch"       : { vMapSwitch        = lValue.dup; break; } 
    3609         case "SymInfoSwitch"   : { vSymInfoSwitch    = lValue.dup; break; } 
    3610         case "BuildImportPath" : { vBuildImportPath  = lValue.dup; break; } 
    3611         case "ImportPathDelim" : { vImportPathDelim  = lValue.dup; break; } 
    3612         case "OutputPath"      : { vOutputPath       = lValue.dup; break; } 
    3613         case "RunSwitch"       : { vRunSwitch        = lValue.dup; break; } 
    3614         case "LibrarianPath"   : { vLibrarianPath    = lValue.dup; break; } 
    3615         case "ResponseExt"     : { vResponseExt      = lValue.dup; break; } 
    3616         case "DefResponseFile" : { vDefResponseFile  = lValue.dup; break; } 
    3617         case "RDFName"         : { source.vRDFName          = lValue.dup; break; } 
    3618         case "DefMacroDefFile" : { vDefMacroDefFile  = lValue.dup; break; } 
    3619         case "LinkerStdOut"    : { vLinkerStdOut     = lValue.dup; break; } 
    3620         case "IgnoredModules"  : { vModulesToIgnore ~= std.string.split(lValue, ","); break; } 
    3621         case "AssumedLibs"     : { vDefaultLibs     ~= std.string.split(lValue, ","); break; } 
    3622         case "PathId"          : { vPathId           = lValue.dup; 
    3623                                    util.fileex.vPathId = vPathId; 
    3624                                    source.vPathId      = vPathId; 
    3625                                    break; 
    3626                                  } 
    3627         case "ModOutPrefix"    : { vModOutPrefix     = lValue.dup; break; } 
    3628         case "ModOutSuffix"    : { vModOutSuffix     = lValue.dup; break; } 
    3629         case "ModOutBody"      : { vModOutBody       = lValue.dup; break; } 
    3630         case "ModOutDelim"     : { vModOutDelim      = lValue.dup; break; } 
    3631         case "ModOutFile"      : { vModOutFile       = lValue.dup; break; } 
    3632         case "GenDebugInfo"    : { vGenDebugInfo     = lValue.dup; break; } 
    3633         case "CompilerDefs"    : { vCompilerDefs     ~= std.string.split(lValue, ","); break; } 
    3634         case "HomePathId"      : { vHomePathId       = lValue.dup; break; } 
    3635         case "EtcPath"         : { vEtcPath          = lValue.dup; break; } 
    3636         case "UDResTypes"      : { vUDResTypes       ~= std.string.split(lValue, ","); break; } 
    3637         case "PostSwitches"    : { util.str.YesNo(lValue, vPostSwitches, false); break; } 
    3638         case "AppendLinkSwitches" : { util.str.YesNo(lValue, vAppendLinkSwitches, false); break; } 
    3639         case "ArgDelim"        : { vArgDelim         = lValue.dup; break; } 
    3640         case "ArgFileDelim"    : { vArgFileDelim     = lValue.dup; break; } 
    3641         // These cater for spelling mistakes used in an earlier version. 
    3642         case "ExeExtention"    : { vExeExtension     = lValue.dup; 
    3643                                    util.fileex.vExeExtension = vExeExtension; 
    3644                                    break; 
    3645                                  } 
    3646         case "LibExtention"    : { vLibExtension     = lValue.dup; break; } 
    3647         case "ObjExtention"    : { vObjExtension     = lValue.dup; break; } 
    3648         case "ShrLibExtention" : { vShrLibExtension  = lValue.dup; break; } 
    3649         case "SrcExtention"    : { vSrcExtension     = lValue.dup; break; } 
    3650         case "MacroExtention"  : { vMacroExtension   = lValue.dup; break; } 
    3651         case "DdocExtention"   : { vDdocExtension    = lValue.dup; break; } 
    3652         default: 
    3653             std.stdio.writefln("Set Internal String '%s' ignored ... unknown name.", pCommand); 
    3654     } 
    3655 
     3353 
     3354    return lCmdCnt; 
     3355
     3356 
     3357version(BuildVerbose) 
     3358
     3359void CheckVerbose(string[] pArgs) 
     3360
     3361    foreach(string lArg; pArgs) 
     3362    { 
     3363        if (lArg == "-V") 
     3364            opts.Verbose = True; 
     3365        else if (lArg == "--V") 
     3366            opts.Verbose = False; 
     3367        else if (lArg == "-v") 
     3368            opts.Verbose = True; 
     3369        else if (lArg == "--v") 
     3370            opts.Verbose = False; 
     3371    } 
     3372 
     3373
     3374
     3375 
     3376void ReadBuildConfigFile() 
     3377
     3378    int lCmdCount; 
     3379 
     3380    // Collect from configuration file(s). 
     3381    lCmdCount += ProcessBuildConfig("+", vCombinedArgs); 
     3382 
     3383    version(Windows) 
     3384    { 
     3385        lCmdCount += ProcessBuildConfig("+Windows", vCombinedArgs); 
     3386        version(DigitalMars) 
     3387        { 
     3388            lCmdCount += ProcessBuildConfig("+Windows:DigitalMars", vCombinedArgs); 
     3389        } 
     3390        version(GNU) 
     3391        { 
     3392            lCmdCount += ProcessBuildConfig("+Windows:GNU", vCombinedArgs); 
     3393        } 
     3394    } 
     3395 
     3396    version(Posix) 
     3397    { 
     3398        lCmdCount += ProcessBuildConfig("+Posix", vCombinedArgs); 
     3399        version(DigitalMars) 
     3400        { 
     3401            lCmdCount += ProcessBuildConfig("+Posix:DigitalMars", vCombinedArgs); 
     3402        } 
     3403        version(GNU) 
     3404        { 
     3405            lCmdCount += ProcessBuildConfig("+Posix:GNU", vCombinedArgs); 
     3406        } 
     3407    } 
     3408 
     3409    version(DigitalMars) 
     3410    { 
     3411        lCmdCount += ProcessBuildConfig("+DigitalMars", vCombinedArgs); 
     3412    } 
     3413 
     3414    version(GNU) 
     3415    { 
     3416        lCmdCount += ProcessBuildConfig("+GNU", vCombinedArgs); 
     3417    } 
     3418 
     3419    version(darwin) 
     3420    { 
     3421        lCmdCount += ProcessBuildConfig("+darwin", vCombinedArgs); 
     3422    } 
     3423 
     3424    if (lCmdCount == 0) 
     3425    { 
     3426        throw new BuildException("No configuration file items found."); 
     3427    } 
     3428
  • trunk/Source/build_bn.d

    r50 r52  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 2514
     4long auto_build_number = 3200
  • trunk/Source/docsrc/change_log.d

    r50 r52  
    55A list of changes and fixes that have been made. 
    66 
    7 $(SUBSECTION_H ,v3.04 -- /October/2006 ) 
     7$(SUBSECTION_H ,v3.05 -- 03/September/2007 ) 
     8$(LIST 
     9    $(ITEM ** $(B CHG) The utility's configuration file is now $(B mandatory ). 
     10    You must supply a configuration file with all the INIT: settings 
     11    particular to the compiler tools you are using. Example configuration 
     12    files are supplied in the distribution package. 
     13    ) 
     14    $(ITEM ** $(B CHG) The output file switch (-of for DMD and -o for GDC) are 
     15     no longer recognized by this tool. They are redundant because the -T 
     16     switch already implements the functionality. 
     17    ) 
     18    $(ITEM ** $(B CHG) The switch -od is now allowed for non-DigitalMars 
     19     compilers. Also, using -od no longer prevents you also using -op. 
     20     However, the results when using -op and/or -od are purely dependant 
     21     on the compiler being used. 
     22    ) 
     23    $(ITEM ** $(B FIX:) Correctly make "-op" a default switch only for 
     24         DigitalMars environments. 
     25    ) 
     26    $(ITEM ** $(B FIX:) The path specified in a "-od" switch can now contain 
     27    embedded spaces. 
     28    ) 
     29    $(ITEM ** $(B FIX:) Libraries are now presented to the linker 
     30      in the same order as supplied on the command line. 
     31    ) 
     32    $(ITEM ** $(B FIX:) Libraries and object files are now presented only 
     33     once to the linker. 
     34    ) 
     35    $(ITEM ** $(B FIX) A new configuration item $(I INIT:ShortPathNames) 
     36    is available for Windows users. If set to $(B Yes) then the tool 
     37    will convert all paths to their $(I short) form. This will get around 
     38    a limitation in the Windows linker that can't handle paths with 
     39    embedded spaces. 
     40    ) 
     41    $(ITEM ** $(B ENH) A new pragma $(I msg) is supported. It outputs the 
     42    user defined message to the console when compiling. 
     43    ) 
     44    $(ITEM ** $(B ENH) A new pragma $(I todo) is supported. It is a memory 
     45    aid for documenting things yet to do in your project. 
     46    ) 
     47    $(ITEM ** $(B ENH) A new switch $(I -showtodo ) is supported. It causes 
     48    the $(I todo) pragma to output its text to the console when compiling. 
     49    ) 
     50    $(ITEM ** $(B ENH) The Configuration File now supports a new $(I FAILURE) 
     51    command that allows you to run jobs after a failed build. 
     52    ) 
     53    $(ITEM ** $(B ENH) The new switch "-ut" allows simple unittest execution 
     54    of a module without the need to have a 'main' function. It is actually 
     55    just a short cut for the switches "-unittest -nolib -exec -full -cleanup" 
     56    ) 
     57    $(ITEM ** $(B ENH) The new switch "-f" is alternative method of 
     58    telling the tool that additional command line items are to be found 
     59    in a file. This works identically to the '@' response file option. 
     60    In other words, "-f cmds" is identical to "@cmds". 
     61    ) 
     62    $(ITEM ** $(B ENH) Configuration file entries, 'msg' and 'todo' pragmas, 
     63    and text macro definitions can now have embedded references to 
     64    environment symbols. 
     65    ) 
     66    $(ITEM ** $(B ENH) The default location of Bud's configuration file for 
     67    unix systems now includes "/etc", "$(ANG progpath)/../etc", "$(DOLLAR)HOME/.build", and 
     68    "$(DOLLAR)HOME/.$(ANG progname)" where "$(ANG progpath)" is the location of this utility 
     69    and "$(ANG progname)" is the name of this utility. 
     70    ) 
     71    $(ITEM ** $(B ENH) All the $(I INIT:) commands in the configuration 
     72    file are now case-insensitive. This means that INIT:ShortPathNames and 
     73    INIT:shortpathnames are treated as the same thing now. 
     74    ) 
     75    $(ITEM ** $(B ENH) All the $(I INIT:) commands can now also be placed 
     76    on the command line (or in a response file). These are processed after 
     77    all the entries in the configuration file, so they can be used to 
     78    temporarily override the respective item in the configuration 
     79    file. Note that if a command line argument includes spaces, they need 
     80    to be enclosed in quotes. 
     81    $(CODE "INIT:LibrarianOpts=-c -p256") 
     82    ) 
     83    $(ITEM ** $(B ENH:) If the $(I -LIBPATH=) switch is supplied without 
     84    a path, it removes all library paths so far declared. 
     85    ) 
     86
     87 
     88$(SUBSECTION_H ,v3.04 -- 16/October/2006 ) 
    889$(LIST 
    990    $(ITEM ** $(B FIX:) Correctly handle INIT:CompilerExe from configuration file 
  • trunk/Source/docsrc/configuration_file.d

    r50 r52  
    44$(SECTION 
    55The utility's configuration file is used to specify your default options 
    6 for the utility. The file is called $(B build.cfg). You can have from zero 
    7 to four configuration files because the $(I Bud) utility looks in each 
    8 of four places for a configuration file, and it uses each one that it finds. 
    9 It looks in the folder that $(I Bud) is installed, then in a user defined 
     6for the utility. The file is called $(B build.cfg). You can have a number 
     7of configuration files because the $(I Bud) utility looks in each 
     8of number of specific places for a configuration file, and it uses each one 
     9that it finds. 
     10Firstly it looks in the folder that $(I Bud) is installed. Then for 
     11Unix systems only, it looks in $(I /etc), $(I <budpath>/../etc), 
     12and $(I ~/.build)., Next it looks in a user defined 
    1013alternative path (defined by -BCFPATH switch), then in the folder 
    1114that the compiler is installed, and finally in the current folder. 
     
    5962successfully created. There can be any number of $(I FINAL) commands 
    6063in a configuration file; they are all executed, and in the order presented. 
     64$(BL) 
     65Note that if your program path may contain spaces, you should enclose it 
     66quotes so that there is no confusion. 
    6167$(BL) 
    6268You can place special tokens in the $(I FINAL) command line and these will 
     
    8187 
    8288$(B INIT:) $(BR) 
    83 This specifies an internal string value. The format is actually 
     89This specifies an internal variable value. The format is actually 
    8490$(I INIT:$(B stringname)) where $(I stringname) identifies the specific 
    85 internal string to set. 
     91internal string to set. Most of these simply replace the current setting 
     92of the particular internal variable however there are some internal 
     93variables that are actually lists. In this case the setting is appended 
     94to the end of the current list contents. If you need to erase an existing 
     95list before building a new one, you need to supply an empty value on the 
     96$(I INIT:) line. An empty value will clear a list. 
    8697$(CODE 
    8798   INIT:MapSwitch = -M 
     99   # Clear the automatically added Windows libraries. 
     100   INIT:AutoLibs = 
     101   # Build a new list of Windows libraries. 
     102   INIT:AutoLibs = gdi32,winsock2 
    88103) 
    89104$(INDENT 
    90105$(SECTION The identifiers for the settable strings are detailed below.) 
    91 $(TABROW ExeExtension, The file extension for executable files. $(EG exe)) 
    92 $(TABROW LibExtension, The file extension for library files.$(EG lib)) 
    93 $(TABROW ObjExtension, The file extension for object files.$(EG obj)) 
     106$(TABROW AutoLibs       , A list of Windows DLL libraries that 
     107                          will be provided to the linker when building 
     108                          a Windows application. If the application being 
     109                          compiled has a WinMain function or is otherwise 
     110                          identified as a Windows application then the 
     111                          following are default libraries automatically 
     112                          passed to the linker. Note that this behaviour 
     113                          can be turned off by the $(I -AutoWinLibs=No) 
     114                          switch. $(BR) 
     115                          $(LIST 
     116                                $(ITEM gdi32.lib) 
     117                                $(ITEM advapi32.lib) 
     118                                $(ITEM COMCTL32.LIB) 
     119                                $(ITEM comdlg32.lib) 
     120                                $(ITEM CTL3D32.LIB) 
     121                                $(ITEM kernel32.lib) 
     122                                $(ITEM ODBC32.LIB) 
     123                                $(ITEM ole32.lib) 
     124                                $(ITEM OLEAUT32.LIB) 
     125                                $(ITEM shell32.lib) 
     126                                $(ITEM user32.lib) 
     127                                $(ITEM uuid.lib) 
     128                                $(ITEM winmm.lib) 
     129                                $(ITEM winspool.lib) 
     130                                $(ITEM wsock32.lib) 
     131                          ) 
     132                          $(BL) 
     133                          $(EG gdi32,user32,kernel32)) 
     134$(TABROW ExeExtension   , The file extension for executable files. $(EG exe)) 
     135$(TABROW LibExtension   , The file extension for library files.$(EG lib)) 
     136$(TABROW ObjExtension   , The file extension for object files.$(EG obj)) 
    94137$(TABROW ShrLibExtension, The file extension for shared libraries files.$(EG dll)) 
    95138$(TABROW SrcExtension   , The file extension for D source files.$(EG d)) 
     
    100143                          it not to link, just compile the files instead.$(EG -c)) 
    101144$(TABROW LinkerExe      , The file name of the linker.$(EG link.exe)) 
     145$(TABROW CFGPath        , The optional additional path to check for Bud's 
     146                          configuration file.  As this 
     147                          is set from a configuration file, its effect only 
     148                          starts after the current configuration file has 
     149                          been processed.  $(EG /var/bud/)) 
    102150$(TABROW ConfigFile     , The name of the compiler's configuration file. $(EG sc.ini)) 
    103151$(TABROW CompilerPath   , If the compiler is not in the standard search PATH,