D on OpenBSD

Step 1: do a normal install of OpenBSD 6.9.

If you're installing a later version, you can probably skip step #2.

Step 2: update to OpenBSD-current from 6.9

# sysupgrade -s

Step 3: install gdc

# pkg_add gdc

Step 4: add 'gdc' to your PATH

$ mkdir ~/bin
$ ln -s /usr/local/bin/egdc ~/bin/gdc

Step 5: add 'gdmd' to your PATH

# pkg_add git
$ mkdir ~/dlang
$ cd ~/dlang
$ git clone https://github.com/D-Programming-GDC/gdmd
$ cp -pv gdmd/dmd-script ~/bin

To make these available to any user on the system, /usr/local/bin's a better directory. Just note that the math/gbc package also tries to install a /usr/local/bin/gdc

Step 6: raise user memory limits

If you don't want to have to compile D programs as root. The defaults are too low for building dub in particular.

# cat >> /etc/login.conf <<'EOF'

# Login class for users that will be building D programs.

# usermod -L dmd USER

You'll may need to log out and log back in to get a session with the new limits. On a desktop with 32GB of RAM and 32GB of swap, 'ulimit -a' reported a data(kbytes) value of 32GB.

Step 7: build and install dub

$ cd ~/dlang
$ git clone https://github.com/dlang/dub
$ cd dub
$ gdc -O -o build build.d
$ ./build
Building dub using gdmd (dflags: ["-g", "-O", "-w"]), this may take a while...
DUB has been built as: /home/USER/dlang/dub/bin/dub
You may want to run `sudo ln -s /home/USER/dlang/dub/bin/dub /usr/local/bin` now

Step 8: confirm dub actually works

... presently, most functions segfault pretty early on.

$ echo 'void main(){writeln("test");}' | dub -q run dfmt -- --brace_style=otbs 
Segmentation fault (core dumped) 

Step 9: get D tools

The OpenBSD gdc package just gives you an 'egdc' bin. You'll probably want at least ddemangle and rdmd

$ cd ~/dlang
$ git clone https://github.com/dlang/tools
$ cd tools
$ perl -i -lpe 's/"-v", // if /-v.*rootModule/' rdmd.d 
$ gdc -O2 -o ~/bin/rdmd rdmd.d
$ rdmd --eval 'writeln("it works")'          
it works
$ gdc -O2 -o ~/bin/ddemangle ddemangle.d
$ objdump -dwr --no-show-raw-insn ~/bin/rdmd|egrep -m1 std.conv 
  18f72d:       jmp    18f730 <_D3std4conv__T10emplaceRefTAyaTQeTQhZQxFKQoKQrZ1S9__xtoHashFNbNeKxSQCnQCm__TQCkTQCbTQCfTQCjZQDaFKQCsKQCwZQCgZm>
shadow$ objdump -dwr --no-show-raw-insn ~/bin/rdmd|egrep -m1 std.conv|ddemangle
  18f72d:       jmp    18f730 <nothrow @trusted ulong std.conv.emplaceRef!(immutable(char)[], immutable(char)[], immutable(char)[]).emplaceRef(ref immutable(char)[], ref immutable(char)[]).S.__xtoHash(ref const(std.conv.emplaceRef!(immutable(char)[], immutable(char)[], immutable(char)[]).emplaceRef(ref immutable(char)[], ref immutable(char)[]).S))>

That perl line strips a -v (verbose) flag out of the command that rdmd passes to gdmd. I haven't looked into why this produces tons of noisy output on OpenBSD but not on Linux, but it's probably a bug.

Step 10: build dmd?

It fails right now, but why not give it a try?

# pkg_add gmake
$ cd ~/dlang
$ for x in dmd druntime phobos; do git clone https://github.com/dlang/$x; done
$ ( cd dmd; HOST_DMD=gdmd gmake -f posix.mak )
$ ( cd druntime; HOST_DMD=gdmd gmake -f posix.mak )
$ ( cd phobos; HOST_DMD=gdmd gmake -f posix.mak )