Changeset 41
- Timestamp:
- 04/06/06 02:45:23 (6 years ago)
- Files:
-
- downloads/build-2.10.doc.zip (added)
- downloads/build-2.10.src.zip (added)
- downloads/build_win_2.10.exe (added)
- trunk/Docs/User_Manual.html (added)
- trunk/Docs/autobuild.html (added)
- trunk/Docs/change_log.html (added)
- trunk/Docs/command_line.html (added)
- trunk/Docs/configuration_file.html (added)
- trunk/Docs/dlls.html (added)
- trunk/Docs/introduction.html (added)
- trunk/Docs/pragmas.html (added)
- trunk/Docs/response_file.html (added)
- trunk/Docs/rules.html (added)
- trunk/Docs/style.css (added)
- trunk/Docs/switches.html (added)
- trunk/Docs/todo.html (added)
- trunk/Source/build.cfg (modified) (1 diff)
- trunk/Source/build.d (modified) (136 diffs)
- trunk/Source/build.def (modified) (1 diff)
- trunk/Source/build.ksp (modified) (1 diff)
- trunk/Source/build.rsp (modified) (1 diff)
- trunk/Source/build_bn.d (modified) (1 diff)
- trunk/Source/docsrc (added)
- trunk/Source/docsrc/User_Manual.d (added)
- trunk/Source/docsrc/autobuild.d (added)
- trunk/Source/docsrc/change_log.d (added)
- trunk/Source/docsrc/command_line.d (added)
- trunk/Source/docsrc/configuration_file.d (added)
- trunk/Source/docsrc/dlls.d (added)
- trunk/Source/docsrc/introduction.d (added)
- trunk/Source/docsrc/pragmas.d (added)
- trunk/Source/docsrc/response_file.d (added)
- trunk/Source/docsrc/rules.d (added)
- trunk/Source/docsrc/style.css (added)
- trunk/Source/docsrc/switches.d (added)
- trunk/Source/docsrc/todo.d (added)
- trunk/Source/docsrc/um.d (added)
- trunk/Source/docsrc/user_manual.ddoc (added)
- trunk/Source/example_build.cfg (added)
- trunk/Source/source.d (modified) (25 diffs)
- trunk/Source/source_bn.d (modified) (1 diff)
- trunk/Source/util/booltype.d (added)
- trunk/Source/util/fdt_bn.d (modified) (1 diff)
- trunk/Source/util/fileex.d (modified) (9 diffs)
- trunk/Source/util/fileex_bn.d (modified) (1 diff)
- trunk/Source/util/linetoken_bn.d (modified) (1 diff)
- trunk/Source/util/pathex.d (modified) (7 diffs)
- trunk/Source/util/pathex_bn.d (modified) (1 diff)
- trunk/Source/util/str.d (modified) (27 diffs)
- trunk/Source/util/str_bn.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Source/build.cfg
r38 r41 1 1 CMDLINE=-info # Show the version of build 2 CMDLINE=-silent # hide linker output 2 CMDLINE=-Iy:\d_proj\build\trunk\source 3 CMDLINE=-Iy:\dlibs 4 CMDLINE=-Ic:\dmd\import 3 5 4 6 LIBCMD=%@D%\..\..\dm\bin\lib.exe 5 7 8 9 BMD=@S\djp.bmd 10 6 11 [dbg] 7 CMDLINE=- unittest --release --inline-g -w -full12 CMDLINE=--release --inline -unittest -g -w -full 8 13 CMDLINE=-T{Target}_{Group} 9 14 trunk/Source/build.d
r38 r41 1 /************************************************************************** 2 3 @file build.d 4 5 Copyright (c) 2005 Derek Parnell 6 1 /* ******************************************************* 2 Build is a tool to assist building applications and libraries written 3 using the D programming language. 4 5 Copyright: (c) 2005 Derek Parnell 6 Authors: Derek Parnell, Melbourne 7 Initial Creation: January 2005 8 Version: 2.10 9 Date: August 2005 10 License: 7 11 This software is provided 'as-is', without any express or implied 8 12 warranty. In no event will the authors be held liable for damages 9 13 of any kind arising from the use of this software. 10 11 14 Permission is hereby granted to anyone to use this software for any 12 15 purpose, including commercial applications, and to alter it and/or 13 redistribute it freely, subject to the following restrictions: 14 16 redistribute it freely, subject to the following restrictions:$(NL) 15 17 1. The origin of this software must not be misrepresented; you must 16 18 not claim that you wrote the original software. If you use this 17 19 software in a product, an acknowledgment within documentation of 18 said product would be appreciated but is not required. 19 20 said product would be appreciated but is not required.$(NL) 20 21 2. Altered source versions must be plainly marked as such, and must 21 not be misrepresented as being the original software. 22 22 not be misrepresented as being the original software.$(NL) 23 23 3. This notice may not be removed or altered from any distribution 24 of the source. 25 24 of the source.$(NL) 26 25 4. Derivative works are permitted, but they must carry this notice 27 26 in full and credit the original source. 28 29 30 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 32 33 @version Initial version, January 2005 34 @author Derek Parnell, Melbourne, Australia. 35 36 37 **************************************************************************/ 38 /* 39 A utility for building executables from source code written 40 with the D programming language. 41 42 This examines a set of D source code files to determine what 43 to build and what needs to be included in the build. It then 44 checks to see which components are current and creates a list 45 of files that need to be compiled and/or included in the target 46 file. 47 48 This is based on the work called 'dmake v0.21' by Helmut Leitner 49 */ 50 51 /* --------- CHANGE LOG -------------------- 52 __ /makedoc title Documentation for Build v2.09 53 54 __ /topic Change Log 55 __ /info 56 __ A list of changes and fixes that have been made. 57 __ 58 __ /b"-- v2.09 -- 10/Aug/2005" 59 __ <ul> 60 __ /li ** /b FIX: /i"thanks to barrett9h (rodolfo)": Now correctly handles the return value 61 __ from Unix system() call. 62 __ /li ** /b FIX: /i"thanks to oniony": Now handles non_ASCII characters in PATH 63 __ environment symbol. 64 __ /li ** /b CHG: The "-silent" switch now also hides the linker stdout display. 65 __ /li ** /b CHG: Now supports and requires DMD v0.126 and GDC v0.13 or later. 66 __ /li ** /b ENH: New pragma(export_version) allows specified version identifiers to 67 __ be passed to all modules being compiled. 68 __ /li ** /b ENH: New command line switch "-run" to run the program 69 __ after a successful link. 70 __ </ul> 71 __ 72 __ /b"-- v2.08 -- 29/May/2005" 73 __ <ul> 74 __ /li ** /b FIX: /i"thanks to teqdruid": In Unix environments, 75 __ any pragma(link, ~<name~>) statements were not sending the correct 76 __ syntax to the compiler's command line. The "~<name~>" is now prefixed 77 __ with "-L-l" for Unix systems. 78 __ /li ** /b FIX: /i"thanks to Carlos": In Unix environments, any "-version" 79 __ switch on the Utility's command line was not being converted to the correct Unix 80 __ format of "-fversion...". So now, if the Build tool gets 81 __ either "-version..." or "-fversion=..." on its command line, it will 82 __ recognise it as a 'Version' request for the compiler /b and output 83 __ it on the command line in the correct format for the environment it 84 __ is running in, namely "-fversion..." for GNU (gdc) and "-version..." 85 __ for Windows. /n 86 __ /b"Note:" The same applies to the "-debug..." and "-fdebug..." switches. 87 __ /li ** /b FIX: The pragma(nolink) was being ignored under some circumstances. 88 __ Now it splits the compilation phase 89 __ from the linking phase and excludes the 'nolink' files from the linker's 90 __ command line. 91 __ /li ** /b FIX: /i"thanks to kris": 'debug' statements were not being taken into account when 92 __ examining code for import statements. 93 __ /li ** /b FIX: 'debug' and 'version' levels are now being taken into account. 94 __ /li ** /b FIX: 'debug' and 'version' values being set inside a source file 95 __ were being made global rather than module scoped. 96 __ /li ** /b FIX: /i"thanks to carlos": The utility was not processing the 97 __ -I switch correctly when using GDC compiler. 98 __ /li ** /b ENH: The utility can now accept the -I switch in two forms: 99 __ /b"-I~<path~>" and /b"-I ~<path~>" on its command line, regardless of which 100 __ compiler is being used. When invoking the compiler, it uses the correct 101 __ format on the command line of the compiler being used, namely "-I~<path~>" to 102 __ DMD compiler and "-I ~<path~>" to GDC. 103 __ /li ** /b ENH: The path of any source file that imports a module 104 __ will be added to the list of root paths to search for module source 105 __ files. This means that you can now have module source files referenced 106 __ relative to the source file that imports them. This is the new default 107 __ behaviour but it can be turned off by using the new -noautoimport switch 108 __ or for individual files by placing them inside parenthesis. 109 __ /li ** /b ENH: New switch /i"-noautoimport" is used to turn off the 110 __ automatic adding of search roots based on the path of the source files 111 __ being compiled. 112 __ /li ** /b ENH: New switch /i"-LIBPATH=" is used to add search paths for 113 __ library files. 114 __ /li ** /b WARN: The utility only does a single scan of each source file 115 __ and thus if an file sets a 'debug' or 'version' value after a function 116 __ which uses that value, it will be ignored. You are requested to ensure that 117 __ all your 'debug' and 'version' setting is done prior to the first module 118 __ member. 119 __ </ul> 120 __ 121 __ /b"-- v2.07 -- 06/May/2005" 122 __ <ul> 123 __ /li ** /b ENH: New switch /i"-nodef" to prevent the utility from 124 __ automatically creating a Module Definition File (.def) 125 __ /li ** /b ENH: You can now specify default, and special, settings for 126 __ the utility's command line. These are placed in a text configuration file called 127 __ /b"build.cfg". The utility first looks in the same directory as the 128 __ utility's executable for the configuration file. After processing any 129 __ configuration file found there, it then looks in the same directory as 130 __ the compiler for a configuration file (build.cfg) and processes it if 131 __ found. 132 __ /li ** /b ENH: To support special command line settings that may be 133 __ specified in the utility's configuration file(s), you can indicate 134 __ one or more setting groups on the command line. These take the format of 135 __ +groupname. The configuration file(s) are scanned for special group settings 136 __ after the default ones have been processed. 137 __ /li ** /b ENH: To remove an earlier specified command line switch, you 138 __ can prepend it with a hyphen. This new feature may be needed when command 139 __ line switches can come from multiple sources (the original command line, 140 __ utility response files, and utility configuration files), and you need 141 __ to remove a switch that may have been provided by some other source. /n 142 __ For example to negate an earlier "-unittest" switch you code add "--unittest" 143 __ to the command line. 144 __ /li ** /b ENH: New switch /i"-od" is used to nominate a directory for 145 __ temporary files. For the DigitalMars compiler, this also is used as the location 146 __ to create object files. 147 __ </ul> 148 __ 149 __ /b"-- v2.06 -- 04/May/2005" 150 __ <ul> 151 __ /li ** /b FIX: /i"thanks to phoenix": When emitting commandline parameters for 152 __ the compiler or librarian, it was possible to have some ending with /b'\"' which caused 153 __ the shell to /i escape the quote character and thus provide incorrect parameters to 154 __ the compiler. 155 __ </ul> 156 __ /b"-- v2.05 -- 02/May/2005" 157 __ <ul> 158 __ /li ** /b FIX: When supplying some forms of relative paths, the 159 __ utility would crash or give the wrong canonical form of the path. This 160 __ effected formats like \..\anything and C:..\anything 161 __ /li ** /b FIX: The utility now assumes the current directory if it can not 162 __ locate the compiler using the paths on the system PATH symbol. 163 __ /li ** /b FIX: The utility now assumes the compiler's location if no path 164 __ for the configuration file has been specified. 165 __ /li ** /b FIX: The utility now supports better parsing of the lines in the 166 __ configuration file. It handles odd variations of embedded quotes. 167 __ /li ** /b ENH: The utility now supports Windows 95/98/ME for file times. 168 __ </ul> 169 __ 170 __ /b"-- v2.04 -- 29/Apr/2005" 171 __ <ul> 172 __ /li ** /b FIX: /i"thanks to Nils Hensel": The utility was not correctly 173 __ parsing the DFLAGS line in the configuration file when it contained 174 __ embedded quote characters. 175 __ /li ** /b FIX: /i"thanks to Anders F Bjoerklund": The utility was not treating 176 __ directory names that contained dots correctly. 177 __ /li ** /b FIX: /i"thanks to Carlos": Unix-style files that end with a nested comment 178 __ delimiter are now handled correctly. 179 __ /li ** /b ENH: /i"thanks to qbert(Charlie)": The location of the librarian tool can now 180 __ be specified. It can be explictly named on a LIBCMD= line inside the 181 __ DMD configuration file, or failing that, implictly assumed to be in the 182 __ same directory as the DMD linker. 183 __ /li ** /b ENH: A new commandline switch -LIBOPT which allows you to pass 184 __ commandline options to the librarian. 185 __ </ul> 186 __ 187 __ /b"-- v2.03 -- 20/Apr/2005" 188 __ <ul> 189 __ /li ** /b FIX: /i"thanks to Carlos": The linux build had a spelling mistake 190 __ in source.d (line 286). The indentifier "lNextMod" should have been coded 191 __ as "lNextModule". 192 __ </ul> 193 __ 194 __ /b"-- v2.02 -- 19/Apr/2005" 195 __ <ul> 196 __ /li ** /b FIX: /i"thanks to Carlos": The utility was not handling the situation 197 __ where a simple statement, rather than a block statement, followed a version 198 __ directive. 199 __ /li ** /b FIX: /i"thanks to aldacron": The utility now respects the compiler's 200 __ 'Output file' switch. Which is '-of[filename]' for DMD and '-o [filename]' 201 __ for GNU. The utility treats it as an alias for its -T switch. 202 __ /li ** /b FIX: /i"thanks to aldacron": The utility now respects the DMD compiler's 203 __ 'Object Path' switch. If you have '-odsomepath' on the command line, the 204 __ utility adds this to the search path when checking for up-to-date files, 205 __ and will clean up files in that directory if requested to (-clean). It will 206 __ also create the directory if it doesn't exist. 207 __ </ul> 208 __ 209 __ /b"-- v2.01 -- 18/Apr/2005" 210 __ <ul> 211 __ /li ** /b FIX: /i"thanks to Justin (jcc7)": If an excluded module (-X) was 212 __ in a package at the current directory level, it was not being excluded. 213 __ </ul> 214 __ 215 __ /b"-- v2.00 -- 08/Apr/2005" 216 __ <ul> 217 __ /li ** /b FIX: Now supports the raw-string delimiter ` in Build's own 218 __ pragma commands. 219 __ /li ** /b FIX: Now handles backslash escapes in Build's own 220 __ pragma commands. 221 __ /li ** /b ENH: New -silent switch avoids all unnecessary messages. 222 __ /li ** /b ENH: New -help switch displays full usage text. Aliases: -h, -? 223 __ </ul> 224 __ 225 __ /b"-- v1.19 -- 04/Apr/2005" 226 __ <ul> 227 __ /li ** /b FIX: /i"thanks to Ben Hinkle". When creating a library in Linux, 228 __ the utility was looking for /i".obj" files instead of /i".o" files. 229 __ /li ** /b FIX" When creating a library, if a source file had more than one 230 __ /i".d" in its name, the utility would look for the wrong object file for it. 231 __ </ul> 232 __ 233 __ /b"-- v1.18 -- 03/Apr/2005" 234 __ <ul> 235 __ /li ** /b FIX: If mixed case was used, it was possible to have duplicate 236 __ element types in a OptLink module definition file. Effected the use of 237 __ pragma(build_def). 238 __ /li ** /b ENH: Some performance improvements. 239 __ </ul> 240 __ 241 __ /b"-- v1.17 -- 30/Mar/2005" 242 __ <ul> 243 __ /li ** /b FIX: In Windows systems, the utility now does case-insensitive 244 __ path name compares. 245 __ /li ** /b FIX: A bug in the String Search function crashed the utility 246 __ when the -T switch was used with target names less than 9 characters long. 247 __ /li ** /b ENH: The new switch /b"-obj" is available. This is just a shorthand 248 __ for having both /i"-nolib" and /i"-nolink" on the command line. 249 __ </ul> 250 __ 251 __ /b"-- v1.16 -- 28/Mar/2005" 252 __ <ul> 253 __ /li ** /b FIX: The utility now handles quotes around pragma(link) references. 254 __ /li ** /b FIX: The utility now handles multiple references to the same module 255 __ even though they are using different 'path' specifications. 256 __ /li ** /b ENH: The utility now has support for making Windows DLL files. 257 __ </ul> 258 __ 259 __ /b"-- v1.15 -- 24/Mar/2005" 260 __ <ul> 261 __ /li ** /b FIX: The utility now checks for more recent libraries and 262 __ object files as added by pragma(link), pragma(build), and command line. It 263 __ didn't used to rebuild the executable if only a new version of a library 264 __ was present. 265 __ /li ** /b FIX: The order of the librarian parameters was incorrect. 266 __ /li ** /b FIX: The utility was not using the correct path name if importing 267 __ modules from some Import paths. 268 __ /li ** /b ENH: Verbose mode now shows the ignored and noticed packages. 269 __ </ul> 270 __ 271 __ /b"-- v1.14 -- 23/Mar/2005" 272 __ <ul> 273 __ /li ** /b FIX: /i"Thanks to teqDruid." For GNU platforms, the utility 274 __ now passes any library name found in pragma(link,...) to the linker. 275 __ /li ** /b FIX: Nows correctly handles unix and Microsoft line-ends. 276 __ /li ** /b FIX: /i"Thanks to Ben Hinkle." Using relative paths '..' and '.' 277 __ now work correctly on the -I switch. 278 __ /li ** /b FIX: /i"Thanks to Ben Hinkle." The correct librarian program 'ar' 279 __ is now called on unix systems. 280 __ /li ** /b ENH: The new switch -names displays the names of the files 281 __ used in building the target. This is not a noisy as verbose mode. 282 __ /li ** /b ENH: New pragma /b include used to identify a file that 283 __ must be included in the compilation process but is not one that 284 __ is imported by any file in the group. Only needed if command line 285 __ file does not otherwise import the required file. Can be used to 286 __ include the file containing the 'main' function from a file that 287 __ does not import that file. Rarely needed. 288 __ /li ** /b ENH: New pragma /b build used to build 'foreign' file types 289 __ that D doesn't know about. 290 __ /li ** /b ENH: New pragma /b target used to nominate the default target 291 __ file name. 292 __ /li ** /b ENH: You can now use a symbolic target name on the -T switch. 293 __ </ul> 294 __ 295 __ /b"-- v1.13 -- 13/Mar/2005" 296 __ <ul> 297 __ /li ** /b FIX: Explictly included paths entered on the -I switch are 298 __ now added to the dmd command line. 299 __ /li ** /b FIX: Explictly excluded modules (via -X) were only checking package 300 __ names. They also check for module names now. 301 __ /li ** /b FIX: Imported files are now looked for relative to the current directory 302 __ before the import paths are checked. 303 __ /li ** /b FIX: The utility now checks the DFLAG environment symbol in 304 __ non-DigitalMars D compilers. 305 __ /li ** /b CHG: The switch -nounittest is now deprecated and ignored if used. 306 __ The default setting is no longer to compile with unittests turned on. 307 __ </ul> 308 __ /b"-- v1.12 -- 6/Mar/2005" 309 __ <ul> 310 __ /li ** /b FIX: The response file (-Ry) is now only the default when using 311 __ DigitalMars tools on Windows. All other environments do not use the response 312 __ file by default. 313 __ </ul> 314 __ /b"-- v1.11 -- 4/Mar/2005" 315 __ <ul> 316 __ /li ** /b FIX: No long outputs empty compiler tool switches. 317 __ </ul> 318 __ 319 __ /b"-- v1.10 -- 4/Mar/2005" 320 __ <ul> 321 __ /li ** /b FIX: /i"Thanks to Carlos." Better support for GDC command line switches. 322 __ /li ** /b FIX: /i"Thanks to Carlos." Cause 'Unix' version to trigger Posix code. 323 __ /li ** /b FIX: /i"Thanks to Carlos." The vUseResponseFile variable was only being 324 __ declared in the Windows version. 325 __ /li ** /b FIX: No passes space-embedded switches and paths to the compiler 326 __ tools correctly. 327 __ /li ** /b ENH: If an environment symbol called DFLAGS has been defined, it is 328 __ analyzed. This is done before any configuration file processing. 329 __ /li ** /b ENH: New command line switch -test. This shows the command lines 330 __ instead of running them. No compiling or linking is done. 331 __ </ul> 332 __ 333 __ /b"-- v1.9 -- 3/Mar/2005" 334 __ <ul> 335 __ /li ** /b FIX: /i"Thanks to Carlos." For unix, it now uses ':' instead of ';' for path 336 __ separators when parsing the configuration file lines. 337 __ /li ** /b FIX: /i"Thanks to Carlos." The default location for the configuration 338 __ file was being ignored. 339 __ /li ** /b ENH: A new command line switch /b"-R" used to control the use 340 __ of a response file for the compiler tools. 341 __ </ul> 342 __ 343 __ /b"-- v1.8 -- 1/Mar/2005" 344 __ <ul> 345 __ /li ** /b FIX: /i"Thanks to Anders F Bjoerklund:" Removed nonASCII chars from source code. 346 __ /li ** /b FIX: /i"Thanks to Anders F Bjoerklund:" Changed version(GDC) to version(GNU) 347 __ /li ** /b FIX: Changed compiler name for GNU versions from 'dmd' to 'gdc' 348 __ /li ** /b FIX: /i"Thanks to Carlos." The application was incorrectly parsing the DFLAGS sc.ini line. 349 __ /li ** /b ENH: /i"Thanks to Anders F Bjoerklund:" Provided a Makefile for the initial 350 __ compile of the application. 351 __ </ul> 352 __ 353 __ /b"-- v1.7 -- 28/Feb/2005" 354 __ <ul> 355 __ /li ** /b FIX: /i"Thanks to clayasaurus." Linux edition was not compiling 356 __ due to a missing 'version(Windows)' block around the use of vWinVer 357 __ </ul> 358 __ 359 __ /b"-- v1.6 -- 28/Feb/2005" 360 __ <ul> 361 __ /li ** /b FIX: /i"Thanks to Kris." The utility was not including the DCPATH value 362 __ when invoking the compiler. 363 __ /li ** /b ENH: When building a Windows app, the .DEF file now includes the 364 __ version of windows that /i this application is being run on. 365 __ /li ** /b ENH: The command line switch /b"-gui" can now have an optional 366 __ version information to specify which Windows version to build for. 367 __ The default Windows Version used is the one for the version running 368 __ this utility. 369 __ /li ** /b ENH: New command line switch -info to display the utility's version #. 370 __ </ul> 371 __ /b"-- v1.5 -- 25/Feb/2005" 372 __ <ul> 373 __ /li ** /b FIX: /i"Thanks to clayasaurus." Now only displays the CFPATH 374 __ and DCPATH messages when /i verbose mode is on. 375 __ /li ** /b FIX: /i"Thanks to kris." Hardcoded default for DMD path was 376 __ misleading when dmd.exe was not in the Windows PATH. 377 __ /li ** /b FIX: The utility was not correctly parsing empty raw strings ``. 378 __ /li ** /b ENH: /i"Thanks to kris." If the -DCPATH switch is used, then 379 __ if the existing DCPATH and CFPATH are the same, this switch changes both. 380 __ </ul> 381 __ 382 __ /b"-- v1.4 -- 24/Feb/2005" 383 __ <ul> 384 __ /li ** /b FIX: /i"Thanks to Abscissa." The -version switch was being interpreted as 385 __ a file to compile. 386 __ /li ** /b FIX: /i"Thanks to brad." Linux version was using the wrong package name 387 __ when formatting a file date for display. 388 __ /li ** /b FIX: /i"Thanks to brad." Linux version was not setting the target 389 __ name correctly which resulted in the first source file being compiled twice. 390 __ /li ** /b FIX: /i"Thanks to brad." Parsing the DFLAG line in the dmd options 391 __ file was not dealing with whitespace delimiters. 392 __ /li ** /b ENH: When specifing an alternate target file, you can now also 393 __ specify a path for the target, and that path is created for you if it 394 __ doesn't exist. 395 __ </ul> 396 __ 397 __ /b"-- v1.3 -- 23/Feb/2005" 398 __ <ul> 399 __ /li ** /b ENH: Put in a workaround for DMD (Windows) not using the sc.ini 400 __ file correctly. The utility now explicitly adds any DFLAG options from 401 __ the sc.ini file into the .rsp file. 402 __ /li ** /b FIX: The utility now correctly handles ';' delimited DFLAG options 403 __ in the sc.ini file. 404 __ /li ** /b ENH: Now supports the use of 'response' files on the command line 405 __ /li ** /b ENH: Now supports the -T command line switch to supply an 406 __ alternate tareget name. 407 __ 408 __ </ul> 409 __ /b"-- v1.2 -- 21/Feb/2005" 410 __ <ul> 411 __ /li ** /b ENH: /i"Thanks to Anders F Bjoerklund:" Added better support for 'darwin' 412 __ and 'gdc'. 413 __ </ul> 414 */ 27 ******************************************************* */ 415 28 416 29 module build; 417 30 private import build_bn; // This module's build number 418 31 419 version(unix) version = Unix;420 version(Unix) version = Posix;32 version(unix) version = Unix; 33 version(Unix) version = Posix; 421 34 version(linux) version = Posix; 422 35 version(darwin) version = Posix; … … 426 39 version(Windows) { 427 40 // OptLink Definition File 428 pragma (build_def, "VERSION 2. 9");41 pragma (build_def, "VERSION 2.10"); 429 42 } 430 43 } … … 433 46 private{ 434 47 // --------- imports ---------------- 435 import source; // Source File class 436 437 import util.str; // non-standard string routines. 438 import util.fdt; // File Date-Time class 439 import util.pathex; // Extended Path routines. 440 import util.fileex; // Extended File routines. 441 import util.macro; // Macro processing routines. 48 import source; // Source File class 49 50 import util.str; // non-standard string routines. 51 import util.fdt; // File Date-Time class 52 import util.pathex; // Extended Path routines. 53 import util.fileex; // Extended File routines. 54 import util.macro; // Macro processing routines. 55 import util.booltype; // definition of True and False 442 56 443 57 import std.c.stdio; … … 488 102 char[] kSrcExtention=`d`; 489 103 char[] kMacroExtention=`mac`; 104 char[] kDdocExtention=`ddoc`; 490 105 491 106 } … … 494 109 version(DigitalMars) { 495 110 version(Windows) { 496 char[] vCompiler =`dmd.exe`;497 char[] vCompile rSwitch= ` -c`;498 char[] vLinker =`dmd.exe`;111 char[] vCompilerExe=`dmd.exe`; 112 char[] vCompileOnlySwitch = ` -c`; 113 char[] vLinkerExe=`link.exe`; 499 114 char[] vConfigFile=`sc.ini`; 500 115 char[] vCompilerPath=``; 116 char[] vLinkerPath=``; 117 char[] vLinkerDefSwitches=`/noi/map`; 501 118 char[] vConfigPath=``; 502 119 char[] vLibPaths = ``; … … 507 124 508 125 version(Posix) { 509 char[] vCompiler =`dmd`;510 char[] vCompile rSwitch= ` -c`;511 char[] vLinker =`dmd`;126 char[] vCompilerExe=`dmd`; 127 char[] vCompileOnlySwitch= ` -c`; 128 char[] vLinkerExe=`ld`; 512 129 char[] vConfigFile=`dmd.conf`; 513 130 char[] vCompilerPath=``; 131 char[] vLinkerPath=``; 132 char[] vLinkerDefSwitches=`/noi/map`; 514 133 char[] vConfigPath=`/etc/`; 515 134 char[] vLibPaths = ``; … … 529 148 version(GNU) { 530 149 version(Windows) { 531 char[] vCompiler =`gdc.exe`;532 char[] vCompile rSwitch= ` -c`;533 char[] vLinker =`gdc.exe`;150 char[] vCompilerExe=`gdc.exe`; 151 char[] vCompileOnlySwitch= ` -c`; 152 char[] vLinkerExe=`gdc.exe`; 534 153 char[] vConfigFile=null; 535 154 char[] vCompilerPath=``; 155 char[] vLinkerPath=``; 156 char[] vLinkerDefSwitches=``; 536 157 char[] vConfigPath=null; 537 158 char[] vLibPaths = ``; … … 542 163 543 164 version(Posix) { 544 char[] vCompiler =`gdc`;545 char[] vCompile rSwitch= ` -c`;546 char[] vLinker =`gdc`;165 char[] vCompilerExe=`gdc`; 166 char[] vCompileOnlySwitch= ` -c`; 167 char[] vLinkerExe=`ld`; 547 168 char[] vConfigFile=null; 548 169 char[] vCompilerPath=`/opt/gdc/bin`; 170 char[] vLinkerPath=``; 171 char[] vLinkerDefSwitches=``; 549 172 char[] vConfigPath=null; 550 173 char[] vLibPaths = ``; … … 563 186 char[] vBuildImportPathSwitch = "-I"; 564 187 char[] vTemporaryPathSwitch = "-od"; 565 char[] vRunSwitch = "- run";188 char[] vRunSwitch = "-exec"; 566 189 char[] vLibrarianPath = ""; 567 190 char[]* vDelayedValue = null; 568 191 char[] vTemporaryPath = ""; 569 bool vTestRun = false; 570 bool vNoLink = false; 571 bool vForceCompile = false; 572 bool vSilent = false; 573 bool vCleanup = false; 574 bool vVerbose = false; 575 bool vNames = false; 576 bool vAllObjects = false; 577 bool vNoDef = false; 578 bool vAutoImports = true; 579 bool vMacroInput = true; 580 bool vExecuteProgram = false; 192 193 Bool vTestRun; 194 Bool vScanImports; 195 Bool vNoLink; 196 Bool vForceCompile; 197 Bool vSilent; 198 Bool vCleanup; 199 Bool vVerbose; 200 Bool vMacroInput; 201 Bool vNames; 202 Bool vAllObjects; 203 Bool vNoDef; 204 Bool vAutoImports; 205 Bool vExecuteProgram; 206 Bool vUseResponseFile; 207 Bool vConsoleApp; 581 208 char[] vRunParms; 582 209 char[] vTargetExe; … … 590 217 char[] vAppPath; 591 218 char[] vAppName; 592 char[] vAppVersion = "2. 9";219 char[] vAppVersion = "2.10"; 593 220 char[] vTargetName; // Output name from first file name. 594 221 char[] vPragmaTargetName; // Output name from pragma. … … 599 226 char[][] vBuildArgs; // Arguments passed to build 600 227 char[][] vCompilerArgs; // Arguments passed to compiler 601 bool vUseResponseFile; 602 bool vConsoleApp = true; 228 char[][] vSourceScanList; // The list of places to find source files. 603 229 char[] vRDFName = "default.rdf"; 604 230 bool[char[]] vNestedDelim; … … 612 238 Substitute[] vSubstitutions; 613 239 614 version(Windows) { 615 char[] vWinVer = ""; 616 ubyte vWinVerNum; 240 241 const static char[] kPathId = "PATH"; // Used to locate the environment symbol 242 243 version(Windows) 244 { 245 char[] vWinVer = ""; 246 ubyte vWinVerNum; 617 247 } 618 248 … … 624 254 //------------------------------------------------------- 625 255 { 626 source.ActivateVersion("build"); 256 source.ActivateVersion("build"); //todo 627 257 628 258 vDefaultCompArgs ~= vKeepPathSwitch; // Keep object files in same folder as source. 629 259 vModulesToIgnore ~= "phobos"; // Assume phobos will be ignored. 260 vSourceScanList ~= "." ~ std.path.sep; 261 vNoLink = False; 262 vTestRun = False; 263 vScanImports = False; 264 vForceCompile = False; 265 vSilent = False; 266 vCleanup = False; 267 vVerbose = False; 268 vMacroInput = True; 269 vNames = False; 270 vAllObjects = False; 271 vNoDef = False; 272 vAutoImports = True; 273 vExecuteProgram = False; 274 vUseResponseFile = False; 275 vConsoleApp = True; 630 276 631 277 version(Posix){ … … 640 286 version(DigitalMars) { 641 287 version(Windows) { 642 vUseResponseFile = true;288 vUseResponseFile = True; 643 289 } 644 290 else 645 291 { 646 vUseResponseFile = false;292 vUseResponseFile = False; 647 293 } 648 294 } else 649 295 { 650 vUseResponseFile = false;296 vUseResponseFile = False; 651 297 } 652 298 … … 657 303 } 658 304 305 static ~this() 306 { 307 // Clean up any resources held by the source files. 308 Source.Finalize(); 309 } 659 310 660 311 //------------------------------------------------------- … … 727 378 writefln(" -Rn will cause command line arguments to be used."); 728 379 writefln(" -R will reverse the current usage."); 380 writefln(" -PP<path> Add a path to the Source Search List"); 729 381 730 382 version(DigitalMars) { … … 737 389 writefln(" ** The default is to use command line arguments"); } 738 390 739 writefln(" - run<param> If the link is successful, this will cause the");391 writefln(" -exec<param> If the link is successful, this will cause the"); 740 392 writefln(" executable just created to run. You can give it "); 741 writefln(" run time parameters. Anything after the '- run' will");393 writefln(" run time parameters. Anything after the '-exec' will"); 742 394 writefln(" placed in the program's command line. You will need"); 743 395 writefln(" to quote any embedded spaces."); … … 779 431 int lTrueRC; 780 432 781 if (vTestRun ) {433 if (vTestRun == True) { 782 434 writefln("Command: '%s'",pCommand); 783 435 return 0; … … 787 439 788 440 789 if(vVerbose ) {441 if(vVerbose == True) { 790 442 writefln("Running '%s'",pCommand); 791 443 } … … 795 447 version(Windows) lTrueRC = lRC; 796 448 797 if(vVerbose ) {449 if(vVerbose == True) { 798 450 if (lTrueRC == 0){ 799 451 writefln("Successful"); … … 822 474 FileDateTime lModsTime = new FileDateTime(); 823 475 824 foreach(int i, char[] lFileName; Source.S ourceIndex.keys)476 foreach(int i, char[] lFileName; Source.ScanOrder) 825 477 { 826 478 // Get the next Source object to examine. … … 832 484 lSource.search(); 833 485 834 if(vVerbose ) {486 if(vVerbose == True) { 835 487 writefln("source file[%d] %s", i, 836 488 util.pathex.AbbreviateFileName(lFileName)); 837 489 } 838 else if(vNames ) {490 else if(vNames == True) { 839 491 writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName)); 840 492 } … … 842 494 if (lSource.DependantsTime > lModsTime) 843 495 { 844 if(vVerbose ) {496 if(vVerbose == True) { 845 497 writefln("Newer time: from %s to %s", 846 498 lModsTime.toString(), … … 858 510 FileDateTime lLinkTime = GetFileTime(lFileName); 859 511 860 if(vVerbose ) {512 if(vVerbose == True) { 861 513 writefln("link file[%d] %s %s", i, 862 514 util.pathex.AbbreviateFileName(lFileName), lLinkTime.toString()); 863 515 } 864 else if(vNames ) {516 else if(vNames == True) { 865 517 writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName)); 866 518 } … … 868 520 if (lLinkTime > lModsTime) 869 521 { 870 if(vVerbose ) {522 if(vVerbose == True) { 871 523 writefln("Newer time: from %s to %s", 872 524 lModsTime.toString(), … … 890 542 }; 891 543 544 892 545 //------------------------------------------------------- 893 546 Rule[] LoadRules() … … 898 551 char[] lRuleDefnFile; 899 552 553 static char[] kRuleKey = "rule="; 900 554 901 555 lRuleDefnFile = util.pathex.LocateFile(vRDFName, 902 getDirName(vAppPath) ~ std.path.pathsep ~ GetEnv( "PATH"));903 if (vVerbose )556 getDirName(vAppPath) ~ std.path.pathsep ~ GetEnv(kPathId)); 557 if (vVerbose == True) 904 558 writefln("Rule Definitions from %s", lRuleDefnFile); 905 lRuleText = GetTextLines( lRuleDefnFile);559 GetTextLines( lRuleDefnFile, lRuleText ); 906 560 foreach(char[] lLine; lRuleText) 907 561 { 908 lLine = std.string.strip(lLine);909 if (util.str.begins(lLine, "rule=") > 0)562 lLine = util.str.strip(lLine); 563 if (util.str.begins(lLine, kRuleKey ) == True) 910 564 { 911 565 lRules.length = lRules.length + 1; … … 914 568 else if (lRules.length > 0) 915 569 { 916 if (util.str.begins(lLine, "in=") > 0)570 if (util.str.begins(lLine, "in=") == True) 917 571 lRules[$-1].Input = lLine[3..$]; 918 else if (util.str.begins(lLine, "out=") > 0)572 else if (util.str.begins(lLine, "out=") == True) 919 573 lRules[$-1].Output = lLine[4..$]; 920 else if (util.str.begins(lLine, "tool=") > 0)574 else if (util.str.begins(lLine, "tool=") == True) 921 575 lRules[$-1].Tool = lLine[5..$]; 922 576 } 923 577 } 924 578 925 if (vVerbose )579 if (vVerbose == True) 926 580 { 927 581 foreach(Rule r; lRules) … … 984 638 lOutDate = new FileDateTime(lOutFile); 985 639 986 if ((lInDate > lOutDate) || vForceCompile)640 if ((lInDate > lOutDate) || (vForceCompile == True)) 987 641 { 988 642 char[] lKeyValues; … … 1015 669 //------------------------------------------------------- 1016 670 { 1017 bool lBuildRequired; 671 Bool lCompiling; 672 Bool lLinking; 673 Bool lBuildRequired; 1018 674 char[][] lFilesToLink; 1019 675 char[][] lFilesToCompile; … … 1023 679 FileDateTime lTargetTime; 1024 680 FileDateTime lMostRecentTime; 1025 bool lCompiling; 1026 bool lLinking; 1027 Source[] lNonLinkingSources; 681 auto Source[] lNonLinkingSources; 1028 682 char[] lDResponseFileName; 1029 683 char[] lLinkResponseFileName; … … 1031 685 char[] lDefName; 1032 686 char[] lOutText; 687 char[] lCompilerOpts; 1033 688 char[] lSourcesToCompile; 1034 689 char[] lCommand; 1035 690 char[][] lObjectFiles; 691 char[][] lLibraryFiles; 692 693 694 lCompiling = False; 695 lLinking = False; 696 lBuildRequired = False; 1036 697 1037 698 // Examine each supplied source file. 1038 699 foreach( char[] lFile; vCmdLineSourceFiles) 1039 700 { 1040 new Source(GetFullPathname(lFile ));701 new Source(GetFullPathname(lFile, vSourceScanList)); 1041 702 } 1042 703 … … 1045 706 lLinking = (vLibraryAction == LibOpt.Build) || 1046 707 (Source.WasMainFound == false) || 1047 (vNoLink == true)1048 ? false : true;708 (vNoLink == True) 709 ? False : True; 1049 710 1050 711 lMostRecentTime = GetNewestDateTime(); … … 1062 723 1063 724 // I'm either creating a library, an executable or neither. 725 726 // If a target name was supplied in a pragma, use that as the 727 // default target name. 1064 728 if (vPragmaTargetName.length != 0) 1065 729 vTargetName = vPragmaTargetName; 730 731 // If a target name was supplied on the command line, use that 732 // instead of the default name. 1066 733 if (vCommandTargetName.length != 0) 1067 734 { … … 1080 747 } 1081 748 749 // Ensure that the path to the target's location will exist. 1082 750 util.pathex.MakePath(vTargetName); 1083 751 752 1084 753 if (vLibraryAction == LibOpt.Build) 754 // Target is a library. 1085 755 lTargetName = ReplaceExtention(vTargetName, kLibExtention); 1086 else if (vNoLink == false) 756 757 else if (vNoLink == False) 758 { 1087 759 if (Source.WasMainFound) 1088 760 if (Source.WasMainDLL) 761 // Target is a shared library. 1089 762 lTargetName = ReplaceExtention(vTargetName, kShrLibExtention); 1090 else { 763 else 764 { 765 // Target is an executable 1091 766 lTargetName = ReplaceExtention(vTargetName, kExeExtention); 1092 767 vTargetExe = lTargetName; 1093 768 } 1094 769 else 1095 lTargetName = "not defined"; 770 { 771 // Possible error. The user wants to link but no 'main' detected 772 // so assume they know what they are doing and also assume an 773 // executable is required. 774 lTargetName = ReplaceExtention(vTargetName, kExeExtention); 775 vTargetExe = lTargetName; 776 } 777 } 1096 778 else 779 // Not linking and not archiving, so no target is required. 1097 780 lTargetName = ""; 1098 781 1099 lTargetName = util.pathex.CanonicalPath(lTargetName, false); 1100 lTargetName = util.pathex.AbbreviateFileName(lTargetName); 1101 1102 if(vVerbose || vNames) { 1103 writefln("\nBuilding target '%s'", lTargetName); 1104 } 1105 1106 if (lTargetName.length > 0 ) 1107 { 1108 lTargetName = util.pathex.CanonicalPath(lTargetName, false); 782 if (lTargetName.length > 0) 783 { 784 // Get the full name of the target's location. 785 lTargetName = util.pathex.CanonicalPath(lTargetName, false); 1109 786 lTargetDir = getDirName(lTargetName); 1110 787 788 // Show user if required to. 789 if((vVerbose == True) || (vNames == True) ) { 790 writefln("\nBuilding target '%s'", lTargetName); 791 } 792 793 // Shorten the target name for future usages. 794 lTargetName = util.pathex.AbbreviateFileName(lTargetName); 795 796 797 // If the target doesn't exist or it is older than 798 // most recently modified dependant file, we need to 799 // rebuild the target. 1111 800 lTargetTime = util.fdt.GetFileTime (lTargetName); 1112 if(vVerbose ) {801 if(vVerbose == True) { 1113 802 writefln("Time %s for %s (target)", lTargetTime.toString(), lTargetName); 1114 803 writefln("Time %s (most recent)", lMostRecentTime.toString()); 1115 804 } 1116 1117 805 if(lTargetTime < lMostRecentTime) { 1118 // If the target doesn't exist or it is older than 1119 // most recently modified dependant file, we need to 1120 // rebuild the target. 1121 lBuildRequired = true; 1122 } 1123 } 1124 806 lBuildRequired = True; 807 } 808 } 809 else if((vVerbose == True) || (vNames == True) ) { 810 writefln("\nCompiling only. No target will be built."); 811 } 812 813 // Run any external tools referenced in the source files. 1125 814 foreach( ExternRef lRef; vExternals) 1126 815 { 1127 816 lRunResult = ProcessExternal( lRef ); 1128 817 if (lRunResult != 0) 818 // If an external tool fails, stop immediately. 1129 819 return lRunResult; 1130 820 } … … 1142 832 { 1143 833 // Only include OBJECT files. 1144 if (util.str.ends(lFileName , kObjExtention) >= 0)834 if (util.str.ends(lFileName , kObjExtention) == True) 1145 835 lFilesToLink ~= lFileName; 1146 836 } 1147 837 } 1148 else foreach (int i, char[] lFileName; Source.S ourceIndex.keys)838 else foreach (int i, char[] lFileName; Source.ScanOrder) 1149 839 { 1150 840 // Check each source to see if we need to recompile it. 1151 841 Source lCurrentSource; 1152 bool lNeedsCompiling;842 Bool lNeedsCompiling; 1153 843 char[] lShortFileName; 844 char[] lFileType; 1154 845 1155 846 lNeedsCompiling = vForceCompile; … … 1160 851 1161 852 lShortFileName = util.pathex.AbbreviateFileName(lFileName); 1162 if (std.path.getExt(lShortFileName) != kSrcExtention) 853 lFileType = std.path.getExt(lShortFileName); 854 if (lFileType != kSrcExtention && lFileType != kDdocExtention) 1163 855 continue; 1164 856 1165 857 // Only source files are examined from here on. 1166 if (lCurrentSource.NoLink) 858 if (lCurrentSource.NoLink || lFileType == kDdocExtention) 859 { 1167 860 lNonLinkingSources ~= lCurrentSource; 861 } 1168 862 1169 863 if(lCurrentSource.FilesTime > lCurrentSource.ObjectsTime) 1170 864 { 1171 if (vVerbose )865 if (vVerbose == True) 1172 866 writefln("%s newer than its object file", lShortFileName); 1173 lNeedsCompiling =true;867 lNeedsCompiling = True; 1174 868 1175 869 } else if(lCurrentSource.DependantsTime > lCurrentSource.ObjectsTime) { 1176 if (vVerbose )870 if (vVerbose == True) 1177 871 writefln("%s has newer dependants than its object file.", 1178 872 lShortFileName); 1179 873 1180 lNeedsCompiling =true;1181 } 1182 1183 if(lNeedsCompiling )1184 { 1185 lBuildRequired = true;1186 lCompiling = true;874 lNeedsCompiling = True; 875 } 876 877 if(lNeedsCompiling == True) 878 { 879 lBuildRequired = True; 880 lCompiling = True; 1187 881 lFilesToCompile ~= lShortFileName; 1188 882 … … 1191 885 lFilesToLink ~= util.pathex.AbbreviateFileName(lCurrentSource.ObjectName); 1192 886 1193 if ( ! vTestRun)887 if (vTestRun == False) 1194 888 { 1195 889 if (lCurrentSource.IncrementBuildNumber()) 1196 890 { 1197 if (vVerbose )891 if (vVerbose == True) 1198 892 writefln("New build number %d for %s", 1199 893 lCurrentSource.BuildNumber, … … 1210 904 } 1211 905 1212 if( lBuildRequired == false )1213 { 1214 if (vSilent == false)906 if( lBuildRequired == False ) 907 { 908 if (vSilent == False) 1215 909 writefln ("Files are up to date, no build required."); 1216 910 return 0; 1217 911 } 1218 1219 lOutText ~= GatherCompilerArgs(lLinking);1220 912 1221 913 foreach(char[] lFileName; lFilesToCompile) … … 1245 937 AddBuildDef("DATA PRELOAD SINGLE WRITE"); 1246 938 } 1247 else if (vConsoleApp ) {939 else if (vConsoleApp == True) { 1248 940 AddBuildDef(`EXETYPE DOS`); 1249 941 } 1250 942 1251 if ((vNoDef == false) && (vBuildDef.length > 0))943 if ((vNoDef == False) && (vBuildDef.length > 0)) 1252 944 { 1253 945 lDefName = ReplaceExtention(lTargetName, "def"); … … 1259 951 util.fileex.CreateTextFile(lDefName, vBuildDef); 1260 952 1261 lOutText ~= util.str.enquote(lDefName) ~ "\n"; 1262 } 1263 } 1264 953 } 954 } 955 956 version(Posix) 957 { 958 vDefaultLibs ~= "c"; 959 } 1265 960 // Add any library or external obj files required. 1266 if (lLinking) { 961 if (lLinking == True) 962 { 963 lLibraryFiles.length = 0; 1267 964 1268 965 foreach (char[] lFileName; vLinkFiles.keys) 1269 966 { 1270 967 char[] lCmdItem; 1271 version(Posix) 1272 char[] lPrefix; 1273 1274 if (lFileName.length > 0) { 968 969 if (lFileName.length > 0) 970 { 1275 971 lCmdItem = lFileName; 1276 version(Posix) 1277 { 1278 int lCut; 1279 if ( (lCut = util.str.ends(lCmdItem, "." ~ kLibExtention)) >= 0) 1280 { 1281 lCmdItem = lCmdItem[0 .. lCut]; // Cut off extentsion. 1282 lPrefix = "-L-l"; // Needed for linker to find the library. 1283 } 1284 } 1285 lCmdItem = util.str.enquote(lCmdItem) ~ "\n"; 1286 1287 version(Posix) 1288 lOutText ~= lPrefix ~ lCmdItem; 1289 version(Windows) 1290 lOutText ~= lCmdItem; 1291 1292 } 1293 } 1294 } 1295 1296 if (lLinking || lCompiling) 1297 { 1298 1299 1300 // COMPILE phase 972 if ( util.str.ends(lCmdItem, "." ~ kLibExtention) == True) 973 { 974 // Cut off extention. 975 lCmdItem.length = lCmdItem.length - kLibExtention.length - 1; 976 // lPrefix = "-L-l"; // Needed for linker to find the library. 977 lLibraryFiles ~= lCmdItem; 978 } 979 else 980 { 981 lFilesToLink ~= lCmdItem; 982 } 983 } 984 } 985 } 986 987 if ((lLinking == True) || (lCompiling == True)) 988 { 989 // COMPILE phase ... 1301 990 if (lSourcesToCompile.length > 0) 1302 991 { 992 // Ok, I have some compiling to do! 1303 993 char[] lCommandLine; 1304 994 1305 lCommandLine = lOutText ~ lSourcesToCompile; 1306 1307 if (vUseResponseFile) { 995 lCommandLine = GatherCompilerArgs(lLinking) ~ lSourcesToCompile; 996 997 if (vUseResponseFile == True) 998 { 1308 999 lDResponseFileName = ReplaceExtention(lTargetName, "rsp"); 1309 1000 if (vTemporaryPath.length != 0) … … 1313 1004 lDResponseFileName = util.pathex.AbbreviateFileName(lDResponseFileName); 1314 1005 util.fileex.CreateTextFile(lDResponseFileName,lCommandLine); 1315 lCommand = vCompilerPath ~ vCompiler ~ vCompilerSwitch ~ " @" ~ lDResponseFileName;1006 lCommand = vCompilerPath ~ vCompilerExe ~ vCompileOnlySwitch ~ " @" ~ lDResponseFileName; 1316 1007 } 1317 1008 else 1318 1009 { // using commandline; may run into limits 1319 1010 lCommandLine=std.string.replace(lCommandLine, "\n", " "); 1320 lCommand = vCompilerPath ~ vCompiler ~ vCompilerSwitch ~ " " ~ lCommandLine;1321 } 1322 1323 if (vVerbose ) {1011 lCommand = vCompilerPath ~ vCompilerExe ~ vCompileOnlySwitch ~ " " ~ lCommandLine; 1012 } 1013 1014 if (vVerbose == True) { 1324 1015 writefln("Compiling with ..........\n%s\n", lCommandLine); 1325 1016 } … … 1328 1019 lRunResult = RunCommand(lCommand); 1329 1020 if (lRunResult != 0) 1330 vExecuteProgram = false; 1331 } 1332 1333 if ( (lRunResult == 0) && (lFilesToLink.length > 0) && (lLinking == true)) 1021 vExecuteProgram = False; 1022 } 1023 1024 // LINK phase ... 1025 if ( (lRunResult == 0) && (lFilesToLink.length > 0) && (lLinking == True)) 1334 1026 { 1335 1027 char[] lCommandLine; 1336 1337 // Ensure the linker gets the right executable name to create. 1338 char[] lSmallName; 1339 lSmallName = util.pathex.AbbreviateFileName(lTargetName); 1340 if (find(lSmallName, " ") != -1) { 1341 version(Posix) { 1342 lOutText ~= std.string.format(`%s"%s"`,vOutFileSwitch,lSmallName); 1343 } 1344 else { 1345 lOutText ~= std.string.format(`"%s%s"`,vOutFileSwitch,lSmallName); 1346 } 1347 } 1348 else 1349 lOutText ~= std.string.format(`%s%s`,vOutFileSwitch,lSmallName); 1350 1351 // Terminate with a newline char. 1352 lOutText ~= "\n"; 1353 1354 // Include the default libraries. 1355 foreach( char[] lLib; vDefaultLibs) 1356 { 1357 lLib = util.str.enquote(lLib) ~"\n"; 1358 version(Windows) 1359 lOutText ~= lLib; 1360 version(Posix) 1361 lOutText ~= "-L-l" ~ lLib; 1362 } 1363 1364 if (vLibPaths.length > 1) 1365 { 1366 vLibPaths = vLibPaths[1..$]; 1367 1368 // Include the paths to the libraries. 1369 version(Windows) { 1370 1371 if (vVerbose) 1372 writefln("Setting LIB=%s", vLibPaths); 1373 putenv("LIB=" ~ vLibPaths[1..$]); 1374 } 1375 version(Posix) 1376 { 1377 if (vVerbose) 1378 writefln("Setting LIB=%s", vLibPaths); 1379 char[][] lLibPaths; 1380 lLibPaths = std.string.split(vLibPaths, vConfigSep); 1381 foreach(char[] lLib; lLibPaths) 1382 { 1383 if (lLib.length > 0) 1384 lOutText ~= "-L-L" ~ lLib ~ "\n"; 1385 } 1386 } 1387 } 1388 1389 1390 lCommandLine = lOutText; 1391 foreach(char[] lFile; lFilesToLink) 1392 lCommandLine ~= lFile ~ "\n"; 1393 1394 if (vUseResponseFile) { 1028 char[] lLinkerSwitches; 1029 Bool IsMapping = False; 1030 1031 // Build the command line for the linker. 1032 lCommandLine = ""; 1033 version(Windows) 1034 { 1035 // Transfer linker switches from Compiler switches. 1036 foreach (char[] lCompileArg; vCompilerArgs) 1037 { 1038 if (util.str.begins(lCompileArg, "-L") == True) 1039 { 1040 lLinkerSwitches ~= lCompileArg[2..$]; 1041 } 1042 } 1043 foreach( char[] lSwitch; std.string.split(vLinkerDefSwitches ~ lLinkerSwitches, "/")) 1044 { 1045 if (lSwitch == "nomap") 1046 { 1047 IsMapping = False; 1048 } 1049 else if (lSwitch == "map") 1050 { 1051 IsMapping = True; 1052 } 1053 } 1054 1055 // (1) Gather the object file names 1056 foreach(char[] lFile; lFilesToLink) 1057 { 1058 lCommandLine ~= lFile ~ "+"; 1059 } 1060 if (lCommandLine.length > 0) 1061 lCommandLine[$-1] = '\n'; 1062 1063 // (2) Set the output file name 1064 lCommandLine ~= util.str.enquote(util.pathex.AbbreviateFileName(lTargetName)) ~ "\n"; 1065 1066 // (3) Set the map name 1067 if (IsMapping == True) 1068 lCommandLine ~= ReplaceExtention(lTargetName, "map"); 1069 1070 lCommandLine ~= "\n"; 1071 1072 // (4) Gather the libraries names. 1073 // Include the default libraries first. 1074 lLibraryFiles = vDefaultLibs ~ lLibraryFiles; 1075 if (lLibraryFiles.length > 0) 1076 { 1077 foreach( char[] lLib; lLibraryFiles) 1078 { 1079 lCommandLine ~= util.str.enquote(lLib) ~"+"; 1080 } 1081 lCommandLine[$-1] = '\n'; 1082 } 1083 else 1084 lCommandLine ~= "\n"; 1085 1086 // Include the explictly named libraries. 1087 if (vLibPaths.length > 1) 1088 { 1089 if (vLibPaths[0..1] == vConfigSep) 1090 vLibPaths = vLibPaths[1..$]; 1091 1092 // Include the paths to the libraries. 1093 if (vVerbose == True) 1094 writefln("Setting LIB=%s", vLibPaths); 1095 putenv("LIB=" ~ vLibPaths[1..$]); 1096 } 1097 1098 // (5) Set the 'def' file name 1099 if (lDefName.length > 0) 1100 lCommandLine ~= util.str.enquote(lDefName) ~ "\n"; 1101 else 1102 lCommandLine ~= "\n"; 1103 1104 // (6) Gather the resource file names 1105 1106 // (7) Gather then switches 1107 lCommandLine ~= vLinkerDefSwitches; 1108 lCommandLine ~= lLinkerSwitches; 1109 lCommandLine ~= "\n"; 1110 } 1111 1112 version(Posix) 1113 { 1114 // Transfer linker switches from Compiler switches. 1115 foreach (char[] lCompileArg; vCompilerArgs) 1116 { 1117 if (util.str.begins(lCompileArg, "-L") == True) 1118 { 1119 lLinkerSwitches ~= lCompileArg[2..$]; 1120 } 1121 } 1122 foreach( char[] lSwitch; std.string.split(vLinkerDefSwitches ~ lLinkerSwitches, "/")) 1123 { 1124 if (lSwitch == "nomap") 1125 { 1126 IsMapping = False; 1127 } 1128 else if (lSwitch == "map") 1129 { 1130 IsMapping = True; 1131 } 1132 } 1133 1134 // (1) Gather the object file names 1135 foreach(char[] lFile; lFilesToLink) 1136 { 1137 lCommandLine ~= lFile ~ "\n"; 1138 } 1139 1140 // (2) Set the output file name 1141 lCommandLine ~= "-o " ~ util.str.enquote(util.pathex.AbbreviateFileName(lTargetName)) ~ "\n"; 1142 1143 // (3) Set the map name 1144 if (IsMapping == True) 1145 lCommandLine ~= "-M\n"; 1146 1147 // (4) Gather the libraries names. 1148 // Include the default libraries first. 1149 foreach( char[] lLib; vDefaultLibs ~ lLibraryFiles) 1150 { 1151 lCommandLine ~= "-l" ~ util.str.enquote(lLib) ~ "\n"; 1152 } 1153 1154 if (vLibPaths.length > 1) 1155 { 1156 if (vLibPaths[0..1] == vConfigSep) 1157 vLibPaths = vLibPaths[1..$]; 1158 1159 // Include the paths to the libraries. 1160 if (vVerbose == True) 1161 writefln("Setting LIB=%s", vLibPaths); 1162 char[][] lLibPaths; 1163 lLibPaths = std.string.split(vLibPaths, vConfigSep); 1164 foreach(char[] lLib; lLibPaths) 1165 { 1166 if (lLib.length > 0) 1167 lCommandLine ~= "-L" ~ util.str.enquote(lLib) ~ "\n"; 1168 } 1169 } 1170 1171 // (4) Gather then switches 1172 lCommandLine ~= vLinkerDefSwitches; 1173 lCommandLine ~= lLinkerSwitches; 1174 lCommandLine ~= "\n"; 1175 } 1176 1177 if (vUseResponseFile == True) 1178 { 1395 1179 lLinkResponseFileName = ReplaceExtention(lTargetName, "ksp"); 1396 1180 if (vTemporaryPath.length != 0) … … 1400 1184 lLinkResponseFileName = util.pathex.AbbreviateFileName(lLinkResponseFileName); 1401 1185 util.fileex.CreateTextFile(lLinkResponseFileName,lCommandLine); 1402 lCommand = v CompilerPath ~ vLinker~ " @" ~ lLinkResponseFileName;1186 lCommand = vLinkerPath ~ vLinkerExe ~ " @" ~ lLinkResponseFileName; 1403 1187 } 1404 1188 else 1405 1189 { // using commandline; may run into limits 1406 1190 lCommandLine=std.string.replace(lCommandLine, "\n", " "); 1407 lCommand = v CompilerPath ~ vLinker~ " " ~ lCommandLine;1408 } 1409 1410 if (vVerbose ) {1191 lCommand = vLinkerPath ~ vLinkerExe ~ " " ~ lCommandLine; 1192 } 1193 1194 if (vVerbose == True) { 1411 1195 writefln("Linking with ..........\n%s\n", lCommandLine); 1412 1196 } 1413 1197 1414 1198 // Run Linker 1415 if (vSilent )1199 if (vSilent == True) 1416 1200 { 1417 1201 version(Posix) lCommand ~= " >/dev/null"; … … 1421 1205 lRunResult = RunCommand(lCommand); 1422 1206 if (lRunResult != 0) 1423 vExecuteProgram = false;1207 vExecuteProgram = False; 1424 1208 } 1425 1209 … … 1427 1211 else 1428 1212 { 1429 if (vSilent == false)1213 if (vSilent == False) 1430 1214 writefln("No build required."); 1431 1215 lRunResult = 0; … … 1439 1223 ulong[] lImpManf; 1440 1224 1441 vExecuteProgram = false;1442 1443 lImpLibPath = util.pathex.LocateFile("implib.exe", GetEnv( "PATH"));1225 vExecuteProgram = False; 1226 1227 lImpLibPath = util.pathex.LocateFile("implib.exe", GetEnv(kPathId)); 1444 1228 if (util.fileex.FileExists(lImpLibPath)) 1445 1229 { … … 1455 1239 } 1456 1240 } 1457 else if ( (vLibraryAction == LibOpt.Build) && (lRunResult == 0) ) 1458 { 1459 vExecuteProgram = false; 1460 1461 lOutText.length = 0; 1462 lOutText ~= vLibrarianOpts ~ std.path.linesep; 1241 else if ( (vLibraryAction == LibOpt.Build) && (lRunResult == 0)) 1242 { 1243 int lFileCount; 1244 1245 vExecuteProgram = False; 1246 1247 lOutText = vLibrarianOpts ~ std.path.linesep; 1463 1248 lOutText ~= lTargetName ~ std.path.linesep; // Create a new library 1464 1249 1465 foreach( char[] lFileName; lFilesToLink) { 1250 foreach( char[] lFileName; lFilesToLink) 1251 { 1466 1252 char[] lFileDir; 1467 1253 1468 1254 lFileDir = getDirName(lFileName); 1469 if (vAllObjects || lFileDir == "" || lFileDir == lTargetDir) { 1255 if ((vAllObjects == True) || lFileDir == "" || lFileDir == lTargetDir) 1256 { 1470 1257 if (lFileName.length > 1 + kSrcExtention.length) 1471 1258 { … … 1475 1262 } 1476 1263 } 1477 1264 lFileCount++; 1478 1265 lOutText ~= lFileName ~ std.path.linesep; 1479 1266 } 1480 1267 } 1481 1268 1482 if (vUseResponseFile) { 1483 lLResponseFileName = ReplaceExtention(lTargetName, "lsp"); 1484 if (vTemporaryPath.length != 0) 1485 { 1486 lLResponseFileName = vTemporaryPath ~ std.path.getBaseName(lLResponseFileName); 1487 } 1488 util.fileex.CreateTextFile(lLResponseFileName,lOutText); 1489 lCommand = vLibrarianPath ~ vLibrarian ~ " @" ~ lLResponseFileName; 1490 } 1491 else 1492 { // using commandline, may run into limits 1493 lCommand = vLibrarianPath ~ vLibrarian ~ " " ~ std.string.replace(lOutText,std.path.linesep," "); 1494 } 1495 1496 if (vVerbose) { 1497 writefln("Librarian with ..........\n%s\n", lOutText); 1498 } 1499 1500 lRunResult = RunCommand(lCommand); 1269 if (lFileCount > 0) 1270 { 1271 if (vUseResponseFile == True) { 1272 lLResponseFileName = ReplaceExtention(lTargetName, "lsp"); 1273 if (vTemporaryPath.length != 0) 1274 { 1275 lLResponseFileName = vTemporaryPath ~ std.path.getBaseName(lLResponseFileName); 1276 } 1277 util.fileex.CreateTextFile(lLResponseFileName,lOutText); 1278 lCommand = vLibrarianPath ~ vLibrarian ~ " @" ~ lLResponseFileName; 1279 } 1280 else 1281 { // using commandline, may run into limits 1282 lCommand = vLibrarianPath ~ vLibrarian ~ " " ~ std.string.replace(lOutText,std.path.linesep," "); 1283 } 1284 1285 if (vVerbose == True) { 1286 writefln("Librarian with ..........\n%s\n", lOutText); 1287 } 1288 1289 lRunResult = RunCommand(lCommand); 1290 } 1501 1291 } 1502 1292 1503 1293 // Optional clean up. 1504 if (vCleanup) { 1294 if (vCleanup == True) 1295 { 1505 1296 char[][] lHitList; 1506 1297 1507 if (vVerbose ) {1298 if (vVerbose == True) { 1508 1299 writefln("Cleaning up ..."); 1509 1300 } 1510 foreach(char[] lFileName; Source.S ourceIndex.keys)1301 foreach(char[] lFileName; Source.ScanOrder) 1511 1302 { 1512 1303 Source lSource; … … 1538 1329 if (util.fileex.FileExists( lFilename ) ) 1539 1330 { 1540 if (vVerbose ) {1331 if (vVerbose == True) { 1541 1332 writefln(" removing %s", lFilename); 1542 1333 } … … 1553 1344 1554 1345 // ------------------------------------------- 1555 char [] GatherCompilerArgs( bool pLinking)1346 char [] GatherCompilerArgs(Bool pLinking) 1556 1347 // ------------------------------------------- 1557 1348 { … … 1597 1388 } 1598 1389 1599 if (pLinking == false)1390 if (pLinking == False) 1600 1391 { // No linking allowed. 1601 1392 if (vNoLinkSwitch.length > 0) … … 1632 1423 vExternals[$-1].FilePath = pPath; 1633 1424 vExternals[$-1].ToolOpts = pOpts; 1634 if (vVerbose ) {1425 if (vVerbose == True) { 1635 1426 writef("Added external file to be built: %s", pPath); 1636 1427 foreach( char[] lOpt; pOpts) … … 1661 1452 vPragmaTargetName = pPath; 1662 1453 else if (vPragmaTargetName != pPath) { 1663 if (vVerbose ) {1454 if (vVerbose == True) { 1664 1455 writefln("Multiple pragma(target,...) detected. '%s' will be used and '%s' rejected.", 1665 1456 vPragmaTargetName, pPath ); … … 1677 1468 static uint[ char[] ] lElementIdx; 1678 1469 1679 if (vNoDef == true)1470 if (vNoDef == True) 1680 1471 return; 1681 1472 … … 1742 1533 version(Windows) lSearchName = std.string.tolower(lFullName); 1743 1534 version(Posix) lSearchName = lFullName; 1744 if( !(lSearchName in lRootHash) ) { 1535 if( !(lSearchName in lRootHash) ) 1536 { 1745 1537 vImportRoots ~= lFullName; 1746 1538 lRootHash[lSearchName] = true; … … 1752 1544 } 1753 1545 1754 bool AutoImports()1546 Bool AutoImports() 1755 1547 { 1756 1548 return vAutoImports; … … 1796 1588 else 1797 1589 { 1798 lSymName = GetEnv(lSymName);1590 lSymName = (GetEnv(std.utf.toUTF8(lSymName))); 1799 1591 } 1800 1592 lLine ~= lSymName; … … 1886 1678 vDefaultCompArgs ~= vImportPathSwitch ~ lRoot; 1887 1679 */ 1888 if(vVerbose ) {1680 if(vVerbose == True) { 1889 1681 if (lRootName.length > 0){ 1890 1682 writefln(" added root from config file %s", lRootName); … … 1897 1689 version(DigitalMars) 1898 1690 { 1899 if (util.str.IsLike(lSwitch, (vOutFileSwitch ~ "*")) )1691 if (util.str.IsLike(lSwitch, (vOutFileSwitch ~ "*")) == True) 1900 1692 { 1901 1693 // Target name (eg. -oftestapp) … … 1917 1709 } 1918 1710 1919 if (util.str.IsLike(lSwitch, std.utf.toUTF32(vTemporaryPathSwitch ~ "*")) )1711 if (util.str.IsLike(lSwitch, std.utf.toUTF32(vTemporaryPathSwitch ~ "*")) == True) 1920 1712 { 1921 1713 char[] lbRoot; … … 1929 1721 lbRoot = AddRoot(vTemporaryPath); 1930 1722 if (lbRoot.length > 0){ 1931 if(vVerbose ) {1723 if(vVerbose == True) { 1932 1724 writefln("Added root from config file Object Write Path = %s",lbRoot); 1933 1725 } … … 1956 1748 if (lSymValue.length > 0 ) 1957 1749 { 1958 if (vVerbose )1750 if (vVerbose == True) 1959 1751 writefln("Analyzing environment symbol DFLAGS=%s", lSymValue); 1960 1752 Process_DFLAGS( lSymValue ); … … 1970 1762 int lPos; 1971 1763 1972 if (vConfigFile is null)1764 if (vConfigFile.length == 0) 1973 1765 { 1974 1766 // There is no configuration file to process … … 1977 1769 1978 1770 lPath = vConfigPath ~ vConfigFile ; 1979 lTextLines = util.fileex.GetTextLines(lPath, util.fileex.GetOpt.Exists);1980 1981 if (vVerbose ) {1771 util.fileex.GetTextLines(lPath, lTextLines, util.fileex.GetOpt.Exists); 1772 1773 if (vVerbose == True) { 1982 1774 writefln("Reading from config: %s", lPath); 1983 1775 } … … 1986 1778 { 1987 1779 // Strip off trailing whitespace. 1988 while(lLine.length > 0 && lLine[lLine.length-1] <= ' ') { 1989 lLine.length = lLine.length-1; 1990 } 1780 lLine = util.str.stripr(lLine); 1781 1991 1782 // Replace any environment symbols with their value. 1992 if (vVerbose ) {1783 if (vVerbose == True) { 1993 1784 writefln(" Line %d: %s", i+1, lLine); 1994 1785 } … … 2032 1823 lPath = lPath[1..length-1]; 2033 1824 } 2034 vLibPaths ~= vConfigSep; 2035 vLibPaths ~= ("\"" ~ util.pathex.CanonicalPath(lPath) ~ "\""); 2036 } 2037 } 2038 if(vVerbose) 1825 vLibPaths ~= vConfigSep ~ `"` ~ util.pathex.CanonicalPath(lPath) ~ `"`; 1826 } 1827 } 1828 if(vVerbose == True) 2039 1829 { 2040 1830 writefln(" use %s",vLibPaths); … … 2052 1842 } 2053 1843 2054 if (vLibrarianPath.length == 0) 2055 { 2056 vLibrarianPath = std.path.getDirName(lLine[8..$]) ~ std.path.sep; 2057 vLibrarianPath = util.pathex.CanonicalPath(vLibrarianPath); 2058 if(vVerbose) { 2059 writefln(" librarian path %s",vLibrarianPath); 2060 } 1844 vLinkerPath = std.path.getDirName(lLine[8..$]) ~ std.path.sep; 1845 vLinkerPath = util.pathex.CanonicalPath(vLinkerPath); 1846 vLinkerExe = std.path.getBaseName(lLine[7..$]); 1847 if(vVerbose == True) { 1848 writefln(" linker path %s",vLinkerPath); 1849 writefln(" linker is %s",vLinkerExe); 2061 1850 } 2062 1851 continue; … … 2074 1863 2075 1864 vLibrarian = std.path.getBaseName(lLine[7..$]); 2076 if(vVerbose ) {1865 if(vVerbose == True) { 2077 1866 writefln(" librarian path %s",vLibrarianPath); 2078 1867 writefln(" librarian is %s",vLibrarian); 2079 1868 } 2080 1869 } 1870 1871 1872 if (vLinkerPath.length == 0) 1873 vLinkerPath = vCompilerPath; 1874 if (vLibrarianPath.length == 0) 1875 vLibrarianPath = vLinkerPath; 2081 1876 } 2082 1877 } … … 2129 1924 2130 1925 // ------------------------------------------------ 2131 char[] GetFullPathname(char[] pFileName) 1926 char[] GetFullPathnameScan(char[] pFileName, int pScanList) 1927 // ------------------------------------------- 1928 { 1929 if (pScanList == 0) 1930 return GetFullPathname(pFileName); 1931 else 1932 return GetFullPathname(pFileName, vSourceScanList); 1933 } 1934 1935 // ------------------------------------------------ 1936 char[] GetFullPathname(char[] pFileName, char[][] pScanList = null) 2132 1937 // ------------------------------------------- 2133 1938 { 2134 1939 char[] lPossiblePath; 2135 1940 char[] lLocalPath; 1941 1942 if (util.pathex.IsRelativePath(pFileName) == True && pScanList.length > 0) 1943 { 1944 // Do explicit scanning of supplied paths. 1945 foreach(char[] lNextRoot; pScanList) { 1946 lPossiblePath = ( lNextRoot ~ pFileName ); 1947 if(util.fileex.FileExists(lPossiblePath)) { 1948 return util.pathex.AbbreviateFileName(lPossiblePath); 1949 } 1950 } 1951 1952 // If not found in scan list, drop through to standard scan. 1953 } 2136 1954 2137 1955 // Look for file in current folder first. … … 2213 2031 source.AddBuildDef = &AddBuildDef; 2214 2032 source.GetFullPathname = &GetFullPathname; 2033 source.GetFullPathnameScan = &GetFullPathnameScan; 2215 2034 source.GetObjWritePath = &GetTemporaryPath; 2216 2035 source.GetMacros = &GetMacros; … … 2218 2037 2219 2038 // Scan the PATH env symbol to locate the D compiler. 2220 lCompPath = FindFileInPathList( "PATH", vCompiler);2039 lCompPath = FindFileInPathList(kPathId, vCompilerExe); 2221 2040 if (lCompPath.length > 0){ 2222 2041 if (lCompPath[length-1] != std.path.sep[0]) … … 2257 2076 GatherArgs( pArgs ); 2258 2077 source.mVerboseMode = vVerbose; 2259 if (vVerbose ){2078 if (vVerbose == True){ 2260 2079 writefln("*** build v%s (build %d)***", vAppVersion, build_bn.auto_build_number); 2261 2080 } … … 2266 2085 2267 2086 source.mMacroInput = vMacroInput; 2268 if (vMacroInput )2087 if (vMacroInput == True) 2269 2088 ProcessMacroDefs(vVerbose); 2270 2089 … … 2273 2092 } 2274 2093 2275 if ( vVerbose || vNames)2094 if ((vVerbose == True) || (vNames == True) ) 2276 2095 writefln("Current Dir '%s'", util.pathex.GetInitCurDir()); 2277 2096 2278 2097 if (lSetPath) 2279 2098 { 2280 if (vVerbose )2099 if (vVerbose == True) 2281 2100 { 2282 2101 writefln("%s not found in PATH symbol, so assuming current directory", 2283 vCompiler );2102 vCompilerExe); 2284 2103 } 2285 2104 } … … 2292 2111 { 2293 2112 vConfigPath = vCompilerPath; 2294 if (vVerbose )2113 if (vVerbose == True) 2295 2114 { 2296 2115 writefln("No configuration file path, so assuming current directory"); 2297 2116 } 2298 2117 } 2299 if ( vConfigPath[length-1] != std.path.sep[0])2118 if (util.str.ends(vConfigPath, std.path.sep) is False) 2300 2119 vConfigPath ~= std.path.sep; 2301 2120 … … 2309 2128 } 2310 2129 2311 if (util.fileex.FileExists(vCompilerPath ~ vCompiler ) == false)2130 if (util.fileex.FileExists(vCompilerPath ~ vCompilerExe) == false) 2312 2131 { 2313 2132 throw new Exception(std.string.format("The compiler '%s' was not found.", 2314 vCompilerPath ~ vCompiler ));2315 } 2316 2317 if (vVerbose ){2133 vCompilerPath ~ vCompilerExe)); 2134 } 2135 2136 if (vVerbose == True){ 2318 2137 writefln("Compiler installed in %s",vCompilerPath); 2319 2138 writefln("Configuration File installed in %s",vConfigPath); … … 2345 2164 foreach( char[] lFile; vCmdLineSourceFiles) 2346 2165 { 2347 if (! util.fileex.FileExists( lFile) )2348 { 2349 if (vSilent == false)2166 if (! util.fileex.FileExists( GetFullPathname(lFile, vSourceScanList)) ) 2167 { 2168 if (vSilent == False) 2350 2169 writefln("** File '%s' not found.", lFile); 2351 2170 lAllExist = false; … … 2360 2179 lBuildResult = Build(); 2361 2180 2362 if(vVerbose ) {2181 if(vVerbose == True) { 2363 2182 writefln(""); 2364 2183 DisplayItems(vBuildArgs, "build args: ..............."); 2365 2184 DisplayItems(vCompilerArgs, "compiler args: ................"); 2366 2185 DisplayItems(vCmdLineSourceFiles, "command line files: ..............."); 2367 DisplayItems(Source.S ourceIndex.keys,2186 DisplayItems(Source.ScanOrder, 2368 2187 "source files: ..............."); 2369 2188 DisplayItems(vLinkFiles.keys, "link files: ..............."); … … 2374 2193 } 2375 2194 2376 if ( vExecuteProgram&& (vTargetExe.length > 0))2195 if ((vExecuteProgram == True) && (vTargetExe.length > 0)) 2377 2196 { 2378 2197 RunCommand( vTargetExe ~ " " ~ std.string.strip(vRunParms)); … … 2384 2203 } 2385 2204 2386 void ProcessResponseFile(char[] pArg, bool pVerbose)2205 void ProcessResponseFile(char[] pArg, Bool pVerbose) 2387 2206 { 2388 2207 // A response file is being used. … … 2391 2210 2392 2211 if (pArg.length == 1) 2393 lRespFileName = " @build.brf";2212 lRespFileName = "build.brf"; 2394 2213 else 2395 2214 lRespFileName = pArg[1..length].dup; … … 2400 2219 } 2401 2220 2402 if (pVerbose )2221 if (pVerbose == True) 2403 2222 writefln("Response file %s", lRespFileName); 2404 2223 … … 2416 2235 lArg = std.string.strip(lArg); 2417 2236 if (lArg.length > 1){ 2418 if (pVerbose )2237 if (pVerbose == True) 2419 2238 writefln("Response file arg: %s", lArg); 2420 2239 GatherOneArg( lArg ); … … 2427 2246 char[] lNewPath; 2428 2247 static char[] lImportSwitch; 2429 int lCut; 2430 2431 if(util.str.begins(pArg, "-version=") > 0) { 2248 2249 if(util.str.begins(pArg, "-version=") == True) { 2432 2250 char[] lVersionString; 2433 2251 … … 2436 2254 pArg = vVersionSwitch ~ lVersionString; 2437 2255 } 2438 else if(util.str.begins(pArg, "-fversion=") > 0) {2256 else if(util.str.begins(pArg, "-fversion=") == True) { 2439 2257 char[] lVersionString; 2440 2258 … … 2452 2270 pArg = vDebugSwitch; 2453 2271 } 2454 else if(util.str.begins(pArg, "-fdebug=") > 0) {2272 else if(util.str.begins(pArg, "-fdebug=") == True) { 2455 2273 char[] lDebugString; 2456 2274 … … 2459 2277 pArg = vDebugSwitch ~ "=" ~ lDebugString; 2460 2278 } 2461 else if(util.str.begins(pArg, "-debug=") > 0) {2279 else if(util.str.begins(pArg, "-debug=") == True) { 2462 2280 char[] lDebugString; 2463 2281 … … 2469 2287 switch(pArg) { 2470 2288 case "-full": 2471 vForceCompile = true;2289 vForceCompile = True; 2472 2290 vBuildArgs ~= pArg; 2473 2291 // Not passed thru. … … 2481 2299 2482 2300 case "-nolink": 2483 vNoLink = true;2301 vNoLink = True; 2484 2302 vBuildArgs ~= pArg; 2485 2303 // Not passed thru. … … 2500 2318 case "-obj": 2501 2319 vLibraryAction = LibOpt.DontBuild; 2502 vNoLink = true;2320 vNoLink = True; 2503 2321 vBuildArgs ~= pArg; 2504 2322 // Not passed thru. … … 2507 2325 case "-nounittest": 2508 2326 // Not passed thru. Deprecated switch is now ignored. 2509 if (vSilent == false)2327 if (vSilent == False) 2510 2328 writefln("Note: '-nounittest' ignored. This switch is no longer used."); 2511 2329 break; … … 2518 2336 2519 2337 case "-silent": 2520 vSilent = true;2338 vSilent = True; 2521 2339 vBuildArgs ~= pArg; 2522 2340 // Not passed thru. … … 2524 2342 2525 2343 case "-noautoimport": 2526 vAutoImports = false;2344 vAutoImports = False; 2527 2345 vBuildArgs ~= pArg; 2528 2346 // Not passed thru … … 2530 2348 2531 2349 case "-nodef": 2532 vNoDef = true;2350 vNoDef = True; 2533 2351 vBuildArgs ~= pArg; 2534 2352 // Not passed thru. … … 2536 2354 2537 2355 case "-nomacro": 2538 vMacroInput = false;2356 vMacroInput = False; 2539 2357 vBuildArgs ~= pArg; 2540 2358 // Not passed thru. … … 2551 2369 2552 2370 case "-allobj": 2553 vAllObjects = true;2371 vAllObjects = True; 2554 2372 vBuildArgs ~= pArg; 2555 2373 // Not passed thru. … … 2557 2375 2558 2376 case "-test": 2559 vTestRun = true;2377 vTestRun = True; 2560 2378 vBuildArgs ~= pArg; 2561 2379 // Not passed thru. … … 2565 2383 // drop through ... 2566 2384 case "-clean": 2567 vCleanup = true;2385 vCleanup = True; 2568 2386 vBuildArgs ~= pArg; 2569 2387 // Not passed thru. … … 2577 2395 case "-names": 2578 2396 vBuildArgs ~= pArg; 2579 vNames = true;2397 vNames = True; 2580 2398 // Not passed thru. 2581 2399 break; … … 2585 2403 { 2586 2404 if (pArg[0] == '-') { 2405 if (pArg == "-g") 2406 { 2407 // Requires symbolic debug info. 2408 vLinkerDefSwitches ~= "/co"; 2409 AddCompilerArg(pArg); 2410 break; 2411 } 2412 2587 2413 // Test for Librarian options. 2588 if (util.str.IsLike(pArg, cast(dchar[])"-LIBOPT*"))2414 if (util.str.IsLike(pArg, "-LIBOPT*"d) == True) 2589 2415 { 2590 2416 vLibrarianOpts ~= " " ~ pArg[7..$].dup; … … 2594 2420 } 2595 2421 2596 if (util.str.begins(pArg, "-LIBPATH=") >= 0)2422 if (util.str.begins(pArg, "-LIBPATH=") == True) 2597 2423 { 2598 2424 vLibPaths ~= vConfigSep ~ pArg[9..$].dup; … … 2602 2428 2603 2429 // Test for alternate install locations. 2604 if (util.str.IsLike(pArg, cast(dchar[])"-DCPATH*"))2430 if (util.str.IsLike(pArg, "-DCPATH?*"d) == True) 2605 2431 { 2606 2432 lNewPath = pArg[7..length].dup; 2607 2433 if (vCompilerPath == vConfigPath) 2608 2434 { 2609 if (vVerbose )2435 if (vVerbose == True) 2610 2436 writefln("CFPATH was %s now %s", vConfigPath, lNewPath); 2611 2437 vConfigPath = lNewPath; 2612 2438 } 2613 if (vVerbose )2439 if (vVerbose == True) 2614 2440 writefln("DCPATH was %s now %s", vCompilerPath, lNewPath); 2615 2441 vCompilerPath = lNewPath; … … 2619 2445 } 2620 2446 2621 if (util.str.IsLike(pArg, cast(dchar[])"-CFPATH*"))2622 { 2623 if (vVerbose )2447 if (util.str.IsLike(pArg, "-CFPATH?*"d) == True) 2448 { 2449 if (vVerbose == True) 2624 2450 writefln("CFPATH was %s now %s", vConfigPath, pArg[7..length]); 2625 2451 vConfigPath = pArg[7..length].dup; … … 2629 2455 } 2630 2456 2631 if (util.str.IsLike(pArg, cast(dchar[])"-RDF*")) 2632 { 2633 if (vVerbose) 2457 if (util.str.IsLike(pArg, "-PP?*"d) == True) 2458 { 2459 char[] lNewPath; 2460 lNewPath = pArg[3..length].dup; 2461 if (vVerbose == True) 2462 writefln("Added %s to Source Scan List", lNewPath); 2463 vBuildArgs ~= pArg; 2464 if ( util.str.ends(lNewPath, std.path.sep) == False) 2465 lNewPath ~= std.path.sep; 2466 vSourceScanList ~= lNewPath; 2467 break; 2468 2469 } 2470 2471 if (util.str.IsLike(pArg, "-RDF?*"d) == True) 2472 { 2473 if (vVerbose == True) 2634 2474 writefln("RDF was %s now %s", vRDFName, pArg[4..$]); 2635 2475 vRDFName = pArg[4..$].dup; … … 2645 2485 break; 2646 2486 } 2647 else if ( (lCut = util.str.begins(pArg, vBuildImportPathSwitch)) >= 0)2487 else if ( util.str.begins(pArg, vBuildImportPathSwitch) == True) 2648 2488 { 2649 2489 char [] lRoot; 2650 foreach(char[] lCmdRoot; std.string.split(pArg[ lCut..$], ";"))2490 foreach(char[] lCmdRoot; std.string.split(pArg[vBuildImportPathSwitch.length .. $], ";")) 2651 2491 { 2652 2492 lRoot = AddRoot(lCmdRoot); 2653 2493 if (lRoot.length > 0){ 2654 if(vVerbose ) {2494 if(vVerbose == True) { 2655 2495 writefln("Added root from command line = %s",lRoot); 2656 2496 } … … 2659 2499 break; 2660 2500 } 2661 if (util.str.IsLike(pArg, std.utf.toUTF32(vRunSwitch ~ "*"))) 2501 2502 if (util.str.IsLike(pArg, std.utf.toUTF32(vRunSwitch ~ "*")) == True) 2662 2503 { 2663 2504 vRunParms ~= pArg[vRunSwitch.length .. $] ~ " "; 2664 vExecuteProgram = true;2505 vExecuteProgram = True; 2665 2506 vBuildArgs ~= pArg; 2666 2507 break; … … 2671 2512 version(DigitalMars) 2672 2513 { 2673 if (util.str.IsLike(pArg, std.utf.toUTF32(vTemporaryPathSwitch ~ "*")) )2514 if (util.str.IsLike(pArg, std.utf.toUTF32(vTemporaryPathSwitch ~ "*")) == True) 2674 2515 { 2675 2516 char[] lRoot; … … 2681 2522 lRoot = AddRoot(vTemporaryPath); 2682 2523 if (lRoot.length > 0){ 2683 if(vVerbose ) {2524 if(vVerbose == True) { 2684 2525 writefln("Added root from Object Write Path = %s",lRoot); 2685 2526 } … … 2692 2533 } 2693 2534 2694 if (util.str.IsLike(pArg, cast(dchar[])"-X*"))2535 if (util.str.IsLike(pArg, "-X?*"d) == True) 2695 2536 { 2696 2537 // Modules to ignore (eg. -Xmylib) … … 2700 2541 } 2701 2542 2702 if (util.str.IsLike(pArg, cast(dchar[])"-M*"))2543 if (util.str.IsLike(pArg, "-M?*"d) == True) 2703 2544 { 2704 2545 // Modules to notice (eg. -Mphobos) … … 2708 2549 } 2709 2550 2710 if (util.str.IsLike(pArg, cast(dchar[])"-T*"))2551 if (util.str.IsLike(pArg, "-T?*"d) == True) 2711 2552 { 2712 2553 // Target name (eg. -Ttestapp) … … 2718 2559 version(DigitalMars) 2719 2560 { 2720 if (util.str.IsLike(pArg, (vOutFileSwitch ~ "*")) )2561 if (util.str.IsLike(pArg, (vOutFileSwitch ~ "*")) == True) 2721 2562 { 2722 2563 // Target name (eg. -oftestapp) … … 2738 2579 } 2739 2580 2740 if (util.str.IsLike(pArg, cast(dchar[])"-R*"))2581 if (util.str.IsLike(pArg, "-R*"d) == True) 2741 2582 { 2742 2583 // Response file usage (eg. -Ry) 2743 2584 if (pArg.length == 2) 2744 vUseResponseFile = (vUseResponseFile ? false : true);2585 vUseResponseFile = ~vUseResponseFile; 2745 2586 2746 2587 else if (pArg[2] == 'y') 2747 vUseResponseFile = true;2588 vUseResponseFile = True; 2748 2589 2749 2590 else 2750 vUseResponseFile = false;2591 vUseResponseFile = False; 2751 2592 2752 2593 vBuildArgs ~= pArg; … … 2755 2596 2756 2597 version(Windows) { 2757 if (util.str.IsLike(pArg, cast(dchar[])"-gui*"))2598 if (util.str.IsLike(pArg, "-gui*"d) == True) 2758 2599 { 2759 2600 Source.WasMainGUI = true; … … 2767 2608 break; 2768 2609 } 2610 2769 2611 if (pArg == "-dll") 2770 2612 { … … 2790 2632 lRoot = AddRoot(lCmdRoot); 2791 2633 if (lRoot.length > 0){ 2792 if(vVerbose ) {2634 if(vVerbose == True) { 2793 2635 writefln("Added root from command line = %s",lRoot); 2794 2636 } … … 2805 2647 } 2806 2648 2649 version(Windows) 2650 { 2651 // Convert non-standard but sometimes used unix seps 2652 // with standard Windows seps. 2653 pArg = std.string.replace(pArg, "/", std.path.sep); 2654 } 2807 2655 switch(std.path.getExt(pArg)) { 2808 2656 case "": … … 2813 2661 case kSrcExtention: 2814 2662 case kMacroExtention: 2663 case kDdocExtention: 2815 2664 vCmdLineSourceFiles ~= pArg; 2816 2665 break; … … 2837 2686 2838 2687 if ((pArg == "-V") || (pArg == "-v")) 2839 vVerbose = true;2688 vVerbose = True; 2840 2689 2841 2690 if ( pArg.length >= 2 && pArg[0..2] == "--") … … 2843 2692 pArg = pArg[1..$]; 2844 2693 if ((pArg == "-V") || (pArg == "-v")) 2845 vVerbose = false;2694 vVerbose = False; 2846 2695 for(int i = vCombinedArgs.length-1; i >= 0; i--) 2847 2696 { 2848 2697 if (pArg[$-1] == '*') 2849 2698 { 2850 if (vCombinedArgs[i].begins(pArg[0..$-1]) > 0)2699 if (vCombinedArgs[i].begins(pArg[0..$-1]) == True) 2851 2700 { 2852 2701 vCombinedArgs = vCombinedArgs[0..i] ~ … … 2896 2745 } 2897 2746 2898 void ProcessMacroDefs( bool pVerbose)2747 void ProcessMacroDefs(Bool pVerbose) 2899 2748 { 2900 2749 // From build.exe location … … 2906 2755 } 2907 2756 2908 void ProcessOneMacroDef( bool pVerbose, char[] pPath)2757 void ProcessOneMacroDef(Bool pVerbose, char[] pPath) 2909 2758 { 2910 2759 char[] lMacroDefFileName; … … 2936 2785 2937 2786 2938 if ( pVerbose&& util.fileex.FileExists(lMacroDefFileName) )2787 if ((pVerbose == True) && util.fileex.FileExists(lMacroDefFileName) ) 2939 2788 writefln("Build Macro Definition file %s", lMacroDefFileName); 2940 2789 lMacroDefLines = util.fileex.GetTextLines(lMacroDefFileName, util.fileex.GetOpt.Always); … … 2957 2806 { 2958 2807 2959 if (lArg.begins("replace ") > 0)2808 if (lArg.begins("replace ") == True) 2960 2809 { 2961 2810 int lStartPos; … … 3034 2883 3035 2884 } 3036 else if (lArg.begins("delim ") > 0)2885 else if (lArg.begins("delim ") == True ) 3037 2886 { 3038 2887 … … 3072 2921 break; 3073 2922 default: 3074 if (pVerbose )2923 if (pVerbose == True) 3075 2924 writefln("Bad Macro 'delim' option '%s'", 3076 2925 lOption); … … 3081 2930 } 3082 2931 } 3083 else if (vVerbose )2932 else if (vVerbose == True) 3084 2933 { 3085 2934 writefln("Bad configuration command '%s'", lArg); … … 3089 2938 } 3090 2939 3091 void ProcessBuildConfig(char[] pArg, bool pVerbose)2940 void ProcessBuildConfig(char[] pArg, Bool pVerbose) 3092 2941 { 3093 2942 // From build.exe location … … 3097 2946 ProcessOneBuildConfig(pArg, pVerbose, vCompilerPath); 3098 2947 3099 } 3100 3101 void ProcessOneBuildConfig(char[] pArg, bool pVerbose, char[] pPath) 2948 // From current location 2949 ProcessOneBuildConfig(pArg, pVerbose, util.pathex.GetInitCurDir() ); 2950 2951 } 2952 2953 void ProcessOneBuildConfig(char[] pArg, Bool pVerbose, char[] pPath) 3102 2954 { 3103 2955 char[] lConfigFileName; … … 3114 2966 lConfigFileName ~= "build.cfg"; 3115 2967 3116 if ( pVerbose&& util.fileex.FileExists(lConfigFileName))2968 if ((pVerbose == True) && util.fileex.FileExists(lConfigFileName)) 3117 2969 writefln("Build Configuration file %s [%s]", lConfigFileName, pArg); 3118 2970 … … 3154 3006 break; // Don't process any more lines. 3155 3007 3156 if (pVerbose )3008 if (pVerbose == True) 3157 3009 writefln("Build Configuration file arg: %s", lArg); 3158 3010 … … 3163 3015 } 3164 3016 3165 if (lArg.begins("CMDLINE=") > 0)3017 if (lArg.begins("CMDLINE=") == True) 3166 3018 { 3167 3019 int lStartPos; … … 3196 3048 3197 3049 } 3198 else if (lArg.begins("LIBCMD=") > 0)3050 else if (lArg.begins("LIBCMD=") == True) 3199 3051 { 3200 3052 int lPos; … … 3208 3060 3209 3061 vLibrarian = std.path.getBaseName(lArg[7..$]); 3210 if(vVerbose ) {3062 if(vVerbose == True) { 3211 3063 writefln(" librarian path %s",vLibrarianPath); 3212 3064 writefln(" librarian is %s",vLibrarian); 3213 3065 } 3214 3066 } 3215 else if (vVerbose) 3067 else if (lArg.begins("LINKSWITCH=") == True) 3068 { 3069 vLinkerDefSwitches = lArg[11..$].dup; 3070 } 3071 else if (vVerbose == True) 3216 3072 { 3217 3073 writefln("Bad configuration command '%s'", lArg); … … 3221 3077 } 3222 3078 } 3223 3224 /* ============= The User Manual ======================================3225 __ /topic Introduction3226 __ /info3227 __ This is a utility to build an application using the D programming language.3228 __ It does this by examining the source file supplied on the command line3229 __ to work out its dependant files, and then determines which need to be3230 __ compiled and which need to be linked to create the executable.3231 __3232 __ Alternatively, it can be used to create a Library file rather than an3233 __ executable.3234 __3235 __ The aim of the utility is to help remove the need for /i make files3236 __ or similar devices.3237 3238 __ /topic Pragma3239 __ /info3240 __ The /b build utility supports the use of various pragma statements.3241 __ A pragma is a special statement embedded in the source code that3242 __ provides information to tools reading the source code.3243 __3244 __ They take the forms ...3245 __ /code3246 __ /b"pragma(" ~<name~> /b");"3247 __ /b"pragma(" ~<name~> /b"," ~<option~> [ /b","~<option~>] /b");"3248 __ /endcode3249 __3250 __ If the D compiler doesn't recognise the pragma, it will fail. So to3251 __ 'hide' them from the compiler, you need to wrap them in a /b version3252 __ block. All the pragmas used by this utility need to be enclosed in3253 __ a /i build version.3254 __3255 __ Example:3256 __ /code3257 __ version(build) { pragma(nolink); }3258 __ /endcode3259 3260 __ /topic Pragma3261 __ /pragma link3262 __ /desc This nominates one or more libraries that are required to be linked in.3263 __ If your applications needs code from a library to be linked in, rather than3264 __ supplying source code, you can tell /i build which libraries are needed.3265 __ This can happen when using a library provided by a third-party.3266 __3267 __ Example 1:3268 __ /code3269 __ /// This app needs the MyGUI.lib library to be used.3270 __ version(build) { pragma(link, MyGUI); }3271 __ /endcode3272 __3273 __ Example 2:3274 __ /code3275 __ /// This app needs the a DB library and TCP library to be used.3276 __ version(build) { pragma(link, EuDB, TCP4Win); }3277 __ /endcode3278 3279 __ /topic Pragma3280 __ /pragma nolink3281 __ /desc This identifies that the current module is not to be be linked in.3282 __ Normally, each object file created by the compiler is linked in, but3283 __ if the supplied source file is just a stub for code which is externally3284 __ defined in a library, then you do not need the 'stub' object file.3285 __3286 __ Example:3287 __ /code3288 __ version(build) { pragma(nolink); }3289 __ /endcode3290 3291 __ /topic Pragma3292 __ /pragma include3293 __ /desc This identifies a required file which is not otherwise imported.3294 __ In some applications, especially ones converted over from C, it is3295 __ possible that the file on the /i Build command line does not directly3296 __ or indirectly import a required file. In those situations, you can3297 __ use this pragma to tell build to include it in the compilation checking3298 __ process.3299 __3300 __ Example:3301 __ /code3302 __ // Tell 'build' that prime.d must be included (it contains the main function.)3303 __ version(build) { pragma(include, "prime"); }3304 __ /endcode3305 3306 __ /topic Pragma3307 __ /pragma target3308 __ /desc This identifies the basename of the target file.3309 __ By default, the target name is based on the first file on the command line.3310 __ But if you include this pragma, the name identified in the pragma becomes3311 __ the default name. In either case, the -T switch overrides the default name.3312 __3313 __ If two or more /i target pragmas are found, the first one is the one3314 __ that is used and the others are ignored (though mentioned if in3315 __ verbose mode).3316 __ Example:3317 __ /code3318 __ //// Tell 'build' to create WhizzBang.exe3319 __ version(build) { pragma(target, "WhizzBang"); }3320 __ /endcode3321 3322 __ /topic Pragma3323 __ /pragma build3324 __ /desc This identifies a file that needs an external program to build it.3325 __ Some applications need to link in object files created by C source, or3326 __ by a /i resource compiler, or whatever. This pragma identifies a file3327 __ that needs to be linked in, but cannot be created by the D compiler. The3328 __ format is /n3329 __ /code3330 __ pragma(build, "FILENAME" [, "OPTIONS"] ...);3331 __ /endcode3332 __ where /i FILENAME is either the file to link in, or the file to use when3333 __ creating the file to link in. For example, if you had a Windows resource file3334 __ that needed to be compiled, you could code the pragma as either ...3335 __3336 __ /code3337 __ //// Compile the images into a resource obj and add images.res to linker.3338 __ pragma(build, "images.rc");3339 __ /endcode3340 __ or /n3341 __ /code3342 __ //// Compile the images into a resource obj and add images.res to linker.3343 __ pragma(build, "images.res");3344 __ /endcode3345 __3346 __ The first example specifies the source file to be passed to the resource3347 __ compiler and the second example specifies the output of the resource compiler.3348 __ In either case, this utility uses the rules in a /"Rule Definition File" to3349 __ decide what to do.3350 __3351 __ The utility searches for the /i"FILENAME" in the currently defined 'import'3352 __ paths.3353 __3354 __ The /i OPTIONS can be included if you need to pass any special values3355 __ to the external tool. There can be any number of these, but each one must3356 __ take the form ~<KEYWORD>=~<VALUE>. For example /n3357 __ /code3358 __ pragma(build, "dbapi.c", "COPT=-wc -x", "HDR=abc.hp");3359 __ /endcode3360 __ The OPTIONS values are used as replacement text for token in the3361 __ Rule Definition File's 'tool' specification. In the example above,3362 __ the tokens {COPT} and {HDR}, if found in the 'tool' line, would be3363 __ replaced with /i"-wc -x" and /i"abc.hp" respectively.3364 __3365 __ The output file to the external tool is checked to see if it is still3366 __ up to date.3367 __3368 __ The output file from the external tool is added to the linkage set.3369 __3370 __ All such external programs are run before the D compiler is invoked.3371 __3372 __ Example:3373 __ /code3374 __ //// Tell 'build' that it needs to call an external program3375 __ //// to build an up-to-date version of 'images.rc'3376 __ version(build) { pragma(build, "images.rc"); }3377 __ /endcode3378 3379 __ /topic Rule Definition File3380 __ /info3381 __ Defines the rules used to build non-D source files.3382 __ This is not as advanced as the typical /b makefile abilities and is3383 __ only useful for simple situations. Specifically, it only caters for3384 __ applications that take a single input file to create the required3385 __ output file.3386 __3387 __ The default Rule Definition File is called "default.rdf". It is found by3388 __ first looking in the directory where the utility is installed, and if3389 __ it is not found there, the directories in the PATH environment symbol3390 __ are scanned.3391 __3392 __ The default RDF can be overridden by the -RDF command line switch.3393 __3394 __ Each rule is defined in a set of four mandatory lines ... /n3395 __ /li rule=~<name>3396 __ /li source=~<extention>3397 __ /li target=~<extention>3398 __ /li tool=~<command pattern>3399 __3400 __ Any other line in the file, not starting with one of the above keywords3401 __ is simply ignored (treated as comments).3402 __3403 __ The /i"tool" line can contain special tokens. These are keywords enclosed3404 __ in braces. At compile time, the tokens are replaced by replacement text3405 __ taken from the pragma(build) statement. There are two predefined tokens3406 __ that can be used. /b"{@IN}" is replaced by the name of the input file,3407 __ and /b"{@OUT}" is replaced by the name of the output file.3408 __3409 __ /code3410 __ ----- Windows Resource Compiler -----3411 __ This uses ` pragma(/b'build', ~<sourcefile>.rc); `3412 __ -------------------------------------3413 __ rule=Resources3414 __ source=rc3415 __ target=res3416 __ tool=rc //r {@IN} //fo {@OUT}3417 __3418 __ -------------------------------------3419 __ DMD C linkage3420 __ This uses ` pragma(build, ~<sourcefile>.c, "COPT=~<options>", "HDR=~<whatever>"); `3421 __ -------------------------------------3422 __ rule=DMD C/C++3423 __ source=c3424 __ target=obj3425 __ tool=dmc -c {COPT} {@IN} -o{@OUT} {HDR}3426 __3427 __ /endcode3428 3429 __ /topic Pragma3430 __ /pragma export_version3431 __ /desc This allows you to set a global version identifier.3432 __ DMD allows you to set a version identifier in your code, but the scope3433 __ of that is only for the module it is set in. This pragma gives you the3434 __ ability to declare a version identifier which is applied to all modules3435 __ being compiled, and not just the 'current' module.3436 __3437 __ Example:3438 __ /code3439 __ version(build) pragma(export_version, Unix);3440 __ version(build) pragma(export_version, Limited);3441 __ /endcode3442 __ These lines will cause the compiler to have these version identifiers3443 __ added to the command line switches, thus making them effectively global.3444 __3445 __ You can list more than one identifier on the pragma statement ...3446 __ /code3447 __ version(build) pragma(export_version, Unix, Limited);3448 __ /endcode3449 3450 __ /topic Pragma3451 __ /pragma build_def3452 __ /desc This supplies an option to be placed in an OptLink definition file.3453 __ You can have /i build create a customised OptLink definition file3454 __ by coding as many /i build_def pragmas as required. However, /i build will3455 __ only allow the first of each type of Definition File command to be used. THis3456 __ means that if you code ... /n3457 __ /code3458 __ pragma (build_def, "EXETYPE DOS");3459 __ pragma (build_def, "EXETYPE NT");3460 __ /endcode3461 __ Then the EXETYPE DOS will be used and the 'NT' line ignored. You can use3462 __ explicit build_def pragmas to override the default ones generated by3463 __ /i build for Windows programs or DLL libraries.3464 __3465 __ The syntax for these pragma is /n3466 __ /code3467 __ pragma(build_def, ~<QUOTED_STRING~> );3468 __ /endcode3469 __3470 __ Example:3471 __ /code3472 __ version(build) {3473 __ pragma (build_def, "VERSION 1.1");3474 __ version(DOS) {3475 __ pragma (build_def, "EXETYPE DOS");3476 __ }3477 __ version(WIN) {3478 __ pragma (build_def, "EXETYPE NT");3479 __ pragma (build_def, "SUBSYSTEM WINDOWS,4.0");3480 __ }3481 __ }3482 __ /endcode3483 __3484 __ You can supply /b any text string and it is used verbatim. There is no3485 __ restrictions on what you can include in the pragma.3486 3487 __ /topic Auto Build Number3488 __ /info3489 __ Automatically Incremented Build Numbering for Modules3490 __ You can optionally specify that the /i build utility automatically3491 __ increments a build number for any module. You do this by supplying3492 __ a single line in your source code in the form ... /n3493 __ /code3494 __ private import /b"~<modulename~>"_bn;3495 __ /endcode3496 __ Typically this line is placed immediately after the source file's3497 __ /b module statement, but that is not strictly necessary.3498 __3499 __ By having this line in your code, /i build then uses a file with the3500 __ suffix "_bn.d" to maintain3501 __ the current build number for the ~<modulename~>. Note that /i build3502 __ will create this file if it doesn't exist. Also note that3503 __ /i build will update this file whenever the module file has been3504 __ updated or its object file needs to be rebuilt, so you really3505 __ shouldn't modify it manually. Any manual changes will be deleted3506 __ by /i build. /n3507 __3508 __ Example: /n3509 __ If your module is called "parser.d" you would have the lines ...3510 __ /code3511 __ module parser;3512 __ private import parser_bn;3513 __ /endcode3514 __3515 __ You can access the build number from within the module thus ... /n3516 __3517 __ /code3518 __ writefln("Build number is %d", auto_build_number);3519 __ /endcode3520 __ You can access the build numbers of other modules in you application3521 __ by importing the appropriate file and prefixing the references with3522 __ the module names. /n3523 __ Example:3524 __ /code3525 __ module parser; /// This module's name.3526 __ private import parser_bn; /// This module's B/N3527 __ private import tokenizer_bn; /// Another module's B/N3528 __ . . .3529 __ writefln("Builds...");3530 __ writefln(" Parser %d", parser_bn.auto_build_number);3531 __ writefln(" Tokens %d", tokenizer_bn.auto_build_number);3532 __ /endcode3533 __3534 __ The "_bn.d" file created by /i build for this module would look like ... /n3535 __ /code3536 __ module parser_bn;3537 __ /// This file is automatically maintained by the BUILD utility,3538 __ /// Please refrain from manually editing it.3539 __ long auto_build_number = 77;3540 __ /endcode3541 __ Of course the number /i 77 is just an example. This number would actually3542 __ start at 1 and increment whenever /i build needed to create a new object3543 __ file for the module.3544 3545 __ /topic Command Line3546 __ /info3547 __ The /i build utility supplies the source file and optional switches via the command line.3548 __ The typical format of the /i build utility's command line is ... /n3549 __ /code3550 __ /b build ~<sourcefile~> [ ~<switches~> ] [ ~<otherfiles~> ]3551 __ /endcode3552 __ You can however specify the files and switches in any order you like.3553 __3554 __ Normally you would only supply a single file name to /i build, that being3555 __ the source file of the top-level file in the application. Typically3556 __ the one that has the 'main()' or 'WinMain()' function, though this is3557 __ not strictly necessary.3558 __3559 __ If you run the utility without any files and without any switches, it3560 __ display a /i help screen with some details about the switches. That looks3561 __ like this ...3562 __ /code3563 __ Path and Version : C:\Program Files\build.exe v3.6(339)3564 __ Usage: build sourcefile [options objectfiles libraries]3565 __ /b sourcefile D source file3566 __ /b"-v" Verbose (passed through to D)3567 __ /b"-V" Verbose (NOT passed through)3568 __ /b"-names" Displays the names of the files used to build the target.3569 __ /b"-DCPATH~<path~> ~<path~>" is where the compiler has been installed.3570 __ Only needed if the compiler is not in the system's3571 __ PATH list. Used if you are testing an alternate3572 __ version of the compiler.3573 __ /b"-CFPATH~<path~> ~<path~>" is where the D config file has been installed.3574 __ /b"-full" Causes all source files, except ignored modules,3575 __ to be compiled.3576 __ /b"-link" Forces the linker to be called instead of the librarian.3577 __ (Only needed if the source files do not contain3578 __ main/WinMain)3579 __ /b"-nolink" Ensures that the linker is not called.3580 __ (Only needed if main/WinMain is found in the source3581 __ files and you do NOT want an executable created.)3582 __ /b"-lib" Forces the object files to be placed in a library.3583 __ (Only needed if main/WinMain is found in the source3584 __ files AND you want it in a library instead of3585 __ an executable.)3586 __ /b"-nolib" Ensures that the object files are not used to form3587 __ a library.3588 __ (Only needed if main/WinMain is not found in the source3589 __ files and you do NOT want a library.3590 __ /b"-obj" This is the same as having both -nolink and -nolib3591 __ switches on the command line. It is just a shorthand.3592 __ /b"-allobj" Ensures that all object files are added to a3593 __ library.3594 __ (Normally only those in the same directory are added.)3595 __ /b"-cleanup" Ensures that all object files created during the run3596 __ are removed at the end of the run, plus other work files.3597 __ /b"-clean" Same as -cleanup3598 __ /b"-test" Does everything as normal except it displays the commands3599 __ instead of running them. Also, the auto-build-numbers are3600 __ not incremented.3601 __ /b"-RDF~<path~>" Overrides the default Rule Definition File3602 __ /b"-gui[:x.y]" Forces a GUI application to be created. The optional3603 __ :x.y can be used to build an application for a3604 __ specific version of Windows. eg. -gui:4.03605 __ (Only needed if WinMain is not found in the source files3606 __ or if you wish to override the default Windows version)3607 __ /b"-dll" Forces a DLL library to be created.3608 __ (Only needed if DllMain is not found in the source files.3609 __ /b"-LIBOPT~<opt~>" Allows you to pass ~<opt~> to the librarian3610 __ /b"-LIBPATH=~<pathlist~>" Used to add a semi-colon delimited list3611 __ of search paths for library files.3612 __ /b"-X~<module~>" Packages and Modules to ignore (eg. -Xmylib)3613 __ /b"-M~<module~>" Packages and Modules to notice (eg. -Mphobos)3614 __ /b"-T~<targetname~>" The name of the target file to create. Normally3615 __ the target name istaken from the first or only name3616 __ of the command line.3617 __ /b"-R~<y|n~>" Indicates whether to use a response file or command line3618 __ arguments with the compiler tools.3619 __ /b"-Ry" will cause a response to be used.3620 __ /b"-Rn" will cause command line arguments to be used.3621 __ /b"-R" will reverse the current usage.3622 __ Note that the default for Windows DigitalMars is to use a response file3623 __ but for all other environments it is to use command line arguments.3624 __ /b"-info" Displays the version and path of the Build application3625 __ /b"-help" Displays the full 'usage' help text.3626 __ /b"-h" Same as /-help, displays the full 'usage' help text.3627 __ /b"-? " Same as /-help, displays the full 'usage' help text.3628 __ /b"-silent" Avoids unnecessary messages being displayed.3629 __ /b"-noautoimport" Turns off the automatic addition of source paths3630 __ to the list of Import Roots.3631 __ /b"-run~<param~>" If the link is successful, this will cause the3632 __ executable just created to run. You can give it3633 __ run time parameters. Anything after the '-run' will3634 __ placed in the program's command line. You will need3635 __ to quote any embedded spaces.3636 __ /b"-od~<path~>" Nominate the directory where temporary (work) files3637 __ are to be created. By default they are created in3638 __ the same directory as the target file.3639 __ /b"-nodef" Prevents a Module Definition File being automatically created.3640 __ This will override any pragma(/build_def) statements in the3641 __ source code.3642 __ /b"[...]" All other options, objectfiles and libraries are3643 __ passed to the compiler3644 __ /endcode3645 __3646 __ See also /"Response File"3647 3648 __ /topic Switches3649 __ /info3650 __ /i Build supports a number of command line switches to control its default assumptions.3651 3652 3653 __ /topic switches3654 __ /switch -nodef3655 __ /desc Prevent a Module Definition File being created.3656 __ Normally, the utility will automatically create a Module Definition File3657 __ for the linker. This will typically contain the EXETYPE command and any other3658 __ commands as specified in any pragma(/build_def) statements found in the source files.3659 __ If you specify this switch, you will have to provide your own Module Definition3660 __ File or its equivalent on the command line.3661 3662 __ /topic switches3663 __ /switch -v3664 __ /desc Set /i verbose mode on for both /i build and for the compiler3665 3666 __ /topic switches3667 __ /switch -V3668 __ /desc Set /i verbose mode on for just /i build and not for the compiler3669 3670 __ /topic switches3671 __ /switch -names3672 __ /desc Displays the names of the files used in building the target.3673 3674 __ /topic switches3675 __ /switch -DCPATH3676 __ /desc Identifies where the compiler has been installed.3677 __ Normally, /i build scans the PATH environment symbol to find where the3678 __ D compiler is located. However, if you need to use the compiler from3679 __ a different location, you would use this switch to tell /i build where3680 __ it is.3681 __3682 __ /b"Note:" If you use this switch, and the current CFPATH value is3683 __ identical to the current DCPATH value, then this switch will change3684 __ both to the new value. The assumption is that the configuration3685 __ file is in the same directory as the compiler. If this is not the case,3686 __ you will also need to use the /-CFPATH switch.3687 __3688 __ Example:3689 __ /code3690 __ -DCPATHc:\old\dmd\bin3691 __ /endcode3692 3693 __ /topic switches3694 __ /switch -CFPATH3695 __ /desc Identifies where the D config file has been installed.3696 __ Normally, /i build looks in the same place that the compiler is3697 __ installed in, but if you need to use a different configuration3698 __ path from that, you would use this switch to tell /i build where3699 __ it is.3700 __3701 __ Example:3702 __ /code3703 __ -CFPATHc:\myproject\configs3704 __ /endcode3705 3706 __ /topic switches3707 __ /switch -full3708 __ /desc Causes all source files, except ignored modules, to be compiled.3709 __ Normally, /i build only compiles a source file if it's object file3710 __ is out of date or missing. This switch forces all source files to be3711 __ recompiled, even if not strictly required.3712 __3713 __ /b "Note:" Modules in the /i ignore list are still ignored though.3714 3715 __ /topic switches3716 __ /switch -link3717 __ /desc Forces the linker to be called instead of the librarian.3718 __ Normally, if /i build does not find a main() or WinMain() function3719 __ in the source files, it creates a library to contain the object3720 __ files. But when this switch is used, /i build will attempt to3721 __ create an application by calling the linker rather than the librarian.3722 __3723 __ You would typically use this if the main() function was being supplied3724 __ from an existing library file rather than one you your source files.3725 3726 __ /topic switches3727 __ /switch -run3728 __ /desc Runs a program after successful linking.3729 __ If the link is successful, this will cause the3730 __ executable just created to run. You can give it3731 __ run time parameters. Anything after the '-run' will3732 __ placed in the program's command line. You will need3733 __ to quote any embedded spaces.3734 __3735 __Example:3736 __/code3737 __ -run"abc.de second"3738 __/endcode3739 3740 __ /topic switches3741 __ /switch -od3742 __ /desc Nominates the temporary file directory.3743 __ By default, the utility creates any work files in the same directory3744 __ as the target file. You can use this switch to nominate an alternative3745 __ location for these files. The directory is created if it doesn't exist.3746 __3747 __ For the DigitalMars compiler, this also specifies the top-level3748 __ location where object files are created. By default, object files3749 __ are created in the same directory as the corresponding source file.3750 __3751 __ Example:3752 __ /code3753 __ -odC:\temp\workarea3754 __ /endcode3755 3756 __ /topic switches3757 __ /switch -nolink3758 __ /desc Ensures that the linker is not called.3759 __ Normally, if /i build finds a main() or WinMain() function, it3760 __ tries to create an application by calling the linker. If you use3761 __ this switch however, the linker will not be called.3762 __3763 __ You would typically do this if you wanted to create a library that3764 __ stores your 'main' function in it, in which case you'd also use the /-lib3765 __ switch. But you could just create a set of object files without linking3766 __ them with this switch.3767 3768 __ /topic switches3769 __ /switch -lib3770 __ /desc Forces the object files to be placed in a library.3771 __ Normally, if /i build finds a main() or WinMain() function, it3772 __ tries to create an application by calling the linker. But if you3773 __ use this switch, the librarian is called instead of the linker.3774 __3775 __ You would typically do this if you wanted to create a library that3776 __ stores your 'main' function in it, in which case you'd also use the /-nolink3777 __ switch.3778 3779 __ /topic switches3780 __ /switch -obj3781 __ /desc Shorthand for using both /"-nolink" and /"-nolib" switches.3782 __ This is literally the same has if you had placed both -nolink and3783 __ -nolib on the command line. As this is a common way to just compile3784 __ modules to get the object files for them, without doing anything else,3785 __ a neat shorthand is available.3786 3787 __ /topic switches3788 __ /switch -nolib3789 __ /desc Ensures that the object files are not used to form a library.3790 __ Normally, if /i build does not find a main() or WinMain() function,3791 __ it calls the librarian to create a library for all your object files.3792 __ But if you use this switch, the librarian is not called.3793 __3794 __ Typically, you would do this if you just wanted to create one or more3795 __ object files and do nothing else.3796 3797 __ /topic switches3798 __ /switch -allobj3799 __ /desc Ensures that all object files are added to a library.3800 __ Normally, /i build will only create a library using the object files3801 __ that are in the same directory as the new library. You would use3802 __ this switch if you wanted all object files created by this build3803 __ session to be included in the library.3804 3805 __ /topic switches3806 __ /switch -cleanup3807 __ /desc Ensures that all working files created during the run are removed.3808 __ Normally, /i build does not delete any object files or working files3809 __ when it finishes a session. You can use this switch to have /i build3810 __ clean up after itself. This will remove all object files created3811 __ in this run, plus any .rsp, .lsp, .bak, .map, .lst, .def files.3812 __3813 __ /b Note: This can also be supplied as /b"-clean" as an alias.3814 3815 __ /topic switches3816 __ /switch -LIBOPT3817 __ /desc Allows commandline options to be passed to the librarian.3818 __ Example:3819 __ /code3820 __ (Set the page size to 32Kb)3821 __ -LIBOPT-p323822 __3823 __ (Embedded spaces enclosed in quotes.)3824 __ "-LIBOPT -l -i"3825 __ /endcode3826 3827 __ /topic switches3828 __ /switch -LIBPATH3829 __ /desc Used to add a list of search paths for library files.3830 __This might be used when you don't want to permanently update the3831 __ standard search paths.3832 __ Example:3833 __ /code3834 __ -LIBPATH=c:\mylibs;d:\3rdparty;c:\lib\debuglibs3835 __ /endcode3836 3837 __ /topic switches3838 __ /switch -R3839 __ /desc Determines if the compiler tools use a response file or not.3840 __ For /i DigitalMars tools in the Windows environment, a response file is3841 __ the default, but for /i other tools and other operating systems the3842 __ default is to use command line arguments.3843 __3844 __ The switch has three formats: /n3845 __ -Ry to use a response file /n3846 __ -Rn to use command line arguments /n3847 __ -R to reverse the current setting.3848 __3849 __ The use of a response file is only really needed when the command line3850 __ arguments are going to be more than the operating system can handle3851 __ on a single command line. However, it is always a safe option, so if3852 __ in doubt you may as well use it.3853 __3854 __ A response file contains all the arguments that would have gone on the3855 __ command line. They are arranged as one argument per line.3856 __3857 __ Not all tools respect the response file idea however the Windows based3858 __ DigitalMars tools do understand it.3859 __3860 __ Without a response file the compiler might be invoked thus:3861 __ /code3862 __ dmd -op -release appmain.d somemod.obj -IC:\DLibs3863 __ /endcode3864 __ But with a response file, these arguments are first written out to3865 __ a text file (the response file) and the compiler is invoked :3866 __ /code3867 __ dmd @appmain.rsp3868 __ /endcode3869 __ The /i "appmain.rsp" would contain the lines :3870 __ /code3871 __ -op3872 __ -release3873 __ appmain.d3874 __ somemod.obj3875 __ -IC:\DLibs3876 __ /endcode3877 3878 __ /topic switches3879 __ /switch -test3880 __ /desc Does a test run only. No compiling, linking or library work is done.3881 __ This will display the command lines instead of running them. It can be used3882 __ to see what would happen without actually building anything.3883 3884 __ /topic switches3885 __ /switch -RDF3886 __ /desc Defines a file to override the default /"Rule Definition File"3887 __ The default file is called "default.rdf". If you need to provide3888 __ an alternate file, you can use this switch.3889 __3890 __ Example:3891 __ /code3892 __ -RDFmyrules.xyz3893 __ /endcode3894 3895 __ /topic switches3896 __ /switch -dll3897 __ /desc Forces a DLL library to be created.3898 __ /b"Note:" This only applies to Windows environment.3899 __3900 __ Normally, if /i build finds a DllMain() function it automatically3901 __ creates a DLL library. However, if you need to force a DLL3902 __ library, you would use this switch.3903 3904 __ /topic switches3905 __ /switch -gui3906 __ /desc Forces a GUI application to be created.3907 __ /b"Note:" This only applies to Windows environment.3908 __3909 __ Normally, if /i build finds a WinMain() function it automatically3910 __ creates a GUI application. However, if you need to force a GUI3911 __ application, you would use this switch.3912 __3913 __ This switch can also be used to specify which version of Windows to3914 __ build the application for. To do this, it takes the format of3915 __ -gui:X.Y where /i"X.Y" is the Windows version number. Use 4.03916 __ for Windows NT, 2000, and ME, and 5.0 for Windows XP.3917 __3918 __ By default, /i build uses the version of Windows it is running under.3919 3920 __ /topic switches3921 __ /switch -info3922 __ /desc Displays the version and path of the /i build application3923 3924 __ /topic switches3925 __ /switch -help3926 __ /desc Displays the full text of the Usage information.3927 __ This has the aliases of "-h" and "-?"3928 3929 __ /topic switches3930 __ /switch -silent3931 __ /desc Prevents unnecessary messages being displayed.3932 __ Some messages are just informational and under some circumstances they3933 __ can interfer with reading the output.3934 3935 __ /topic switches3936 __ /switch -noautoimport3937 __ /desc Prevents source file paths from being added to the list of Import Roots3938 __ By default, for each source file that imports a module, it's path is added3939 __ to the list of paths that will be searched for module source files. If you3940 __ do not wish that behaviour, you will need to use this switch. In that case,3941 __ the compiler will only search the paths specified in the compiler's3942 __ configuration file, the current directory, and any explicitly added paths3943 __ on the command line.3944 __3945 __ Example:3946 __ /code3947 __ build myApp -noautoimport3948 __ /endcode3949 3950 __ /topic switches3951 __ /switch -X3952 __ /desc Identifies a module or package to ignore3953 __ Normally, /i build assumes that all imported modules are available3954 __ to be recompiled if required. You would use this switch if you explictly3955 __ did not want /i build to recompile a module.3956 __3957 __ /b"Note:" The /i Phobos package of modules is automatically ignored. This3958 __ means that /i build does not try to recompile phobos.3959 __3960 __ Example - ignore the 'parser' module (or package)3961 __ /code3962 __ -Xparser3963 __ /endcode3964 3965 __ /topic switches3966 __ /switch -M3967 __ /desc Identifies a module or a package to notice (not ignore)3968 __ You would use this to name any module that is not part of the target's3969 __ dependancies, or is one of the /i ignored modules.3970 __3971 __ You can use this switch to recompile /i phobos.3972 __3973 __ Example (notice the Phobos package):3974 __ /code3975 __ -Mphobos3976 __ /endcode3977 3978 __ /topic switches3979 __ /switch -T3980 __ /desc Identifies the target name to build.3981 __ Normally, /i build derives the target name from the first file name3982 __ on the command line, or from the pragma(target) if present.3983 __ If however, you wish to override that, use this switch.3984 __3985 __ /b"Note:" This switch allows the use of a special token, /b"{Target}",3986 __ which is replaced by the default target name. You can use3987 __ to create a generic /"Response File" that can be used for building3988 __ any application.3989 __3990 __ Example3991 __ /code3992 __ -Ttestapp3993 __3994 __ -Ttest_(Target} # Generate a name based on the default name.3995 __ /endcode3996 3997 __ /topic Response File3998 __ /info3999 __ A response file is a file that contains command line values.4000 __4001 __ You can specify all or any command line values in a4002 __ response file. Each value appears in its own line in the4003 __ response file and you reference this file by prefixing4004 __ its name with an '@' symbol on the command line.4005 __4006 __ You may place comments in a response file. A comment starts4007 __ with a /b'#' character and extends to the end of the line.4008 __4009 __ Example:4010 __ /code4011 __ build @final4012 __ /endcode4013 __ where a file called 'final.brf' contains the command4014 __ line values, including other response file references.4015 __4016 __ Example: (contents of final.brf)4017 __ /code4018 __ # This creates a production (release) edition of the app.4019 __ -T{Target}_release # Set the name of the executable.4020 __ -release # Don't generate runtime checks.4021 __ -full # Force compilation of all files.4022 __ -cleanup # remove work files when completed4023 __ -inline # Allow inlining to occur4024 __ /endcode4025 __4026 __ The command line for your build could then look like ...4027 __ /code4028 __ build myapp @final4029 __ /endcode4030 __4031 __ If the response file reference is just a single '@' then4032 __ build looks for a file called 'build.brf'4033 __4034 __ You can any number of response file references on a command line. They4035 __ are processed in the order they appear.4036 4037 4038 __ /topic Configuration File4039 __ /info4040 __ The utility configuration file is used to specify your default options for the utility.4041 __4042 __ Each option is specified in a single text line, but you can have any4043 __ number of option lines in the configuration file.4044 __4045 __ The options take the form of4046 __ /code4047 __ ~<COMMAND~>=~<VALUE~>4048 __ /endcode4049 __4050 __ /b"Supported Commands" /n4051 __ The commands currently supported are ... /n4052 __ /b CMDLINE /n4053 __ You can specify all command line switch values with this configuration4054 __ option. You can also specify multiple switches on the same option line./n4055 __ /code4056 __ CMDLINE=-inline -w4057 __ /endcode4058 __4059 __ /b LIBCMD /n4060 __ This specifies the location and program name for the librarian application4061 __ you want to invoke when creating libraries. /n4062 __ /code4063 __ LIBCMD=D:\Applications\dm\bin\lib.exe4064 __ /endcode4065 __4066 __ /b"Environment Symbol Substitution" /n4067 __ Before each configuration file option line is processed, it is first checked4068 __ for any references to Environment symbols. Each reference is replaced by4069 __ the value of that symbol. References take the form /b"%~<SYMNAME~>%" /n4070 __ There are two special symbols: /b"@D" is replaced by the compiler's4071 __ path, and /b"@P" is replaced by the compiler's configuration file's path.4072 __4073 __Example: Assuming you had set BUILDOPTS=-w -g4074 __ /code4075 __ CMDLINE=%BUILDOPTS% # Allow switches to be passed via enviroment symbol.4076 __ /endcode4077 __ would mean that "-w -g" would be automatically placed on the utility's4078 __ commandline whenever you ran it.4079 __4080 __ /b"Groups" /n4081 __ It is possible to specify groups of configuration options that are only4082 __ applied if explictly nominated on the command line. A group starts with4083 __ a line in the format /b"[~<groupname~>]" where /i groupname can be any4084 __ text that doesn't include spaces. A group ends on the last line before the4085 __ next group in the file.4086 __4087 __ Example of a Group4088 __ /code4089 __ [dbg] # To produce a debug edition of an application.4090 __ CMDLINE=-unittest4091 __ CMDLINE=--release4092 __ CMDLINE=--inline4093 __ CMDLINE=-g4094 __ CMDLINE=-w4095 __ CMDLINE=-full4096 __ CMDLINE=-T{Target}_{Group}4097 __ /endcode4098 __4099 __ All the options lines before the first group are known as the default4100 __ options because these are always applied. To apply the options in a group4101 __ you need to specify which group(s) you want on the command line, or via4102 __ a /"response file". The group name is prepended with a plus sign on4103 __ the command line. To apply the 'debug' group in the above example, you4104 __ place on the command line /b"+dbg"4105 __4106 __ /b"Comments" /n4107 __ You may place comments in a configuration file. A comment starts4108 __ with a /b'#' character and extends to the end of the line.4109 __4110 __ Example:4111 __ /code4112 __ build myapp.d +final4113 __ /endcode4114 __ where if a group called '[final]' is contained in any configuration4115 __ file, the options in that group are used.4116 __4117 __ Example: (contents of [final])4118 __ /code4119 __ # This creates a production (release) edition of the app.4120 __ [final]4121 __ CMDLINE=-T{Target}_{Group} # Set the name of the executable.4122 __ CMDLINE=-release # Don't generate runtime checks.4123 __ CMDLINE=-full # Force compilation of all files.4124 __ CMDLINE=-cleanup # remove work files when completed4125 __ CMDLINE=-inline # Allow inlining to occur4126 __ CMDLINE=--debug* # Turn off any debug switches4127 __ CMDLINE=--unittest # Turn off any unittest switches4128 __ CMDLINE=--w # Turn off warnings4129 __ CMDLINE=--g # Turn off embedded debug symbolic info.4130 __ /endcode4131 __4132 __ You can any number of configuration file group references on a command line. They4133 __ are processed in the order they appear.4134 4135 __ /topic To Do4136 __ /info4137 __ Ideas that have yet to be implemented.4138 __ Note that some of these may never be implemented but they are still4139 __ listed here as a reminder.4140 __4141 __ /li Be able to update a library rather than just create libraries.4142 __ /li Support the concept of a 'Plugin' block of code. /n4143 __ /code4144 __ version (build) pragma(plugin, ~<tool>[,delim=xxx],[, ~<parms>] ) { [body] }4145 __ /endcode4146 __ This block would be replaced by the stdout data of calling 'tool ~<params>' and4147 __ sending it the content of ~<body> via stdin.4148 __ /li Support limited preprocessor capability. /n4149 __ Something like pragma(macro, ~<preprocessor commands>); and replacing4150 __ source text of the form @{tokenname}@ with the value of the token.4151 4152 __ /topic DLL Libraries4153 __ /info4154 __ How to create a DLL library using Build.4155 __ When Build finds a DllMain() function, or the -dll switch is used, it4156 __ creates a special type of Module Definition file, and sets the target to4157 __ to be a DLL file. The Module Definition file generated takes the form ...4158 __ /code4159 __ LIBRARY "~<targetname>.dll";4160 __ EXETYPE NT4161 __ SUBSYSTEM WINDOWS,~<version>4162 __ CODE PRELOAD DISCARDABLE SHARED EXECUTE4163 __ DATA PRELOAD SINGLE WRITE4164 __ /endcode4165 __4166 __ You can replace any of these by explicitly coding a pragma(/build_def)4167 __ with different options than these defaults shown here.4168 __4169 __ Also, if you have the program /b implib in your path, it will be run4170 __ after the DLL file is created, in order to also create a /b".lib"4171 __ library to interface with the DLL. Build currently supports both the4172 __ DigitalMars version and the Borland (Inprise) version of /b implib.4173 */trunk/Source/build.def
r38 r41 1 VERSION 2. 91 VERSION 2.10 2 2 EXETYPE DOS trunk/Source/build.ksp
r38 r41 1 -release 2 -inline 3 -op 4 -Iz:\d_proj\build\trunk\source\ 5 -Iz:\dlibs\ 6 -Iz:\dmd\src\phobos\ 7 -IZ:\D_Proj\build\trunk\Source\util\ 1 build.obj+build_bn.obj+source.obj+source_bn.obj+util\str.obj+util\str_bn.obj+util\linetoken.obj+util\linetoken_bn.obj+util\booltype.obj+util\fdt.obj+util\fdt_bn.obj+util\pathex.obj+util\pathex_bn.obj+util\fileex.obj+util\fileex_bn.obj+util\macro.obj 2 build.exe 3 build.map 4 8 5 build.def 9 -ofbuild.exe 10 util\linetoken.obj 11 build_bn.obj 12 util\pathex.obj 13 util\fileex.obj 14 util\str_bn.obj 15 util\macro.obj 16 source.obj 17 source_bn.obj 18 build.obj 19 util\fdt.obj 20 util\pathex_bn.obj 21 util\linetoken_bn.obj 22 util\str.obj 23 util\fdt_bn.obj 24 util\fileex_bn.obj 6 /noi/map trunk/Source/build.rsp
r38 r41 1 -release2 -inline3 1 -op 4 -Iz:\d_proj\build\trunk\source\ 5 -Iz:\dlibs\ 6 -Iz:\dmd\src\phobos\ 7 -IZ:\D_Proj\build\trunk\Source\util\ 8 build.def 9 util\linetoken.d 2 -Iy:\dmd\src\phobos\ 3 -IY:\D_Proj\build\trunk\Source\ 4 -IY:\D_Proj\build\trunk\Source\util\ 5 build.d 10 6 build_bn.d 11 util\pathex.d12 util\fileex.d13 util\str_bn.d14 util\macro.d15 7 source.d 16 8 source_bn.d 17 build.d 9 util\str.d 10 util\str_bn.d 11 util\linetoken.d 12 util\linetoken_bn.d 13 util\booltype.d 18 14 util\fdt.d 15 util\fdt_bn.d 16 util\pathex.d 19 17 util\pathex_bn.d 20 util\linetoken_bn.d 21 util\str.d 22 util\fdt_bn.d 18 util\fileex.d 23 19 util\fileex_bn.d 20 util\macro.d trunk/Source/build_bn.d
r38 r41 2 2 // This file is automatically maintained by the BUILD utility, 3 3 // Please refrain from manually editing it. 4 long auto_build_number = 1 197;4 long auto_build_number = 1557; trunk/Source/source.d
r38 r41 51 51 import util.fileex; 52 52 import util.macro; 53 import util.booltype; 53 54 54 55 import std.stdio; … … 96 97 void function(char[] pArg) AddCompilerArg; 97 98 char[][] function () GetImportRoots; 98 bool function() AutoImports;99 Bool function() AutoImports; 99 100 void function(char[] pPath) AddTarget; 100 101 void function(char[] pPath) AddLink; … … 102 103 void function(char[] pText, bool pReplace=false) AddBuildDef; 103 104 char[][] function( ) ModulesToIgnore; 104 char[] function(char[] pFile) GetFullPathname; 105 char[] function(char[] pFile, char[][] pScanList = null) GetFullPathname; 106 char[] function(char[] pFile, int pScanList) GetFullPathnameScan; 105 107 char[] function() GetObjWritePath; 106 108 Substitute[] function() GetMacros; 107 109 108 bool mVerboseMode = false;109 bool mMacroInput = false;110 Bool mVerboseMode; 111 Bool mMacroInput; 110 112 111 113 } … … 122 124 AttributeBlocks["public"] = true; 123 125 AttributeBlocks["export"] = true; 126 mVerboseMode = False; 127 mMacroInput = False; 124 128 debug(1) 125 129 { … … 130 134 public class Source { 131 135 private static Source[char[]] SourceIndex; 136 private static char[][] ScanOrder; 132 137 133 138 private { … … 180 185 181 186 // -------------------------------------------------------------------- 187 static void Finalize() 188 // -------------------------------------------------------------------- 189 { 190 for(int i = ScanOrder.length-1; i >= 0; i--) 191 { 192 Source x; 193 x = SourceIndex[ScanOrder[i]]; 194 delete x; 195 } 196 } 197 198 // -------------------------------------------------------------------- 182 199 this(char[] pFileName) 183 200 // -------------------------------------------------------------------- … … 187 204 mReferencedImports.length = 0; 188 205 mHasBeenSearched = false; 189 mNoLink = false;190 206 mIgnore = false; 191 207 mFileName = pFileName; 192 mModuleName = FileToModulename(pFileName); 193 lObjectName = addExt(pFileName,ObjExt); 194 mObjectName = GetFullPathname(lObjectName); 208 if (std.path.getExt(pFileName) != "ddoc") 209 { 210 mNoLink = false; 211 mModuleName = FileToModulename(pFileName); 212 lObjectName = addExt(pFileName,ObjExt); 213 mObjectName = GetFullPathname(lObjectName); 214 } 215 else 216 { 217 mNoLink = true; 218 mModuleName = ""; 219 lObjectName = ""; 220 mObjectName = ""; 221 } 195 222 196 223 version(DigitalMars) … … 201 228 prepend the specified object location path. 202 229 */ 203 if (GetObjWritePath().length != 0 )230 if (GetObjWritePath().length != 0 && mObjectName.length != 0) 204 231 { 205 232 if (mObjectName == lObjectName) … … 219 246 UpdateDependantTime(mObjectTime); 220 247 221 if(mVerboseMode ) {248 if(mVerboseMode == True) { 222 249 writefln("Time %s for %s",mFileTime.toString(),mFileName); 223 250 writefln("Time %s for %s",mObjectTime.toString(),mObjectName); … … 230 257 } 231 258 259 // -------------------------------------------------------------------- 260 ~this() 261 // -------------------------------------------------------------------- 262 { 263 // writefln("Finis: %s", mFileName); 264 } 265 266 267 // -------------------------------------------------------------------- 232 268 void search() { 269 // -------------------------------------------------------------------- 233 270 char[] [] lFiles; 234 271 FileDateTime lCurFileTime; … … 237 274 char[] lFileText; 238 275 239 if(mHasBeenSearched) { 276 if(mHasBeenSearched) 277 { 240 278 return; 241 279 } 242 else { 243 if(mVerboseMode) { 244 writefln("Scanning %s", util.pathex.AbbreviateFileName(mFileName)); 245 } 246 247 // Grab the original text. 248 lFileText = GetText(mFileName); 280 281 if(mVerboseMode == True) 282 { 283 writefln("Scanning %s", util.pathex.AbbreviateFileName(mFileName)); 284 } 285 ScanOrder.length = ScanOrder.length + 1; 286 ScanOrder[$-1] = mFileName; 287 288 // Grab the original text, which must exist. 289 lFileText = GetText(mFileName, GetOpt.Exists); 249 290 250 291 // Check if any macro processing is required. 251 if ( mMacroInput&& (std.path.getExt(mFileName) != "d"))292 if ((mMacroInput == True) && (std.path.getExt(mFileName) != "d")) 252 293 { 253 294 if (util.macro.RunMacro(lFileText, GetMacros())) … … 258 299 mHasBeenSearched = true; 259 300 mIgnore = true; 260 if(mVerboseMode ) {301 if(mVerboseMode == True) { 261 302 writefln("Macro output %s", lNewFile); 262 303 } … … 271 312 lCurFileTime = new FileDateTime(); 272 313 // Examine each extracted module file. 273 if ( (mReferencedImports.length > 0) && (AutoImports() == true))314 if ( (mReferencedImports.length > 0) && (AutoImports() == True)) 274 315 { 275 316 276 317 AddRoot( std.path.getDirName(util.pathex.CanonicalPath(mFileName, false)) ); 277 318 } 278 foreach(char[] lNextFile; mReferencedImports) { 319 foreach(char[] lNextFile; mReferencedImports) 320 { 279 321 if(lNextFile in SourceIndex) { 280 322 // Known file so just grab its mod time … … 348 390 349 391 if( lFindPos >= 0) { 350 if (mVerboseMode )392 if (mVerboseMode == True) 351 393 writefln("Ignoring %s (%s: %s)", lNextFile, lType, lNextModule); 352 394 … … 358 400 if (lCanUse){ 359 401 // Not known yet, so add it and grab its mod time 360 lNextFile = GetFullPathname (lNextFile);402 lNextFile = GetFullPathnameScan(lNextFile, ~0); 361 403 lCurFileTime = (new Source(lNextFile)).DependantsTime; 362 404 } … … 369 411 370 412 mHasBeenSearched = true; 371 }372 } 373 413 } 414 415 // -------------------------------------------------------------------- 374 416 void UpdateDependantTime(FileDateTime pDateTime) 417 // -------------------------------------------------------------------- 375 418 { 376 419 if (pDateTime > mDependantsTime) 377 420 { 378 if (mVerboseMode )421 if (mVerboseMode == True) 379 422 { 380 423 writefln("Updating %s dependants time from %s to %s", … … 397 440 static void WasMainDLL(bool pValue) { mainDLL = pValue; } 398 441 442 // -------------------------------------------------------------------- 399 443 bool IncrementBuildNumber() 444 // -------------------------------------------------------------------- 400 445 { 401 446 char[] lFileName; … … 535 580 536 581 lblNextToken: 537 while ((lPrevToken = lCurToken.dup, lCurToken = GetNextToken (pFileText, pPos)) !is null) {538 582 while ((lPrevToken = lCurToken.dup, lCurToken = GetNextToken (pFileText, pPos)) !is null) 583 { 539 584 switch(lCurToken) { 540 585 case kOpenBrace: … … 602 647 break; 603 648 649 case "Ddoc": 650 if (lPrevToken.length == 0) 651 { 652 // Only applies if 'Ddoc' is first token in file. 653 mNoLink = true; 654 break lblNextToken; 655 } 656 break; 657 604 658 case "pragma": 605 659 doPragma(pFileText, pPos); … … 906 960 { 907 961 mModuleName = lModName; 908 if (mVerboseMode )962 if (mVerboseMode == True) 909 963 { 910 964 writefln("Module name set to '%s'", mModuleName); … … 1049 1103 { 1050 1104 lCurrentToken = GetNextToken(pFileText,pPos); 1051 if ( (lCurrentToken == "\"") || (lCurrentToken == "`") ) { 1105 if ( (lCurrentToken == "\"") || (lCurrentToken == "`") ) 1106 { 1052 1107 lCurrentToken = GetStringLit(pFileText,pPos, lCurrentToken[0]); 1053 1108 } 1054 mReferencedImports ~= ModuleToFilename(lCurrentToken); 1109 else 1110 { 1111 char[] lLookAhead; 1112 lSavedPos = pPos; 1113 lLookAhead = GetNextToken(pFileText,pPos); 1114 while(lLookAhead != kCloseParen) 1115 { // Append everything until we find a closing paren. 1116 lCurrentToken ~= lLookAhead; 1117 lSavedPos = pPos; 1118 lLookAhead = GetNextToken(pFileText,pPos); 1119 } 1120 pPos = lSavedPos; 1121 } 1122 if (std.string.tolower(std.path.getExt(lCurrentToken)) == "ddoc") 1123 { 1124 mReferencedImports ~= lCurrentToken; 1125 } 1126 else 1127 { 1128 mReferencedImports ~= ModuleToFilename(lCurrentToken); 1129 } 1055 1130 } 1056 1131 … … 1260 1335 lFileName = util.str.ReplaceChar(pModuleName.dup, '.', std.path.sep[0]); 1261 1336 // Add the 'd' extention and append the full path 1262 lFileName = GetFullPathname ( addExt( lFileName, "d" ));1263 1264 if(mVerboseMode ) {1337 lFileName = GetFullPathnameScan( addExt( lFileName, "d" ), ~0 ); 1338 1339 if(mVerboseMode == True) { 1265 1340 writefln(" module->file %s => %s",pModuleName,lFileName); 1266 1341 } … … 1297 1372 lModuleName = util.str.ReplaceChar(lModuleName, std.path.sep[0], '.'); 1298 1373 1299 if(mVerboseMode ) {1374 if(mVerboseMode == True) { 1300 1375 writefln(" file->module %s => %s",pFileName,lModuleName); 1301 1376 } … … 1324 1399 foreach (char[] lLine; lFileLines) 1325 1400 { 1326 if ( util.str.IsLike(lLine, cast(dchar[])"*long auto_build_number = *;*") )1401 if ( util.str.IsLike(lLine, cast(dchar[])"*long auto_build_number = *;*") == True ) 1327 1402 { 1328 1403 for(int i = find(lLine,"=") + 2; i < lLine.length; i++) … … 1406 1481 version(D_InlineAsm) ActivateVersion("D_InlineAsm"); 1407 1482 1408 if (mVerboseMode )1483 if (mVerboseMode == True) 1409 1484 foreach(char[] k; vActiveVersions.keys){ 1410 1485 writefln("Active Version: '%s'", k); trunk/Source/source_bn.d
r38 r41 2 2 // This file is automatically maintained by the BUILD utility, 3 3 // Please refrain from manually editing it. 4 long auto_build_number = 1 049;4 long auto_build_number = 1409; trunk/Source/util/fdt_bn.d
r38 r41 2 2 // This file is automatically maintained by the BUILD utility, 3 3 // Please refrain from manually editing it. 4 long auto_build_number = 815;4 long auto_build_number = 1175; trunk/Source/util/fileex.d
r38 r41 45 45 import std.path; 46 46 import std.ctype; 47 48 debug(1) 49 { 50 import std.stdio; 51 } 52 53 47 import std.regexp; 48 49 import std.stdio; 50 51 char[][] vGrepOpts; 54 52 55 53 } … … 77 75 { 78 76 char[] lFileText; 79 80 77 if (std.file.exists( pFileName)) 81 78 { … … 97 94 char[][] lLines; 98 95 char[] lText; 99 100 96 lText = GetText(pFileName, pOpt); 101 lLines = std.string.splitlines( lText );97 lLines = util.str.splitlines( lText ); 102 98 return lLines; 103 99 } 100 void GetTextLines(char[] pFileName, out dchar[][] pResult, GetOpt pOpt = GetOpt.Always) 101 { 102 dchar[] lText; 103 104 lText = std.utf.toUTF32(GetText(pFileName, pOpt)); 105 pResult = util.str.splitlines( lText ); 106 } 107 108 void GetTextLines(char[] pFileName, out wchar[][] pResult, GetOpt pOpt = GetOpt.Always) 109 { 110 wchar[] lText; 111 112 lText = std.utf.toUTF16(GetText(pFileName, pOpt)); 113 pResult = util.str.splitlines( lText ); 114 } 115 116 void GetTextLines(char[] pFileName, out char[][] pResult, GetOpt pOpt = GetOpt.Always) 117 { 118 char[] lText; 119 120 lText = GetText(pFileName, pOpt); 121 pResult = util.str.splitlines( lText ); 122 } 123 104 124 105 125 enum CreateOpt … … 129 149 for(int i = lText.length-1; i >= 0; i--) 130 150 { 131 if ( find(std.path.linesep, lText[i]) == -1)151 if (std.string.find(std.path.linesep, lText[i]) == -1) 132 152 { 133 153 if (i != lText.length-1) … … 150 170 151 171 // Split into lines, disregarding line-end conventions. 152 lLines = std.string.splitlines(pLines);172 lLines = util.str.splitlines(pLines); 153 173 // Write out the text using the opsys' line-end convention. 154 174 CreateTextFile(pFileName, lLines, pOpt); 175 } 176 177 int grep(char[] pData, char[] pPattern) 178 { 179 return std.regexp.find(pData, pPattern, vGrepOpts[$-1]); 155 180 } 156 181 … … 163 188 auto char[] lBuffer; 164 189 int lPos; 190 int lStartPos; 165 191 ulong[] lResult; 166 167 // TODO //168 // Implement options. ---------------------------------- // 192 int function(char[] a, char[] b) lFind; 193 char[] lGrepOpt; 194 169 195 170 196 lCaseSensitive = true; 171 if (find(pOptions, 'i') != -1)172 lCaseSensitive = true;173 if (find(pOptions, 'I') != -1)174 lCaseSensitive = true;175 176 197 lRegExp = false; 177 if (find(pOptions, 'r') != -1) 178 lRegExp = true; 179 if (find(pOptions, 'R') != -1) 180 lRegExp = true; 181 198 lGrepOpt = "m"; 182 199 lWordOnly = false; 183 if (find(pOptions, 'w') != -1)184 lWordOnly = true;185 if (find(pOptions, 'W') != -1)186 lWordOnly = true;187 188 200 lCounting = true; 189 if (find(pOptions, 'a') != -1) 190 lCounting = false; 191 if (find(pOptions, 'A') != -1) 192 lCounting = false; 193 201 foreach (char c; pOptions) 202 { 203 switch (c) 204 { 205 case 'i', 'I': 206 lCaseSensitive = false; 207 break; 208 209 case 'r', 'R': 210 lRegExp = true; 211 break; 212 213 case 'w', 'W': 214 lWordOnly = true; 215 break; 216 217 case 'a', 'A': 218 lCounting = false; 219 break; 220 221 case 'd', 'D': 222 lCaseSensitive = true; 223 lRegExp = false; 224 lWordOnly = false; 225 lCounting = true; 226 break; 227 228 default: 229 // Ignore unrecognized options. 230 break; 231 } 232 } 233 234 if (lRegExp) 235 { 236 lFind = &grep; 237 if (lCaseSensitive) 238 lGrepOpt ~= 'i'; 239 240 vGrepOpts ~= lGrepOpt; 241 lWordOnly = false; 242 } 243 else 244 { 245 if (lCaseSensitive) 246 lFind = &std.string.find; 247 else 248 lFind = &std.string.ifind; 249 } 250 251 // Pull the entire text into RAM. 194 252 lBuffer = cast(char[])std.file.read(pFileName); 195 lResult.length = 0; 196 lPos = 0;197 198 while ( (lPos = find(lBuffer[lPos..$], pText)) != -1)199 {253 254 // Locate next instance and process it. 255 while ( lStartPos = lPos, (lPos = lFind(lBuffer[lStartPos..$], pText)) != -1) 256 { 257 lPos += lStartPos; 200 258 if (lWordOnly) 201 259 { 260 // A 'word' is an instance not surrounded by alphanumerics. 202 261 if (lPos > 0) 203 262 { 204 263 if (std.ctype.isalnum(lBuffer[lPos-1]) ) 205 264 { 265 // Instance preceeded by a alphanumic so I 266 // move one place to the right and try to find 267 // another instance. 206 268 lPos++; 207 269 continue; … … 212 274 if (std.ctype.isalnum(lBuffer[lPos + pText.length - 1]) ) 213 275 { 276 // Instance followed by a alphanumic so I 277 // move one place to the right and try to find 278 // another instance. 214 279 lPos++; 215 280 continue; … … 218 283 } 219 284 220 lResult.length = lResult.length + 1; 221 lResult[$-1] = lPos; 285 // Add this instance's position to the results list. 286 lResult ~= lPos; 287 288 // If I'm counting the number of hits, see if I've got the 289 // requested number yet. If so, stop searching. 222 290 if (lCounting) 223 291 { … … 227 295 } 228 296 297 // Skip over current instance. 229 298 lPos += pText.length; 299 300 // If there is not enough characters left, then stop searching. 230 301 if ((lBuffer.length - lPos) < pText.length) 231 302 break; 232 } 303 304 } 305 if (vGrepOpts.length > 0) 306 vGrepOpts.length = vGrepOpts.length - 1; 307 233 308 return lResult; 234 309 } trunk/Source/util/fileex_bn.d
r38 r41 2 2 // This file is automatically maintained by the BUILD utility, 3 3 // Please refrain from manually editing it. 4 long auto_build_number = 758;4 long auto_build_number = 1243; trunk/Source/util/linetoken_bn.d
r38 r41 2 2 // This file is automatically maintained by the BUILD utility, 3 3 // Please refrain from manually editing it. 4 long auto_build_number = 859;4 long auto_build_number = 1322; trunk/Source/util/pathex.d
r38 r41 46 46 import util.str; 47 47 import util.fileex; 48 import util.booltype; 48 49 49 50 import std.path; … … 81 82 lCurDir = getcwd(); 82 83 // Ensure that it ends in a path separator. 83 if ( lCurDir[$-std.path.sep.le
