133

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.

Szabolcs Dombi
  • 5,493
  • 3
  • 39
  • 71
dala
  • 1,975
  • 3
  • 14
  • 15
  • 1
    Would it be sufficient to pass the flag -m32 to gcc? How would I then do that in cmake? – dala Aug 13 '09 at 14:46
  • Possible duplicate of [The proper way of forcing a 32-bit compile using CMake](https://stackoverflow.com/questions/5805874/the-proper-way-of-forcing-a-32-bit-compile-using-cmake) – maxschlepzig Dec 29 '17 at 14:18

7 Answers7

128
export CFLAGS=-m32
caf
  • 233,326
  • 40
  • 323
  • 462
  • 2
    It should do. You could also modify the cmake script to create a 32 bit target - it would just add `-m32` to the `CFLAGS`, probably by setting `CMAKE_REQUIRED_FLAGS`. – caf Aug 13 '09 at 22:55
  • 5
    Well, the problem is that this is of course not necessarily enough. You may need to tweak the linker, too! – László Papp Nov 19 '13 at 11:03
  • 6
    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 Sep 29 '15 at 10:09
  • 1
    @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). – caf Sep 29 '15 at 11:55
  • 1
    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. – Tomáš Zato Sep 29 '15 at 12:38
  • 4
    @caf, could you please elaborate on your answer? Your answer is very terse and does explain nothing. – Bulat M. Oct 02 '16 at 10:57
79
$ 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)

andri
  • 11,171
  • 2
  • 38
  • 49
17

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.

Nathan Monteleone
  • 5,430
  • 29
  • 43
  • +1. I'm trying to build 32-bit taglib(http://developer.kde.org/~wheeler/taglib.html) on a 64-bit snow leopard. This works for me. – edwardw Jul 16 '11 at 17:05
  • 3
    … to do it globally: `cmake -D CMAKE_CXX_FLAGS=-m32 . && make` – dyomas Sep 07 '17 at 14:28
8

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.

Sam Watkins
  • 7,819
  • 3
  • 38
  • 38
8

For C++, you could do:

export CXXFLAGS=-m32

This works with cmake.

euccas
  • 755
  • 9
  • 13
6

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

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • 2
    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? – Fredrik Aug 13 '09 at 14:48
  • 3
    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. – Dirk Eddelbuettel Aug 13 '09 at 14:51
  • 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. – Fredrik Aug 13 '09 at 16:05
  • Frederik, do you also deploy them in 32 bit on the 64 bit build host? – Dirk Eddelbuettel Aug 13 '09 at 16:21
  • @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 Aug 13 '09 at 16:42
  • @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. – Fredrik Aug 13 '09 at 17:24
  • @Fredrik: I don't deploy any anything in /usr/bin which doesn't come from the distribution. – AProgrammer Aug 14 '09 at 11:53
  • 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. – ojblass Dec 20 '13 at 18:29
0

Let's not forget to install the 32 bit libraries (C or C++)

sudo apt install gcc-multilib
sudo apt install g++-multilib

Then use the -m32 flag

gcc -o a.out -m32 my_program.c

or

g++ -o a.out -m32 my_program.cpp
Olivier Lasne
  • 679
  • 6
  • 12