How to compile a 32-bit binary on a 64-bit linux machine with gcc/cmake
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.
dala
Updated on July 18, 2022Comments
-
dala almost 2 years
Is it possible to compile a project in 32-bit with
cmake
andgcc
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.-
dala over 14 yearsWould it be sufficient to pass the flag -m32 to gcc? How would I then do that in cmake?
-
maxschlepzig over 6 yearsPossible duplicate of The proper way of forcing a 32-bit compile using CMake
-
-
Fredrik over 14 yearsFeels 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 over 14 yearsGreat thanks! Yes, I do have 32-bit versions of the dependencies.
-
Dirk Eddelbuettel over 14 yearsIt 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 over 14 yearsI 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 over 14 yearsFrederik, do you also deploy them in 32 bit on the 64 bit build host?
-
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 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 over 14 years@Fredrik: I don't deploy any anything in /usr/bin which doesn't come from the distribution.
-
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 over 10 yearsWell, the problem is that this is of course not necessarily enough. You may need to tweak the linker, too!
-
ojblass over 10 yearsAs 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 over 8 yearsWhat does
export
mean? Where does it belong? Te header files? Themakefile
? Nope, totally not an answer for me as a beginner. -
Tomáš Zato over 8 yearsHow can I install 32bit versions of the libraries?
-
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 usingmake
instead). -
Tomáš Zato over 8 yearsWell, 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 over 8 yearsinteresting. Can I use it to compile
atom
text editor for 32bit in 64bit machine? -
Sam Watkins over 8 years@Anwar, I guess so. It should work to build anything.
-
Bulat M. over 7 years@caf, could you please elaborate on your answer? Your answer is very terse and does explain nothing.
-
Kingo almost 7 years@TomášZato
sudo apt-get install gcc-multilib
-
dyomas over 6 years… to do it globally:
cmake -D CMAKE_CXX_FLAGS=-m32 . && make