Как создать 32-разрядную общую библиотеку на 64-битной платформе с помощью autotools
Я использую autotools для создания моей системы, которая состоит прежде всего из библиотеки. На 64-битных платформах Red Hat мне нужно создать библиотеку, способную работать на 32-разрядных платформах Red Hat.
Когда я добавляю -m32
в строки компиляции, все работает отлично, чтобы создать статическую (.a
) библиотеку, но как только я попытаюсь создать общую библиотеку, я получаю такую ошибку:
/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'
Я вижу, что проблема заключается в том, что он включает 64-битные файлы объектов из /usr/lib 64 вместо правильных 32-разрядных из /usr/lib (они там в порядке), но я не могу выяснить, как это исправить.
Ответы
Ответ 1
Сначала убедитесь, что у вас есть поддержка компилятора /libc для 32-разрядной компиляции. В некоторых дистрибутивах, таких как Ubuntu, вам нужно установить пакеты gcc-multilib
и/или g++-multilib
:
sudo apt-get install gcc-multilib g++-multilib
Затем при вызове configure укажите 32-битный хост и передайте 32-битные флаги компиляции:
./configure --host=i686-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
Если у вас нет установленного multilib, вы получите сообщение об ошибке, например configure: error: C compiler cannot create executables
при передаче флага -m32
.
Ответ 2
У меня была эта проблема на RHEL6. Это сработало
./configure --host=i386-redhat-linux --build=i386-redhat-linux "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" "LTCC=gcc -m32"
LTCC=gcc -m32
было волшебным заклинанием, необходимым для того, чтобы libtool создавал библиотеку 32 бит
Ответ 3
У меня была такая же проблема. Но я не использую autotools. Затем, в Makefile, отредактированном вручную, я заметил, что в строке
$(CC) -shared -Wl,-soname,lib$(NAME).so.0 -o lib$(NAME).so.$(VERSION) $(OBJ)
не было никакой опции для gcc, указывающей 32-битную архитектуру. Как только мой CFLAGS уже имеет вариант -m32, я решил поместить его в строку, упомянутую выше:
$(CC) $(CFLAGS) -shared -Wl,-soname,lib$(NAME).so.0 -o lib$(NAME).so.$(VERSION) $(OBJ)
и вуаля. Он работает!
Итак, в autotools возможно установка переменной CFLAGS для включения опции -m32.
Надеюсь, я помог...
Ответ 4
Вы бы попытались:
CFLAGS=-m32 -Wl,-m32
CXXFLAGS=-m32 -Wl,-m32
LDFLAGS=-m32
в вашем файле makefile, так как некоторые скрипты пытаются связать использование gcc или g++ вместо ld, как мы ожидаем?
Обновление. Если вы вручную модифицируете каждый вызов gcc/g++, попробуйте использовать -m32 -Wl, -m32 вместо простого -m32 в качестве дополнительной опции.
Ответ 5
У меня была такая же проблема: на 64-битной машине Ubuntu мне удалось скомпилировать и связать 32-разрядные хосты с помощью export CFLAGS=-m32; ./configure --host=i386
, но libtool все равно будет генерировать 64-разрядную общую библиотеку.
Я работал над этим, создав 32-битную среду сборки и chrooting в нее. Ubuntu делает это легко через debootstrap.
Ответ 6
Флаг компоновщика GNU для создания 32-битного общего объекта на 64-битной машине: -m elf_i386
Так, пожалуйста, например. напишите в файле Makefile:
LDFLAGS=-m elf_i386
Ответ 7
Быстрое исправление....
Создайте приложение на другом ПК с 32-разрядным Linux и передайте приведенные
файлы приложений (библиотека и т.д.) на желаемую 64-битную Linux-машину. Посмотрите, работает ли это. Это сработало для меня.