Как скомпилировать glibc 32bit на машине x86_64
Я пытаюсь скомпилировать glibc (как вторичную, а не замену системы) 2.6 на x86_64 и пытаться получить ее для создания 32-битных объектов. Когда я даю ему стандартную конфигурацию, она компилируется отлично, создавая обычные 64-битные объекты библиотеки. Некоторая информация:
$ 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)
Помимо прочего, я пробовал следующее:
Попытка 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."
Попытка 2:
$ ../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \
--host=i386-pc-linux-gnu
...
$ make
Конфигурация завершается успешно, но make
вызывает поток ошибок компиляции, которые выглядят следующим образом:
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:
Я получаю тот же результат, если я добавлю --with-tls и/или --target = i386-pc-linux-gnu.
[EDIT: Похоже, я сбивал с толку - собираю для --build. Я попытался добавить --build = i386-pc-linux-gnu вместо этого, а также для всех других попыток, которые я пытался --target. Во всех случаях я получил точно такой же результат, как раньше.]
Попытка 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"
Опять же, то же самое происходит с --with-tls
Попытка 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
Я чувствую, что это должно быть проще. Я что-то пропустил?
Если вам нужна дополнительная информация, дайте мне знать, и я предоставлю ее.
[EDIT]
Попытка 5 (предложенная 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
На этот раз сборка выполняется успешно в течение длительного времени, прежде чем она достигнет ошибки. Я сделал поиск и нашел что-то, предлагая добавить флаг "-march", который я сделал. Это, наконец, сработало:
Попытка 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
Спасибо всем!
Ответы
Ответ 1
Я редактировал вопрос, но потом я понял, что правильный способ - добавить ответ. Вот что, наконец, сработало:
$ ../../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"
Я думаю, что ставить -m32
в CC и CXX вместо CFLAGS и CXXFLAGS было важно, потому что во время make, который не использовал CFLAGS или CXXFLAGS, была, по крайней мере, одна операция компиляции, и -m32
абсолютно всегда должно быть там, Не уверен, почему -march=i686
был необходим (с учетом частей -m32
и опций --host/build
), но это было.
Ответ 2
Для меня работает следующее:
../../src/glibc-2.6/configure --prefix=$HOME/glibc32-2.6 \
CC="gcc -m32" CXX="g++ -m32" i686-linux-gnu
Ответ 3
Три важных флага ./configure
:
-
--build=
Система, выполняющая сборку. Похоже, у вас x86_64-pc-linux-gnu
.
-
--host=
Система, в которой будут использоваться сгенерированные объекты. Вы хотите установить значение i386-pc-linux-gnu
.
-
--target=
Если вы строите компилятор, система, для которой встроенный компилятор будет генерировать объекты.
Чтобы выполнить кросс-компиляцию, вы должны указать как --build=
, так и --host=
. Когда вы укажете только --host=
, он все равно попытается создать встроенный (x86_64
) glibc.