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

172,275

Solution 1

export CFLAGS=-m32

Solution 2

$ 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)

Solution 3

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.

Solution 4

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.

Solution 5

For C++, you could do:

export CXXFLAGS=-m32

This works with cmake.

Share:
172,275
dala
Author by

dala

Updated on July 18, 2022

Comments

  • dala
    dala almost 2 years

    Is it possible to compile a project in 32-bit with cmake and gcc on a 64-bit system? It probably is, but how do I do it?

    When I tried it the "ignorant" way, without setting any parameters/flags/etc, just setting LD_LIBRARY_PATH to find the linked libraries in ~/tools/lib it seems to ignore it and only look in subdirectories named lib64.

  • Fredrik
    Fredrik over 14 years
    Feels a bit extreme to setup a chroot environment just to build 32-bit apps, doesn't it? Any particular reason why you recommend that?
  • dala
    dala over 14 years
    Great thanks! Yes, I do have 32-bit versions of the dependencies.
  • Dirk Eddelbuettel
    Dirk Eddelbuettel over 14 years
    It gives you a complete environment in which to also run code. We use that to build (and run) full 32 bit binaries on 64 bit hosts -- sometimes you only get 32 bit builds of third party libraries. For Debian work, we use it to build 32 bit packages on 64 bit hosts.
  • Fredrik
    Fredrik over 14 years
    I have never experienced any problems what so ever building and running full 32-bit binaries on neither linux, Solaris nor any other 64-bit platform. But I am not using Debian much.
  • Dirk Eddelbuettel
    Dirk Eddelbuettel over 14 years
    Frederik, do you also deploy them in 32 bit on the 64 bit build host?
  • Fredrik
    Fredrik over 14 years
    @Dirk: the 32 bit binaries work on both 32 and 64 bit machines (of course), the 64 bit binaries only works on 64 bit machines. It doesn't matter if it is a customer machine or a build host. I honestly don't see where the problem would be unless it is kernel modules you are building.
  • Fredrik
    Fredrik over 14 years
    @Dirk: I think I just understood your issue... You want to deploy your 32-bit apps in something like /usr/bin just like you would have done on a pure 32-bit machine? In my world that's just bad, I need things to be able to coexist with previous versions and other architectures so that is not a problem I ever face.
  • AProgrammer
    AProgrammer over 14 years
    @Fredrik: I don't deploy any anything in /usr/bin which doesn't come from the distribution.
  • edwardw
    edwardw almost 13 years
    +1. I'm trying to build 32-bit taglib(developer.kde.org/~wheeler/taglib.html) on a 64-bit snow leopard. This works for me.
  • László Papp
    László Papp over 10 years
    Well, the problem is that this is of course not necessarily enough. You may need to tweak the linker, too!
  • ojblass
    ojblass over 10 years
    As a curiosity where do you deploy stuff that doesn't come from the distribution? I tend to use opt but I am not exactly sure why.
  • Tomáš Zato
    Tomáš Zato over 8 years
    What does export mean? Where does it belong? Te header files? The makefile? Nope, totally not an answer for me as a beginner.
  • Tomáš Zato
    Tomáš Zato over 8 years
    How can I install 32bit versions of the libraries?
  • caf
    caf over 8 years
    @TomášZato: At the shell prompt, before invoking cmake (however in your case, if you have a Makefile, then you would be using make instead).
  • Tomáš Zato
    Tomáš Zato over 8 years
    Well, this indeed launched 32bit build however it can't even fetch 32bit version of standard libraries... I'm sorry, but I'm really used to much longer answers on broad questions such as this one.
  • Anwar
    Anwar over 8 years
    interesting. Can I use it to compile atom text editor for 32bit in 64bit machine?
  • Sam Watkins
    Sam Watkins over 8 years
    @Anwar, I guess so. It should work to build anything.
  • Bulat M.
    Bulat M. over 7 years
    @caf, could you please elaborate on your answer? Your answer is very terse and does explain nothing.
  • Kingo
    Kingo almost 7 years
    @TomášZato sudo apt-get install gcc-multilib
  • dyomas
    dyomas over 6 years
    … to do it globally: cmake -D CMAKE_CXX_FLAGS=-m32 . && make