Как я могу изменить имя общей библиотеки после создания программы, которая зависит от нее? - PullRequest
19 голосов
/ 03 мая 2010

У меня есть программа, которая зависит от разделяемой библиотеки, которую она ожидает найти глубоко внутри структуры каталогов. Я хотел бы переместить эту общую библиотеку в лучшее место. На OS X это можно сделать с помощью install_name_tool. Я не могу найти эквивалент для Linux.

Для справки readelf -d myprogram выплевывает следующий перефразированный вывод:

Dynamic section at offset 0x1e9ed4 contains 30 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [this/is/terrible/library.so]
 0x00000001 (NEEDED)                     Shared library: [libGL.so.1]
 0x00000001 (NEEDED)                     Shared library: [libGLU.so.1]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
(continues in an uninteresting fashion)

(и по запросу ldd myprogram:)

    linux-gate.so.1 =>  (0x0056a000)
    this/is/terrible/library.so => not found
    libGL.so.1 => /usr/lib/mesa/libGL.so.1 (0x0017d000)
    libGLU.so.1 => /usr/lib/libGLU.so.1 (0x00a9c000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00710000)
   (etc, etc)

и я хотел бы, чтобы ошибка "this / is / terrible / library.so" была "shared / library.so". Обратите внимание, что если оставить программу в «встроенном» месте, где фактически существует относительный путь this / is / terrible / library.so, то ldd сможет найти его, как и следовало ожидать.

Я знаю о RPATH, и это не то, что я ищу, мне не нужно менять пути поиска глобально.

Ответы [ 4 ]

12 голосов
/ 13 июня 2017

Мы можем использовать patchelf :

patchelf --replace-needed liboriginal.so.1 libreplacement.so.1 my-program

Мы также можем удалить зависимость:

patchelf --remove-needed libfoo.so.1 my-program

Добавить зависимость:

patchelf --add-needed libfoo.so.1 my-program

Или измените путь для поиска библиотек ( rpath ):

patchelf --set-rpath /path/to/lib:/other/path my-program
8 голосов
/ 03 мая 2010

Опубликовать предварительное, ужасное, хакерское решение.

Зависимости библиотеки хранятся в блоке ELF, известном как блок .depends. Формат этого блока представляет собой большой массив пар идентификатор / указатель строки, причем указатель строки указывает на стандартную строку C с нулевым символом в конце, расположенную где-то в двоичном файле.

Вы видите, куда это идет, верно?

Да, пока новый путь, который вам нужен, не больше, чем старый, вы можете просто добраться до двоичного файла и выполнить простую замену строки. Убедитесь, что не добавляете и не удаляете байты, иначе вы сломаете весь двоичный файл. Если вы хотите быть в безопасности от этого, вы могли бы на самом деле пройти через структуру ELF, чтобы убедиться, что вы нашли правильное местоположение - сейчас я просто проверяю, чтобы строка-источник отображалась ровно один раз.

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

«Реальным решением» была бы утилита, позволяющая низкоуровневые обобщенные манипуляции со структурой ELF. Насколько я могу судить, такой утилиты не существует, за исключением нескольких специализированных случаев (в основном RPATH). Я не претендую на то, чтобы понять, насколько сложно написать такую ​​утилиту.

Мне бы очень хотелось найти лучшее решение, но пока это работает.

5 голосов
/ 03 мая 2010

HT - это может быть полезно.

HT - редактор файлов / программа просмотра / анализа исполняемых файлов. Цель состоит в том, чтобы объединить низкоуровневую функциональность отладчика и удобство использования IDE. Мы планируем реализовать все (шестнадцатеричные) функции редактирования и поддержку наиболее важных форматов файлов.

Я не смог найти что-то сильно отличающееся от решения ZorbaTHut, но, возможно, можно задать имя с другой длиной и при этом сохранить действительный двоичный файл.

gelf - это тоже может быть полезно.

GElf - это универсальный, независимый от класса API-интерфейс для манипулирования в объектных файлах ELF. GElf обеспечивает единую, общую face для обработки 32-битных и 64-битных объектных файлов в формате ELF.

0 голосов
/ 03 мая 2010

Вы можете использовать LD_LIBRARY_PATH, чтобы изменить путь поиска для разделяемых библиотек. Если ваша программа зависит от определенного относительного пути, как показано в примере, вам все равно потребуется структура каталогов. Другими словами, вы можете переместить библиотеку с /home/user/dev/project/this/is/terrible/library.so на /usr/local/lib/this/is/terrible/library.so, но не на /usr/local/lib/library.so

Если вы можете перестроить свою программу, вы можете изменить относительный путь, который она использует для библиотеки.

Еще немного информации об общих библиотеках в Linux на http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

...