Как разделяемые библиотеки работают в смешанной 64-битной / 32-битной системе? - PullRequest
16 голосов
/ 10 ноября 2009

Доброе утро,

на 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-битные программы и наоборот.

Как это вообще должно работать? Я уверен, что я не первый человек с этой проблемой под рукой. Как это обычно решается?

С уважением, Stefan

Ответы [ 5 ]

10 голосов
/ 20 августа 2012

Добавьте и 32-битные и 64-битные каталоги в LD_LIBRARY_PATH.

Если вы сделаете это, то для ld.so для 32-битных или 64-битных будут использоваться правильные библиотеки.

например. 32-разрядное тестовое приложение «test32» и 64-разрядное тестовое приложение «test» с локально установленной копией (более новой версии) gcc и binutils в домашнем каталоге пользователя, чтобы избежать путаницы общесистемной установки 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). Я ожидаю, что другие дистрибутивы будут работать аналогично, но я не проверял это.

Впрочем, это могло начаться только позже, чем ваша (не указанная) версия дистрибутива.

3 голосов
/ 12 ноября 2009

В Solaris можно использовать LD_LIBRARY32_PATH и LD_LIBRARY64_PATH, но это не поддерживается в Linux.

В общем, вам просто никогда не нужно нужно , чтобы вообще установить LD_LIBRARY_PATH:

  • либо установите необходимые библиотеки в /usr/lib32 или /usr/lib64 как соответствующий или
  • создайте 32-битное приложение с помощью -Wl,-rpath=/path/to/32-bit/libs
2 голосов
/ 10 ноября 2009

В качестве обходного пути, оберните вызов Java в небольшой скрипт оболочки, который unset s LD_LIBRARY_PATH, а затем вызывает исполняемый файл. Кроме того, это может также работать:

LD_LIBRARY_PATH= java...

Обратите внимание на пробел между "=" и именем исполняемого файла.

0 голосов
/ 05 апреля 2012

Я столкнулся с точно такой же проблемой при повторной установке 32-битной системы tinycore64 с 64-битным ядром.

После долгих поисков я обнаружил, почему эти комментарии имеют смысл для них обоих.

"Это было бы неплохо, но - по крайней мере, в моей среде - это не так Похоже на работу. Загрузчик жаловался; это не просто пропустить библиотеки, которые не соответствуют разрядности. Печально! "- струппи

"Это очень странно, не могли бы вы описать, как все провалилось? возможно опубликовать вывод ldd? "- Адам Гуд

И почему этот комментарий может показаться верным, но на самом деле неверным.

Компоновщик игнорирует библиотеки, которые он не может прочитать.

Эта ссылка проливает свет на это. http://www.markusbe.com/2009/09/about-running-32-bit-programs-on-64-bit-ubuntu-and-shared-libraries/

И, более конкретно, вы найдете man-страницу ld.so поучительной.

Оказывается, имя пути может иметь значение в том, что компоновщик среды выполнения ld.so выбирает в качестве библиотеки для загрузки. В моей 64-битной системе Linux у меня есть ряд нечетных имен каталогов в дополнение к стандартным. например / Библиотека / x86_64-Linux-гну. Я действительно думал, что поэкспериментирую, переместив библиотеки по этому пути в / lib64 Когда я это сделал, угадай, что случилось? внезапно мое 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-битные - только в 32-битные / lib и / usr / lib.

Затем добавьте 64-битные пути в ld.so.conf и обновите кеш с помощью ldconfig. Теперь ваши 32-битные и 64-битные приложения будут работать без проблем.

0 голосов
/ 13 ноября 2009

Просто установите LD_LIBRARY_PATH на оба пути (используйте двоеточия для разделения). Компоновщик будет игнорировать библиотеки, которые он не может прочитать.

...