У меня есть программа, которая зависит от общей библиотеки, которую она ожидает находить глубоко в структуре каталогов. Я хотел бы выгнать ту общую библиотеку с квартиры и в лучшее место. На 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, и это не то, что я ищу, я не должен изменять пути поиска глобально.
HT - это может быть полезно.
HT - это редактор / просмотрщик / анализатор файлов для исполняемых файлов. Цель состоит в том, чтобы объединить низкоуровневую функциональность отладчика и удобство использования IDE. Мы планируем реализовать все функции (шестнадцатеричного) редактирования и поддержку наиболее важных форматов файлов.
Я не смог найти чего-то очень отличного от решения ZorbaTHut, но, возможно, можно указать имя другой длины и при этом сохранить действующий двоичный файл.
gelf - тоже может пригодиться.
GElf - это общий, независимый от классов ELF API для управления - объектными файлами ELF. GElf предоставляет единый общий интерфейс для обработки 32-битных и 64-битных объектных файлов формата ELF.
Публикация пробного, ужасного, хакерского решения.
Зависимости библиотеки хранятся в блоке ELF, известном как блок .depends. Формат этого блока представляет собой большой массив пар идентификатор / указатель строки, при этом указатель строки указывает на стандартную строку C с завершающим нулем, расположенную где-то в двоичном файле.
Вы видите, к чему все идет, не так ли?
Ага, если новый путь, который вам нужен, не больше старого, вы можете просто войти прямо в двоичный файл и выполнить простую замену строки. Убедитесь, что вы не добавляете и не удаляете байты, иначе вы сломаете весь двоичный файл. Если вы хотите быть в большей безопасности, вы можете пересечь структуру ELF, чтобы убедиться, что у вас правильное местоположение - прямо сейчас я просто проверяю, чтобы исходная строка отображалась ровно один раз.
ELF включает контрольную сумму, но очевидно, что нет загрузчика, который действительно ее проверяет, поэтому игнорировать "безопасно" - хотя и беспорядочно.
«Настоящее решение» - это утилита, позволяющая низкоуровневые обобщенные манипуляции со структурой ELF. Насколько я могу судить, такой утилиты не существует ни для чего, кроме нескольких специализированных случаев (в основном RPATH). Я не претендую на то, чтобы знать, насколько сложно было бы написать такую утилиту.
Я бы очень хотел найти лучшее решение для этого, но пока что, похоже, это работает.
Вы можете использовать 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