Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compile a 32-bit binary on a 64-bit linux machine with gcc/cmake

People also ask

How do I compile 32 bit programs on 64 bit gcc?

Now in order to compile with 32-bit gcc, just add a flag -m32 in the command line of compiling the 'C' language program. For instance, to compile a file of geek. c through Linux terminal, you must write the following command with -m32 flag. After that you will be able to compile a 32-bit binary on a 64-bit system.

How can I tell if gcc is 32 or 64 bit?

To check this, we have to type this command. gcc –v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu ........... ........... ...........

What is gcc m32?

The -m32 flag tells GCC to compile in 32-bit mode.

What is gcc Multilib?

gcc-multilib is useful for cross-compiling, that is, compiling a program to run on a different processor architecture. For example, you would need gcc-multilib if you are running on 64-bit Ubuntu and want to compile a program to run on 32-bit Ubuntu (or on ARM etc. you get the idea).


export CFLAGS=-m32

$ gcc test.c -o testc
$ file testc
testc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ ldd testc 
    linux-vdso.so.1 =>  (0x00007fff227ff000)
    libc.so.6 => /lib64/libc.so.6 (0x000000391f000000)
    /lib64/ld-linux-x86-64.so.2 (0x000000391ec00000)
$ gcc -m32 test.c -o testc
$ file testc
testc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ ldd testc
    linux-gate.so.1 =>  (0x009aa000)
    libc.so.6 => /lib/libc.so.6 (0x00780000)
    /lib/ld-linux.so.2 (0x0075b000)

In short: use the -m32 flag to compile a 32-bit binary.

Also, make sure that you have the 32-bit versions of all required libraries installed (in my case all I needed on Fedora was glibc-devel.i386)


In later versions of CMake, one way to do it on each target is:

set_target_properties(MyTarget PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")

I don't know of a way to do it globally.


For any complex application, I suggest to use an lxc container. lxc containers are 'something in the middle between a chroot on steroids and a full fledged virtual machine'.

For example, here's a way to build 32-bit wine using lxc on an Ubuntu Trusty system:

sudo apt-get install lxc lxc-templates
sudo lxc-create -t ubuntu -n my32bitbox -- --bindhome $LOGNAME -a i386 --release trusty
sudo lxc-start -n my32bitbox
# login as yourself
sudo sh -c "sed s/deb/deb-src/ /etc/apt/sources.list >> /etc/apt/sources.list"
sudo apt-get install devscripts
sudo apt-get build-dep wine1.7
apt-get source wine1.7
cd wine1.7-*
debuild -eDEB_BUILD_OPTIONS="parallel=8" -i -us -uc -b
shutdown -h now   # to exit the container

Here is the wiki page about how to build 32-bit wine on a 64-bit host using lxc.


For C++, you could do:

export CXXFLAGS=-m32

This works with cmake.


One way is to setup a chroot environment. Debian has a number of tools for that, for example debootstrap