Как общие библиотеки работают в смешанной 64-битной/32-битной системе?
Доброе утро,
в 64-битном поле RedHat мы должны скомпилировать и запустить 32-битное приложение. Тем временем мне удалось собрать нужную версию gcc (4.0.3) и все необходимые библиотеки времени выполнения в 32 бит и установить LD_LIBRARY_PATH для указания на 32-битные версии, но теперь в течение оставшегося процесса сборки должна быть выполнена небольшая программа Java, которая установлен в /usr/bin как 64-битная программа, которая теперь находит 32-битную версию libgcc_s.so в первую очередь.
В общем, если я установил LD_LIBRARY_PATH в 32-битные версии, я сломаю 64-битные программы и наоборот.
Как это должно работать вообще? Я уверен, что я не первый человек с этой проблемой. Как это обычно решается?
С уважением,
Стефан
Ответы
Ответ 1
Добавьте обе 32-разрядные и 64-разрядные каталоги в LD_LIBRARY_PATH.
Если вы это сделаете, то ld.so для 32-разрядных или 64-разрядных будет использовать правильные библиотеки.
например. 32-разрядное тестовое приложение "test32" и 64-разрядное тестовое приложение "test" с локально установленной копией (более новой версии) gcc и binutils в пользовательском homedir, чтобы избежать сглаживания общесистемной установки gcc
=> export LD_LIBRARY_PATH=/home/user1/pub/gcc+binutils/lib:/home/user1/pub/gcc+binutils/lib64
=> ldd ./test32
libstdc++.so.6 => /home/user1/pub/gcc+binutils/lib/libstdc++.so.6 (0x00111000)
libgcc_s.so.1 => /home/user1/pub/gcc+binutils/lib/libgcc_s.so.1 (0x00221000)
=> ldd ./test
libstdc++.so.6 => /home/user1/pub/gcc+binutils/lib64/libstdc++.so.6 (0x00007ffff7cfc000)
libgcc_s.so.1 => /home/user1/pub/gcc+binutils/lib64/libgcc_s.so.1 (0x00007ffff7ad2000)
(Менее интересные пути библиотеки удалены)
Это показывает, что загрузчики знают, что игнорируют библиотеки неправильной архитектуры, по крайней мере, в этой Scientific Linux 6.3 (RHEL-производной) системе. Я ожидал бы, что другие дистрибутивы будут работать аналогичным образом, но не проверили это.
Возможно, это произошло только в последнее время, чем ваша (неуказанная) версия дистрибутива.
Ответ 2
В Solaris можно использовать LD_LIBRARY32_PATH
и LD_LIBRARY64_PATH
, но это не поддерживается в Linux.
В общем, вам просто не нужно вообще устанавливать LD_LIBRARY_PATH
:
- либо установите необходимые библиотеки в
/usr/lib32
или /usr/lib64
как
или
- создайте свое 32-битное приложение с помощью
-Wl,-rpath=/path/to/32-bit/libs
Ответ 3
Как обходной способ, оберните вызов Java в маленькой оболочке script, которая unset
LD_LIBRARY_PATH
, а затем вызывает исполняемый файл. В качестве альтернативы это может также работать:
LD_LIBRARY_PATH= java...
Обратите внимание на пробел между "=" и именем исполняемого файла.
Ответ 4
Просто установите LD_LIBRARY_PATH
на оба пути (используйте двоеточия для разграничения). Компилятор будет игнорировать библиотеки, которые он не может прочитать.
Ответ 5
Я столкнулся с такой же проблемой при ремастеринг 32-битной системы tinycore64, работающей на 64-битном ядре.
После долгих поисков я обнаружил, почему эти комментарии имеют смысл для обоих.
"Это было бы неплохо, но, по крайней мере, в моей среде - это не работают. Погрузчик пожаловался; он не просто пропускал библиотеки, которые не соответствуют бит-ности. К сожалению!" - struppi
"Это очень странно, не могли бы вы описать, как все провалилось? Кроме того, возможно, опубликовать вывод ldd?" - Adam Goode
И почему этот комментарий может показаться истинным, но на самом деле неверен.
Компонент игнорирует библиотеки, которые он не может прочитать.
Эта ссылка пролила свет на него.
http://www.markusbe.com/2009/09/about-running-32-bit-programs-on-64-bit-ubuntu-and-shared-libraries/
И более того, вы найдете просветительскую страницу ld.so.
Оказывается, имя пути может иметь значение в том, что компоновщик времени выполнения ld.so выбирает как загружаемую библиотеку. В моей 64-битной Linux-системе у меня есть ряд нечетных имен каталогов в дополнение к стандартным. например/Library/x86_64-Linux-гну. Я действительно думал, что экспериментирую, переместив библиотеки по этому пути в /lib 64. Когда я это сделал, угадайте, что случилось? неожиданно мое 64-битное приложение (brctl в этом случае) не работало и жаловалось на "Неверный класс ELF". Привет... теперь мы на что-то.
Теперь я не уверен на 100%, но ключ, похоже, связан с расширением маркера rpath.
Я подозреваю, что расширение ${PLATFORM} может иметь к этому какое-то отношение. И имя x86_64 должно быть частью этого.
В любом случае, я обнаружил, когда я поместил свои 64-битные библиотеки в пути библиотек с именем
x86_64-linux-gnu, как и для lib64, тогда они были предпочтительнее, чем 32-битные, и все работало.
В вашем случае вы, вероятно, захотите сделать что-то очень похожее для 32-битных библиотек на 64. Попробуйте i386-linux-gnu.
Итак, в моем случае, когда я устанавливаю 64-битные общие библиотеки на 32-битное пользовательское пространство, я создал следующие пути:
mkdir /lib/x86_64-linux-gnu/
mkdir /usr/lib/x86_64-linux-gnu/
ln -s /lib/x86_64-linux-gnu /lib64
ln -s /usr/lib/x86_64-linux-gnu /usr/lib64
Добавьте 64-битные библиотеки на 64-битные пути и 32-битные библиотеки только на пути 32bit/lib и /usr/lib.
Затем добавьте 64-битные конкретные пути к ld.so.conf и обновите кеш ldconfig
Теперь ваши 32-битные и 64-битные приложения будут работать без проблем.