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 ou开发者_高级运维tput
/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.
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.
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
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...
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.
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.
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
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.
精彩评论