18

I'm using autotools to build my system, which consists primarily of a library. On 64-bit Red Hat platforms, I need to be able to produce a library capable of working on 32-bit Red Hat platforms.

When I add -m32 to the compile lines everything works fine to produce a static (.a) library, but as soon as I try to create a shared-library, I get error like this:

/usr/bin/ld: warning: i386:x86-64 architecture of input file `/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o' is incompatible with i386 output
/usr/bin/ld: warning: i386:x86-64 architecture of input file `/usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbeginS.o' is incompatible with i386 output  
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbeginS.o: In function `__do_global_dtors_aux':  
crtstuff.c:(.text+0x29): undefined reference to `__DTOR_END__'  
collect2: ld returned 1 exit status' 

I can see the problem is that it's including 64-bit object files out of /usr/lib64 instead of the correct 32-bit ones out of /usr/lib (they're there alright), but I can't figure out how to fix it.

Kevdog777
  • 908
  • 7
  • 20
  • 43
John Gordon
  • 2,576
  • 3
  • 24
  • 29
  • this thread has some ideas http://www.mail-archive.com/libtool@gnu.org/msg11662.html – osgx Aug 04 '11 at 01:30
  • You're getting the wrong crti.o See [this previous question about inspecting the include path](http://stackoverflow.com/questions/91576/crti-o-file-missing). Are you sure you have a 32-bit crti.o in your library path? (And that it's present in the path before the 64-bit version occurs.) – Conspicuous Compiler Aug 18 '11 at 12:50
  • As far as I can tell the include path is built into the compiler/linker. Since I want to build either 32 or 64-bit versions depending on arguments to the autotools configure script, rebuilding the tools isn't an option. I also need this to work on my clients machines. – John Gordon Aug 19 '11 at 17:15
  • 1
    Do you actually have the 32-bit glibc-devel installed? – jørgensen Dec 19 '11 at 15:42

7 Answers7

15

First, make sure you have compiler/libc support for 32-bit compilation. In some distros like Ubuntu, what you need to do is install packages gcc-multilib and/or g++-multilib:

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

Then, when calling configure, specify a 32-bit host and pass 32-bit compilation flags:

./configure --host=i686-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"

If you do not have multilib installed, you will get an error like configure: error: C compiler cannot create executables when passing the -m32 flag.

volpato
  • 1,262
  • 17
  • 21
4

I had this problem on RHEL6. This worked

./configure --host=i386-redhat-linux --build=i386-redhat-linux "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" "LTCC=gcc -m32"

LTCC=gcc -m32 was the magic incantation needed to get libtool to build library 32 bit

1

I've had this same problem. But I don't use autotools. Then, in the Makefile edited by hand, I noticed that in line

$(CC) -shared -Wl,-soname,lib$(NAME).so.0 -o lib$(NAME).so.$(VERSION) $(OBJ)

there was no option to gcc that indicates the 32bit architeture. Once my CFLAGS has already the option -m32, I decided to put it in the line mentioned above:

$(CC) $(CFLAGS) -shared -Wl,-soname,lib$(NAME).so.0 -o lib$(NAME).so.$(VERSION) $(OBJ)

and voilà. It works!

So, in autotools, maybe setting CFLAGS variable to include -m32 option works for you too.

Hope I have helped...

  • I would love to verify if the works for me, but since I asked this question, the program has pretty much wound down and I've switched companies. – John Gordon Sep 10 '13 at 15:35
0

The GNU linker flag to build a 32 bit shared object on a 64 bit machine is: -m elf_i386 So please e.g. write in the Makefile:

LDFLAGS=-m elf_i386
Taryn
  • 242,637
  • 56
  • 362
  • 405
  • 1
    Sorry, but I can't even try it anymore. I gave up and ripped out all references to this from my makefiles quite a while ago. I require 32-bit builds be performed on 32-bit platforms, and no one seemed to find that unreasonable. – John Gordon Jul 24 '12 at 13:39
  • The question is about autotools. How can this be done when using autotools? – Craig McQueen Jul 17 '13 at 23:47
0

A quick fix....

Build application on a different PC with 32 bit linux and transfer the resulted application files ( library, etc) to the desired 64 bit linux machine. See if it works. It worked for me.

0

Would you try:

CFLAGS=-m32 -Wl,-m32
CXXFLAGS=-m32 -Wl,-m32
LDFLAGS=-m32

in your makefile, since some scripts try linking using gcc or g++ instead of ld as we expect?

Update: In case you manually modifying every gcc/g++ call, just try use -m32 -Wl,-m32 instead of simple -m32 as additional option.

shr
  • 525
  • 4
  • 7
  • I get the same result. The linking is performed by a libtool, a script generated by the autotools configure script, that doesn't seem to use the *FLAGS variables in the makefiles. – John Gordon Aug 19 '11 at 13:40
  • (1) I found someone suggests LDFLAGS="-m32 -L/usr/lib" ( [http://www.mail-archive.com/autoconf@gnu.org/msg16323.html] ). (2) But it would be much desirable if your configure script correctly generate scripts with --host option: (e.g.: ./configure --host i686-redhat-linux ) – shr Aug 19 '11 at 14:33
  • I tried feeding the configure script variations of the cross compilation flags using -host ect., and I found that the autotools expects cross compilation to be accomplished by installing different compilers for each target platform. – John Gordon Aug 19 '11 at 15:53
  • To make a long story short, I've fetched libiconv-1.14.bz2 and succeed to build `ELF 32-bit LSB shared object` in Centos 5.6 x86_64, using following command: `CC="gcc -m32" sh configure && make` . I wish this will help you. – shr Aug 19 '11 at 18:56
  • The question is about autotools. How can this be done when using autotools? – Craig McQueen Jul 17 '13 at 23:46
0

I've had this same problem: Running on an Ubuntu 64-bit machine, I managed to compile and link for 32-bit hosts using export CFLAGS=-m32; ./configure --host=i386, but libtool would still generate a 64-bit shared library.

I worked around this by creating a 32-bit build environment and chrooting into it. Ubuntu makes this easy via debootstrap.

Grodriguez
  • 21,501
  • 10
  • 63
  • 107