Ren-C Builds on Haiku!

So Haiku does now provide a modern toolchain out of the box.

All you have to do is say setarch x86 and suddenly you've got gcc 13.3

Despite being modern, it's missing some things on Haiku like Address Sanitizer. But it works well enough.

After a long night of tinkering and consulting with AI... I have my working branch running, as the first R3-derived executable with networking on Haiku! (thanks to using libuv...)

What Work Had To Be Done?

We're still in a state where the bootstrap executable is a different wonky old codebase that's fast and stable enough to build the current very-experimental branch.

So this means I had to get two codebases working, with fairly different concerns.

It did take a pretty long time, but a lot of that was me figuring out what to use for a debugger on Haiku, and just generally struggling with the medium. (Finding the setarch x86 was itself a good hour of discovery.) The ultimate changes were somewhat minimal:

Haiku Memory Alignment is Non-Standard

Ren-C has to have careful consideration to make sure that when raw memory is returned from a malloc() to be laid out by the system, that manual layout puts 64-bit double at 64-bit aligned pointers.

The way we do this alignment is by trusting that what comes back from malloc() is itself 64-bit aligned. This is required by the standard:

"If allocation succeeds, returns a pointer that is suitably aligned for any object type with fundamental alignment."

That should include double, hence at least 64-bits. But Haiku's legacy aligns on 32-bit, and we have asserts and problems that start firing if we notice bad alignment.

I found a switch for -malign-double which tells gcc to align on 64-bit boundaries and I thought that fixed it well enough. But unfortunately any Haiku system calls you make expect the structures to not have that alignment, and so you start to notice problems once you're making OS calls.

There's things you can do, like ask for an allocation that's slightly larger, and track when you have to offset it to match the alignment. But the reason Haiku has managed to get away with this bad behavior is because they only have distributions on x86 (and now x64), where bad double alignments still work... they're just slower. There's no need to bulletproof Ren-C for a non-C-standards-compliant system... in the 32-bit version of the OS... just to make accesses to double precision floating point faster.

So the right answer here was just to turn off alignment checking for Haiku (discovered only after figuring out -malign-double was the culprit for breaking OS calls).

Haiku's int_fast8_t can hold 255

This is something where I screwed up, and said int_fast8_t where I should have said uint_fast8_t. As it so happens, Mac ARM and x86 Linux and Windows all use a signed char to implement int_fast8_t, so if you assign 255 to it you'll get -1 ... but Haiku uses a larger signed int, so it's still 255.

Pretty random, but took a while to figure out what was going on.

Explicit includes needed some places

Haiku apparently factors the headers a bit more. e.g. you can't just say #include <termios.h> and get everything, you have to say:

#include <sys/select.h>  // for FD_ZERO, FD_SET, select()
#include <sys/time.h>    // for struct timeval
#include <sys/types.h>   // for fd_set

#include <termios.h>

Different-sized network address info for IPv4 addresses

As a kind of sanity check on what was going on, I had an assert that for an IPv4 address:

assert(req.addrinfo->ai_addrlen == 16);

But for whatever reason this isn't true on Haiku, it has seemingly extra space...that you can ignore. It's voodoo to me. I changed the assert:

assert(req.addrinfo->ai_addrlen >= 16);

Anyway, Gave Up on the C++98 Build

It was an interesting trick to use the super old compiler to build Ren-C. But it's no longer necessary, and I think TCC represents a better choice for a minimal target--more likely to be applicable to strange embedded platforms than Haiku's old compiler.

2 Likes