Changeset 217
- Timestamp:
- 01/28/07 13:23:21 (2 years ago)
- Files:
-
- trunk/build_common.txt (modified) (1 diff)
- trunk/buildme.d (modified) (6 diffs)
- trunk/docs/build.html (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/build_common.txt
r211 r217 4 4 -v1 5 5 -w 6 -op 6 7 -Xphobos trunk/buildme.d
r202 r217 8 8 import std.file; 9 9 import std.path; 10 import std.string; 11 } 10 } 11 12 // compiler command 13 version(DigitalMars) 14 { 15 private static const char[] compilerCmd = "dmd "; 16 version(Windows) 17 { 18 version = WinExt; // standard windows file extensions & commands 19 } 20 else 21 { 22 version = NixExt; // unix file extensions & commands 23 } 24 } 25 else version(GNU) 26 { 27 private static const char[] compilerCmd = "gdmd "; 28 version = NixExt; 29 } 30 else 31 { 32 static assert(0, "Unsupported compiler"); 33 } 34 35 // file extensions, prefixes and commands 36 version(WinExt) 37 { 38 private static const char[] objExt = ".obj"; 39 private static const char[] libExt = ".lib"; 40 private static const char[] libCmd = "@lib -n "; 41 private static const char[] libCreateCmd = "@lib -c -n "; 42 private static const char[] libPre = ""; 43 private static const char[] delCmd = "@del "; 44 } 45 else 46 { 47 private static const char[] objExt = ".o"; 48 private static const char[] libExt = ".a"; 49 private static const char[] libCmd = "ar -q "; 50 private static const char[] libCreateCmd = "ar -cr "; 51 private static const char[] libPre = "lib"; 52 private static const char[] delCmd = "rm -f "; 53 } 54 12 55 13 56 // build configurations … … 18 61 } 19 62 20 // name of the build tool 21 private static const char[] buildName = "bud"; 22 23 // name of the text file found in each package directory 24 private static const char[] forBuild = "forbuild.txt"; 25 26 // possible build configuration file names 27 private static const char[][] configs = 28 [ 29 "build_debug.txt", 30 "build_release.txt" 31 ]; 32 33 // the actual build configuration file to use 34 private char[] configTxt; 35 36 // name of the text file containing swtiched common to all configurations 37 private static const char[] commonTxt = "build_common.txt"; 38 39 // buffer to store the contents of commonTxt and configTxt at startup 40 private static char[] brfBuf = ""; 41 42 // name of the temporary Build Response File generated by this script 43 private static const char[] tempBrf = "temp.brf"; 44 45 // build configuration. 63 // build configuration 46 64 private Mode mode = Mode.Release; 47 65 48 version(Windows) 49 { 50 // Windows delete command 51 private static const char[] delCmd = "@del "; 52 53 // Windows library extension 54 private static const char[] libExt = ".lib"; 55 } 56 else version(linux) 57 { 58 // Linux delete command 59 private static const char[] delCmd = "rm -f "; 60 61 // Linux library extension 62 private static const char[] libExt = ".a"; 63 } 64 else 65 { 66 static assert(0); 67 } 66 // compiler flags 67 private static const COMPILE_FLAGS_DEBUG = " -debug -g "; 68 private static const COMPILE_FLAGS_RELEASE = " -release -inline -O "; 69 private static const COMPILE_FLAGS_COMMON = " -c -op -v1 -w "; 70 71 // use bud? 72 private bool useBud = false; 73 74 // by which name shall bud be known? 75 private char[] budName; 68 76 69 77 void main(char[][] args) 70 { 78 { 71 79 // check if the first arg is the cleanlib argument 72 80 if(args.length == 2 && args[1].tolower().cmp("cleanlib") == 0) 73 81 { 74 // no building to be done, just delete the libs75 82 doCleanLib(); 76 83 return; 77 84 } 78 85 79 // flag to indicate if a build configuration was passed on the command line 80 bool modeSet = false; 81 82 // look for a build configuration in the command line 83 foreach(char[] c; args) 84 { 85 if(c.tolower().cmp("release") == 0) 86 { 87 mode = Mode.Release; 88 modeSet = true; 89 break; 90 } 91 else if(c.tolower().cmp("debug") == 0) 92 { 93 mode = Mode.Debug; 94 modeSet = true; 95 break; 96 } 97 } 98 99 // set the name of the build configuration text file 100 configTxt = configs[mode]; 101 102 // build a buffer of the commonTxt and configTxt so that it is done 103 // one time only and not once for each file 104 buildBRFBuffer(); 105 106 if(args.length == 1 || (modeSet && args.length == 2)) 107 { 108 // if no command line args were given, scan the directory for buildable packages 86 // list of packages passed on the command line 87 char[] packageList; 88 89 // look for a build configuration and compiler name in the command line 90 foreach(c; args) 91 { 92 char[] lower = c.tolower(); 93 switch(lower) 94 { 95 case "release": 96 mode = Mode.Release; 97 break; 98 case "debug": 99 mode = Mode.Debug; 100 break; 101 case "bud": 102 useBud = true; 103 budName = "bud"; 104 break; 105 case "build": 106 useBud = true; 107 budName = "build"; 108 break; 109 default: 110 if(lower.find("derelict") == 0) 111 { 112 packageList ~= c; 113 } 114 } 115 } 116 117 // if bud is being used, initialize the brf buffer 118 if(useBud) 119 { 120 buildBRFBuffer(); 121 } 122 123 // were any package names passed on the command line? 124 if(packageList.length == 0) 125 { 126 // scan the currnet directory for buildable packages 109 127 scan(); 110 128 } 111 129 else 112 { 113 // parse the command line for individual package names and build each package 114 foreach(char[] c; args) 130 { 131 // only build the specified packages 132 auto packages = packageList.split(); 133 foreach(c; packages) 115 134 { 116 135 buildPackage(c); … … 119 138 } 120 139 121 //============================================================================== 122 private char[] modeString() 123 { 124 if(mode == Mode.Debug) 125 { 126 return "Debug"; 127 } 128 return "Release"; 129 } 130 131 void doCleanLib() 140 private void doCleanLib() 132 141 { 133 142 // execute the system delete command on all of the library files in the lib dir 134 writefln("Deleting all libraries in Derelict's lib directory...");143 writefln("Deleting all %s libraries in Derelict's lib directory...", libExt); 135 144 system(toStringz(delCmd ~ "lib" ~ sep ~ "*" ~ libExt)); 136 145 writefln("Finished!\n\n"); 137 146 } 138 147 139 private char[] libString(char[] packageName)140 { 141 // build a string which will be used as the name of the library file142 version(Windows)143 { 144 // PackageName.lib145 return packageName ~ libExt;146 } 147 else version(linux)148 {149 // libPackageName.a150 return "lib" ~ packageName ~ libExt;148 private void buildPackage(char[] packageName) 149 { 150 // do not process further if the package name does not begin with 'Derelict' 151 if(packageName.find("Derelict") != 0) 152 { 153 writefln("Nothing to do for directory \'%s\'", packageName); 154 return; 155 } 156 157 if(!useBud) 158 { 159 compile(packageName); 151 160 } 152 161 else 153 162 { 154 static assert(0); 155 } 156 157 } 163 build(packageName); 164 } 165 } 166 167 private void scan() 168 { 169 // call listdir to cycle through every Derelict directory 170 writefln("\nScanning for buildable packages...\n\n"); 171 172 auto list = listdir("."); 173 foreach(c; list) 174 { 175 176 // if this filename is a directory, pass it to buildPackage for 177 // further processing 178 if(isdir(c) && c[0] != '.') 179 { 180 buildPackage(c); 181 } 182 } 183 184 writefln("Finished!\n\n"); 185 } 186 187 //============================================================================== 188 // DMD & GDMD 189 private char[] processPackage(char[] dir) 190 { 191 writefln("Processing %s", dir); 192 193 char[] fileList; 194 195 auto list = listdir(dir); 196 foreach(c; list) 197 { 198 // skip anything that begins with a '.' 199 if(c[0] == '.') 200 continue; 201 202 // prepend the current directory name to the filename 203 c = dir ~ sep ~ c; 204 205 // if this filename is a directory, recurse 206 if(isdir(c)) 207 { 208 fileList ~= processPackage(c); 209 } 210 // otherwise, if it is a D source file, append it to the return string 211 else 212 { 213 if(c[$-2 .. $].cmp(".d") == 0) 214 { 215 fileList = fileList ~ " " ~ c; 216 } 217 } 218 } 219 return fileList; 220 } 221 222 private void compile(char[] packageName) 223 { 224 // build a list of source files 225 char[] fileList = processPackage(packageName); 226 char[][] files = fileList.split(); 227 228 // build up an import list from forBuild.txt 229 char[] importList = "-IDerelictUtil -I" ~ packageName; 230 char[] txt = cast(char[])read(packageName ~ sep ~ "forbuild.txt"); 231 char[][] lines = txt.split("\n"); 232 foreach(c; lines) 233 { 234 if(c.length >= 2 && c[0] == '-' && c[1] == 'I') 235 importList = importList ~ " " ~ c; 236 } 237 238 // compile each file 239 writefln("Compiling package %s in %s mode...", packageName, (mode == Mode.Debug) ? "Debug" : "Release"); 240 auto flags = importList ~ COMPILE_FLAGS_COMMON; 241 flags ~= (mode == Mode.Debug) ? COMPILE_FLAGS_DEBUG : COMPILE_FLAGS_RELEASE; 242 foreach(c; files) 243 { 244 writefln("Compiling source file %s", c); 245 auto cmdline = compilerCmd ~ flags ~ c; 246 if(system(toStringz(cmdline)) != 0) 247 { 248 throw new Exception("Failed to compile " ~ c); 249 } 250 } 251 252 // create the library 253 auto libName = libPre ~ packageName ~ libExt; 254 writefln("Creating library %s...", libName); 255 foreach(i, c; files) 256 { 257 auto obj = c.replace(".d", objExt); 258 auto cmd = i == 0 ? libCreateCmd : libCmd; 259 260 writefln("Adding object file %s", obj); 261 if(system(toStringz(cmd ~ "lib" ~ sep ~ libName ~ " " ~ obj)) != 0) 262 { 263 throw new Exception("Failed to create library " ~ libName); 264 } 265 writefln("Deleting object file %s", obj); 266 system(toStringz(delCmd ~ obj)); 267 } 268 269 version(NixExt) 270 { 271 if(mode == Mode.Release) 272 { 273 writefln("Stripping library " ~ libName); 274 system(toStringz("strip lib" ~ sep ~ libName)); 275 } 276 } 277 } 278 279 //============================================================================== 280 // BUD 281 282 // the debug or release build configuration file 283 private char[] configTxt; 284 285 // buffer to store the contents of the config files at startup 286 private static char[] brfBuf = ""; 158 287 159 288 private void buildBRFBuffer() 160 289 { 161 // if a common switchesfile is present...162 if(exists( commonTxt))290 // if a common config file is present... 291 if(exists("build_common.txt")) 163 292 { 164 293 // read it in and assign it to the brf buffer 165 brfBuf = cast(char[])read( commonTxt) ~ "\n";294 brfBuf = cast(char[])read("build_common.txt") ~ "\n"; 166 295 } 167 296 168 297 // if a build configuration file is present... 298 configTxt = (mode == Mode.Debug) ? "build_debug.txt" : "build_release.txt"; 169 299 if(exists(configTxt)) 170 300 { 171 // ... read it in and append it to thebuffer301 // read it in and append it to the brf buffer 172 302 brfBuf ~= cast(char[])read(configTxt); 173 303 } 174 175 version(linux)176 {177 brfBuf ~= "\n-op";178 }179 304 } 180 305 … … 183 308 writefln("Reading build tool arguments..."); 184 309 185 // read the package forbuild file310 // read the forbuild.txt in this package 186 311 char[] txt = cast(char[])read(path); 187 312 188 // this will store all of the text to be output to the temp b uild response file313 // this will store all of the text to be output to the temp brf 189 314 char[] brf = ""; 190 315 … … 195 320 brf ~= "\n-I" ~ packageName; 196 321 197 // if the current package is not DerelictUtil, then DerelictUtil must be 198 // on the import path and excluded from being compiled322 // if the current package is not DerelictUtil, then DerelictUtil must be on 323 // the import path and excluded from compilation 199 324 if(packageName.cmp("DerelictUtil") != 0) 200 325 { … … 202 327 } 203 328 204 // append a switch to set the output path of the library 205 brf ~= "\n-Tlib/" ~ lib String(packageName)~ "\n" ~ txt;206 207 // write the temporary b uild response fileto disk208 writefln("Creating temporary build response file...");209 write( tempBrf, cast(void[])brf);210 } 211 212 private void build Package(char[] packageName)329 // append a switch to set the output path of the library and append the config file 330 brf ~= "\n-Tlib/" ~ libPre ~ packageName ~ libExt ~ "\n" ~ txt; 331 332 // write the temporary brf to disk 333 writefln("Creating temporary Build Response File..."); 334 write("temp.brf", cast(void[])brf); 335 } 336 337 private void build(char[] packageName) 213 338 { 214 339 // construct a path to the package's forbuild file 215 char[] path = packageName ~ sep ~ forBuild;340 char[] path = packageName ~ sep ~ "forbuild.txt"; 216 341 if(!exists(path)) 217 342 { 218 // if there is no forbuild file in the subdirectory then this isn't 219 // a Derelict package and there is nothing to do 343 // if there is no forbuild in the subdirectory then this isn't a 344 // Derelict package and there is nothing to be done 345 writefln("Could not find %s", path); 220 346 return; 221 347 } 222 348 223 // create the temp orary build responsefile224 writefln("Preparing to build package %s in %s mode...", packageName, modeString);349 // create the temp brf file 350 writefln("Preparing to build package %s in %s mode...", packageName, (mode == Mode.Debug) ? "Debug" : "Release"); 225 351 createBRF(packageName, path); 226 352 227 // call out to build with the name of the temporary build response file as an arg 228 writefln("Building package..."); 229 int ret = system(toStringz(buildName ~ " @temp")); 230 if(ret != 0) 231 { 232 writefln("\n\n " ~ packageName ~ " failed to build.\n"); 233 version(Windows) system(toStringz("pause")); 234 } 235 236 // delete the temporary build response file 237 writefln("Deleting temporary build response file...\n\n"); 238 system(toStringz(delCmd ~ tempBrf)); 239 240 } 241 242 private void scan() 243 { 244 // call listdir to cycle through every Derelict directory 245 writefln("\nScanning for buildable packages...\n\n"); 246 247 char[][] list = listdir("."); 248 foreach(char[] filename; list) { 249 // if this filename is a directory, pass it to buildpackage for 250 // further processing 251 if(isdir(filename)) 252 { 253 buildPackage(filename); 254 } 255 } 256 257 writefln("Finished!\n\n"); 258 } 259 353 // call out to build with the name of the temp brf as an arg 354 if(system(toStringz(budName ~ " @temp")) != 0) 355 { 356 throw new Exception("Failed to build package " ~ packageName); 357 } 358 359 writefln("Deleting temporary Build Response File...\n\n"); 360 system(toStringz(delCmd ~ "temp.brf")); 361 } trunk/docs/build.html
r195 r217 1 1 <html lang="en"> 2 2 <head> 3 <title>Building Derelict with Derek Parnell's Bud</title>3 <title>Building Derelict</title> 4 4 <link rel="stylesheet" type="text/css" href="styles.css"> 5 5 </head> … … 7 7 <hr> 8 8 <hr> 9 <h2 align="center">Building Derelict with Derek Parnell's Bud</h2>9 <h2 align="center">Building Derelict</h2> 10 10 <hr> 11 11 <hr> 12 12 <h3>Introduction</h3> 13 In the top-level Derelict directory ($DERELICT_HOME) you will find a D module 14 named <tt>buildme.d</tt>. It can, and is intended to, be run as a script. Executing 15 this file will create one or more libraries from the Derelict packages. At the 16 end of execution, all of the libraries that were created will be found in the 17 $DERELICT_HOME/lib directory. 18 19 <div class="note">You may be tempted to compile buildme.d into an executable. It 20 is strongly recommended that you do not. The script is intended to be run from 21 the command line of a console window, as a script, so that you may see any 22 error text that is output. Should you compile an executable and launch from the 23 desktop, or any other non-console window, you will not see the error text.</div> 24 25 <h3>Options</h3> 26 Before executing the build script, you need to decide which libraries you want 27 to build and how you want to build them. There are a few command line options 28 you can pass along. When reading the options below, keep in mind that they 29 can be specified in any order. 30 31 <h4>Which Compiler?</h4> 32 The script supports compiling directly 33 with DMD and GDC (gdmd), or indirectly with <a href="#bud">Derek Parnell's Bud</a>. Executing the script 34 with no arguments will compile all libraries with the compiler used to execute 35 the script: 36 37 <pre> 38 cd $DERELICT_HOME 39 dmd -run buildme.d <-- This will compile with DMD 40 gdmd -run buildme.d <-- This will compile with GDC 41 </pre> 42 43 If you have Bud installed, you can use it to build the libraries by passing 44 "bud" on the command line: 45 46 <pre> 47 cd $DERELICT_HOME 48 dmd -run buildme.d bud 49 </pre> 50 51 This should work whether you execute the script with dmd or gdmd. Bud will 52 use the compiler for which it is configured. 53 54 <h4>Debug or Release?</h4> 55 By default, each package will be built in Release mode. You can specify debug 56 mode by passing 'debug' on the command line: 57 58 <pre> 59 cd $DERELICT_HOME 60 dmd -run buildme.d debug 61 </pre> 62 63 The script also accepts 'release' as a command line argument. 64 65 <p> 66 If you are using Bud, you can find the configuration options in the following 67 files: 68 </p> 69 70 <pre> 71 $(DERELICT_HOME)/build_common.txt 72 $(DERELICT_HOME)/build_release.txt 73 $(DERELICT_HOME)/build_debug.txt 74 </pre> 75 76 77 <tt>build_common.txt</tt>, <tt>build_debug.txt</tt>, and <tt>build_release.txt</tt> 78 may all be edited to your preference. The rules for editing these files are the 79 same as those for editing <a href="http://build.dsource.org/response_file.html">Bud 80 Response Files</a>, but there are some caveats. Because <tt>buildme.d</tt> automates 81 the build process, some assumptions are made. The first is that the output directory 82 will be the <tt>$DERELICT_HOME/lib</tt> subdirectory. Adding -TsomeDir to any of 83 the three files will have no effect. Second, the import paths for building each 84 package are set automatically. Third, the DerelictUtil package and other dependencies 85 are excluded from the compilation automatically via the -X Bud option, so you 86 need not do so yourself. 87 88 89 <p> 90 If you are not using Bud, you can find configuration options in the script itself. 91 The following variables are what you should look for: 92 </p> 93 94 <pre> 95 COMPILE_FLAGS_DEBUG 96 COMPILE_FLAGS_RELEASE 97 COMPILE_FLAGS_COMMON 98 </pre> 99 100 The options in COMPILE_FLAGS_COMMON are used in both Debug and Release builds. 101 102 For most users, there is no need to edit any of the options. But feel free to 103 do so if you need to. 104 105 <h4>Which Packages?</h4> 106 If you only want to build one or more specific packages, rather than all of them, 107 you can specify the package names on the command line: 108 109 <pre> 110 cd $DERELICT_HOME 111 dmd -run buildme.d DerelictAL DerelictUtil 112 </pre> 113 114 The above will build only the DerelictAL and DerelictUtil libraries. 115 116 <h4>Cleaning Up</h4> 117 During compilation, all object files will be deleted by the script. If you want 118 to delete all of the libraries, you can do so with the following command: 119 120 <pre> 121 cd $DERELICT_HOME 122 dmd -run buildme.d cleanlib 123 </pre> 124 125 This will delete the libraries in $(DERELICT_HOME/lib). Unlike the other command 126 line options, this option must be specified first. Any options following it will 127 be ignored. If it is not first, it will be ignored. 128 129 <div class=Note> 130 On windows, executing the cleanlib option with DMD will cause the script to delete 131 files with the .lib extension, while doing so with GDC (gdmd) will cause the 132 script to delete files with the .a extension. 133 </div> 134 135 <a name="bud"><h3>Derelict Parnell's Bud</h3></a> 13 136 Bud, created and maintained by Derek Parnell, is an incredibly 14 137 useful tool. Feed it one D source module on the command line and it will automatically … … 28 151 </p> 29 152 30 <h 3>Getting Your Hands on Bud</h3>153 <h4>Getting Your Hands on Bud</h4> 31 154 The latest version of Bud may always be found at the 32 155 <a href="http://www.dsource.org/projects/build"> … … 36 159 of the topic list). 37 160 38 <h3>Building the Derelict Libraries</h3>39 It is quite possible to use Derelict without compiling the libraries. D's compiliation40 speed combined with Bud's ease of use makes it fast and simple to compile41 even complex D applications. As long as the Derelict packages you use are on your42 import path, then you are set. If you aren't using Bud to build your application,43 though, this approach is not recommended as every Derelict module would need to44 be passed to the compiler manually. In the latter case, and for those who just45 prefer not to compile the Derelict modules every time, Derelict includes a D46 script that allows you to build all of the Derelict libraries or just the ones47 you need.48 49 <h4>Building All Packages</h4>50 51 In the top-level Derelict directory ($DERELICT_HOME) you will find a D module52 named <tt>buildme.d</tt>. This is an actual D module that can be run as a script.53 You can build all of the derelict packages in two easy steps:54 55 <pre>56 cd $DERELICT_HOME57 dmd -run buildme.d58 </pre>59 60 The -run switch tells the compiler to treat a D module as a script and executes61 it in place without creating any object files or other output. On Linux, you62 can also make the script executable so that you can replace the above command line63 with this:64 65 <pre>66 ./buildme.d67 68 </pre>69 70 You'll have to use chmod to make the script executable. You'll also have to open71 <tt>buildme.d</tt> and edit the first line, <tt>#!~/bin/dmd -run</tt>, so that72 the path points to your D compiler.73 74 <p>75 Regardless of how you execute the script, when the build completes the libraries76 will be found in $DERELICT_HOME/lib.77 </p>78 79 <h4>Building Individual Packages</h4>80 You can also build individual Derelict packages using <tt>buildme.d</tt>. Follow81 the steps above, but add to the command line the names of the packages you want82 to build. For example, if you wanted to build both DerelictGL and83 DerelictSDL, you would use this command line:84 85 <pre>86 dmd -run buildme DerelictGL DerelictSDL87 </pre>88 89 You can specify package names in any order. When the build completes, the libraries90 will be found in $DERELICT_HOME/lib.91 92 <h4>Build Configurations</h4>93 Derelict includes support for two build configurations: release and debug. The default94 compiler and Bud switches for each configuration can be found in the95 files <tt>build_release.txt</tt> and <tt>build_debug.txt</tt>. You can specify96 which configuration to use by passing either <tt>release</tt> or <tt>debug</tt>97 on the command line. You can pass either option along with package names in98 any order. When neither option is given, the debug configuration99 is used by default. Switches that are common to both configurations100 can be found in <tt>build_common.txt</tt>. Examples:101 102 <pre>103 Build all packages in Release mode:104 dmd -run buildme.d release105 106 Build all packages in Debug mode:107 dmd -run buildme.d debug108 109 Build all packages in Debug mode (same result as above):110 dmd -run buildme.d111 112 Build DerelictGL and DerelictSDL in Debug Mode113 dmd -run buildme.d debug DerelictGL DerelictSDL114 115 Build DerelictGL and DerelictSDL in Debug Mode (same result as above):116 dmd -run buildme.d DerelictSDL debug DerelictGL117 </pre>118 119 <p>120 <tt>build_common.txt</tt>, <tt>build_debug.txt</tt>, and <tt>build_release.txt</tt>121 may all be edited to your preference. The rules for editing these files are the122 same as those for editing <a href="http://build.dsource.org/response_file.html">Bud123 Response Files</a>, but there are some caveats. Because <tt>buildme.d</tt> automates124 the build process, some assumptions are made. The first is that the output directory125 will be the <tt>$DERELICT_HOME/lib</tt> subdirectory. Adding -TsomeDir to any of126 the three files will have no effect. Second, the import paths for building each127 package are set automatically. Third, the DerelictUtil package and other dependencies128 are excluded from the compilation automatically via the -X Bud option, so you129 need not do so yourself.130 </p>131 132 <div class="note">You may be tempted to compile buildme.d into an executable. It133 is strongly recommended that you do not. The script is intended to be run from134 the command line of a console window, as a script, so that you may see any135 error text that is output. Should you compile an executable and launch from the136 desktop, or any other non-console window, you will not see the error text.</div>137 138 139 <h4>Other Options</h4>140 Sometimes you may find yourself wanting to delete the library files generated141 by the build script. You can do this by running the build script with the142 <tt>cleanlib</tt> argument, like so:143 <pre>144 dmd -run buildme.d cleanlib145 </pre>146 147 All library files in $DERELICT_HOME/lib will be deleted.148 161 149 162 <h3>Troubleshooting</h3>
