Как скомпилировать 32-битный glibc на компьютере x86_64

#linux #glibc

#linux #glibc

Вопрос:

Я пытаюсь скомпилировать 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.

[РЕДАКТИРОВАТЬ: похоже, я перепутал —target для —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
  

Я чувствую, что это должно быть проще. Я что-то упускаю?

Если вам нужна дополнительная информация, дайте мне знать, и я ее предоставлю.

[ПРАВИТЬ]

Попытка 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 опции), но это было.

Комментарии:

1. Это сработало и для меня с glibc-2.10.0 (32 бит) на 64-битном хосте под управлением Proxmox VE 2.2.

2. Сегодня, с Glibc 2.23, мне не нужны были —build или -march (следовательно, никаких CFLAGS или CXXFLAGS). Поскольку ни в одном из них не должно быть необходимости, я полагаю, что с момента этого вопроса / ответа была исправлена какая-то ошибка.

3. моя версия Ubuntu 14.04.5 LTS / kernel: 4.4.0-31-generic работает.

Ответ №2:

Для меня работает следующее:

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

Комментарии:

1. Эта сборка пошла намного дальше, чем любая другая, но в конечном итоге выдала ошибку. Однако я нашел сборку, которая сработала, добавив к этому несколько вещей. Я все еще пытаюсь выяснить, почему это сработало.

Ответ №3:

Три важных ./configure флага:

  • --build= Система, выполняющая сборку. Похоже, что ваш x86_64-pc-linux-gnu .
  • --host= Система, в которой будут использоваться сгенерированные объекты. Вы хотите установить для этого значение i386-pc-linux-gnu .
  • --target= Если вы создаете компилятор, система, для которой встроенный компилятор, будет генерировать объекты.

Для выполнения кросс-компиляции необходимо указать оба --build= и --host= . Когда вы только укажете --host= , он все равно попытается создать собственный ( x86_64 ) glibc.

Комментарии:

1. Спасибо, я перепутал —target для —build. К сожалению, когда я переделал все тесты, я получил те же результаты, что и раньше.