Difference between revisions of "Building DMD"

From D Wiki
Jump to: navigation, search
m (Windows - AIO solutions)
m (Update redirect)
 
(7 intermediate revisions by 5 users not shown)
Line 1: Line 1:
If you're looking for a stable version of D, you probably want to download the [http://dlang.org/download.html official releases]. This page is for those who want to try out D on platforms that aren't yet officially supported, those who are adventurous and wish to try out the latest development (unstable!) version of D, and developers who wish to contribute to D development.
+
#REDIRECT [[Starting as a Contributor#Building from source]]
 
 
==Existing tools==
 
 
 
There exist tools which can do some of the below steps automatically:
 
 
 
* [https://github.com/D-Programming-Language/tools/blob/master/update.sh tools/update.sh] is a simple script that either installs anew or updates an existing D development tree. Just download the script and run.
 
* [https://github.com/CyberShadow/Digger Digger] - can download and build D from any point in its recent history.
 
* [https://github.com/jacob-carlborg/dvm DVM] - can build and locally install D from source code.
 
 
 
==Getting the sources==
 
 
 
===Official releases===
 
 
 
The official release of DMD is available from the [http://dlang.org/download.html official download page].
 
 
 
===Latest git===
 
 
 
This is for those who want to test or contribute to the development version of D. The latest source code for the D compiler, runtime library, and standard library are available on [https://github.com/D-Programming-Language GitHub]. To build a working D compiler toolchain, you will need to checkout at least dmd, druntime, and phobos.
 
 
 
==Source code structure==
 
 
 
The D source code assumes a particular directory structure, which you probably would want to adopt so that you don't have to fiddle with the Makefiles all the time.
 
 
 
===Posix===
 
 
 
For Posix, it is assumed that you will have a common root directory where the compiler and library sources will sit under. For example, you can choose the common root directory to be /usr/src/d, then you can checkout the sources under this directory:
 
 
 
<syntaxhighlight lang=bash>
 
mkdir /usr/src/d
 
cd /usr/src/d
 
git clone git://github.com/D-Programming-Language/dmd.git
 
git clone git://github.com/D-Programming-Language/druntime.git
 
git clone git://github.com/D-Programming-Language/phobos.git
 
</syntaxhighlight>
 
 
 
Optionally, if you want some related tools, you can also checkout tools.git:
 
 
 
<syntaxhighlight lang=bash>
 
git clone git://github.com/D-Programming-Language/tools.git
 
</syntaxhighlight>
 
 
 
 
 
'''Note:''' if you're planning to submit [[Pull Requests|pull requests]], you should replace the above URLs with the URLs for your ''fork'' of the official sources, not the official sources themselves.
 
 
 
You should end up with this directory structure:
 
 
 
<pre>
 
/usr/src/d/
 
/usr/src/d/dmd
 
/usr/src/d/druntime
 
/usr/src/d/phobos
 
(/usr/src/d/tools)
 
</pre>
 
 
 
===Windows===
 
 
 
For windows, you can follow the first posix steps regarding checking out files from github.
 
 
 
You can checkout the sources wherever you like. If we call {{code|%DM_HOME%}} the root path, the it is ''recommended'' to have this structure:
 
 
 
<pre>
 
%DM_HOME%\dmd2\src
 
%DM_HOME%\dmd2\src\dmd
 
%DM_HOME%\dmd2\src\druntime
 
%DM_HOME%\dmd2\src\phobos
 
</pre>
 
 
 
Additionally, you should extract the digital mars compiler inside {{code|%DM_HOME%}}, alongside {{code|dmd2}}. You should finally create a {{code|windows}} directory with a {{code|bin}} and {{code|lib}} directory inside it. Your final structure should look like this:
 
 
 
<pre>
 
%DM_HOME%\dm
 
%DM_HOME%\dmd2\src
 
%DM_HOME%\dmd2\src\dmd
 
%DM_HOME%\dmd2\src\druntime
 
%DM_HOME%\dmd2\src\phobos
 
%DM_HOME%\dmd2\windows
 
%DM_HOME%\dmd2\windows\bin
 
%DM_HOME%\dmd2\windows\lib
 
</pre>
 
 
 
==Building the sources==
 
 
 
===Posix===
 
 
 
See also [https://xtzgzorex.wordpress.com/2011/07/31/d-building-dmd-and-phobos-on-linux/ Alex Rønne Petersen's blog post on building DMD (a dead link, author has been queried via e-mail; awaiting response)]
 
 
 
Assuming your sources are checked out in {{code|/usr/src/d}}, you can do the following to build them:
 
 
 
<syntaxhighlight lang=bash>
 
cd /usr/src/d/dmd/src
 
make -f posix.mak
 
cd ../../druntime
 
make -f posix.mak DMD=../dmd/src/dmd
 
cd ../phobos
 
make -f posix.mak DMD=../dmd/src/dmd
 
</syntaxhighlight>
 
 
 
Note that the compiler, runtime library, and standard library have to be built in that order, as each depends on the previous one.  The addition of the build option  DMD=../dmd/src/dmd ensures that your newly-built dmd is being used to build druntime and phobos.
 
 
 
If you're using a 64-bit platform, you may want to append {{code|MODEL&#x3d;64}} to your make commands, as the default makefiles will build for 32-bit:
 
 
 
<syntaxhighlight lang=bash>
 
cd /usr/src/d/dmd/src
 
make -f posix.mak MODEL=64
 
cd ../../druntime
 
make -f posix.mak MODEL=64 DMD=../dmd/src/dmd
 
cd ../phobos
 
make -f posix.mak MODEL=64 DMD=../dmd/src/dmd
 
</syntaxhighlight>
 
 
 
Parallel make can drastically speed up compilation times. The {{code|-j<integer>}} option allows you to specify the number of job slots. Number_of_cores + 1 is a often a good choice E.g.:
 
 
 
<syntaxhighlight lang=bash>
 
make -f posix.mak -j5
 
</syntaxhighlight>
 
 
 
for a machine with 4 cores.
 
 
 
After building, you should have a working D compiler in {{code|/usr/src/d/dmd/src/dmd}}. You may need to edit {{code|dmd.conf}} so that the compiler can find druntime and phobos. Your {{code|dmd.conf}} should contain:
 
 
 
<pre>
 
[Environment]
 
 
 
DFLAGS=-I/path/to/src/phobos -I/path/to/src/druntime/import -L-L/path/to/libs -L--no-warn-search-mismatch -L--export-dynamic
 
</pre>
 
 
 
Where the first two flags ({{code|-I}}) must be followed by the path to {{code|src/phobos}} et {{code|src/druntime/import}}. The {{code|-L-L}} flag must be followed by the path to {{code|libphobos.a}} (for example: {{code|-L-L/usr/local/lib/lib64}}).
 
 
 
You should probably also run the unittests to make sure your build is working correctly:
 
 
 
<syntaxhighlight lang=bash>
 
cd ../druntime
 
make -f posix.mak -j5 unittest
 
cd ../phobos
 
make -f posix.mak -j5 unittest
 
</syntaxhighlight>
 
 
 
(Running the unittests with {{code|-j}} is recommended if you have a multicore CPU, as some of them may take a while to run.)
 
 
 
====Installation====
 
{{code|posix.mak}} does not come with an install option (user supplied sample install script here: [[Attachment:posix-make-install-dmd.sh]]), but you can copy files manually to an appropriate location such as {{code|/usr/local}} or {{code|/opt/dmd}}.  For example:
 
 
 
<syntaxhighlight lang=bash>
 
cd /usr/src/d/dmd/src
 
mkdir /opt/dmd
 
mkdir /opt/dmd/bin
 
cp dmd /opt/dmd/bin
 
 
 
cd ../../druntime
 
mkdir /opt/dmd/include
 
mkdir /opt/dmd/include/d2
 
cp -r import/* /opt/dmd/include/d2
 
 
 
cd ../phobos
 
mkdir /opt/dmd/lib
 
cp generated/linux/release/64/libphobos2.a /opt/dmd/lib    # for 64-bit version
 
cp generated/linux/release/32/libphobos2.a /opt/dmd/lib    # for 32-bit version
 
cp -r std /opt/dmd/include/d2
 
cp -r etc /opt/dmd/include/d2
 
</syntaxhighlight>
 
 
 
Then, create the following {{code|dmd.conf}} in the {{code|/opt/dmd/bin}} directory:
 
 
 
<syntaxhighlight lang=bash>
 
[Environment]
 
DFLAGS=-I/opt/dmd/include/d2 -L-L/opt/dmd/lib -L--no-warn-search-mismatch -L--export-dynamic
 
</syntaxhighlight>
 
 
 
Note that you will have to add {{code|/opt/dmd/bin}} to your {{code|PATH}} to make use of your newly installed DMD.
 
 
 
'''Uninstallation''' is then as simple as removing the {{code|/opt/dmd}} directory.
 
 
 
===Windows - step by step===
 
The following instructions work for win32. May or may not work with win64. This scheme is a suggestion. These instructions should work when building from a clean repository, however, this repository contains autogenerated code that may be left behind after switching branches so running a git clean after switching branches is a good idea:
 
 
 
<syntaxhighlight lang=dos>
 
git clean -xfd
 
</syntaxhighlight>
 
 
 
Assuming your sources are checked out {{code|C:\D}}, and that {{code|make}} from digital mars is in your path, you can do the following to build them:
 
 
 
<syntaxhighlight lang=dos>
 
set DM_HOME=C:\D
 
cd %DM_HOME%\dmd2\src\dmd\src
 
make -fwin32.mak release
 
</syntaxhighlight>
 
 
 
From there, it is suggested to move the built binaries into your {{code|%DM_HOME%\windows\bin}} directory, and add that to your path:
 
<syntaxhighlight lang=dos>
 
copy *.exe %DM_HOME%\dmd2\windows\bin
 
set path=%path%;%DM_HOME%\dmd2\windows\bin
 
</syntaxhighlight>
 
 
 
From there, you have to create a {{code|sc.ini}} in your {{code|DMD.exe}} directory. It is suggested to just copy paste the one provided in the packaged {{Latest DMD Version}}, instead of writing your own.
 
 
 
Now build druntime:
 
<syntaxhighlight lang=dos>
 
cd %DM_HOME%\dmd2\src\druntime
 
make -fwin32.mak
 
</syntaxhighlight>
 
 
 
And phobos:
 
<syntaxhighlight lang=dos>
 
cd %DM_HOME%\dmd2\src\phobos
 
make -fwin32.mak
 
</syntaxhighlight>
 
 
 
You should copy the phobos lib into your {{code|windows\lib}} folder:
 
<syntaxhighlight lang=dos>
 
copy phobos.lib %DM_HOME%\dmd2\windows\lib
 
</syntaxhighlight>
 
 
 
Optionally, you can build rdmd from source if you have checked out {{code|tools}} in your sources:
 
<syntaxhighlight lang=dos>
 
cd %DM_HOME%\dmd2\src\tools
 
make -fwin32.mak rdmd.exe
 
copy *.exe %DM_HOME%\dmd2\windows\bin
 
</syntaxhighlight>
 
 
 
The last step is getting the additional libs. curl for D2 can be found at the bottom of the download section of dlang.org: [[http://dlang.org/download.html download]].
 
 
 
Additional libs that are necessary can simply be copy pasted from the {{Latest DMD Version}} package (without overwriting your {{code|phobos.lib}})
 
 
 
The very last step is to verify that everything works by unittesting phobos:
 
 
 
<syntaxhighlight lang=dos>
 
cd %DM_HOME%\dmd2\src\phobos
 
make -fwin32.mak unittest
 
</syntaxhighlight>
 
 
 
===Windows - AIO solutions===
 
 
 
====Using a batch file====
 
 
 
The following solution proposes to build '''dmd''', '''druntime''' and '''phobos''' ''All In One'', under Windows 32 bit, with the help of a single '''.bat''' script. Note that it's not related at all to the '''step by step''' way.
 
 
 
The first thing to do is to clone the three main '''D-Programming-Language repositories''' in a common folder.
 
 
 
You must have something similar to:
 
 
 
<syntaxhighlight lang=text>
 
+--- D-Programming-Language
 
  |
 
  +---dmd 
 
  +---druntime
 
  +---phobos
 
</syntaxhighlight>
 
 
 
in the root directory ('''D-Programming-Language''') create a new '''.bat''' file and paste the following script:
 
 
 
<syntaxhighlight lang=dos>
 
:: master paths
 
set setupfold=dmd2master
 
set ROOT=%cd%
 
md %setupfold%\windows\bin
 
md %setupfold%\windows\lib
 
 
 
::current DMD used to bootstrap
 
set HOST_DC=dmd.exe
 
 
 
:: DMD
 
cd dmd\src
 
make -fwin32.mak release
 
copy dmd.exe %ROOT%\%setupfold%\windows\bin
 
 
 
:: back and give priority to new dmd.exe
 
cd %ROOT%
 
set path=%cd%\%setupfold%\windows\bin;%path%
 
 
 
:: creates SC.INI indicating where sources will be found
 
:: (keep repo location for now)
 
(
 
echo [Environment]
 
echo DFLAGS="-I%%@P%%\..\..\..\phobos" "-I%%@P%%\..\..\..\druntime\import"
 
echo LIB="%%@P%%\..\lib"
 
echo [Environment32]
 
echo LIB="%%@P%%\..\lib"
 
) > %ROOT%\%setupfold%\windows\bin\sc.ini
 
 
 
:: new DMD as HOST_DC
 
set HOST_DC=%cd%\%setupfold%\windows\bin\dmd.exe
 
 
 
:: RUNTIME
 
cd druntime
 
make -fwin32.mak
 
cd lib
 
copy *.lib %ROOT%\%setupfold%\windows\lib
 
 
 
:: PHOBOS
 
:: (here SC.INI is mandatory)
 
cd %ROOT%
 
cd phobos
 
make -fwin32.mak
 
copy *.lib %ROOT%\%setupfold%\windows\lib
 
</syntaxhighlight>
 
 
 
Save the file and double click.
 
Wait a few minutes and the sub folder '''dmd2master''' will contain a basic dmd setup, based on the head of each repository.
 
 
 
Note that you can change the target folder name by redefining the value of the script variable '''setupfold'''
 
 
 
<syntaxhighlight lang=dos>
 
set setupfold=yourcall
 
</syntaxhighlight>
 
 
 
Don't forget to read the following note in case you'd encounter the error related to '''masm'''.
 
Another requirement is that the paths to '''dmc''' and '''make''' must be known by Windows !
 
 
 
====Using a D script====
 
 
 
The same task can be achieved using a D script. It requires DMD to be already setup as well as '''DMC''', '''GIT''' and '''MAKE''' (the one shipped with a dmd setup).
 
 
 
The following script goes a bit further than the '''.bat''' file.
 
 
 
* '''--noUpdate''': avoids to pull the git repository.
 
* '''--noDoc''': avoid to generate dlang.org and phobos documentation.
 
* first parameter: if set to a directory then it's used as target for the new dmd setup.
 
 
 
Compile and copy the program where you wish the things to happen then double click to start the operations:
 
 
 
<syntaxhighlight lang=D>
 
module CampaignDlangCampSetup;
 
 
 
import core.thread;
 
import std.stdio, std.file, std.path, std.process, std.array, std.getopt;
 
 
 
static struct repos
 
{
 
    static immutable baseUrl    = "https://github.com/D-Programming-Language/";
 
    static immutable dmd        = baseUrl ~ "dmd.git";
 
    static immutable druntime  = baseUrl ~ "druntime.git";
 
    static immutable phobos    = baseUrl ~ "phobos.git";
 
    static immutable org        = baseUrl ~ "dlang.org.git";
 
}
 
 
 
string envFind(string filename, string envVar = "PATH")
 
 
    auto env = environment.get(envVar);
 
    if (!env) return null;
 
    foreach(string dir; env.split(";")) {
 
        string maybe = dir ~ dirSeparator ~ filename;
 
        if (maybe.exists) return maybe;
 
    }
 
    return "";
 
}
 
 
 
void main(string[] args)
 
{
 
 
 
    bool noUpdate;
 
    bool noDoc;
 
    getopt(args, config.passThrough, "noUpdate", &noUpdate, "noDoc", &noDoc); 
 
   
 
    //check that the 3rd part tools are in the environment
 
    if (envFind("git.exe") == "")  assert(0, "GIT is missing");
 
    if (envFind("dmc.exe") == "")  assert(0, "DMC is missing");
 
    if (envFind("make.exe") == "") assert(0, "MAKE is missing");
 
    if (envFind("masm386.bat") == "") assert(0, "a dummy file named 'masm386.bat' must be located in one of the system PATH !");
 
    auto currDMD = envFind("dmd.exe");
 
    if (currDMD == "" ) assert(0, "DMD is missing");
 
   
 
    string[string] env = environment.toAA;
 
    env["HOST_DC"] = currDMD;
 
   
 
    // define the root path for the campaign-dlang-camp
 
    string rootDir;
 
    if (args.length == 1) rootDir = args[0].dirName;
 
    else rootDir = args[1]; 
 
    if (!rootDir.exists) return;
 
   
 
    // define the path were dmd will be setup
 
    string dmdPath = rootDir ~ r"\dmd2master";
 
   
 
    // clones or updates the repositories.
 
    if (!noUpdate)
 
    {
 
        Pid dmdPid, rtPid, phPid, orgPid;
 
       
 
        dmdPid = exists(rootDir ~ r"\dmd\.git\") ?
 
            spawnProcess(["git", "pull"], null, Config.none, rootDir ~ r"\dmd\") :
 
            spawnProcess(["git", "clone", repos.dmd], null, Config.none, rootDir);
 
   
 
        rtPid = exists(rootDir ~ r"\druntime\.git\") ?
 
            spawnProcess(["git", "pull"], null, Config.none, rootDir ~ r"\druntime\") :
 
            spawnProcess(["git", "clone", repos.druntime], null, Config.none, rootDir);       
 
           
 
        phPid = exists(rootDir ~ r"\phobos\.git\") ?
 
            spawnProcess(["git", "pull"], null, Config.none, rootDir ~ r"\phobos\") :
 
            spawnProcess(["git", "clone", repos.phobos], null, Config.none, rootDir);         
 
           
 
        orgPid = exists(rootDir ~ r"\dlang.org\.git\") ?
 
            spawnProcess(["git", "pull"], null, Config.none, rootDir ~ r"\dlang.org\") :
 
            spawnProcess(["git", "clone", repos.org], null, Config.none, rootDir);
 
   
 
        // wait for the cloning/pulling to be complete. 
 
        while(true)
 
        {
 
            Thread.sleep(dur!"msecs"(10));
 
            if (!dmdPid.tryWait.terminated) continue;
 
            if (!rtPid.tryWait.terminated)  continue;
 
            if (!phPid.tryWait.terminated)  continue;
 
            if (!orgPid.tryWait.terminated) continue;
 
            break;
 
        }
 
    }
 
    chdir(rootDir);
 
       
 
    // creates setup path
 
    std.file.mkdirRecurse(dmdPath ~ r"\windows\bin");
 
    std.file.mkdirRecurse(dmdPath ~ r"\windows\lib");
 
   
 
    string sourceDir;
 
     
 
    // compile DMD and move file set as first findable dmd in env
 
    sourceDir = rootDir ~ r"\dmd\src";
 
    chdir(sourceDir);
 
    spawnProcess(["make", "-fwin32.mak", "clean"], env, Config.none, sourceDir).wait;
 
    spawnProcess(["make", "-fwin32.mak", "AUTO_BOOTSTRAP=1"], env, Config.none, sourceDir).wait;
 
   
 
    std.file.copy(r"dmd.exe", dmdPath ~ r"\windows\bin\dmd.exe");
 
 
    // creates the SC.INI file
 
    auto scFname = dmdPath ~ r"\windows\bin\sc.ini";
 
    std.file.write(scFname,"[Environment]\r\n");
 
    std.file.append(scFname,"DFLAGS=\"-I%@P%\\..\\..\\..\\phobos\" \"-I%@P%\\..\\..\\..\\druntime\\import\"\r\n");
 
    std.file.append(scFname,"LIB=\"%@P%\\..\\lib\"\r\n");
 
    std.file.append(scFname,"[Environment32]\r\n");
 
    std.file.append(scFname,"LIB=\"%@P%\\..\\lib\"\r\n");
 
 
 
    // in this new environment, the latest dmd will be found first
 
    env["HOST_DC"] = dmdPath ~ r"\windows\bin;";
 
    env["PATH"] = dmdPath ~ r"\windows\bin;" ~ env["PATH"];
 
   
 
    // compile DRUNTIME and move file
 
    sourceDir = rootDir ~ r"\druntime";
 
    chdir(sourceDir);
 
    spawnProcess(["make", "-fwin32.mak", "clean"], env, Config.none, sourceDir).wait;
 
    spawnProcess(["make", "-fwin32.mak"], env, Config.none, sourceDir).wait;
 
 
 
    // compile PHOBOS and move file
 
    sourceDir = rootDir ~ r"\phobos";
 
    chdir(sourceDir);
 
    spawnProcess(["make", "-fwin32.mak", "clean"], env, Config.none, sourceDir).wait;
 
    spawnProcess(["make", "-fwin32.mak"], env, Config.none, sourceDir).wait;
 
    std.file.copy("phobos.lib", dmdPath ~ r"\windows\lib\phobos.lib");
 
   
 
    if (!noDoc)
 
    {
 
        // generate PHOBOS documentation
 
        sourceDir = rootDir ~ r"\phobos";
 
        chdir(sourceDir);
 
        spawnProcess(["make", "html", "-fwin32.mak"], env, Config.none, sourceDir).wait;   
 
        // dlang.org
 
        sourceDir = rootDir ~ r"\dlang.org";
 
        chdir(sourceDir);
 
        spawnProcess(["make", "-fwin32.mak"], env, Config.none, sourceDir).wait;
 
    }
 
}
 
</syntaxhighlight>
 
 
 
===Common Windows issues===
 
 
 
* missing MASM386:
 
If when building druntime you get errors about missing MASM386, it's due to a required assembling of a file called '''minit.asm'''. However the druntime repository includes a prebuilt minit.obj file so you shouldn't need to assemble it again. As a workaround for the make error create an empty '''masm386.bat''' file and put it in a directory that's in your '''PATH'''.
 
 
 
It's also recommended that you use the cmd.exe terminal. Others, like Powershell, are known to experience issues with legacy tools.
 
 
 
* garbages lead to several errors:
 
The three main components (DMD, DRUNTIME, PHOBOS) should always be build at the same time. The garbages generated by a previous build can lead to a failure so it's advisable to run
 
 
 
<syntaxhighlight lang=dos>
 
make -fwin32.mak clean
 
</syntaxhighlight>
 
 
 
on each component before starting the process.
 
 
 
==Additional Tools==
 
 
 
If you cloned {{code|D-Programming-Language/tools.git}}, you also have a {{code|tools}} folder where small helping programs live. There is no need to build them, you can just compile them using DMD:
 
 
 
<syntaxhighlight lang=dos>
 
dmd rdmd.d;
 
dmd ddemangle.d;
 
dmd dtab;
 
dmd tolf;
 
</syntaxhighlight>
 
 
 
{{code|rdmd}} builds your D modules automatically, from the one containing {{code|main}}. It'll deduce dependencies and compile/link them for you.
 
{{code|ddemangle}} will demangle its input, replacing all mangled D symbols with their unmangled form.
 
{{code|dtab}} transforms tabs into spaces in source code.
 
{{code|tolf}} replaces line endings with LF.
 
 
 
Using {{code|dtab}} and {{code|tolf}} is a good idea if you want to contribute to the D-Programming-Language repos.
 
 
 
== Building the Docs ==
 
<syntaxhighlight lang=bash>
 
git clone https://github.com/D-Programming-Language/tools.git
 
cd tools
 
make
 
cd generated/linux/default
 
PATH=$PATH:`pwd`
 
export PATH
 
cd ../../../..  # you should be in your top D folder
 
 
 
git clone https://github.com/D-Programming-Language/dlang.org.git
 
cd dlang.org
 
make -f posix.mak DMD=../dmd/src/dmd
 
cd ..
 
ln -s dlang.org/web .
 
 
 
cd phobos
 
make -f posix.mak DMD=../dmd/src/dmd html
 
cd ..
 
$BROWSER web/phobos-prerelease/std_YOUR_CHOICE.html
 
</syntaxhighlight>
 
 
 
Note that the full build of the dlang.org repository requires a lot of tools, such as LaTeX, Kindle, etc.. If you only need the HTML docs, use the html target only:
 
<syntaxhighlight lang=bash>
 
cd /path/to/dlang.org
 
make -f posix.mak html
 
</syntaxhighlight>
 
 
 
==Running the test suite==
 
 
 
Naturally if you are hacking on the dmd compiler (to fix your favorite bug, right?!), you'll want to run the test suite to ensure that you haven't broken anything.
 
 
 
===Windows===
 
 
 
On Windows, the test suite requires a very specific environment and careful configuration to run successfully:
 
 
 
* The <tt>PATH</tt> must be set up such that <tt>link.exe</tt> will execute [[OPTLINK]], however the test suite <tt>Makefile</tt> is written using GNU syntax.
 
* The <tt>CC</tt> variable must be set correspondingly to the C compiler for your Windows version: <tt>dmc</tt> for 32-bit, <tt>cl</tt> (Microsoft Visual C++) for 64-bit.
 
* To force the makefile to use the 32-bit C compiler on a 64-bit Windows machine, the <tt>OS</tt> variable must be overridden.
 
 
 
With that, here's how to get the test suite working on Windows:
 
 
 
* Get and install [http://www.cygwin.com/ Cygwin]. You'll need the basic packages containing <tt>make</tt>, <tt>mkdir</tt>, etc.
 
* Create the following batch file in the test directory (<tt>dmd\test\run_test_suite.bat</tt>):
 
@echo off
 
set PATH=C:\dm\bin;C:\cygwin\bin;%WINDIR%\System32;%WINDIR%
 
set CC=dmc
 
set MAKE=C:/cygwin/bin/make.exe
 
%MAKE% OS=win32 quick %*
 
:If necessary, replace the paths to DMC and Cygwin appropriately. Note that the <tt>MAKE</tt> variable must use forward slashes.
 
* Create an <tt>sc.ini</tt> file in the dmd source directory (<tt>dmd\src\sc.ini</tt>). This file has the same format as <tt>dmd.conf</tt> in the instructions for POSIX below. Here is an example:
 
[Environment]
 
LIB="%@P%\..\..\phobos"
 
DFLAGS="-I%@P%\..\..\phobos" "-I%@P%\..\..\druntime\import"
 
LINKCMD=C:\dm\bin\link.exe
 
:Again, replace <tt>C:\dm</tt> as appropriate.
 
 
 
This should allow running the test suite on Windows. See the POSIX section below for non-Windows-specific information.
 
 
 
===POSIX (Linux, OS X, FreeBSD)===
 
 
 
Since it wasn't obvious how to run the test suite, or why it failed the first couple of times, I'll add notes here on how to build on Linux/x86_64. If you are not on Linux and not on 64-bit, then you'll simply have to adjust the lines below. I wanted to be specific to avoid confusion.
 
 
 
====How to run the test suite in '''dmd/test''' ====
 
 
 
Location: If dmd/src/ is your source directory (that contains mars.c, impcnvgen.c, dmd_msc.vcproj, posix.mak, etc) then '''dmd/test''' is the test suite directory.
 
 
 
Before running: a freshly built dmd at '''dmd/src/dmd'''  does not have a '''dmd.conf''' file. You'll need to make '''dmd/src/dmd.conf''' file in order to run the tests.
 
 
 
Here's an example of a '''dmd.conf''' config file when working with git-head versions of dmd, druntime, and phobos:
 
 
 
<syntaxhighlight lang=bash>
 
[Environment32]
 
DFLAGS=-I%@P%/../../phobos -I%@P%/../../druntime/import -L-L%@P%/../../phobos/generated/linux/release/64 -L--export-dynamic
 
 
 
[Environment64]
 
DFLAGS=-I%@P%/../../phobos -I%@P%/../../druntime/import -L-L%@P%/../../phobos/generated/linux/release/64 -L--export-dynamic
 
</syntaxhighlight>
 
 
 
The linker switches are not actually necessary when running the DMD test-suite, since DMD's tests should never reference Druntime or Phobos code.
 
However when building apps or running the Druntime/Phobos git-head tests with the git-head version of DMD, you will need the above linker switches.
 
 
 
To run the tests: (this will take a while)
 
 
 
<syntaxhighlight lang=bash>
 
cd dmd/test
 
make MODEL=64
 
</syntaxhighlight>
 
 
 
====Common problems and their solutions====
 
 
 
a) common error number one: lack of correct dmd.conf, and dmd.conf must point to the installed include files.
 
 
 
If you do not have a dmd.conf in place, you will get error:
 
<syntaxhighlight lang=bash>
 
Error: cannot find source code for runtime library file 'object.d'
 
      dmd might not be correctly installed. Run 'dmd -man' for installation instructions.
 
Specify path to file 'object.d' with -I switch
 
</syntaxhighlight>
 
 
 
See the installation section above.
 
 
 
b) common error number two: If you just say 'make' without adding the MODEL designation, you will get the default 32-bit tests on your 64-bit platform. You have to say 'make MODEL=64' in the src/dmd/test dir.
 
 
 
If you are on 64-bit and you do not do the MODEL=64, you will get this error:
 
 
 
<syntaxhighlight lang=bash>
 
Running runnable tests
 
... runnable/A16.d                (-inline -release -gc -O -fPIC)
 
Test failed.  The logged output:
 
../src/dmd -m32 -Irunnable  -odtest_results/runnable -oftest_results/runnable/A16_0 runnable/A16.d runnable/imports/A16a.d
 
/usr/bin/ld: cannot find -lphobos2
 
collect2: ld returned 1 exit status
 
--- errorlevel 1
 
 
 
 
 
==============================
 
Test failed: expected rc == 0, exited with rc == 1
 
</syntaxhighlight>
 
 
 
==== Run the druntime and phobos unit tests ====
 
 
 
Next run the unit tests for the standard libraries.
 
 
 
<syntaxhighlight lang=bash>
 
cd ../../druntime
 
make -f posix.mak MODEL=64 DMD=../dmd/src/dmd unittest
 
cd ../phobos
 
make -f posix.mak MODEL=64 DMD=../dmd/src/dmd unittest
 
</syntaxhighlight>
 
 
 
See also: [[Pull Requests]].
 
 
 
===DMD profiling and test coverage===
 
 
 
The DMD makefile provides some options to make a debug build of DMD that is instrumented with profiling and coverage options. This may be useful to diagnose performance problems or improve test coverage of the compiler.
 
 
 
Both profiling and coverage are enabled by building with the following options:
 
 
 
<syntaxhighlight lang=bash>
 
cd /path/to/dmd/src
 
make -f posix.mak DEBUG=1 ENABLE_PROFILING=1
 
</syntaxhighlight>
 
 
 
Now running the compiler will accumulate profiling and coverage statistics. You can now run the test suite to accumulate the data, or run the compiler on your own test cases to get data on a specific compilation scenario. '''Note:''' due to the way the system C/C++ compilers tend to work, it's recommended that you invoke the compiler from the dmd/src subdirectory (that is, the same directory as where the source files are). Some coverage tools may get confused otherwise.
 
 
 
Once you have collected the data, you can use the '''gcov''' target of the makefile to produce source code listings annotated with coverage counts:
 
 
 
<syntaxhighlight lang=bash>
 
# Note: should be in dmd/src directory
 
make -f posix.mak gcov
 
</syntaxhighlight>
 
 
 
This will produce a bunch of .gcov files containing the annotated source file listings.
 
 
 
[[Category:DMD Compiler]]
 

Latest revision as of 12:50, 5 May 2019