Building 32-bit/i386 binaries on x86-64 Fedora

x86-64 Linux distributions have adopted different approaches to handling compatibility with 32-bit i386 binaries, depending on whether seamless compatibility or support for a pure 64-bit installation was the priority. Fedora falls on the seamless compatibility side. This means that you can install binaries built for Fedora i386 onto a Fedora x86-64 system, and they generally just work. What seems to be less well known is that you can easily build for i386 on a Fedora x86-64 system. I had to search around a bit to find the necessary option. But once you know the secret, it is very straightforward.

Why would you want to build for i386 on an x86-64 system? My motivation was developing software that I wanted to build and test for both platforms, without having to run two development machines. Another potential reason is the slight performance advantage that some applications enjoy on i386 (pointers are 32-bits, so some data structures are smaller, so processor caches are more effective).

The trick is the -m32 flag to gcc:

$ cat >hello.c
#include <stdio.h>

int main(void)
        printf("Hello, world!\n");
        return 0;
$ gcc -m32 hello.c -o hello
$ file ./hello
./hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically l
inked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ ./hello 
Hello, world!

It can also be used when building a package with a autoconf configure script or similar. This worked for FreeCiv:

$ CFLAGS="-m32" ./configure

Fedora usually installs both the 32-bit and 64-bit versions of each library package, including the -devel packages. There are some exceptions: My system had cairo-devel.x86-64, but not cairo-devel.i386. But such things are easy to fix.