Как общие библиотеки работают в смешанной 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-битные приложения будут работать без проблем.