Ubuntu – Building a 32-bit app in 64-bit Ubuntu

64-bitgcc

After hours of googling, I decide to give up and ask you experts. I am trying to build a 32-bit application (xgap if anyone interested) in my 64 Ubuntu 11.10. I added the CFLAGS=-m32 and the LDFLAGS=-L/usr/lib32 in the makefile. The objects are built into 32 bit fine. The last step is to link all the objects and libraries for X windows into this executable—xgap. Somehow it keeps giving me this error:

gcc -o xgap xcmds.o utils.o gapgraph.o gaptext.o pty.o popdial.o xgap.o selfile.o   -L/usr/lib32 -lXaw -lXmu -lXt -lXext -lX11  -lSM -lICE

/usr/bin/ld: skipping incompatible /usr/lib32/libXmu.so when searching for -lXmu
...

/usr/bin/ld: i386 architecture of input file `xcmds.o' is incompatible with i386:x86-64 output
...

I have installed ia32-libs and mutilib support. I think I just need to force the linker to generate a i386 output. I tried to put two ld flags in my gcc command as shown above: -melf_i386 and -oformat elf32-i386. But what happens is that gcc doesn't search for the 32 bit library in /usr/lib32 anymore. I wonder if I need to put those flags in some fixed order?

Thanks for any idea and help!

EDIT: when I add the -m32 flag in my last gcc command (the linking stage I believe), even if I have the -L/usr/lib32 flag in place, gcc doesn't search in /usr/lib32 anymore ( really weird…) and generates the following error:

/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../libXaw.so when searching for -lXaw
/usr/bin/ld: skipping incompatible /usr/lib/libXaw.so when searching for -lXaw
/usr/bin/ld: cannot find -lXaw
collect2: ld returned 1 exit status

Any one has any idea why this happens? I am using the auto tool to configure and make. I am really good at modifying those script files.

EIDT:I solved the problem. I think that gcc was expecting a static library archive. I used the getlibs script from http://ubuntuforums.org/showthread.php?t=474790 to download all the .a archives needed for linking. Then gcc worked. I think gcc did search in /usr/lib32 directory but didn't find the .a archives so went on to search in the standard directory which is /usr/lib, where it finds the incompatible *.so files.

But then the question is: the *.so files in /usr/lib32/ from package ia32-libs doesn't really have the libraries needed for linking? What are those files in /usr/lib32/ used for?

Best Answer

LDFLAGS should include -m32 as well. Following should work:

export LDFLAGS='-m32 -L/usr/lib32'

In fact, you can drop -L/usr/lib32 part, since this is a default directory for 32bit libs, and your system is aware about that.

Basically, the simplest way to build 32bit application on 64bit machine is:

export CFLAGS='-m32'
export CXXFLAGS='-m32'
export LDFLAGS='-m32'
make

..or feed those variables to configure script if you're using autotools.

UPDATE:

Seems like you are not really familiar about the differences in linking with static and dynamic libraries. I'll try to be as minimal as possible:

  • Both static and dynamic development libraries have the same file extension .a
  • If you have installed both static and dynamic versions of the same library, one of them might have additional postfix, like libname.a for dynamic and libname_s.a for static version.
  • Sure, static and dynamic library versions differs in size. Static version is heavier.
  • If you link with static library - your application has no dependencies. If you link with dynamic library, it will rely on .so runtime library that should be present in your system.

Please note, we are not talking about advanced tricks here, like explicit loading of DSO's using the dlopen()/dlsym() API.