Dr. Brian Robert Callahan

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



[prev]
[next]

2021-10-20
An LDC bootstrap compiler and LDC package for OpenBSD

Remember when I said "Porting LDC would be nice, but it is not high on my priority list right now"? Yeah me too, since it was last week in the previous blog post. Turns out I lied. I have ported LDC, and posted it to ports@.

I am going to need the knowledge on how to port LDC to other CPU archs eventually, so let's write down what we did so that I don't forget.

How building an LDC bootstrap works (at least on OpenBSD)

LDC permits building with either DMD or GDC, so long as they support version 2.076.0 of D. At least as of LDC version 1.28.0 though I imagine that until GDC is updated to a more modern version of the language, LDC will refrain from using D constructs that would fail on GDC. The LDC team also suggests using GDC for the bootstrap compiler if you don't yet have LDC on your system.

And so I did just that: took my system's GDC compiler and used it as the bootstrap compiler for the bootstrap LDC. I fought far more with LDC than I did with either DMD or GDC. But that's OK. All the patches live in the port so I never have to do that again.

After building LDC, I installed on the system as normal. I then made a new directory in my $HOME called ldc-1.28.0-bootstrap. Inside that directory, I made an amd64 directory to hold the bootstrap binaries and libraries specifically for amd64. The binaries you need for the bootstrap are: ldc2 and ldmd2. The D libraries you need are: libdruntime-ldc.a and libphobos2-ldc.a. On top of that, you also need a copy of ldc2.conf, which I placed with the bootstrap binaries and libraries for reasons that will make more sense when we turn our attention to the LDC port itself. I also in these bootstraps throw in copies of the system shared libraries the binaries need so that my life can be a bit easier when system shared library version numbers change. The system libraries you need are: libc.so, libc++.so, libc++abi.so, libm.so, libpthread.so, and libz.so.

Finally, you do need to put all the D headers in the bootstrap. Since those are architecture-neutral, I placed them in ldc-1.28.0-bootstrap/d/ for ease of use.

With that, your bootstrap LDC environment is ready to be tarred and gzipped, and placed on a server (I used GitHub).

Using the bootstrap in the LDC port

I used this ugly sed trick to edit the ldc2.conf file to replace the default includes and library directories to match what is in the bootstrap directory structure:

# I put a vanilla ldc2.conf in the bootstrap tarball.
# This fixes it up for the specifics for each arch.
post-patch:
        sed -i 's#/usr/local/include/d#${WRKDIR}/ldc-${V}-bootstrap/d#g' \
                ${WRKDIR}/ldc-${V}-bootstrap/${MACHINE_ARCH}/ldc2.conf
        sed -i 's#"/usr/local/lib",#"/usr/local/lib","${WRKDIR}/ldc-${V}-bootstrap/${MACHINE_ARCH}",#g' \
                ${WRKDIR}/ldc-${V}-bootstrap/${MACHINE_ARCH}/ldc2.conf

Unfortunately, the rules for finding the ldc2.conf file state that it'll either be in /etc or in the same directory as the binaries, with the same directory preferred over /etc. So that's why each arch needs its own copy of ldc2.conf. I suppose I could have a single global ldc2.conf that you then move into the correct binary directory for that arch, but the file is not so big so I don't care that much.

I then need to tell the ports system where the bootstrap compiler lives:

CONFIGURE_ENV = DMD="${WRKDIR}/ldc-${V}-bootstrap/${MACHINE_ARCH}/ldmd2"

And that's it! Now I can reproduce the LDC bootstrap environment for any other CPU arch I want.

Conclusion

A short post today so I can get this knowledge written down. Perhaps it may help FreeBSD, NetBSD, and DragonFly BSD with their ports of the D compilers. As of this writing, only OpenBSD has ports/packages of all three D compilers. But hopefully that improves soon!

Top

RSS