Dr. Brian Robert Callahan

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



[prev]
[next]

2023-06-26
GCC --enable-languages=all on OpenBSD

I would imagine that when most people think about GCC, they think about a C compiler, a C++ compiler, and maybe also a Fortran compiler. However, GCC is much more than just that. GCC can compile nine different languages, with an tenth on the way: Ada, C, C++, D, Fortran, Go, Modula-2, Objective-C, and Objective-C++. Rust is on the way; GCC has an experimental frontend available as of GCC 14.

A little bit of history: GCC has removed frontends from time to time. Perhaps most memorable is the removal of GCJ in GCC 7. But there have been others too. The CHILL frontend was removed in GCC 3, g77 (the original Fortran frontend) was removed in GCC 4, Cilk Plus was removed in GCC 7, and BRIG (HSAIL) in GCC 11.

Additionally, there are some frontends that have not yet or never made it into GCC mainline. GNU Pascal never made it into mainline, and seems to have atrophied. A shame really; I would love to have a Pascal compiler in GCC. Ada and Modula-2 are nice, but I have an affinity for Pascal. It was the first non-BASIC programming language I ever learned. gcobol is a COBOL frontend currently in active development.

It cannot be overstated just how successful GCC has been since its introduction over 35 years ago.

What I'm interested in exploring today is if we can build all of these frontends for OpenBSD. If we can, I would like to explore their usability on OpenBSD.

I am using amd64 but I believe arm64 and perhaps even riscv64 would also be OK, but alas I don't have any RISC-V machines and my paltry Raspberry Pi 3B+ isn't all that healthy anymore.

Building binutils from a vanilla checkout

I began with a vanilla git checkout of both GNU binutils and GCC of their latest code. While OpenBSD does have a package for binutils, and it is kept up-to-date, I figured if I was going to compile the latest GCC I should compile the latest binutils as well. I am really only interested in the GNU assembler here, so I can have GCC use it. This builds out-of-the-box without issue. OpenBSD uses LLD from LLVM as the system linker and there is no reason to use anything else.

Building GCC from a vanilla checkout

Unfortunately, building GCC from a vanilla checkout is not as straightforward as binutils. Fortunately, pascal@ has done an amazing job maintaining the GCC package for OpenBSD. We can use his work as our starting point. I will break down the patches needed to build GCC as a whole and then the individual languages.

General GCC

I think these could probably be upstreamed if there was enough interest to do so, but the patches are small enough that I'm not sure it matters too much for OpenBSD's purposes.

And that's it. The changes are minimal. It might be nice for convenience sake to upstream these but the maintenance burden is not so great.

C, C++, Fortran, Objective-C, Objective-C++, Modula-2, and Rust

These all build out-of-the-box, no changes required or desired.

Ada

OpenBSD maintains its own Ada support. It works, but has never been upstreamed. It might be nice to upstream it. The Ada compiler is written in Ada.

Ada support for OpenBSD requires the addition of new files for each of the CPU architectures that OpenBSD has Ada support for: amd64, arm, hppa, i386, mips64, mips64el, powerpc, and sparc64. It is probably possible to add support for additional CPU architectures like arm64 and riscv64, but that likely requires building a cross compiler and then building a native compiler from that cross compiler. Without the hardware to test the resulting native Ada compilers, it's a little outside what I can do right now.

However, amd64 works perfectly fine and I can easily build and rebuild the Ada compiler on amd64.

D

Readers of this blog know that I have the dubious distinction of being the person to first publish having completed the final mile and getting GDC working on OpenBSD. The Dlang team is great and very receptive to ports of their compilers to new platforms. I've had the privilege of speaking at DConf about the state of D on OpenBSD.

Like Ada, the D compiler is written in its own language. Earlier versions of GDC have a D compiler written in C++. So if you need to bootstrap, get one of those earlier versions. GCC 9.1 is a good bootstrap compiler for D.

The changes needed for D are minimal. There are two functions in the D compiler that need an additional overload to deal with the fact that size_t is always unsigned long on OpenBSD. In libphobos, the D standard library, there are no changes needed but we build it for more platforms than upstream currently claims. I'd like to get this libphobos bit upstreamed, but I'm not in much of a rush for that since we do ship the GDC package with support for amd64, arm64, armv7, i386, powerpc, and powerpc64. We are very close to having a sparc64 package as well; we need someone to write assembly versions of the setcontext family of functions and then a sparc64 GDC package should be complete. I'd do it myself but I don't know sparc64 assembly anywhere near well enough to be confident I did it correctly. Plus I don't have any sparc64 machines around.

Go

Go is the odd one out. It needed extensive work to get building. The compiler itself built without any changes but libgo in upstream GCC simply does not support OpenBSD. I am not terribly surprised by this, as even the OpenBSD Go package has a lot of patches. It is a huge effort by jsing@ to keep it all up-to-date and huge thanks to him for doing so.

However, with enough wrestling and reading through libgo code, I was finally able to get Go building.

So yes, it is possible to build GCC with --enable-languages=all on OpenBSD!

Running our complete GCC

But just because we can build all the frontends, it does not necessarily follow that they all work.

Ada, C, C++, D, Fortran, Objective-C, and Objective-C++

I have never had any problems with these languages on OpenBSD. Admittedly, I am not an Objective-C or Objective-C++ coder, so there could be problems with these two languages I am unaware of. But I doubt it.

We must remember that later versions of the original BSD from UC Berkeley switched to GCC as its compiler. This means that, for all modern BSDs, GCC has been a known and understood compiler since effectively the beginning of time. I would have been very surprised if any of these languages had issues on OpenBSD.

Modula-2

For reasons that I believe have something to do with OpenBSD's lack of thread-local storage, when using the ISO dialect, the resulting binaries segfault on startup. This does not happen with the PIM2 (default), PIM3, or PIM4 dialects. I have never written any Modula-2 code that required the ISO dialect, so this problem doesn't affect me. But I would like to figure something out eventually to get the ISO dialect working. The Modula-2 developer is very receptive to OpenBSD fixes, and he worked with me to get patches in to build Modula-2 out-of-the-box on OpenBSD while he was also getting the Modula-2 frontend into GCC mainline.

Rust

The Rust frontend is far from complete. It requires a long and convoluted -frust-incomplete-and-experimental-compiler-do-not-use flag to even compile any code. It cannot yet compile a Hello world program due to lack of macro support. However, if you can write Rust code that the Rust frontend can compile, it will compile that code just fine and the resulting binaries will work on OpenBSD just fine. This is a good sign for future Rust frontend development and I will continue to monitor its development closely so that OpenBSD can benefit from this new compiler.

Go

The Go frontend can compile Go code; libgo is written in Go so we have a good test that the Go frontend does in fact work. However, any binaries built with the Go frontend instantly segfault when you try to run them. This suggests to me that I made a mistake somewhere in the libgo support. I am not terribly surprised by this and I intend to figure out my mistakes and get libgo working properly.

Conclusion

It is indeed possible to build all GCC frontends on OpenBSD with minimal to no patches, excluding Go. This is a testament to the quality of the work the GCC team continues to produce in their development of a world-class compiler suite.

While OpenBSD does ship with clang in its base system, LLVM does not feature nearly as many frontends built-in as GCC.

If people want a package of my GCC, let me know and I can put one online in the next few days.

Top

RSS