Developing DMD / Phobos on Windows 8

From D Wiki
Jump to: navigation, search

WORK IN PROGRESS

NB! This guide is heavily biased towards those coming from Posix-like operating systems wanting to get a similar simple experience for testing code on Windows. It may use very non-idiomatic solutions that will make any experienced Windows developer laugh. Development environment is based on Bash shell provided by Windows git distribution.

Script itself is not very polished and is tuned to suit my personal needs.

Installing prerequisites

  1. Windows git distribution : http://msysgit.github.io
  2. Free version of Visual C++ for non-commercial usage : http://www.visualstudio.com/en-US/products/visual-studio-express-vs
  3. Windows SDK : http://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx
  4. Digital Mars C Compiler & tool : (contains make binary)

This guide should be at least partially applicable to different versions of Visual Studio and Windows but you may need different download links

Creating development environment

Preparing folder layout

  1. Create "dlang" folder somewhere which will contain all files related to D development. In my case it is C:\Users\Dicebot\Desktop\dlang
  2. Create "dlang/bin" folder that will contain all generated binaries and intermediate tools
  3. Download Digital Mars C Compiler & tools distribution (http://downloads.dlang.org/other/dm857c.zip), copy dm\bin\make.exe to dlang\bin\make.exe
Setting PATH

Create .bash_profile file in your user home folder (C:\Users\<username>) which contains single line:

export $PATH=$PATH:<path to dlang/bin>

In my case it was:

export $PATH=$PATH:/C/Users/Mihails/Desktop/devel/dlang/bin
build.sh

Put this script in your dlang/bin folder as build.sh:

#! /bin/bash
set -e

VCVARS='C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat'
VSMODEL='x86_amd64'
SLNFILE='dmd_msc_vs12.sln'

function print_help() 
{
    echo "Takes one argument - action to perform. Always operates in current directory."
    echo
    echo "Available actions:"
    echo "	fetch (get upstream dmd/druntime/phobos repositories)"
    echo "	build (builds all projects)"
}

function clone_or_update()
{
    local repo=$1
    
    if [ -z "$repo" ]
    then
        echo "clone_or_update must have one argument - repo name"
    fi

    if [ -d "./$repo" ]
    then
        echo "Updating / rebasing $repo"
        cd ./$repo
        git fetch origin
        git stash -q
        git rebase origin/master
        if [ $? -ne 0 ]
        then
            git rebase --abort
            echo "Can't rebase because of conflicts, please do it manually"
            exit 1
        fi
        git stash pop -q || echo "No local changes to restore from stash"
        cd -
    else
        git clone https://github.com/D-Programming-Language/$repo.git
    fi
}

function run_in_vsenv()
{
    local command=$1
    
    if [ -z "$command" ]
    then
        echo "run_in_vsenv must have one argument - command to run"
    fi
    
    # Can't use && because env vars get expanded too early
    echo "call \"$VCVARS\" $VSMODEL" > ./_tmp.bat
    echo "$command" >> ./_tmp.bat
    cmd.exe "/Q /C _tmp.bat"
    rm ./_tmp.bat
}

function build_dmd()
{    
    if [ -d "./dmd" ]
    then
        local slnpath="dmd\src\\$SLNFILE"
        run_in_vsenv "msbuild "$slnpath" /p:Configuration=Release /p:Platform=x64"
        cp dmd/src/vcbuild/x64/Release/dmd_msc12.exe bin/dmd.exe
    else
        echo "Run 'build.sh fetch' first"
    fi
}

function build_library()
{   
    if [ -d "./$1" ]
    then
        cd $1        
        run_in_vsenv "make -f win64.mak DMD=dmd.exe CC=cl LD=link AR=lib"
        cd -
    else
        echo "Run 'build.sh fetch' first"
    fi
}

if [ -z $1 ]
then
    print_help
fi

case $1 in
    fetch)
        clone_or_update "dmd"
        clone_or_update "druntime"
        clone_or_update "phobos"
        clone_or_update "tools"
        ;;
    build)
        build_dmd
        build_library "druntime"
        build_library "phobos"
        ;;
esac

echo "All done."

It is supposed to be run from git bash shell. build.sh fetch will clone repositories or update existing ones, build.sh build will build dmd, druntime and phobos in one go, taking care of all environment setup.