Dr. Brian Robert Callahan

academic, developer, with an eye towards a brighter techno-social life



[prev]
[next]

2021-03-20
A working D compiler on OpenBSD

I got GDC, the GNU D Compiler, working on OpenBSD. Supporting D has been a very long time coming. Here's the story of how we got here and where we need to go next.

2017: First inklings and small steps forward

Way back in 2017 is when I first learned about D. Seemed interesting and we didn't have a port of it. I like challenges so I figured I would give it a try. I eventually managed to get LDC, the LLVM D Compiler, to build on OpenBSD. Or, at least, its LTS version. That is the last version that does not need a D compiler to bootstrap and it claims to be able to build current versions of LDC. I never ended up trying it so I was never able to directly confirm this, but I have no reason to doubt them.

But then I was stuck. See, D inherits the C library entirely. And the D standard library, Phobos, effectively requires complete bindings to libc. There were none for OpenBSD, though there was a completed Phobos for FreeBSD. I tried to replicate the FreeBSD bindings on OpenBSD but was never able to finish it. There are enough subtle differences between FreeBSD and OpenBSD and I just did not have the time to finish it. It would have to be on the perpetual back burner until I could devote substantial resources to it.

2017-2021: Work continued without me

In the interim years, people continued to add support for OpenBSD. There have been commits targeting OpenBSD support for dmd, the D reference compiler, druntime, the static support library that provides the libc bindings, and phobos, the D standard library. I suspect no one really ever attempted to run the complete D toolchain on OpenBSD however. These commits were not enough. However, I am glad that I did not have to do that work so much thanks to everyone who made my job that much easier!

2021: The last mile

I had the time. It was time to finish this project.

It began with a stroke of happenstance. It is no secret that I have been tracking GCC head on OpenBSD for a long time. As of GCC 9, GDC is incorporated into gcc. And it just so happens that at the moment GDC's D frontend is still written in C++. We might well be able to compile it! So I added d to the list of languages to build on my buildbot and waited to see what happened.

Well it failed. Probably unsurprisingly. First order of business: add OpenBSD to libphobos's configure.tgt. Try again and... more failure. In the math library bindings for OpenBSD, druntime was looking for an __fpclassifyd symbol but on OpenBSD that symbol is named __fpclassify. Fix that and... well, it built! But it didn't actually support OpenBSD. Turns out you have to add additional support files to the gcc build to get gdc to recognize OpenBSD. It took far too long to figure that out than I would have expected.

Some other fixes later and we finally had a fully built gdc that recognized OpenBSD. Most things worked. But strangely, dub, the D package manager, would segfault when trying to fetch packages remotely. I ultimately discovered that using the static libgphobos.a rather than the shared libgphobos.so fixed the issue. I do not know why this works but I have gone ahead and disabled the building and installing of the shared libgphobos for now. It is akin to statically compiling libc into all your C programs, which I personally don't mind so much. The Phobos library is not that large and I don't have many D programs on my machine right now.

Getting the changes upstream

I ended up forward-porting OpenBSD support for dmd, which was committed. This dmd, which can be bootstrapped from gdc, is able to rebuild itself when using the forward-ported druntime, which is pending commit. Having the reference compiler able to rebuild itself is a great step towards ensuring continual D support. Even though the D Language Foundation does not officially support OpenBSD, Walter Bright, the creator of D, told me that upstreaming support for OpenBSD is welcome. I am happy with that arrangement and it is much appreciated.

Using a D compiler on OpenBSD

While all three D compilers can be built once you have GDC, only GDC fully works. This is because D requires thread-local storage, which OpenBSD does not yet support. GDC gets around this by using the emulated TLS from GCC, with the addition of GDC's own additional TLS emulation. This works fine on OpenBSD. I have not yet tried to port the GDC TLS emulation over to DMD or LDC, but it is on my list of things to try. Perhaps that will be sufficient.

Bringing OpenBSD's security features to D

The very first thing I did after getting GDC fully working was to create a package that provides D bindings for pledge(2). Any decent language has such bindings. It was extremely easy to implement as well. And now that the package is published, you can simply add it as a dependency to your D programs and benefit from OpenBSD's security features. Yes, I will add unveil(2) too eventually.

A port?

I am not sure how a port of gdc would work. I still need to upstream the changes for gdc. I guess if people want to try gdc for themselves, I can provide you with packages that set it up on your system. But you will get the entirety of gcc-11.0.1. No apologies there. And zero support whatsoever. Not only is it not a real package, by the time you install it, I will already have moved on to whatever the latest HEAD of the gcc tree is. More ideally, we will get emulated TLS support on either DMD or LDC (or both). I could then easily perform the bootstrap with gdc. We can easily provide ports for both dmd and ldc once they are bootstrapped and have emulated TLS.

Conclusion

That's the condensed story of how I finished the last mile for D support on OpenBSD. I think I may submit this as a talk to the next DConf conference. I think that would be fun and would provide a different kind of talk that would still be quite interesting for everyone.

Top

RSS