简体   繁体   中英

How to compile glibc 32bit on an x86_64 machine

I'm trying to compile glibc (as a secondary, not a system replacement) 2.6 on an x86_64, and trying to get it to produce 32-bit objects. When I give it a standard configure, it compiles fine, producing the usual 64-bit library objects. Some info:

 $ uname -a Linux localhost.localdomain 2.6.18-164.11.1.el5 #1 SMP Wed Jan 20 07:32:21 \\ EST 2010 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/redhat-release CentOS release 5.4 (Final) 

Among other things, I've tried the following:

Attempt 1:

 $ # [in build/glibc-2.6] $ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \\ --with-cpu=i386-pc-linux-gnu ... checking sysdep dirs... configure: error: The i386-pc-linux-gnu subspecies of x86_64 is not supported." 

Attempt 2:

 $ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \\ --host=i386-pc-linux-gnu ... $ make 

The configure succeeds, but make causes a stream of compilation errors which all look like this:

 nptl/sysdeps/i386/tls.h:65:3: error: #error "TLS support is required." In file included from include/tls.h:6, from sysdeps/unix/sysv/linux/i386/sysdep.h:30, from <stdin>:1: 

I get the same result if I add --with-tls, and/or --target=i386-pc-linux-gnu.

[EDIT: It looks like I was confusing --target for --build. I tried adding --build=i386-pc-linux-gnu instead, and also for all of the other attempts where I tried --target. In all cases, I got exactly the same result as before.]

Attempt 3:

 $ CFLAGS=-m32 \\ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \\ --host=i386-pc-linux-gnu \\ ... In file included from ./../include/libc-symbols.h:55, from <command line>:1: /home/USER/build/glibc32-2.6/config.h:3:3: error: #error "glibc cannot be \\ compiled without optimization" 

Again, the same thing happens with --with-tls

Attempt 4:

 $ CFLAGS="-m32 -O2" \\ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \\ --host=i386-pc-linux-gnu \\ ... gcc ../sysdeps/unix/sysv/linux/i386/sysdep.S -c -I../include \\ -I/home/USER/build/glibc32-2.6/csu \\ -I/home/USER/build/glibc32-2.6 -I../sysdeps/i386/elf \\ -I../nptl/sysdeps/unix/sysv/linux/i386 \\ -I../sysdeps/unix/sysv/linux/i386 \\ -I../nptl/sysdeps/unix/sysv/linux \\ -I../nptl/sysdeps/pthread -I../sysdeps/pthread \\ -I../sysdeps/unix/sysv/linux -I../sysdeps/gnu \\ -I../sysdeps/unix/common -I../sysdeps/unix/mman \\ -I../sysdeps/unix/inet -I../sysdeps/unix/sysv/i386 \\ -I../nptl/sysdeps/unix/sysv -I../sysdeps/unix/sysv \\ -I../sysdeps/unix/i386 -I../nptl/sysdeps/unix \\ -I../sysdeps/unix -I../sysdeps/posix \\ -I../sysdeps/i386/fpu -I../nptl/sysdeps/i386 \\ -I../sysdeps/i386 -I../sysdeps/wordsize-32 \\ -I../sysdeps/ieee754/ldbl-96 \\ -I../sysdeps/ieee754/dbl-64 \\ -I../sysdeps/ieee754/flt-32 -I../sysdeps/ieee754 \\ -I../sysdeps/generic/elf -I../sysdeps/generic \\ -I../nptl -I.. -I../libio -I. \\ -D_LIBC_REENTRANT -include ../include/libc-symbols.h \\ -DHAVE_INITFINI -DASSEMBLER \\ -I/home/USER/build/glibc32-2.6/csu/. -DGAS_SYNTAX \\ -Wa,--noexecstack \\ -o /home/USER/build/glibc32-2.6/csu/sysdep.o \\ -MD -MP \\ -MF /home/USER/build/glibc32-2.6/csu/sysdep.o.dt \\ -MT /home/USER/build/glibc32-2.6/csu/sysdep.o ../sysdeps/unix/i386/sysdep.S: Assembler messages: ../sysdeps/unix/i386/sysdep.S:51: Error: @NTPOFF reloc is not supported \\ with 64-bit output format ../sysdeps/unix/i386/sysdep.S:51: Error: junk `@NTPOFF' after expression 

I feel like this should be easier. Am I missing something?

If you need any more information, let me know and I'll provide it.

[EDIT]

Attempt 5 (suggested by EmployedRussian)

 $ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \\ CC="gcc -m32" CXX="g++ -m32" i686-linux-gnu ... gcc -m32 -nostdlib -nostartfiles -shared \\ -o /home/USER/build/glibc32-2.6/elf/ld.so -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -Wl,-z,defs /home/USER/build/glibc32-2.6/elf/librtld.os \\ -Wl,--version-script=/home/USER/build/glibc32-2.6/ld.map \\ -Wl,-soname=ld-linux.so.2 \\ -T /home/USER/build/glibc32-2.6/elf/ld.so.lds /home/USER/build/glibc32-2.6/elf/librtld.os: In function `add_dependency': /home/USER/src/glibc-2.6/elf/dl-lookup.c:106: undefined reference to `__sync_fetch_and_add_4' /home/USER/src/glibc-2.6/elf/dl-lookup.c:110: undefined reference to `__sync_val_compare_and_swap_4' /home/USER/build/glibc32-2.6/elf/librtld.os: In function `_dl_profile_fixup': /home/USER/src/glibc-2.6/elf/dl-runtime.c:196: undefined reference to `__sync_val_compare_and_swap_4' /home/USER/src/glibc-2.6/elf/dl-runtime.c:205: undefined reference to `__sync_fetch_and_add_4' /home/USER/build/glibc32-2.6/elf/librtld.os: In function `_dl_fixup': /home/USER/src/glibc-2.6/elf/dl-runtime.c:102: undefined reference to `__sync_val_compare_and_swap_4' /home/USER/src/glibc-2.6/elf/dl-runtime.c:110: undefined reference to `__sync_fetch_and_add_4' /home/USER/build/glibc32-2.6/elf/librtld.os: In function `dl_open_worker': /home/USER/src/glibc-2.6/elf/dl-open.c:425: undefined reference to `__sync_val_compare_and_swap_4' /home/USER/src/glibc-2.6/elf/dl-open.c:427: undefined reference to `__sync_fetch_and_add_4' /home/USER/build/glibc32-2.6/elf/librtld.os: In function `_dl_close_worker': /home/USER/src/glibc-2.6/elf/dl-close.c:407: undefined reference to `__sync_val_compare_and_swap_4' /home/USER/src/glibc-2.6/elf/dl-close.c:409: undefined reference to `__sync_fetch_and_add_4' collect2: ld returned 1 exit status make[2]: *** [/home/USER/build/glibc32-2.6/elf/ld.so] Error 1 make[2]: Leaving directory `/home/USER/src/glibc-2.6/elf' make[1]: *** [elf/subdir_lib] Error 2 make[1]: Leaving directory `/home/USER/src/glibc-2.6' make: *** [all] Error 2 

This time the build runs successfully for a long time before it reaches an error. I did a search and found something suggesting that I add a "-march" flag, which I did. This finally worked:

Attempt 6:

 $ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \\ CC="gcc -m32" CXX="g++ -m32" \\ CFLAGS="-O2 -march=i686" \\ CXXFLAGS="-O2 -march=i686" \\ i686-linux-gnu 

Thanks everyone!

I edited the question, but then I realized the proper way is to add an answer. Here's what finally worked:

 $ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \
     --host=i686-linux-gnu \
     --build=i686-linux-gnu \
     CC="gcc -m32" CXX="g++ -m32" \
     CFLAGS="-O2 -march=i686" \
     CXXFLAGS="-O2 -march=i686"

I think putting -m32 in CC and CXX instead of CFLAGS and CXXFLAGS was important because there was at least one compile operation during the make which didn't use CFLAGS or CXXFLAGS, and -m32 absolutely has to always be there. Not sure why -march=i686 was necessary (given the -m32 parts and the --host/build options), but it was.

The following works for me:

../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \
 CC="gcc -m32" CXX="g++ -m32" i686-linux-gnu

Three important ./configure flags:

  • --build= The system performing the build. Looks like yours is x86_64-pc-linux-gnu .
  • --host= The system on which the generated objects will be used. You want to set this to i386-pc-linux-gnu .
  • --target= If you are building a compiler, the system for which the built compiler will generate objects.

To perform a cross-compile, you must specify both --build= and --host= . When you only specify --host= , it will still attempt to build a native ( x86_64 ) glibc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM