Brian Robert Callahan

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



[prev]
[next]

2021-05-20
The GNU D Compiler on OpenBSD/arm64

Today, I got the following to display on my new Pinebook Pro:

/home/brian $ gdc --version
gdc (GCC) 12.0.0 20210520 (experimental)
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

/home/brian $ uname -a
OpenBSD pine.my.domain 6.9 GENERIC.MP#1171 arm64

It works just as well as GDC on OpenBSD/amd64. I want to walk through how I made it happen so that others can replicate if they so choose. And so I can replicate for other archs, like armv7.

The setup

I began with my GDC for amd64. That would be a normal gcc git checkout with this patch applied to it.

Not having an installation of gcc already installed on the machine, I opted to install gcc-8.4.0 from ports with a quick doas pkg_add g++. On arm64, this also installs the GNU assembler, since arm64 does not ship with it. That's good, because we need it for gdc.

The build

I used the build script I normally use for amd64, though I much reduced it so that I would only build the C and D compilers.1 It looks like this:

#!/bin/sh

# Get latest sources
cd /home/brian/gcc/gcc
git pull

# Setup
rm -rf /home/brian/gcc/gcc-build
mkdir /home/brian/gcc/gcc-build
cd /home/brian/gcc/gcc-build

# Configure and build gcc
CC=/usr/local/bin/egcc CXX=/usr/local/bin/eg++ ../gcc/configure --verbose --enable-languages=c,d --disable-nls --with-system-zlib --disable-libgomp --disable-libitm --enable-libssp --enable-threads=posix --enable-wchar_t --disable-libstdcxx-pch --enable-default-ssp --enable-default-pie --enable-cpp --with-gmp=/usr/local --with-as=/usr/local/bin/gas --with-ld=/usr/bin/ld --enable-linker-build-id --prefix=/usr/local/gnu --with-local-prefix=/usr/local/gnu --disable-tls --with-gxx-libcxx-include-dir=/usr/include/c++/v1 --disable-bootstrap
gmake AUTOCONF_VERSION=2.69 AUTOMAKE_VERSION=1.16 -j6

Getting fixes from the OpenBSD ports tree

I had to incorporate some fixes to get it working.

It turns out that AArch64 support for OpenBSD has not yet been upstreamed, so I needed to pull the appropriate patches from the ports tree. You don't need all of them, or even most of them. I just took the bare minimum to get things built: 1, 2, 3, and 4.

Teaching Phobos about OpenBSD/arm64

At this point, I had to teach Phobos, the D Standard Library, about OpenBSD/arm64. It wasn't actually Phobos itself that needed teaching, but rather DRuntime, the low-level runtime library that links into Phobos. It's not the best analogy, but you can think of Phobos and DRuntime as you would think of libstdc++ and libsupc++ for C++. Again, it's not really a great analogy but oftentimes libsupc++ gets linked into libstdc++ and much the same, DRuntime gets linked into Phobos.

For GDC, turning the building of Phobos and DRuntime on is very simple. In libphobos/configure.tgt, add the following lines:

  aarch64*-*-openbsd*)
	LIBPHOBOS_SUPPORTED=yes
	;;

And then the build infrastructure will do the right thing.

However, there was one actual bit of teaching we still needed to do. In libphobos/libdruntime/core/sys/posix/setjmp.d, there was an identifier missing for AArch64, which caused the build to fail. I submitted a small Pull Request which was quickly committed. At some point, GDC will sync with the reference library and the fix will be included with GDC when that happens. Again, shoutouts to the D team for the quick turnaround with these patches.

The first binaries

After waiting some time for the build to complete, I was absolutely shocked to discover that it all just worked, and I now had a D compiler on my Pinebook Pro. But, as I soon discovered, my work wasn't quite finished. I began by trying to compile our Intel 8080/Zilog Z80 assembler that we wrote together. The build went fine. Linking, however, failed. The libraries were looking for a bunch of atomics that did not seem to exist. This does not appear to be the fault of gdc, but nonetheless I had to figure it out.

Stripping -moutline-atomics

In gcc 10 and later, the -moutline-atomics flag is turned on by default. It seems like something is missing in OpenBSD support for these atomics or I might not know how to properly use them (or both). In any event, my solution was to take the heavy-handed approach of telling the compiler that we unconditionally do not have support for this, which disables -moutline-atomics globally. This matches the default situation for gcc-8.4.0, so I guess I am fine with it. It was the final change needed to get gdc working, and gdc on arm64 appears to work just as well as gdc on amd64, so to me it is fine.

The second binaries

I rebuilt gdc just to be sure and it works great! Our assembler compiles perfectly well and works the same as it does on amd64. I consider this a successful morning project!

A package?

If people want, I can toss a package up on GitHub. Let me know.

More archs coming

I suppose I can replicate this for more archs. I am beginning the build on my BeagleBone Black so that we can also have OpenBSD/armv7 support. But since that's building on an SD card, presume it will take a while! I could also get mips64{,el} support up too if I am feeling sufficiently un-slacker enough to pull those machines out of storage. Anyone want to give me access to a sparc64 machine?

1 For comparison, on amd64 I build the C, C++, Objective-C, Objective-C++, D, and Fortran compilers.

Top

RSS