How to Compile 32-bit Apps on 64-bit Ubuntu?

This is known to work on Ubuntu 16.04 through 22.04:

sudo apt install gcc-multilib g++-multilib

Then a minimal hello world:

main.c

#include <stdio.h>

int main(void) {
    puts("hello world");
    return 0;
}

compiles without warning with:

gcc -m32 -ggdb3 -O0 -pedantic-errors -std=c89 \
  -Wall -Wextra -pedantic -o main.out main.c

And

./main.out

outputs:

hello world

And:

file main.out

says:

main.out: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=87c87a83878ce7e7d23b6236e4286bf1daf59033, not stripped

and:

qemu-i386 main.out

also gives:

hello world

but fails on an x86_64 executable with:

./main.out: Invalid ELF image for this architecture

Furthermore, I have:

So I think it works 🙂

See also: Cannot find crtn.o, linking 32 bit code on 64 bit system

It is a shame that this package conflicts with the cross compilers like gcc-arm-linux-gnueabihf https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211

Running versions of the question:

We are able to run 32-bit programs directly on 64-bit Ubuntu because the Ubuntu kernel is configured with:

CONFIG_IA32_EMULATION=y

according to:

grep CONFIG_IA32_EMULATION "/boot/config-$(uname -r)"

whose help on the kernel source tree reads:

Include code to run legacy 32-bit programs under a
64-bit kernel. You should likely turn this on, unless you're
100% sure that you don't have any 32-bit programs left.

This is in turn possible because x86 64 bit CPUs have a mode to run 32-bit programs that the Linux kernel uses.

TODO: what options does gcc-multilib get compiled differently than gcc?

Leave a Comment