Is it possible to compile i386 (32-Bit) binary on a x86_64 (64-Bit) Haiku system?

I’m running a 64-Bit (x86_64) Haiku system and I wonder if I can cross-compile 32-Bit (i386) binaries.

Using the -m32 option of GCC doesn’t seem to work:

gcc -Ilib/include -std=gnu99 -Wall -m32 -O3 -DNDEBUG main.o -o bin/program -lpthread
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: skipping incompatible /boot/system/develop/lib/libpthread.a when searching for -lpthread
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: cannot find -lpthread
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: skipping incompatible /boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/libgcc.a when searching for -lgcc
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: cannot find -lgcc
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: skipping incompatible /boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/libgcc_s.so.1 when searching for libgcc_s.so.1
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: cannot find libgcc_s.so.1
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: skipping incompatible /boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/libgcc.a when searching for -lgcc
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: cannot find -lgcc
collect2: error: ld returned 1 exit status
Makefile:120: recipe for target failed
make: *** [frontend/bin] Error 1

Is there any other way, or do I really need to have a separate 32-Bit install?

Thank you!

On 64-Bit Linux, I can install a package like crossbuild-essential-i386.
This gives me a separate “cross-compiler” variant of GCC that I can use to build for 32-Bit (i686) target:

i686-linux-gnu-gcc

But on Haiku, it appears that there is no gcc-x86 package (or similar) that I can install in 64-Bit system.

Or am I overlooking something? Thank you!

Multi-lib configuration is not yet supported (and maybe it won’t ever) on Haiku. The normal GCC package from the depot can only produce executables for the main architecture.

Thank you for the information.

If “multilib” isn’t supported, then maybe “multiarch” could be supported?

I am not entirely sure how it is solved on other OS (i only recall it seemed to be a huge hack, which needed a second set of libraries and headers, and a target specific compiler).

If you build x86 Haiku on 64 bit Haiku, you have to use the buildtools repo, which is essentially a crosscompiler, which targets 32 bit. MAybe that’s what you are searching for.
The buildtools compiler is not available in the Depot, you have to build it.

It is possible to crosscompile with Clang, but you need all dependency libraries for target architecture and manually set include/library paths.

This is the easiest way. You can use a 32 bit Haiku hosted in qemu for example.

I plan to add ability to install and run binaries of any architecture by using UserlandVM. Non-native packages can be installed as secondary architecture.

2 Likes

If it can be used to build normal “user land” programs for 32-Bit target on 64-it system, then it would be a great option, I think And we don’t have to keep separate 32-Bit system.

Okay, I will give this a try.

I dont think it is that easy, if the program needs external libs.

But why dont you publish the sources and write a recipe to let the buildbots build the program for every arch?

I don’t need “external” libs, only the basic C runtime and pthread library.

Publishing the sources is no problem, but “write a recipe to let the buildbots build the program” is beyond my knowledge at this point. I have quite some background in Linux, various BSDs (and macOS). On all these platforms, I just fire up my Makefile and that’s it - provided we have the “correct” GCC or Clang installed for the target platform. But, most important: For the Average Joe user, it is more convenient to just grab a pre-compiled binary, just as you would get it from your “native” package manager. So that is why I prefer to provide pre-compiled binaries for each supported platform (in addition to source code).

As said before, on Linux we can easily install “cross-build” version of GCC from the package manager, so I can build for x86_64, i686 and even aarch64 targets all from a single x86_64 machine. On FreeBSD, we can use -m32 and -m64 options of GCC to build for 32-Bit and 64-Bit systems from a single 64-Bit machine. And, on macOS, we can use -target option to build for x86_64 and aarch64 (Apple Silicon) from a single x86_64 MacBook. So, I was just hoping it would be somewhat similar on Haiku too :slight_smile:

(my favorite platform is GNU/Hurd, because no fancy stuff like 64-Bit or multiple-processor support!)

Here you can find info about the recipes and many examples:

This is exactly what the recipes are for.

Uh. I tought you were joking, but it seems they are still focusing on PDP8.

After several hours, the i586-pc-haiku-gcc has now been created from the sources! :+1:

Command used to build was:

./configure --cross-tools-source ../buildtools --build-cross-tools x86

But the resulting i586-pc-haiku-gcc fails to find the fundamental header file:

make -B CC=/boot/home/Desktop/haiku/generated/cross-tools-x86/bin/i586-pc-haiku-gcc

/boot/home/Desktop/haiku/generated/cross-tools-x86/bin/i586-pc-haiku-gcc -Ilib/include -std=gnu99 -Wall -O3 -DNDEBUG -c frontend/src/utils.c -o frontend/obj/utils.o
In file included from frontend/src/utils.h:9,
                 from frontend/src/utils.c:14:
frontend/src/platform.h:9:10: fatal error: stdlib.h: No such file or directory
    9 | #include <stdlib.h>
      |          ^~~~~~~~~~
compilation terminated.
Makefile:128: recipe for target 'frontend/obj/utils.o' failed

Any ideas?

As mentionned before in this thread: for this to work you need to provide the header files and libraries for the target architecture. You can’t go very far with just a compiler.

I see. Anyway, the required header files are there, somewhere in the generated/cross-tools-x86 directory. It’s just that the i586-pc-haiku-gcc binary doesn’t seem to be configured correctly to look for the headers in the right directory. I tried to explicitly add the directory where stdlib.h is located to the search path, with -I option, but it only resulted in additional errors. It seems like more “include” directories are needed, probably in a specific order. Not so easy to figure out. When I use cross-compiler like i686-linux-gnu-gcc on Linux machine, this binary “knows” how to find the headers for the target platform by itself. Can this be accomplished in Haiku system with the buildtools in a similar fashion?

At this point I have almost given up on the idea to cross-build for 32-Bit Haiku from 64-Bit Haiku system and will probably have to keep a separate 32-Bit system around. But Haiku has a package repository, where binary packages can be downloaded from (via pkgman tool). How do the package maintainers normally approach this? They always have to keep separate machines for providing 32-Bit and 64-Bit packages?

As mentionned above: we use haikuporter build servers. When we write a recipe and put it on the github repository, it is automatically compiled on our servers for all currently supported architectures. If there is a failure there, it can be fixed later in an update commit.

It is possible in theory but no one has written the needed procedure yet. So I don’t know how to do it.

Cross compiling isn’t specific to Haiku: using a sysroot with required headers and libs. This means unpacking packages, or copying their contents from a Haiku running image which also works.

1 Like

What about mounting them into the sysroot?

sure, but I never tried so I can’t help here.