Changeset 52
- Timestamp:
- 03/01/08 11:07:11 (4 years ago)
- Files:
-
- trunk/Source/Makefile.dos (modified) (2 diffs)
- trunk/Source/Makefile.gdc (modified) (1 diff)
- trunk/Source/Makefile.unix (modified) (1 diff)
- trunk/Source/build.d (modified) (170 diffs)
- trunk/Source/build_bn.d (modified) (1 diff)
- trunk/Source/docsrc/change_log.d (modified) (1 diff)
- trunk/Source/docsrc/configuration_file.d (modified) (6 diffs)
- trunk/Source/docsrc/um.d (modified) (3 diffs)
- trunk/Source/docsrc/um.mac (added)
- trunk/Source/docsrc/user_manual.ddoc (deleted)
- trunk/Source/docsrc/user_manual_html.ddoc (added)
- trunk/Source/example_build.cfg (modified) (2 diffs)
- trunk/Source/gdc_build.cfg (added)
- trunk/Source/nix_dmd_build.cfg (modified) (2 diffs)
- trunk/Source/nix_gdmd_build.cfg (added)
- trunk/Source/nix_gnu_build.cfg (modified) (2 diffs)
- trunk/Source/opts.d (added)
- trunk/Source/opts_bn.d (added)
- trunk/Source/source.d (modified) (59 diffs)
- trunk/Source/source_bn.d (modified) (1 diff)
- trunk/Source/util/booltype.d (modified) (6 diffs)
- trunk/Source/util/fdt.d (modified) (10 diffs)
- trunk/Source/util/file2.d (modified) (4 diffs)
- trunk/Source/util/file2_bn.d (modified) (1 diff)
- trunk/Source/util/fileex.d (modified) (14 diffs)
- trunk/Source/util/fileex_bn.d (modified) (1 diff)
- trunk/Source/util/linetoken.d (modified) (5 diffs)
- trunk/Source/util/linetoken_bn.d (modified) (1 diff)
- trunk/Source/util/macro.d (deleted)
- trunk/Source/util/macroex.d (added)
- trunk/Source/util/pathex.d (modified) (29 diffs)
- trunk/Source/util/pathex_bn.d (modified) (1 diff)
- trunk/Source/util/str.d (modified) (68 diffs)
- trunk/Source/util/str_bn.d (modified) (1 diff)
- trunk/Source/win_dmd_build.cfg (modified) (2 diffs)
- trunk/Source/win_gnu_build.cfg (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Source/Makefile.dos
r48 r52 1 1 DMD=dmd 2 DFLAGS=-op -release -inline 2 DFLAGS=-op -release -inline -version=BuildVerbose 3 3 SOURCES=$(SOURCES) build.d 4 SOURCES=$(SOURCES) util/pathex_bn.d 5 SOURCES=$(SOURCES) util/pathex.d 4 SOURCES=$(SOURCES) opts.d 5 SOURCES=$(SOURCES) util\pathex_bn.d 6 SOURCES=$(SOURCES) util\pathex.d 6 7 SOURCES=$(SOURCES) source_bn.d 7 SOURCES=$(SOURCES) util /str.d8 SOURCES=$(SOURCES) util\str.d 8 9 SOURCES=$(SOURCES) build_bn.d 9 SOURCES=$(SOURCES) util /fdt_bn.d10 SOURCES=$(SOURCES) util /str_bn.d10 SOURCES=$(SOURCES) util\fdt_bn.d 11 SOURCES=$(SOURCES) util\str_bn.d 11 12 SOURCES=$(SOURCES) source.d 12 SOURCES=$(SOURCES) util /fdt.d13 SOURCES=$(SOURCES) util /fileex.d14 SOURCES=$(SOURCES) util /fileex_bn.d15 SOURCES=$(SOURCES) util /linetoken.d16 SOURCES=$(SOURCES) util /linetoken_bn.d17 SOURCES=$(SOURCES) util /macro.d18 SOURCES=$(SOURCES) util /booltype.d19 SOURCES=$(SOURCES) util /file2.d13 SOURCES=$(SOURCES) util\fdt.d 14 SOURCES=$(SOURCES) util\fileex.d 15 SOURCES=$(SOURCES) util\fileex_bn.d 16 SOURCES=$(SOURCES) util\linetoken.d 17 SOURCES=$(SOURCES) util\linetoken_bn.d 18 SOURCES=$(SOURCES) util\macro.d 19 SOURCES=$(SOURCES) util\booltype.d 20 SOURCES=$(SOURCES) util\file2.d 20 21 21 22 … … 23 24 24 25 build: $(SOURCES) 25 $(DMD) $(DFLAGS) -of $@$(SOURCES)26 $(DMD) $(DFLAGS) -ofbud $(SOURCES) 26 27 27 28 clean: trunk/Source/Makefile.gdc
r48 r52 1 1 DMD=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.d2 DFLAGS=-op -release -inline -version=BuildVerbose 3 SOURCES=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 4 4 5 5 all: build 6 6 7 7 build: $(SOURCES) 8 $(DMD) $(DFLAGS) -of $@$(SOURCES)8 $(DMD) $(DFLAGS) -ofbud $(SOURCES) 9 9 10 10 clean: trunk/Source/Makefile.unix
r48 r52 1 1 DMD=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.d2 DFLAGS=-op -release -inline -version=BuildVerbose 3 SOURCES=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 4 4 5 5 all: build 6 6 7 7 build: $(SOURCES) 8 $(DMD) $(DFLAGS) -of $@$(SOURCES)8 $(DMD) $(DFLAGS) -ofbud $(SOURCES) 9 9 10 10 clean: trunk/Source/build.d
r50 r52 1 1 /* ******************************************************* 2 Buildis a tool to assist building applications and libraries written2 This is a tool to assist building applications and libraries written 3 3 using the D programming language. 4 4 … … 6 6 Authors: Derek Parnell, Melbourne 7 7 Initial Creation: January 2005 8 Version: 3.0 49 Date: October 20068 Version: 3.05 9 Date: September 2007 10 10 License: 11 11 This software is provided 'as-is', without any express or implied … … 30 30 private import build_bn; // This module's build number 31 31 32 alias char[] text; 33 34 version(D_Version2) 35 { 36 mixin("alias invariant(dchar) dcharc;"); 37 mixin("alias invariant(wchar) wcharc;"); 38 mixin("alias invariant(char) charc;"); 39 } 40 else 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 32 51 version(unix) version = Unix; 33 52 version(Unix) version = Posix; 34 53 version(linux) version = Posix; 35 54 version(darwin) version = Posix; 36 version(DigitalMars) version(Windows) version = UseResponseFile; 55 56 const vMyVersion = "3.05"; 57 version(build) pragma(todo, "Single file compilation"); 58 version(build) pragma(todo, "Output Paths"); 37 59 38 60 version(build) … … 40 62 version(Windows) { 41 63 // OptLink Definition File 42 pragma (build_def, "VERSION 3.04"); 43 } 44 } 45 64 pragma (build_def, "VERSION 3.05"); 65 } 66 } 46 67 47 68 private{ 48 alias char[] string;49 69 // --------- imports ---------------- 50 70 static import source; // Source File class 71 static import opts; // Run time options 51 72 52 73 static import util.str; // non-standard string routines. … … 54 75 static import util.pathex; // Extended Path routines. 55 76 static import util.fileex; // Extended File routines. 56 static import util.macro ; // Macro processing routines.77 static import util.macroex; // Macro processing routines. 57 78 static import util.booltype; // definition of True and False 58 79 alias util.booltype.True True; … … 72 93 static import std.c.windows.windows; 73 94 } 74 75 95 else version(linux) 76 96 { … … 93 113 this(string pMsg) 94 114 { 95 super (v AppName ~ ":" ~ pMsg);115 super (vMyName ~ ":" ~ pMsg); 96 116 } 97 117 } … … 100 120 enum LibOpt {Implicit, Build, DontBuild} 101 121 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`;122 122 123 123 // ---------- 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 262 132 Bool vScanImports; 263 133 Bool vNoLink; 264 Bool vForceCompile;265 134 Bool vSilent; 266 135 Bool vSymbols; 267 136 Bool vCleanup; 268 version(BuildVerbose) Bool vVerbose;269 137 Bool vMacroInput; 270 138 Bool vCollectUses; … … 274 142 Bool vAutoImports; 275 143 Bool vExecuteProgram; 276 Bool vUseResponseFile;277 144 Bool vConsoleApp; 278 145 Bool vUseFinal; 279 146 Bool vEmptyArgs; 147 Bool vCleanDummy; 280 148 281 149 string vUsesOutput; … … 283 151 string vRunParms; 284 152 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; 294 159 string vTargetName; // Output name from first file name. 295 160 string vPragmaTargetName; // Output name from pragma. 296 161 string vCommandTargetName; // Output name from switches. 297 162 string[] vCmdLineSourceFiles; // List of source files from command line 298 bool[string]vLinkFiles; // List of non-source files from command line163 string[] vLinkFiles; // List of non-source files from command line 299 164 string[] vCombinedArgs; // All the args are gathered here prior to processing. 300 165 string[] vBuildArgs; // Arguments passed to build 301 166 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. 303 168 bool[string] vResourceFileTypes; 304 string[] vUDResTypes;305 169 306 170 307 171 version(Windows) 308 172 { 309 string vWinVer = "";310 ubyte vWinVerNum;311 bool vAutoWinLibs = true;173 string vWinVer; 174 ubyte vWinVerNum; 175 bool vAutoWinLibs = true; 312 176 } 313 177 … … 324 188 vSourceScanList ~= "." ~ std.path.sep; 325 189 vNoLink = False; 326 vTestRun = False;327 vExplicit = False;328 190 vScanImports = False; 329 191 vUseFinal = True; 330 192 vEmptyArgs = True; 331 vForceCompile = False;332 193 vSilent = False; 333 194 vCleanup = False; 334 version(BuildVerbose) vVerbose = False;335 195 vMacroInput = True; 336 196 vCollectUses = False; … … 340 200 vAutoImports = True; 341 201 vExecuteProgram = False; 342 vUseResponseFile = False;343 202 vSymbols = False; 344 203 vConsoleApp = True; 204 vCleanDummy = False; 345 205 346 206 version(Posix) 347 207 { 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. 349 209 } 350 210 … … 354 214 } 355 215 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)); 363 219 364 220 } … … 371 227 std.stdio.writefln( 372 228 "Path and Version : %s v%s(%d)\n built on %s" 373 ,v AppPath, vAppVersion, build_bn.auto_build_number,229 ,vMyPath, vMyVersion, build_bn.auto_build_number, 374 230 __TIMESTAMP__); 375 231 if (pFull == false) … … 379 235 std.stdio.writefln( 380 236 "Usage: %s sourcefile [options objectfiles libraries]" 381 , v AppName);237 , vMyName); 382 238 std.stdio.writefln(" sourcefile D source file"); 383 239 std.stdio.writefln(" -v Verbose (passed through to D)"); … … 388 244 std.stdio.writefln(" PATH list. Used if you are testing an alternate"); 389 245 std.stdio.writefln(" version of the compiler."); 390 std.stdio.writefln(" -CFPATH<path> <path> is where the Dconfig file has been installed.");391 std.stdio.writefln(" -BCFPATH<path> <path> is where the Buildconfig 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."); 392 248 std.stdio.writefln(" -full Causes all source files, except ignored modules,"); 393 249 std.stdio.writefln(" to be compiled."); … … 467 323 std.stdio.writefln(" -noautoimport Turns off the automatic addition of source paths"); 468 324 std.stdio.writefln(" to the list of Import Roots."); 469 std.stdio.writefln(" -info Displays the version and path of th e Buildapplication.");325 std.stdio.writefln(" -info Displays the version and path of this application."); 470 326 std.stdio.writefln(" -nodef Prevents a Module Definition File from being created."); 471 327 std.stdio.writefln(" -UMB=<Yes/No> If 'Yes' this forces the utility to expect"); … … 516 372 version(BuildVerbose) 517 373 { 518 if( vVerbose == True) {374 if(opts.Verbose == True) { 519 375 std.stdio.writefln("source file[%d] %s", i, 520 util.pathex.AbbreviateFileName(lSource.FileName));376 source.ReducePathName(lSource.FileName)); 521 377 } 522 378 else if(vNames == True) { 523 std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lSource.FileName));379 std.stdio.writefln(" [ %s ]", source.ReducePathName(lSource.FileName)); 524 380 } 525 381 } else { 526 382 if(vNames == True) { 527 std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lSource.FileName));383 std.stdio.writefln(" [ %s ]", source.ReducePathName(lSource.FileName)); 528 384 } 529 385 } … … 533 389 version(BuildVerbose) 534 390 { 535 if( vVerbose == True)391 if(opts.Verbose == True) 536 392 std.stdio.writefln("Newer time: from %s to %s", 537 393 lModsTime.toString(), … … 548 404 549 405 // Examine any link file dependancies too. 550 foreach(int idx, string lFileName; vLinkFiles .keys)406 foreach(int idx, string lFileName; vLinkFiles) 551 407 { 552 408 util.fdt.FileDateTime lLinkTime = new util.fdt.FileDateTime(lFileName); … … 554 410 version(BuildVerbose) 555 411 { 556 if( vVerbose == True) {412 if(opts.Verbose == True) { 557 413 std.stdio.writefln("link file[%d] %s %s", idx, 558 util.pathex.AbbreviateFileName(lFileName), lLinkTime.toString());414 source.ReducePathName(lFileName), lLinkTime.toString()); 559 415 } 560 416 else if(vNames == True) { 561 std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName));417 std.stdio.writefln(" [ %s ]", source.ReducePathName(lFileName)); 562 418 } 563 419 } else { 564 420 if(vNames == True) { 565 std.stdio.writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName));421 std.stdio.writefln(" [ %s ]", source.ReducePathName(lFileName)); 566 422 } 567 423 } … … 570 426 version(BuildVerbose) 571 427 { 572 if( vVerbose == True)428 if(opts.Verbose == True) 573 429 std.stdio.writefln("Newer time: from %s to %s", 574 430 lModsTime.toString(), … … 584 440 } 585 441 586 587 /* Build the target. Return an error code if there 442 //------------------------------------------------------- 443 int 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 588 483 was a problem, else return zero. 589 484 */ 590 485 //------------------------------------------------------- 591 int Build()486 int MakeItSo() 592 487 //------------------------------------------------------- 593 488 { … … 614 509 string[] lLibraryFiles; 615 510 616 617 511 lCompiling = False; 618 512 lLinking = False; … … 622 516 foreach( string lFile; vCmdLineSourceFiles) 623 517 { 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) 626 521 { 627 522 version(BuildVerbose) 628 523 { 629 if ( vVerbose == True)630 std.stdio.writefln("Macro file '%s' being processed.", lF ile);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 lF ile = 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; 636 531 else 637 532 { 638 533 version(BuildVerbose) 639 534 { 640 if ((vSilent != True) || ( vVerbose == True))641 std.stdio.writefln("Macro file '%s' failed to generate output", lF ile);535 if ((vSilent != True) || (opts.Verbose == True)) 536 std.stdio.writefln("Macro file '%s' failed to generate output", lFullFile); 642 537 } else { 643 538 if (vSilent != True) 644 std.stdio.writefln("Macro file '%s' failed to generate output", lF ile);645 } 646 lF ile.length = 0;647 } 648 } 649 650 if (lF ile.length > 0)651 { 652 new source.Source(lF ile);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); 653 548 } 654 549 } … … 657 552 // found, and I was not explicitly told not to link. 658 553 lLinking = (vLibraryAction == LibOpt.Build) || 659 (source.Source.WasMainFound == false) ||554 (source.Source.WasMainFound == False) || 660 555 (vNoLink == True) 661 556 ? False : True; … … 665 560 // If not explictly known, set the library action 666 561 // 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 { 669 566 vLibraryAction = LibOpt.DontBuild; 670 567 } 671 else { 568 else 569 { 672 570 vLibraryAction = LibOpt.Build; 673 571 } 674 572 } 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 675 591 676 592 // I'm either creating a library, an executable or neither. … … 683 599 version(BuildVerbose) 684 600 { 685 if( vVerbose == True)601 if(opts.Verbose == True) 686 602 std.stdio.writefln("Pragma target override is '%s'", std.path.getName(vTargetName)); 687 603 } … … 697 613 version(BuildVerbose) 698 614 { 699 if( vVerbose == True)615 if(opts.Verbose == True) 700 616 std.stdio.writefln("Cmdline target override is '%s'", vTargetName); 701 617 } 702 618 } 619 620 vTargetName = source.ExpandPathName(vTargetName, False); 703 621 704 622 // Ensure that the path to the target's location will exist. … … 708 626 if (vLibraryAction == LibOpt.Build) 709 627 // Target is a library. 710 lTargetName = util.pathex.ReplaceExtension(vTargetName, vLibExtension);628 lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.LibExtension); 711 629 712 630 else if (vNoLink == False) 713 631 { 714 if (source.Source.WasMainFound )632 if (source.Source.WasMainFound == True) 715 633 if (source.Source.WasMainDLL) 716 634 // Target is a shared library. 717 lTargetName = util.pathex.ReplaceExtension(vTargetName, vShrLibExtension);635 lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.ShrLibExtension); 718 636 else 719 637 { 720 638 // Target is an executable 721 lTargetName = util.pathex.ReplaceExtension(vTargetName, vExeExtension);639 lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.ExeExtension); 722 640 vTargetExe = lTargetName; 723 641 } … … 727 645 // so assume they know what they are doing and also assume an 728 646 // executable is required. 729 lTargetName = util.pathex.ReplaceExtension(vTargetName, vExeExtension);647 lTargetName = util.pathex.ReplaceExtension(vTargetName, opts.ExeExtension); 730 648 vTargetExe = lTargetName; 731 649 } … … 733 651 else 734 652 // Not linking and not archiving, so no target is required. 735 lTargetName = "";653 lTargetName.length = 0; 736 654 737 655 if (lTargetName.length > 0) 738 656 { 739 657 // Get the full name of the target's location. 740 lTargetName = util.pathex.CanonicalPath(lTargetName, false);658 lTargetName = source.ExpandPathName(lTargetName, False); 741 659 lTargetDir = std.path.getDirName(lTargetName); 742 660 … … 744 662 version(BuildVerbose) 745 663 { 746 if(( vVerbose == True) || (vNames == True) )664 if((opts.Verbose == True) || (vNames == True) ) 747 665 std.stdio.writefln("\nBuilding target '%s'", lTargetName); 748 666 } 749 667 750 668 // Shorten the target name for future usages. 751 lTargetName = util.pathex.AbbreviateFileName(lTargetName);669 lTargetName = source.ReducePathName(lTargetName); 752 670 753 671 … … 758 676 version(BuildVerbose) 759 677 { 760 if( vVerbose == True) {678 if(opts.Verbose == True) { 761 679 std.stdio.writefln("Time %s for %s (target)", lTargetTime.toString(), lTargetName); 762 680 std.stdio.writefln("Time %s (most recent)", lMostRecentTime.toString()); … … 772 690 version(BuildVerbose) 773 691 { 774 if(( vVerbose == True) || (vNames == True) )692 if((opts.Verbose == True) || (vNames == True) ) 775 693 std.stdio.writefln("\nCompiling only. No target will be built."); 776 694 } else { … … 789 707 // No files to compile, just link files, so collect 790 708 // all the object files to link in. 791 foreach( string lFileName; vLinkFiles .keys)709 foreach( string lFileName; vLinkFiles) 792 710 { 793 711 // Only include OBJECT files. 794 if (util.str.ends(lFileName , vObjExtension) == True)712 if (util.str.ends(lFileName , opts.ObjExtension) == True) 795 713 lFilesToLink ~= lFileName; 796 714 } … … 823 741 string lFileType; 824 742 825 lNeedsCompiling = vForceCompile;743 lNeedsCompiling = opts.ForceCompile; 826 744 827 745 if (lCurrentSource.Ignore) 828 746 return 0; 829 747 830 lShortFileName = util.pathex.AbbreviateFileName(lCurrentSource.FileName);748 lShortFileName = source.ReducePathName(lCurrentSource.FileName); 831 749 lFileType = std.path.getExt(lShortFileName); 832 if (lFileType != vSrcExtension && lFileType != vDdocExtension)750 if (lFileType != opts.SrcExtension && lFileType != opts.DdocExtension) 833 751 return 0; 834 752 835 753 // Only source files are examined from here on. 836 if (lCurrentSource.NoLink || lFileType == vDdocExtension)754 if (lCurrentSource.NoLink || lFileType == opts.DdocExtension) 837 755 { 838 756 lNonLinkingSources ~= lCurrentSource; … … 843 761 version(BuildVerbose) 844 762 { 845 if ( vVerbose == True)763 if (opts.Verbose == True) 846 764 std.stdio.writefln("%s newer than its object file", lShortFileName); 847 765 } … … 852 770 version(BuildVerbose) 853 771 { 854 if ( vVerbose == True)772 if (opts.Verbose == True) 855 773 std.stdio.writefln("%s has newer dependants than its object file.", 856 774 lShortFileName); … … 870 788 // Check to see if I'm allowed to link this file. 871 789 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) 875 793 { 876 794 if (lCurrentSource.IncrementBuildNumber()) … … 878 796 version(BuildVerbose) 879 797 { 880 if ( vVerbose == True)798 if (opts.Verbose == True) 881 799 std.stdio.writefln("New build number %d for %s", 882 800 lCurrentSource.BuildNumber, … … 888 806 else if (lCurrentSource.NoLink == false) 889 807 { 890 lFilesToLink ~= util.pathex.AbbreviateFileName(lCurrentSource.ObjectName);808 lFilesToLink ~= source.ReducePathName(lCurrentSource.ObjectName); 891 809 } 892 810 … … 919 837 if (vAutoWinLibs == true) 920 838 { 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 } 936 843 } 937 844 } … … 957 864 lDefName = vTemporaryPath ~ std.path.getBaseName(lDefName); 958 865 } 959 lDefName = util.pathex.AbbreviateFileName(lDefName);866 lDefName = source.ReducePathName(lDefName); 960 867 util.fileex.CreateTextFile(lDefName, vBuildDef); 961 868 … … 965 872 // Add any library and any external object files required. 966 873 lLibraryFiles.length = 0; 967 foreach (string lFileName; vLinkFiles .keys)874 foreach (string lFileName; vLinkFiles) 968 875 { 969 876 string lCmdItem; … … 972 879 { 973 880 lCmdItem = lFileName; 974 if ( util.str.ends(lCmdItem, "." ~ vLibExtension) == True)881 if ( util.str.ends(lCmdItem, "." ~ opts.LibExtension) == True) 975 882 { 976 883 // Cut off extension. 977 lCmdItem.length = lCmdItem.length - vLibExtension.length - 1;884 lCmdItem.length = lCmdItem.length - opts.LibExtension.length - 1; 978 885 lLibraryFiles ~= lCmdItem; 979 886 } … … 995 902 lCommandLine = GatherCompilerArgs(lLinking) ~ lSourcesToCompile; 996 903 997 if ( vUseResponseFile == True)904 if (opts.UseResponseFile == True) 998 905 { 999 906 lDResponseFileName = util.pathex.ReplaceExtension(lTargetName, "rsp"); … … 1002 909 lDResponseFileName = vTemporaryPath ~ std.path.getBaseName(lDResponseFileName); 1003 910 } 1004 lDResponseFileName = util.pathex.AbbreviateFileName(lDResponseFileName);911 lDResponseFileName = source.ReducePathName(lDResponseFileName); 1005 912 util.fileex.CreateTextFile(lDResponseFileName,lCommandLine); 1006 lCommand = vCompileOnly ~ " @" ~ lDResponseFileName;913 lCommand = opts.CompileOnly ~ " " ~ util.str.enquote("@" ~ lDResponseFileName); 1007 914 } 1008 915 else 1009 916 { // using commandline; may run into limits 1010 917 lCommandLine=std.string.replace(lCommandLine, "\n", " "); 1011 lCommand = vCompileOnly ~ " " ~ lCommandLine;918 lCommand = opts.CompileOnly ~ " " ~ lCommandLine; 1012 919 } 1013 920 1014 921 version(BuildVerbose) 1015 922 { 1016 if ( vVerbose == True)923 if (opts.Verbose == True) 1017 924 std.stdio.writefln("Compiling with ..........\n%s\n", lCommandLine); 1018 925 } 1019 926 1020 927 // 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); 1022 929 if (lRunResult != 0) 1023 930 vExecuteProgram = False; … … 1034 941 if (vResourceFileTypes.length == 0) 1035 942 { 1036 if (vUDResTypes.length == 0) 1037 { 1038 vUDResTypes ~= "res"; 1039 } 1040 foreach( string lResType; vUDResTypes) 943 foreach( string lResType; opts.UDResTypes) 1041 944 { 1042 945 vResourceFileTypes[lResType] = true; … … 1044 947 } 1045 948 1046 // Buildthe command line for the linker.1047 lCommandLine = "";949 // Construct the command line for the linker. 950 lCommandLine.length = 0; 1048 951 version(Windows) 1049 952 { … … 1053 956 if (util.str.begins(lCompileArg, "-L") == True) 1054 957 { 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, "/")) 1059 962 { 1060 963 if (lSwitch == "nomap") … … 1074 977 { 1075 978 // Only include OBJECT files. 1076 if (std.path.getExt(lFile) == vObjExtension)979 if (std.path.getExt(lFile) == opts.ObjExtension) 1077 980 { 1078 981 if (lCnt > 0) 1079 lCommandLine ~= vArgFileDelim; 1080 lCommandLine ~= lFile; 982 lCommandLine ~= opts.ArgFileDelim; 983 lCommandLine ~= source.ReducePathName( 984 source.ExpandPathName(lFile, False)); 1081 985 lCnt++; 1082 986 } … … 1086 990 1087 991 // (2) Set the output file name 1088 lCommandLine ~= util.str.enquote(util.pathex.AbbreviateFileName(lTargetName)) ~ "\n";992 lCommandLine ~= source.ReducePathName(lTargetName) ~ "\n"; 1089 993 1090 994 // (3) Set the map name 1091 995 if (IsMapping == True) 1092 lCommandLine ~= util.pathex.ReplaceExtension(lTargetName, "map");996 lCommandLine ~= source.ReducePathName(util.pathex.ReplaceExtension(lTargetName, "map")); 1093 997 1094 998 lCommandLine ~= "\n"; … … 1096 1000 // (4) Gather the libraries names. 1097 1001 // Include the default libraries first. 1098 lLibraryFiles = vDefaultLibs ~ lLibraryFiles;1002 lLibraryFiles = opts.DefaultLibs ~ lLibraryFiles; 1099 1003 if (lLibraryFiles.length > 0) 1100 1004 { 1101 1005 foreach( int i, string lLib; lLibraryFiles) 1102 1006 { 1103 lLib = std.path.addExt(lLib, vLibExtension); 1007 string lLibFile; 1008 lLibFile = util.pathex.EnsureExtension(lLib, opts.LibExtension); 1104 1009 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)); 1108 1014 } 1109 1015 } … … 1111 1017 1112 1018 // 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 { 1118 1021 // Include the paths to the libraries. 1119 1022 version(BuildVerbose) 1120 1023 { 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); 1125 1028 } 1126 1029 1127 1030 // (5) Set the 'def' file name 1128 1031 if (lDefName.length > 0) 1129 lCommandLine ~= util.str.enquote(lDefName) ~ "\n";1032 lCommandLine ~= source.ReducePathName(source.ExpandPathName(lDefName, False)) ~ "\n"; 1130 1033 else 1131 1034 lCommandLine ~= "\n"; … … 1144 1047 { 1145 1048 if (lCnt > 0) 1146 lCommandLine ~= vArgFileDelim; 1147 lCommandLine ~= lFile; 1049 lCommandLine ~= opts.ArgFileDelim; 1050 lCommandLine ~= source.ReducePathName( 1051 source.ExpandPathName(lFile, False)); 1148 1052 lCnt++; 1149 1053 } … … 1153 1057 1154 1058 // (7) Gather then switches 1155 lLinkerSwitches = util.str.strip( vLinkerDefs ~ lLinkerSwitches);1059 lLinkerSwitches = util.str.strip(opts.LinkerDefs ~ lLinkerSwitches); 1156 1060 } 1157 1061 … … 1163 1067 if (util.str.begins(lCompileArg, "-L") == True) 1164 1068 { 1165 lLinkerSwitches ~= lCompileArg[2..$] ~ vArgDelim;1069 lLinkerSwitches ~= lCompileArg[2..$] ~ opts.ArgDelim; 1166 1070 } 1167 1071 } … … 1174 1078 1175 1079 // (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"; 1177 1081 1178 1082 // (3) Set the map name 1179 1083 if (IsMapping == True) 1180 lLinkerSwitches ~= vMapSwitch ~ vArgDelim;1084 lLinkerSwitches ~= opts.MapSwitch ~ opts.ArgDelim; 1181 1085 1182 1086 // (4) Gather the libraries names. 1183 1087 // 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 { 1194 1097 // Include the paths to the libraries. 1195 1098 version(BuildVerbose) 1196 1099 { 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); 1199 1102 } 1200 1103 1201 1104 string[] lLibPaths; 1202 lLibPaths = std.string.split( vLibPaths, vConfigSep);1105 lLibPaths = std.string.split(opts.LibPaths, opts.ConfigSep); 1203 1106 foreach(string lLib; lLibPaths) 1204 1107 { 1205 1108 if (lLib.length > 0) 1206 lCommandLine ~= vLibPathSwitch ~ util.str.enquote(lLib) ~ "\n"; 1109 lCommandLine ~= opts.LibPathSwitch ~ 1110 util.str.enquote(lLib) ~ 1111 "\n"; 1207 1112 } 1208 1113 } 1209 1114 1210 1115 // (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) 1215 1120 { 1216 1121 lLinkResponseFileName = util.pathex.ReplaceExtension(lTargetName, "ksp"); … … 1219 1124 lLinkResponseFileName = vTemporaryPath ~ std.path.getBaseName(lLinkResponseFileName); 1220 1125 } 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) 1226 1131 { 1227 1132 lCommandLine = util.str.stripr(lCommandLine); … … 1232 1137 lCommandLine = lLinkerSwitches ~ "\n" ~ lCommandLine; 1233 1138 util.fileex.CreateTextFile(lLinkResponseFileName,lCommandLine); 1234 lCommand = "@" ~ lLinkResponseFileName; 1139 lCommand = util.str.enquote("@" ~ 1140 source.ReducePathName( 1141 source.ExpandPathName(lLinkResponseFileName, False))); 1235 1142 } 1236 1143 else 1237 1144 { // using commandline; may run into limits 1238 if ( vPostSwitches)1145 if (opts.PostSwitches) 1239 1146 lCommandLine ~= lLinkerSwitches ~ "\n"; 1240 1147 else 1241 1148 lCommandLine = lLinkerSwitches ~ "\n" ~ lCommandLine; 1242 1149 1243 lCommandLine=std.string.replace(lCommandLine, "\n", vArgDelim);1150 lCommandLine=std.string.replace(lCommandLine, "\n", opts.ArgDelim); 1244 1151 // Locate switches and change delim from a comma to a blank, 1245 1152 // then remove any trailing comma too. … … 1248 1155 int lPos = std.string.find(lCommandLine, lLinkerSwitches[0]); 1249 1156 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; 1255 1162 lCommand = lCommandLine; 1256 1163 } … … 1258 1165 version(BuildVerbose) 1259 1166 { 1260 if ( vVerbose == True)1167 if (opts.Verbose == True) 1261 1168 std.stdio.writefln("Linking with ..........\n%s\n", lCommandLine); 1262 1169 } … … 1265 1172 if (vSilent == True) 1266 1173 { 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); 1271 1178 if (lRunResult != 0) 1272 1179 vExecuteProgram = False; … … 1284 1191 if ( (source.Source.WasMainDLL) && (lRunResult == 0) ) 1285 1192 { 1286 string lTargetFileName;1287 string lImpLibPath;1288 string lImpLibArgs;1193 string lTargetFileName; 1194 string lImpLibPath; 1195 string lImpLibArgs; 1289 1196 ulong[] lImpManf; 1290 1197 1291 1198 vExecuteProgram = False; 1292 1199 1293 lImpLibPath = util.pathex.LocateFile("implib.exe", util.str.GetEnv( vPathId));1200 lImpLibPath = util.pathex.LocateFile("implib.exe", util.str.GetEnv(opts.PathId)); 1294 1201 if (util.file2.FileExists(lImpLibPath)) 1295 1202 { … … 1302 1209 lTargetFileName = std.path.getBaseName(lTargetName); 1303 1210 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 ); 1306 1213 } 1307 1214 } … … 1312 1219 vExecuteProgram = False; 1313 1220 1314 lOutText = vLibrarianOpts ~ std.path.linesep;1221 lOutText = opts.LibrarianOpts ~ std.path.linesep; 1315 1222 lOutText ~= lTargetName ~ std.path.linesep; // Create a new library 1316 1223 … … 1318 1225 { 1319 1226 string lFileDir; 1227 string lFullFileName; 1228 1320 1229 1321 1230 lFileDir = std.path.getDirName(lFileName); 1231 lFullFileName = lFileName; 1322 1232 if ((vAllObjects == True) || lFileDir == "" || lFileDir == lTargetDir) 1323 1233 { 1324 if (lF ileName.length > 1 + vSrcExtension.length)1325 { 1326 if (lF ileName[$-vSrcExtension.length .. $] == vSrcExtension)1327 { 1328 lF ileName = 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; 1329 1239 } 1330 1240 } 1331 1241 lFileCount++; 1332 lOutText ~= lF ileName ~ std.path.linesep;1242 lOutText ~= lFullFileName ~ std.path.linesep; 1333 1243 } 1334 1244 } … … 1336 1246 if (lFileCount > 0) 1337 1247 { 1338 if ( vUseResponseFile == True) {1248 if (opts.UseResponseFile == True) { 1339 1249 lLResponseFileName = util.pathex.ReplaceExtension(lTargetName, "lsp"); 1340 1250 if (vTemporaryPath.length != 0) … … 1352 1262 version(BuildVerbose) 1353 1263 { 1354 if ( vVerbose == True)1264 if (opts.Verbose == True) 1355 1265 std.stdio.writefln("Librarian with ..........\n%s\n", lOutText); 1356 1266 } 1357 1267 1358 lRunResult = util.fileex.RunCommand( vLibrarianPath ~ vLibrarian, lCommand);1268 lRunResult = util.fileex.RunCommand(opts.LibrarianPath ~ opts.Librarian, lCommand, &RunCallBack); 1359 1269 } 1360 1270 } … … 1367 1277 version(BuildVerbose) 1368 1278 { 1369 if ( vVerbose == True)1279 if (opts.Verbose == True) 1370 1280 std.stdio.writefln("Cleaning up ..."); 1371 1281 } … … 1384 1294 } 1385 1295 ); 1386 // Build's own temprary files.1296 // The utilities's own temprary files. 1387 1297 lHitList ~= lDResponseFileName; 1388 1298 lHitList ~= lLinkResponseFileName; … … 1395 1305 lHitList ~= util.pathex.ReplaceExtension(lTargetName, "lst"); 1396 1306 1307 1397 1308 foreach(string lFilename; lHitList) 1398 1309 { … … 1403 1314 version(BuildVerbose) 1404 1315 { 1405 if ( vVerbose == True)1316 if (opts.Verbose == True) 1406 1317 std.stdio.writefln(" removing %s", lFilename); 1407 1318 } … … 1413 1324 } 1414 1325 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 1432 1364 1433 1365 return lRunResult; … … 1436 1368 1437 1369 // ------------------------------------------- 1438 char []GatherCompilerArgs(Bool pLinking)1370 string GatherCompilerArgs(Bool pLinking) 1439 1371 // ------------------------------------------- 1440 1372 { 1441 1373 string lOutText; 1442 1374 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. 1452 1381 foreach (string lCompileArg; vCompilerArgs) 1453 1382 { … … 1462 1391 // Strip off any trailing shell escape lead-in character. 1463 1392 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); 1466 1396 } 1467 1397 else … … 1477 1407 if (pLinking == False) 1478 1408 { // 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); 1483 1413 else 1484 lOutText ~= vCompileOnly;1414 lOutText ~= opts.CompileOnly; 1485 1415 // Terminate with a newline char. 1486 1416 lOutText ~= "\n"; 1487 1417 1488 AddCompilerArg( vCompileOnly );1418 AddCompilerArg( opts.CompileOnly ); 1489 1419 } 1490 1420 } … … 1498 1428 // ------------------------------------------- 1499 1429 { 1500 return vModulesToIgnore;1430 return opts.ModulesToIgnore; 1501 1431 } 1502 1432 … … 1506 1436 // ------------------------------------------- 1507 1437 { 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 1512 1454 } 1513 1455 … … 1527 1469 if (vPragmaTargetName != pPath) 1528 1470 { 1529 if ( vVerbose == True)1471 if (opts.Verbose == True) 1530 1472 std.stdio.writefln("Multiple pragma(target,...) detected. '%s' will be used and '%s' rejected.", 1531 1473 vPragmaTargetName, pPath ); … … 1560 1502 } 1561 1503 else { 1562 vBuildDef ~= pText; 1504 vBuildDef ~= pText; 1505 1563 1506 lElementIdx[ lLowerText ] = vBuildDef.length-1; 1564 1507 } … … 1577 1520 { 1578 1521 if (pArg[0..3] == `+v+`) 1579 pArg = vVersionSwitch ~ "=" ~ pArg[3..$];1522 pArg = opts.VersionSwitch ~ "=" ~ pArg[3..$]; 1580 1523 } 1581 1524 … … 1605 1548 return pRootName; 1606 1549 1607 lFullName = util.pathex.CanonicalPath(pRootName);1550 lFullName = source.ExpandPathName(pRootName, True /* Always a path */ ); 1608 1551 version(Windows) lSearchName = std.string.tolower(lFullName); 1609 1552 version(Posix) lSearchName = lFullName; … … 1636 1579 string[] lRoots; 1637 1580 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); 1680 1583 1681 1584 foreach(string lSwitch; lArgs) 1682 1585 { 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 ); 1767 1587 } 1768 1588 } 1769 1589 1770 1590 // ------------------------------------------- 1771 void ReadEnviron()1591 void GetEnvironSwitches() 1772 1592 // ------------------------------------------- 1773 1593 { … … 1780 1600 version(BuildVerbose) 1781 1601 { 1782 if ( vVerbose == True)1602 if (opts.Verbose == True) 1783 1603 std.stdio.writefln("Analyzing environment symbol DFLAGS=%s", lSymValue); 1784 1604 } … … 1792 1612 // ------------------------------------------- 1793 1613 { 1614 string[] lPotentialPaths; 1794 1615 string lConfigPath; 1795 1616 string[] lTextLines; 1796 1617 int lPos; 1797 1618 1798 if ( vConfigFile.length == 0)1619 if (opts.ConfigFile.length == 0) 1799 1620 { 1800 1621 // There is no configuration file to process … … 1802 1623 } 1803 1624 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 ; 1806 1676 else 1807 lConfigPath = vConfigPath ~ vConfigFile ;1677 lConfigPath = opts.ConfigPath ~ opts.ConfigFile ; 1808 1678 version(BuildVerbose) 1809 1679 { 1810 if ( vVerbose == True)1680 if (opts.Verbose == True) 1811 1681 std.stdio.writefln("Reading from config: %s", lConfigPath); 1812 1682 } … … 1816 1686 foreach(int i, string lLine; lTextLines) 1817 1687 { 1688 string lText; 1689 1818 1690 // Strip off trailing whitespace. 1819 l Line= util.str.stripr(lLine);1691 lText = util.str.stripr(lLine); 1820 1692 1821 1693 // Replace any environment symbols with their value. 1822 1694 version(BuildVerbose) 1823 1695 { 1824 if ( vVerbose == True)1825 std.stdio.writefln(" Line %d: %s", i+1, l Line);1826 } 1827 1828 l Line = 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); 1829 1701 1830 1702 // Examine DFLAGS 1831 lPos = std.string.find(l Line, "DFLAGS=");1703 lPos = std.string.find(lText, "DFLAGS="); 1832 1704 if(lPos == 0) 1833 1705 { 1834 Process_DFLAGS(l Line[lPos+7..length]);1706 Process_DFLAGS(lText[lPos+7..length]); 1835 1707 } // end of DFLAGS processing. 1836 1708 1837 1709 // Examine LIB 1838 lPos = std.string.find(l Line, "LIB=");1710 lPos = std.string.find(lText, "LIB="); 1839 1711 if(lPos == 0) 1840 1712 { 1841 1713 string[] lPaths; 1842 l Line = lLine[lPos+4 .. length];1714 lText = lText[lPos+4 .. length]; 1843 1715 lPaths.length = 1; 1844 foreach(char lChar; l Line)1716 foreach(char lChar; lText) 1845 1717 { 1846 1718 if (lChar == '"') {} … … 1862 1734 if (lPath.length > 0) 1863 1735 { 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 1870 1746 version(BuildVerbose) 1871 1747 { 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); 1874 1750 } 1875 1751 continue; … … 1880 1756 if(lPos == 0) 1881 1757 { 1882 SetFileLocation(lLine[8..$], vLinkerPath, vLinkerExe, "linker");1758 SetFileLocation(lLine[8..$], opts.LinkerPath, opts.LinkerExe, "linker"); 1883 1759 continue; 1884 1760 } … … 1886 1762 lPos = std.string.find(lLine, "LIBCMD="); 1887 1763 if(lPos == 0) { 1888 SetFileLocation(lLine[7..$], vLibrarianPath, vLibrarian, "librarian");1764 SetFileLocation(lLine[7..$], opts.LibrarianPath, opts.Librarian, "librarian"); 1889 1765 continue; 1890 1766 } … … 1892 1768 } 1893 1769 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"); 1899 1775 } 1900 1776 … … 1905 1781 int lPos; 1906 1782 1907 lCmdValue = pCmdValue.dup;1783 lCmdValue = util.str.ExpandEnvVar(pCmdValue); 1908 1784 1909 1785 // Strip out any quotes … … 1913 1789 } 1914 1790 1915 if ( vExeExtension.length > 0)1791 if (opts.ExeExtension.length > 0) 1916 1792 { 1917 1793 if (std.path.getExt(lCmdValue).length == 0) 1918 lCmdValue ~= "." ~ vExeExtension;1794 lCmdValue ~= "." ~ opts.ExeExtension; 1919 1795 } 1920 1796 1921 1797 if (util.pathex.IsRelativePath(lCmdValue) == True) 1922 1798 { 1923 pFilePath = util.pathex.FindFileInPathList( vPathId,lCmdValue);1799 pFilePath = util.pathex.FindFileInPathList(opts.PathId,lCmdValue); 1924 1800 if (util.str.ends(pFilePath, std.path.sep) == False) 1925 1801 pFilePath ~= std.path.sep; 1926 1802 1927 pFilePath = util.pathex.CanonicalPath(pFilePath ~ lCmdValue, false);1803 pFilePath = source.ExpandPathName(pFilePath ~ lCmdValue, False); 1928 1804 } 1929 1805 else 1930 1806 { 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); 1934 1810 pFilePath = std.path.getDirName(pFilePath) ~ std.path.sep; 1935 1811 1936 1812 version(BuildVerbose) 1937 1813 { 1938 if( vVerbose == True)1814 if(opts.Verbose == True) 1939 1815 { 1940 1816 std.stdio.writefln(" %s path '%s'",pType, pFilePath); … … 1946 1822 // Display each entry in the supplied list. 1947 1823 // ------------------------------------------- 1948 void DisplayItems(string[] pList, string pTitle = "")1824 void DisplayItems(string[] pList, in string pTitle = "") 1949 1825 // ------------------------------------------- 1950 1826 { … … 1960 1836 1961 1837 // ------------------------------------------- 1962 void DisplayItems(source.ExternRef[] pList, string pTitle = "")1838 void DisplayItems(source.ExternRef[] pList, in string pTitle = "") 1963 1839 // ------------------------------------------- 1964 1840 { … … 2004 1880 string GetAppPath() 2005 1881 { 2006 return v AppPath.dup;1882 return vMyPath; 2007 1883 } 2008 1884 … … 2027 1903 2028 1904 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; 2033 1909 } 2034 1910 lFileBase = std.path.getName(pFileName); … … 2044 1920 lPossiblePath = ( lNextRoot ~ lTestFileName ); 2045 1921 if(util.file2.FileExists(lPossiblePath)) { 2046 return util.pathex.AbbreviateFileName(lPossiblePath);1922 return source.ReducePathName(lPossiblePath); 2047 1923 } 2048 1924 } … … 2052 1928 2053 1929 // Look for file in current folder first. 2054 lLocalPath = util.pathex.CanonicalPath(lTestFileName, false);1930 lLocalPath = source.ExpandPathName(lTestFileName, False); 2055 1931 if(util.file2.FileExists(lLocalPath)) 2056 1932 { 2057 return util.pathex.AbbreviateFileName(lLocalPath);1933 return source.ReducePathName(lLocalPath); 2058 1934 } 2059 1935 … … 2064 1940 if(util.file2.FileExists(lPossiblePath)) 2065 1941 { 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); 2072 1948 } 2073 1949 … … 2081 1957 if (util.str.begins(vReceivedArgs[i].ArgText, pArg[0..$-1]) == True) 2082 1958 { 2083 vReceivedArgs[i].ArgText = "";1959 vReceivedArgs[i].ArgText.length = 0; 2084 1960 vReceivedArgs[i].CompilerArg = False; 2085 1961 } … … 2087 1963 else if (vReceivedArgs[i].ArgText == pArg) 2088 1964 { 2089 vReceivedArgs[i].ArgText = "";1965 vReceivedArgs[i].ArgText.length = 0; 2090 1966 vReceivedArgs[i].CompilerArg = False; 2091 1967 } … … 2111 1987 if (util.str.begins(pArgGroup[i], lArg[0..$-1]) == True) 2112 1988 { 2113 pArgGroup[i] = "";1989 pArgGroup[i].length = 0; 2114 1990 break; 2115 1991 } … … 2117 1993 else if (pArgGroup[i] == lArg) 2118 1994 { 2119 pArgGroup[i] = "";1995 pArgGroup[i].length = 0; 2120 1996 break; 2121 1997 } 2122 1998 } 2123 pArgGroup[j] = "";1999 pArgGroup[j]= string.init; 2124 2000 } 2125 2001 } … … 2146 2022 int lBuildResult; 2147 2023 string lCompPath; 2148 bool lSetPath = false; 2024 2025 version(BuildVerbose) bool lSetPath = false; 2149 2026 2150 2027 /* Set routine addresses in the Source module. This allows … … 2163 2040 source.AddCompilerArg = &AddCompilerArg; 2164 2041 source.GetAppPath = &GetAppPath; 2165 source.vPathId = vPathId;2166 util.fileex.vPathId = vPathId;2167 util.fileex.vExeExtension = vExeExtension;2168 2042 2169 2043 // 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); 2182 2048 2183 2049 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) 2186 2069 { 2187 2070 // No other arguments so show usage message. … … 2191 2074 else 2192 2075 { 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. 2219 2093 if (lCompPath[length-1] != std.path.sep[0]) 2220 2094 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 2233 2115 source.mCollectUses = vCollectUses; 2234 source.vForceCompile = vForceCompile;2235 2116 source.ObjWritePath = vTemporaryPath; 2236 source.vExplicit = vExplicit;2237 2117 2238 2118 // Grab the external macro definitions unless otherwise told not to. 2239 2119 source.mMacroInput = vMacroInput; 2240 2120 if (vMacroInput == True) 2241 version(BuildVerbose) 2242 { 2243 ProcessMacroDefs(vVerbose); 2244 } else { 2245 ProcessMacroDefs(False); 2246 } 2121 ProcessMacroDefs(); 2247 2122 2248 2123 if( (vTargetName.length == 0) && (vCommandTargetName.length == 0) ){ … … 2252 2127 version(BuildVerbose) 2253 2128 { 2254 if (( vVerbose == True) || (vNames == True) )2129 if ((opts.Verbose == True) || (vNames == True) ) 2255 2130 std.stdio.writefln("Current Dir '%s'", util.pathex.GetInitCurDir()); 2256 2131 } else { … … 2259 2134 } 2260 2135 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) 2266 2141 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) 2327 2159 { 2328 2160 throw new BuildException(std.string.format("The compiler '%s' was not found.", 2329 vCompilerPath ~ vCompilerExe));2161 opts.CompilerPath ~ opts.CompilerExe)); 2330 2162 } 2331 2163 2332 2164 version(BuildVerbose) 2333 2165 { 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); 2336 2168 } 2337 2169 2338 2170 source.SetKnownVersions(); 2339 2171 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(); 2367 2173 2368 2174 // 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) { 2372 2178 // 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]; 2374 2180 i--; 2375 2181 } … … 2399 2205 2400 2206 // Process the files 2401 lBuildResult = Build();2207 lBuildResult = MakeItSo(); 2402 2208 2403 2209 // After processing analysis. 2404 2210 version(BuildVerbose) 2405 2211 { 2406 if( vVerbose == True)2212 if(opts.Verbose == True) 2407 2213 { 2408 2214 std.stdio.writefln(""); … … 2412 2218 DisplayItems(source.Source.AllFiles, 2413 2219 "source files: ..............."); 2414 DisplayItems(vLinkFiles .keys, "link files: ...............");2220 DisplayItems(vLinkFiles, "link files: ..............."); 2415 2221 DisplayItems(source.Externals,"externally built files: ..............."); 2416 2222 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: ................."); 2419 2225 } 2420 2226 } … … 2439 2245 if (lModuleCount == 0) 2440 2246 { 2441 lSymbolData ~= vModOutPrefix;2247 lSymbolData ~= opts.ModOutPrefix; 2442 2248 } 2443 2249 lModuleCount++; … … 2445 2251 if (lModuleCount > 1) 2446 2252 { 2447 lSymbolData ~= vModOutDelim;2448 } 2449 2450 lSymbolData ~= util.str.Expand( vModOutBody, "mod=" ~ lSource.ModuleName2253 lSymbolData ~= opts.ModOutDelim; 2254 } 2255 2256 lSymbolData ~= util.str.Expand(opts.ModOutBody, "mod=" ~ lSource.ModuleName 2451 2257 ~ "," ~ "src=" ~ lSource.FileName 2452 2258 ); … … 2456 2262 if (lModuleCount != 0) 2457 2263 { 2458 lSymbolData ~= vModOutSuffix;2264 lSymbolData ~= opts.ModOutSuffix; 2459 2265 } 2460 2266 2461 2267 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) 2465 2271 { 2466 2272 // ensure requested path exists. … … 2488 2294 { 2489 2295 lFile ~= lLine ~ "\n"; 2490 lPrevLine = lLine .dup;2296 lPrevLine = lLine; 2491 2297 } 2492 2298 } … … 2499 2305 { 2500 2306 lFile ~= lLine ~ "\n"; 2501 lPrevLine = lLine .dup;2307 lPrevLine = lLine; 2502 2308 } 2503 2309 } … … 2506 2312 vUsesOutput = util.pathex.GetBaseName(vTargetName) ~ ".use"; 2507 2313 2508 if ( vTestRun == False)2314 if (opts.TestRun == False) 2509 2315 { 2510 2316 // ensure requested path exists. … … 2528 2334 std.stdio.writefln(""); 2529 2335 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 2532 2345 } 2533 2346 … … 2537 2350 } 2538 2351 2539 void ProcessResponseFile(string pArg , Bool pVerbose)2352 void ProcessResponseFile(string pArg) 2540 2353 { 2541 2354 // A response file is being used. … … 2546 2359 return; 2547 2360 if (pArg == "@") 2548 lRespFileName = vDefResponseFile;2361 lRespFileName = opts.DefResponseFile; 2549 2362 else if (pArg[0] == '@') 2550 lRespFileName = pArg[1..length] .dup;2363 lRespFileName = pArg[1..length]; 2551 2364 else 2552 2365 lRespFileName = pArg; 2553 2554 2366 if (std.path.getExt(lRespFileName).length == 0) 2555 2367 { 2556 lRespFileName ~= "." ~ vResponseExt;2368 lRespFileName ~= "." ~ opts.ResponseExt; 2557 2369 } 2558 2370 2559 2371 version(BuildVerbose) 2560 2372 { 2561 if ( pVerbose == True)2373 if (opts.Verbose == True) 2562 2374 std.stdio.writefln("Response file %s", lRespFileName); 2563 2375 } 2564 2376 2565 2377 lRespLines = util.fileex.GetTextLines(lRespFileName, util.fileex.GetOpt.Exists); 2566 foreach( string lArg; lRespLines)2378 foreach(ref string lArg; lRespLines) 2567 2379 { 2568 2380 // Locate any comment text in the line. 2381 // 'Truncate' the line at the '#' character. 2569 2382 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]); 2577 2389 if (lArg.length > 1) 2578 2390 { 2579 2391 version(BuildVerbose) 2580 2392 { 2581 if ( pVerbose == True)2393 if (opts.Verbose == True) 2582 2394 std.stdio.writefln("Response file arg: %s", lArg); 2583 2395 } … … 2598 2410 { 2599 2411 static string lImportSwitch; 2600 2412 static string lResponseFileRef; 2413 2414 pArg = util.str.ExpandEnvVar(pArg); 2601 2415 // 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) 2603 2417 { 2604 2418 string lVersionString; 2605 2419 2606 lVersionString=pArg [ vVersionSwitch.length .. $];2420 lVersionString=pArg [opts.VersionSwitch.length .. $]; 2607 2421 if (lVersionString.length > 0 && lVersionString[0] == '=') 2608 2422 lVersionString = lVersionString[1..$]; … … 2612 2426 } 2613 2427 } 2614 else if(pArg == vDebugSwitch)2428 else if(pArg == opts.DebugSwitch) 2615 2429 { 2616 2430 source.ActivateDebug("1"); 2617 2431 } 2618 else if(util.str.begins(pArg, vDebugSwitch) == True)2432 else if(util.str.begins(pArg, opts.DebugSwitch) == True) 2619 2433 { 2620 2434 string lDebugString; 2621 2435 2622 lDebugString = pArg [ vDebugSwitch.length .. $];2436 lDebugString = pArg [opts.DebugSwitch.length .. $]; 2623 2437 if (lDebugString.length > 0 && lDebugString[0] == '=') 2624 2438 lDebugString = lDebugString[1..$]; … … 2632 2446 { 2633 2447 vReceivedArgs.length = vReceivedArgs.length + 1; 2634 vReceivedArgs[$-1].ArgText = pArg .dup;2448 vReceivedArgs[$-1].ArgText = pArg; 2635 2449 vReceivedArgs[$-1].CompilerArg = False; 2636 2450 vReceivedArgs[$-1].DFlag = False; … … 2639 2453 switch(pArg) { 2640 2454 case "-full": 2641 vForceCompile = True;2455 opts.ForceCompile = True; 2642 2456 // Not passed thru. 2643 2457 break; 2644 2458 2645 2459 case "-link": 2646 source.Source.WasMainFound = true;2460 source.Source.WasMainFound = True; 2647 2461 // Not passed thru. 2648 2462 break; … … 2714 2528 2715 2529 case "-test": 2716 vTestRun = True;2530 opts.TestRun = True; 2717 2531 // Not passed thru. 2718 2532 break; 2719 2533 2720 2534 case "-explicit": 2721 vExplicit = True;2535 opts.Explicit = True; 2722 2536 // Not passed thru. 2723 2537 break; … … 2743 2557 { 2744 2558 if (pArg[0] == '-') { 2745 if (pArg == vGenDebugInfo)2559 if (pArg == opts.GenDebugInfo) 2746 2560 { 2747 2561 // Requires symbolic debug info. 2748 vLinkerDefs ~= vSymInfoSwitch;2562 opts.LinkerDefs ~= opts.SymInfoSwitch; 2749 2563 vReceivedArgs[$-1].CompilerArg = True; 2750 2564 break; … … 2754 2568 if (util.str.IsLike(pArg, "-LIBOPT*"c) == True) 2755 2569 { 2756 vLibrarianOpts ~= " " ~ pArg[7..$].dup;2570 opts.LibrarianOpts ~= " " ~ pArg[7..$]; 2757 2571 break; 2758 2572 … … 2761 2575 if (util.str.begins(pArg, "-LIBPATH=") == True) 2762 2576 { 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 } 2764 2587 break; 2765 2588 } … … 2777 2600 lFile = m.match(1); 2778 2601 } 2779 version(BuildVerbose) 2780 { 2781 ProcessOneBuildConfig("+" ~ lSubSection, vVerbose, lFile, lLocalArgs); 2782 } else { 2783 ProcessOneBuildConfig("+" ~ lSubSection, False, lFile, lLocalArgs); 2784 } 2602 ProcessOneBuildConfig("+" ~ lSubSection, lFile, lLocalArgs); 2785 2603 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)); 2786 2610 break; 2787 2611 } … … 2810 2634 if (util.str.IsLike(pArg, "-DCPATH?*"c) == True) 2811 2635 { 2812 string lNewPath = pArg[7..length] .dup;2636 string lNewPath = pArg[7..length]; 2813 2637 if (util.str.ends(lNewPath, std.path.sep) == False) 2814 2638 lNewPath ~= std.path.sep; 2815 2639 version(BuildVerbose) 2816 2640 { 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)); 2822 2646 break; 2823 2647 … … 2826 2650 if (util.str.IsLike(pArg, "-CFPATH?*"c) == True) 2827 2651 { 2828 string lNewPath = pArg[7..length] .dup;2652 string lNewPath = pArg[7..length]; 2829 2653 if (util.str.ends(lNewPath, std.path.sep) == False) 2830 2654 lNewPath ~= std.path.sep; 2831 2655 version(BuildVerbose) 2832 2656 { 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)); 2838 2662 break; 2839 2663 … … 2842 2666 if (util.str.IsLike(pArg, "-BCFPATH?*"c) == True) 2843 2667 { 2844 string lNewPath = pArg[8..length] .dup;2668 string lNewPath = pArg[8..length]; 2845 2669 if (util.str.ends(lNewPath, std.path.sep) == False) 2846 2670 lNewPath ~= std.path.sep; 2847 2671 version(BuildVerbose) 2848 2672 { 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; 2853 2677 break; 2854 2678 … … 2857 2681 if (util.str.IsLike(pArg, "-PP?*"c) == True) 2858 2682 { 2859 string lNewPath = pArg[3..length] .dup;2683 string lNewPath = pArg[3..length]; 2860 2684 version(BuildVerbose) 2861 2685 { 2862 if ( vVerbose == True)2686 if (opts.Verbose == True) 2863 2687 std.stdio.writefln("Added %s to Source Scan List", lNewPath); 2864 2688 } … … 2875 2699 version(BuildVerbose) 2876 2700 { 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..$]; 2882 2706 break; 2883 2707 … … 2888 2712 version(BuildVerbose) 2889 2713 { 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..$]; 2895 2719 break; 2896 2720 2897 2721 } 2898 2722 2899 if (pArg == vBuildImportPath)2723 if (pArg == opts.BuildImportPath) 2900 2724 { 2901 2725 vDelayedValue = &lImportSwitch; 2902 2726 break; 2903 2727 } 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)) 2909 2733 { 2910 2734 lRoot = AddRoot(lCmdRoot); … … 2913 2737 version(BuildVerbose) 2914 2738 { 2915 if( vVerbose == True)2739 if(opts.Verbose == True) 2916 2740 std.stdio.writefln("Added root from command line = %s",lRoot); 2917 2741 } … … 2921 2745 } 2922 2746 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 .. $] ~ " "; 2926 2761 vExecuteProgram = True; 2927 2762 break; … … 2945 2780 { 2946 2781 2947 vUseModBaseName = util.str.YesNo(pArg, true); 2948 source.Source.UseModBaseName(vUseModBaseName); 2782 util.str.YesNo(pArg, opts.UseModBaseName, True); 2949 2783 break; 2950 2784 } … … 2975 2809 2976 2810 // 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) 2980 2812 { 2981 2813 string lRoot; 2982 2814 2983 vTemporaryPath = pArg[ vOutputPath.length .. $];2815 vTemporaryPath = pArg[opts.OutputPath.length .. $]; 2984 2816 if (vTemporaryPath.length > 0 && vTemporaryPath[$-1..$] != std.path.sep) 2985 2817 vTemporaryPath ~= std.path.sep; … … 2989 2821 version(BuildVerbose) 2990 2822 { 2991 if( vVerbose == True)2823 if(opts.Verbose == True) 2992 2824 std.stdio.writefln("Added root from Object Write Path = %s",lRoot); 2993 2825 } 2994 util.pathex.MakePath(lRoot);2995 2826 } 2996 2827 2997 2828 2998 2829 // 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 }3005 2830 } 3006 2831 … … 3008 2833 { 3009 2834 // Modules to ignore (eg. -Xmylib) 3010 vModulesToIgnore ~= pArg[2..$];2835 opts.ModulesToIgnore ~= pArg[2..$]; 3011 2836 break; 3012 2837 } … … 3015 2840 { 3016 2841 // Modules to notice (eg. -Mphobos) 3017 vModulesToNotice ~= pArg[2..$];2842 opts.ModulesToNotice ~= pArg[2..$]; 3018 2843 break; 3019 2844 } 3020 2845 2846 3021 2847 if (util.str.IsLike(pArg, "-T?*"c) == True) 3022 2848 { 3023 2849 // Target name (eg. -Ttestapp) 3024 3025 2850 if (vCommandTargetName.length > 0) 3026 2851 { … … 3030 2855 } 3031 2856 else 3032 vCommandTargetName = pArg[2..$] .dup;2857 vCommandTargetName = pArg[2..$]; 3033 2858 3034 2859 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 }3055 2860 } 3056 2861 … … 3060 2865 // Response file usage (eg. -R=Yes) 3061 2866 if (pArg.length == 2) 3062 vUseResponseFile = ~vUseResponseFile; 2867 // Reverse the current meaning. 2868 opts.UseResponseFile = ~opts.UseResponseFile; 3063 2869 else 3064 util.str.YesNo(pArg, vUseResponseFile, False);2870 util.str.YesNo(pArg, opts.UseResponseFile, False); 3065 2871 break; 3066 2872 } … … 3096 2902 if ( vDelayedValue == &lImportSwitch) 3097 2903 { 3098 char [] lRoot; 2904 string lRoot; 2905 vDelayedValue = null; 3099 2906 foreach(string lCmdRoot; std.string.split(pArg, ";")) 3100 2907 { … … 3103 2910 version(BuildVerbose) 3104 2911 { 3105 if( vVerbose == True)2912 if(opts.Verbose == True) 3106 2913 std.stdio.writefln("Added root from command line = %s",lRoot); 3107 2914 } … … 3109 2916 } 3110 2917 } 2918 else if ( vDelayedValue == &lResponseFileRef) 2919 { 2920 vDelayedValue = null; 2921 ProcessResponseFile(pArg); 2922 } 3111 2923 else 3112 2924 { 3113 2925 *vDelayedValue = pArg; 2926 vDelayedValue = null; 3114 2927 vReceivedArgs[$-1].ArgText ~= " " ~ pArg; 3115 2928 } 3116 vDelayedValue = null; 2929 3117 2930 break; 3118 2931 } … … 3124 2937 pArg = std.string.replace(pArg, "/", std.path.sep); 3125 2938 } 3126 pArg = util.pathex.AbbreviateFileName(util.pathex.CanonicalPath(pArg, false));3127 autolArgExt = std.path.getExt(pArg);2939 pArg = source.ReducePathName(source.ExpandPathName(pArg, False)); 2940 string lArgExt = std.path.getExt(pArg); 3128 2941 if (lArgExt == "") 3129 2942 { 3130 pArg ~= "." ~ vSrcExtension;2943 pArg ~= "." ~ opts.SrcExtension; 3131 2944 vCmdLineSourceFiles ~= pArg; 3132 2945 } 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) 3136 2949 { 3137 2950 vCmdLineSourceFiles ~= pArg; 3138 2951 } 3139 else if (lArgExt == vResponseExt)2952 else if (lArgExt == opts.ResponseExt) 3140 2953 { 3141 2954 } … … 3146 2959 3147 2960 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) 3150 2963 ) 3151 2964 ) 3152 2965 { 3153 vTargetName = std.path.getName(pArg.dup);2966 vTargetName = util.pathex.GetFileBaseName(pArg); 3154 2967 version(BuildVerbose) 3155 2968 { 3156 if( vVerbose == True)2969 if(opts.Verbose == True) 3157 2970 std.stdio.writefln("Default target is '%s'", vTargetName); 3158 2971 } … … 3167 2980 { 3168 2981 static bool[string] lKnownArgs; 2982 static string lDelayed; 3169 2983 3170 2984 pArg = std.string.strip(pArg); … … 3177 2991 } 3178 2992 2993 if (lDelayed == "-f") 2994 { 2995 lDelayed.length = 0; 2996 ProcessResponseFile(pArg); 2997 return; 2998 } 2999 3179 3000 version(BuildVerbose) 3180 3001 { 3181 3002 if ((pArg == "-V") || (pArg == "-v")) 3182 vVerbose = True;3003 opts.Verbose = True; 3183 3004 } 3184 3005 … … 3188 3009 { 3189 3010 if ((pArg == "--V") || (pArg == "--v")) 3190 vVerbose = False;3011 opts.Verbose = False; 3191 3012 } 3192 3013 // Defer removing the earlier arg until I've examined all args. … … 3197 3018 3198 3019 if ( (pArg[0] == '@') || 3199 (util.str.ends(pArg, "." ~ vResponseExt) is True)3020 (util.str.ends(pArg, "." ~ opts.ResponseExt) is True) 3200 3021 ) 3201 3022 { 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..$] ); 3208 3044 } 3209 3045 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 } 3216 3049 else 3217 3050 { // Only add an argument if it is not already been added. … … 3220 3053 pArgGroup ~= pArg; 3221 3054 lKnownArgs[pArg] = true; 3055 if (pArg == "-unittest") 3056 opts.UnitTesting = True; 3222 3057 } 3223 3058 } … … 3231 3066 the contents of any response files. 3232 3067 */ 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(); 3292 3070 3293 3071 // 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 3080 void ProcessMacroDefs() 3309 3081 { 3310 3082 // From build.exe location 3311 ProcessOneMacroDef( pVerbose, std.path.getDirName(vAppPath));3083 ProcessOneMacroDef(vMyDir); 3312 3084 3313 3085 // From compiler location 3314 ProcessOneMacroDef( pVerbose, vCompilerPath);3086 ProcessOneMacroDef(opts.CompilerPath); 3315 3087 3316 3088 // 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 3092 void ProcessOneMacroDef(string pPath) 3321 3093 { 3322 3094 string lMacroDefFileName; … … 3326 3098 static bool[ string ] lUsedPaths; 3327 3099 3328 lMacroDefFileName = pPath .dup;3100 lMacroDefFileName = pPath; 3329 3101 3330 3102 if ((lMacroDefFileName.length > 0) && … … 3332 3104 lMacroDefFileName ~= std.path.sep; 3333 3105 3334 lMacroDefFileName ~= vDefMacroDefFile;3106 lMacroDefFileName ~= opts.DefMacroDefFile; 3335 3107 3336 3108 if (lMacroDefFileName in lUsedPaths) … … 3340 3112 version(BuildVerbose) 3341 3113 { 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); 3344 3117 } 3345 3118 3346 3119 lMacroDefLines = util.fileex.GetTextLines(lMacroDefFileName, util.fileex.GetOpt.Always); 3347 3120 3348 util.macro .AddMacros( "build", lMacroDefLines, lMessages);3121 util.macroex.AddMacros( "build", lMacroDefLines, lMessages); 3349 3122 version(BuildVerbose) 3350 3123 { 3351 if ( pVerbose == True)3124 if (opts.Verbose == True) 3352 3125 { 3353 3126 foreach(string lMsg; lMessages) … … 3360 3133 } 3361 3134 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); 3135 int 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 } 3366 3162 3367 3163 // 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); 3370 3166 3371 3167 // compiler path 3372 ProcessOneBuildConfig(pArg, pVerbose, vCompilerPath, pArgGroup);3168 lCmdCnt += ProcessOneBuildConfig(pArg, opts.CompilerPath, pArgGroup); 3373 3169 3374 3170 // 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 3176 int ProcessOneBuildConfig(string pArg, string pPath, inout string[] pArgGroup) 3380 3177 { 3381 3178 string lConfigFileName; 3382 3179 string[] lConfigLines; 3180 string lKey; 3383 3181 bool lFoundGroup; 3384 3182 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; 3393 3186 if (util.file2.FileExists(lConfigFileName) == false) 3394 3187 { … … 3398 3191 lConfigFileName ~= std.path.sep; 3399 3192 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); 3404 3201 if (pArg.length == 0) 3405 3202 pArg = "+"; 3406 3203 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; 3412 3217 3413 3218 … … 3421 3226 } 3422 3227 3423 foreach( string lArg; lConfigLines)3228 foreach(ref string lArg; lConfigLines) 3424 3229 { 3425 3230 if (lArg.length == 0) … … 3455 3260 version(BuildVerbose) 3456 3261 { 3457 if ( pVerbose == True)3458 std.stdio.writefln(" BuildConfiguration file arg: %s", lArg);3262 if (opts.Verbose == True) 3263 std.stdio.writefln("Configuration file arg: %s", lArg); 3459 3264 } 3460 3265 … … 3469 3274 int lEndPos; 3470 3275 bool lEndFound; 3276 3471 3277 lArg = std.string.strip(lArg[8..$]); 3472 3278 lStartPos = 0; … … 3475 3281 while(lEndPos < lArg.length) 3476 3282 { 3477 if ( !lEndFound)3283 if (lEndFound == false) 3478 3284 { 3479 3285 if (lArg[lEndPos] == ' ') … … 3489 3295 lStartPos = lEndPos; 3490 3296 lEndFound = false; 3297 lCmdCnt += 1; 3491 3298 } 3492 3299 } … … 3496 3303 { 3497 3304 GatherOneArg( lArg[lStartPos..lEndPos], pArgGroup ); 3305 lCmdCnt += 1; 3498 3306 } 3499 3307 … … 3502 3310 { 3503 3311 vFinalProc ~= lArg[6..$]; 3312 lCmdCnt += 1; 3313 } 3314 else if (util.str.begins(lArg, "FAILURE=") == True) 3315 { 3316 vFailureProc ~= lArg[8..$]; 3317 lCmdCnt += 1; 3504 3318 } 3505 3319 else if (util.str.begins(lArg, "LIBCMD=") == True) 3506 3320 { 3507 SetFileLocation(lArg[7..$], vLibrarianPath, vLibrarian, "librarian"); 3321 SetFileLocation(lArg[7..$], opts.LibrarianPath, opts.Librarian, "librarian"); 3322 lCmdCnt += 1; 3508 3323 } 3509 3324 else if (util.str.begins(lArg, "COMPCMD=") == True) 3510 3325 { 3511 SetFileLocation(lArg[8..$], vCompilerPath, vCompilerExe, "compiler"); 3326 SetFileLocation(lArg[8..$], opts.CompilerPath, opts.CompilerExe, "compiler"); 3327 lCmdCnt += 1; 3512 3328 } 3513 3329 else if (util.str.begins(lArg, "LINKCMD=") == True) 3514 3330 { 3515 SetFileLocation(lArg[8..$], vLinkerPath, vLinkerExe, "linker"); 3331 SetFileLocation(lArg[8..$], opts.LinkerPath, opts.LinkerExe, "linker"); 3332 lCmdCnt += 1; 3516 3333 } 3517 3334 else if (util.str.begins(lArg, "LINKSWITCH=") == True) 3518 3335 { 3519 vLinkerDefs = lArg[11..$].dup; 3336 opts.LinkerDefs = lArg[11..$]; 3337 lCmdCnt += 1; 3520 3338 } 3521 3339 else if (util.str.begins(lArg, "INIT:") == True) 3522 3340 { 3523 SetInternalString( lArg[5..$] );3341 lCmdCnt += opts.SetInternalString( lArg[5..$] ); 3524 3342 } 3525 3343 else { 3526 3344 version(BuildVerbose) 3527 3345 { 3528 if ( vVerbose == True)3346 if (opts.Verbose == True) 3529 3347 std.stdio.writefln("Bad configuration command '%s' ignored.", lArg); 3530 3348 } … … 3533 3351 } 3534 3352 } 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 3357 version(BuildVerbose) 3358 { 3359 void 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 3376 void 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 2 2 // This file is automatically maintained by the BUILD utility, 3 3 // Please refrain from manually editing it. 4 long auto_build_number = 2514;4 long auto_build_number = 3200; trunk/Source/docsrc/change_log.d
r50 r52 5 5 A list of changes and fixes that have been made. 6 6 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 ) 8 89 $(LIST 9 90 $(ITEM ** $(B FIX:) Correctly handle INIT:CompilerExe from configuration file trunk/Source/docsrc/configuration_file.d
r50 r52 4 4 $(SECTION 5 5 The 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 6 for the utility. The file is called $(B build.cfg). You can have a number 7 of configuration files because the $(I Bud) utility looks in each 8 of number of specific places for a configuration file, and it uses each one 9 that it finds. 10 Firstly it looks in the folder that $(I Bud) is installed. Then for 11 Unix systems only, it looks in $(I /etc), $(I <budpath>/../etc), 12 and $(I ~/.build)., Next it looks in a user defined 10 13 alternative path (defined by -BCFPATH switch), then in the folder 11 14 that the compiler is installed, and finally in the current folder. … … 59 62 successfully created. There can be any number of $(I FINAL) commands 60 63 in a configuration file; they are all executed, and in the order presented. 64 $(BL) 65 Note that if your program path may contain spaces, you should enclose it 66 quotes so that there is no confusion. 61 67 $(BL) 62 68 You can place special tokens in the $(I FINAL) command line and these will … … 81 87 82 88 $(B INIT:) $(BR) 83 This specifies an internal stringvalue. The format is actually89 This specifies an internal variable value. The format is actually 84 90 $(I INIT:$(B stringname)) where $(I stringname) identifies the specific 85 internal string to set. 91 internal string to set. Most of these simply replace the current setting 92 of the particular internal variable however there are some internal 93 variables that are actually lists. In this case the setting is appended 94 to the end of the current list contents. If you need to erase an existing 95 list 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. 86 97 $(CODE 87 98 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 88 103 ) 89 104 $(INDENT 90 105 $(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)) 94 137 $(TABROW ShrLibExtension, The file extension for shared libraries files.$(EG dll)) 95 138 $(TABROW SrcExtension , The file extension for D source files.$(EG d)) … … 100 143 it not to link, just compile the files instead.$(EG -c)) 101 144 $(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/)) 102 150 $(TABROW ConfigFile , The name of the compiler's configuration file. $(EG sc.ini)) 103 151 $(TABROW CompilerPath , If the compiler is not in the standard search PATH, …
