Changeset 217

Show
Ignore:
Timestamp:
01/28/07 13:23:21 (2 years ago)
Author:
aldacron
Message:

* eliminated the dependency upon Bud. While Bud is still supported, the build script can now be used without it. The packaged can be compiled directly with DMD and GDC(gdmd).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/build_common.txt

    r211 r217  
    44-v1 
    55-w 
     6-op 
    67-Xphobos 
  • trunk/buildme.d

    r202 r217  
    88    import std.file; 
    99    import std.path; 
    10     import std.string; 
    11 
     10
     11 
     12// compiler command 
     13version(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
     25else version(GNU) 
     26
     27    private static const char[] compilerCmd = "gdmd "; 
     28    version = NixExt; 
     29
     30else 
     31
     32    static assert(0, "Unsupported compiler"); 
     33
     34 
     35// file extensions, prefixes and commands 
     36version(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
     45else 
     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 
    1255 
    1356// build configurations 
     
    1861} 
    1962 
    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 
    4664private Mode mode = Mode.Release; 
    4765 
    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 
     67private static const COMPILE_FLAGS_DEBUG = " -debug -g "; 
     68private static const COMPILE_FLAGS_RELEASE = " -release -inline -O "; 
     69private static const COMPILE_FLAGS_COMMON = " -c -op -v1 -w "; 
     70 
     71// use bud? 
     72private bool useBud = false; 
     73 
     74// by which name shall bud be known? 
     75private char[] budName; 
    6876 
    6977void main(char[][] args) 
    70 {   
     78{ 
    7179    // check if the first arg is the cleanlib argument 
    7280    if(args.length == 2 && args[1].tolower().cmp("cleanlib") == 0) 
    7381    { 
    74         // no building to be done, just delete the libs 
    7582        doCleanLib(); 
    7683        return; 
    7784    } 
    7885     
    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 
    109127        scan(); 
    110128    } 
    111129    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) 
    115134        { 
    116135            buildPackage(c); 
     
    119138} 
    120139 
    121 //============================================================================== 
    122 private char[] modeString() 
    123 
    124     if(mode == Mode.Debug) 
    125     { 
    126         return "Debug"; 
    127     } 
    128     return "Release"; 
    129 
    130  
    131 void doCleanLib() 
     140private void doCleanLib() 
    132141{ 
    133142    // 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); 
    135144    system(toStringz(delCmd ~ "lib" ~ sep ~ "*" ~ libExt)); 
    136145    writefln("Finished!\n\n"); 
    137146} 
    138147 
    139 private char[] libString(char[] packageName) 
    140 { 
    141     // build a string which will be used as the name of the library file 
    142     version(Windows
    143     { 
    144         // PackageName.lib 
    145         return packageName ~ libExt;        
    146     } 
    147     else version(linux) 
    148     { 
    149        // libPackageName.a 
    150         return "lib" ~ packageName ~ libExt
     148private 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)
    151160    } 
    152161    else 
    153162    { 
    154         static assert(0); 
    155     } 
    156      
    157 
     163        build(packageName); 
     164    } 
     165
     166 
     167private 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 
     189private 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 
     222private 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 
     283private char[] configTxt; 
     284 
     285// buffer to store the contents of the config files at startup 
     286private static char[] brfBuf = ""; 
    158287 
    159288private void buildBRFBuffer() 
    160289{ 
    161     // if a common switches file is present... 
    162     if(exists(commonTxt)) 
     290    // if a common config file is present... 
     291    if(exists("build_common.txt")) 
    163292    { 
    164293        // 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"; 
    166295    } 
    167296     
    168297    // if a build configuration file is present... 
     298    configTxt = (mode == Mode.Debug) ? "build_debug.txt" : "build_release.txt"; 
    169299    if(exists(configTxt)) 
    170300    { 
    171         // ... read it in and append it to the buffer 
     301        // read it in and append it to the brf buffer 
    172302        brfBuf ~= cast(char[])read(configTxt); 
    173303    } 
    174      
    175     version(linux) 
    176     { 
    177         brfBuf ~= "\n-op"; 
    178     } 
    179304} 
    180305 
     
    183308    writefln("Reading build tool arguments..."); 
    184309     
    185     // read the package forbuild fil
     310    // read the forbuild.txt in this packag
    186311    char[] txt = cast(char[])read(path); 
    187312     
    188     // this will store all of the text to be output to the temp build response file 
     313    // this will store all of the text to be output to the temp brf 
    189314    char[] brf = ""; 
    190315     
     
    195320    brf ~= "\n-I" ~ packageName; 
    196321     
    197     // if the current package is not DerelictUtil, then DerelictUtil must be 
    198     // on the import path and excluded from being compiled 
     322    // if the current package is not DerelictUtil, then DerelictUtil must be on 
     323    // the import path and excluded from compilation 
    199324    if(packageName.cmp("DerelictUtil") != 0) 
    200325    { 
     
    202327    } 
    203328     
    204     // append a switch to set the output path of the library 
    205     brf ~= "\n-Tlib/" ~ libString(packageName) ~ "\n" ~ txt; 
    206      
    207     // write the temporary build response file to disk 
    208     writefln("Creating temporary build response file..."); 
    209     write(tempBrf, cast(void[])brf); 
    210 } 
    211  
    212 private void buildPackage(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 
     337private void build(char[] packageName) 
    213338{ 
    214339    // construct a path to the package's forbuild file 
    215     char[] path = packageName ~ sep ~ forBuild
     340    char[] path = packageName ~ sep ~ "forbuild.txt"
    216341    if(!exists(path)) 
    217342    { 
    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); 
    220346        return; 
    221347    } 
    222348     
    223     // create the temporary build response file 
    224     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"); 
    225351    createBRF(packageName, path); 
    226352     
    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  
    11<html lang="en"> 
    22<head> 
    3     <title>Building Derelict with Derek Parnell's Bud</title> 
     3    <title>Building Derelict</title> 
    44    <link rel="stylesheet" type="text/css" href="styles.css"> 
    55</head> 
     
    77<hr> 
    88<hr> 
    9 <h2 align="center">Building Derelict with Derek Parnell's Bud</h2> 
     9<h2 align="center">Building Derelict</h2> 
    1010<hr> 
    1111<hr> 
    1212<h3>Introduction</h3> 
     13In the top-level Derelict directory ($DERELICT_HOME) you will find a D module  
     14named <tt>buildme.d</tt>. It can, and is intended to, be run as a script. Executing 
     15this file will create one or more libraries from the Derelict packages. At the 
     16end 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 
     20is strongly recommended that you do not. The script is intended to be run from 
     21the command line of a console window, as a script, so that you may see any  
     22error text that is output. Should you compile an executable and launch from the 
     23desktop, or any other non-console window, you will not see the error text.</div> 
     24 
     25<h3>Options</h3> 
     26Before executing the build script, you need to decide which libraries you want 
     27to build and how you want to build them. There are a few command line options 
     28you can pass along. When reading the options below, keep in mind that they 
     29can be specified in any order. 
     30 
     31<h4>Which Compiler?</h4> 
     32The script supports compiling directly 
     33with DMD and GDC (gdmd), or indirectly with <a href="#bud">Derek Parnell's Bud</a>. Executing the script  
     34with no arguments will compile all libraries with the compiler used to execute  
     35the 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 
     43If 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 
     51This should work whether you execute the script with dmd or gdmd. Bud will 
     52use the compiler for which it is configured. 
     53 
     54<h4>Debug or Release?</h4> 
     55By default, each package will be built in Release mode. You can specify debug 
     56mode by passing 'debug' on the command line: 
     57 
     58<pre> 
     59    cd $DERELICT_HOME 
     60    dmd -run buildme.d debug 
     61</pre> 
     62 
     63The script also accepts 'release' as a command line argument. 
     64 
     65<p> 
     66If you are using Bud, you can find the configuration options in the following 
     67files: 
     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> 
     78may all be edited to your preference. The rules for editing these files are the 
     79same as those for editing <a href="http://build.dsource.org/response_file.html">Bud 
     80Response Files</a>, but there are some caveats. Because <tt>buildme.d</tt> automates 
     81the build process, some assumptions are made. The first is that the output directory 
     82will be the <tt>$DERELICT_HOME/lib</tt> subdirectory. Adding -TsomeDir to any of 
     83the three files will have no effect. Second, the import paths for building each 
     84package are set automatically. Third, the DerelictUtil package and other dependencies 
     85are excluded from the compilation automatically via the -X Bud option, so you 
     86need not do so yourself. 
     87 
     88 
     89<p> 
     90If you are not using Bud, you can find configuration options in the script itself. 
     91The following variables are what you should look for: 
     92</p> 
     93 
     94<pre> 
     95COMPILE_FLAGS_DEBUG 
     96COMPILE_FLAGS_RELEASE 
     97COMPILE_FLAGS_COMMON 
     98</pre> 
     99 
     100The options in COMPILE_FLAGS_COMMON are used in both Debug and Release builds. 
     101 
     102For most users, there is no need to edit any of the options. But feel free to 
     103do so if you need to. 
     104 
     105<h4>Which Packages?</h4> 
     106If you only want to build one or more specific packages, rather than all of them, 
     107you 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 
     114The above will build only the DerelictAL and DerelictUtil libraries. 
     115 
     116<h4>Cleaning Up</h4> 
     117During compilation, all object files will be deleted by the script. If you want 
     118to 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 
     125This will delete the libraries in $(DERELICT_HOME/lib). Unlike the other command  
     126line options, this option must be specified first. Any options following it will  
     127be ignored. If it is not first, it will be ignored. 
     128 
     129<div class=Note> 
     130On windows, executing the cleanlib option with DMD will cause the script to delete 
     131files with the .lib extension, while doing so with GDC (gdmd) will cause the 
     132script to delete files with the .a extension. 
     133</div> 
     134 
     135<a name="bud"><h3>Derelict Parnell's Bud</h3></a> 
    13136Bud, created and maintained by Derek Parnell, is an incredibly 
    14137useful tool. Feed it one D source module on the command line and it will automatically 
     
    28151</p> 
    29152 
    30 <h3>Getting Your Hands on Bud</h3
     153<h4>Getting Your Hands on Bud</h4
    31154The latest version of Bud may always be found at the 
    32155<a href="http://www.dsource.org/projects/build"> 
     
    36159of the topic list). 
    37160 
    38 <h3>Building the Derelict Libraries</h3> 
    39 It is quite possible to use Derelict without compiling the libraries. D's compiliation 
    40 speed combined with Bud's ease of use makes it fast and simple to compile 
    41 even complex D applications. As long as the Derelict packages you use are on your 
    42 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 to 
    44 be passed to the compiler manually. In the latter case, and for those who just 
    45 prefer not to compile the Derelict modules every time, Derelict includes a D 
    46 script that allows you to build all of the Derelict libraries or just the ones 
    47 you need. 
    48  
    49 <h4>Building All Packages</h4> 
    50  
    51 In the top-level Derelict directory ($DERELICT_HOME) you will find a D module  
    52 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_HOME 
    57     dmd -run buildme.d 
    58 </pre> 
    59  
    60 The -run switch tells the compiler to treat a D module as a script and executes 
    61 it in place without creating any object files or other output. On Linux, you 
    62 can also make the script executable so that you can replace the above command line 
    63 with this:  
    64  
    65 <pre> 
    66     ./buildme.d 
    67      
    68 </pre> 
    69  
    70 You'll have to use chmod to make the script executable. You'll also have to open  
    71 <tt>buildme.d</tt> and edit the first line, <tt>#!~/bin/dmd -run</tt>, so that  
    72 the path points to your D compiler. 
    73  
    74 <p> 
    75 Regardless of how you execute the script, when the build completes the libraries 
    76 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>. Follow  
    81 the steps above, but add to the command line the names of the packages you want  
    82 to build. For example, if you wanted to build both DerelictGL and 
    83 DerelictSDL, you would use this command line:  
    84  
    85 <pre> 
    86     dmd -run buildme DerelictGL DerelictSDL 
    87 </pre> 
    88  
    89 You can specify package names in any order. When the build completes, the libraries 
    90 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 default 
    94 compiler and Bud switches for each configuration can be found in the 
    95 files <tt>build_release.txt</tt> and <tt>build_debug.txt</tt>. You can specify 
    96 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 in 
    98 any order. When neither option is given, the debug configuration 
    99 is used by default. Switches that are common to both configurations 
    100 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 release 
    105      
    106     Build all packages in Debug mode: 
    107     dmd -run buildme.d debug 
    108      
    109     Build all packages in Debug mode (same result as above): 
    110     dmd -run buildme.d 
    111      
    112     Build DerelictGL and DerelictSDL in Debug Mode 
    113     dmd -run buildme.d debug DerelictGL DerelictSDL 
    114      
    115     Build DerelictGL and DerelictSDL in Debug Mode (same result as above): 
    116     dmd -run buildme.d DerelictSDL debug DerelictGL 
    117 </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 the 
    122 same as those for editing <a href="http://build.dsource.org/response_file.html">Bud 
    123 Response Files</a>, but there are some caveats. Because <tt>buildme.d</tt> automates 
    124 the build process, some assumptions are made. The first is that the output directory 
    125 will be the <tt>$DERELICT_HOME/lib</tt> subdirectory. Adding -TsomeDir to any of 
    126 the three files will have no effect. Second, the import paths for building each 
    127 package are set automatically. Third, the DerelictUtil package and other dependencies 
    128 are excluded from the compilation automatically via the -X Bud option, so you 
    129 need not do so yourself. 
    130 </p> 
    131  
    132 <div class="note">You may be tempted to compile buildme.d into an executable. It 
    133 is strongly recommended that you do not. The script is intended to be run from 
    134 the command line of a console window, as a script, so that you may see any  
    135 error text that is output. Should you compile an executable and launch from the 
    136 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 generated 
    141 by the build script. You can do this by running the build script with the 
    142 <tt>cleanlib</tt> argument, like so:  
    143 <pre> 
    144     dmd -run buildme.d cleanlib 
    145 </pre> 
    146  
    147 All library files in $DERELICT_HOME/lib will be deleted. 
    148161 
    149162<h3>Troubleshooting</h3>