Как вы указываете расположение библиотек в бинарный файл? (Linux)

34

Для этого вопроса я буду использовать конкретный пример, но на самом деле это обобщает практически любой бинарный файл в linux, который не может найти свои зависимые библиотеки. Итак, у меня есть программа, которая не запускается из-за отсутствия библиотек:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

ldd проливает свет на проблему:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

Однако корона установлена:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

Как мне указать двоичному файлу, где искать «недостающую» библиотеку?

скуловая кость
источник

Ответы:

43

Для разового выбора установите для переменной LD_LIBRARY_PATHсписок каталогов, разделенных двоеточиями, для поиска. Это аналогично PATHдля исполняемых файлов, за исключением того, что стандартные системные каталоги дополнительно ищутся после тех, которые указаны в среде.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

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

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

Список стандартных системных каталогов хранится в /etc/ld.so.conf. Последние системы позволяют этому файлу включать другие файлы; если у вас есть что-то вроде этого include /etc/ld.so.conf.d/*.conf, создайте новый файл, /etc/ld.so.conf.d/mala.confсодержащий каталоги, которые вы хотите добавить. После того, как вы изменили /etc/ld.so.confили включили файл, запустите, /sbin/ldconfigчтобы ваши изменения вступили в силу (это обновит кеш).

( LD_LIBRARY_PATHтакже применимо ко многим другим приложениям, включая FreeBSD, NetBSD, OpenBSD, Solaris и Tru64. HP-UX имеет SHLIB_PATHи Mac OS X имеет DYLD_LIBRARY_PATH. /etc/ld.so.confУ большинства аналогов есть аналоги, но расположение и синтаксис отличаются более широко.)

Жиль "ТАК - перестань быть злым"
источник
1
Фантастика, большое спасибо. Я понятия не имел о /etc/ld.so.conf, и это будет очень полезно для меня в будущем.
Мала
15

Если вы хотите избежать LD_LIBRARY_PATH, вы также можете сделать это во время ссылки:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

-Wl, ... используется для передачи дополнительных команд компоновщику, и в этом случае с -R вы указываете компоновщику сохранить этот путь как «путь поиска по умолчанию» для .so.

Я держу заметки о многих маленьких советах, подобных этому, на моем сайте:

https://www.thanassis.space/tricks.html

ttsiodras
источник
Но если у рассматриваемой библиотеки есть общие библиотеки для поиска, rpath, хранящийся в двоичном файле, не применяется рекурсивно к поискам в подбиблиотеке. Я не нашел способа обойти это, кроме установки LD_LIBRARY_PATH в среде, которая затем применяется к рекурсивным поискам ...
Этан
@Ethan: правда. Но что также верно, так это то, что обычные сценарии, в которых вы хотите «упаковать» разделяемые библиотеки для некоторого двоичного файла, это то, где вы помещаете их все вместе; Например /opt/mypackage/bin/someBinary, вам понадобятся библиотеки, в которых вы храните /opt/mypackage/lib/. Практически все проприетарные SW, установленные в / opt, следуют этому правилу - это означает, что описанный выше способ будет охватывать все такие установки. Затем они обычно добавляют также символическую ссылку в / usr / bin, которая указывает на двоичный файл в / opt - зная, что «путь поиска по умолчанию» найдет .soфайлы в соответствующей /opt/.../libпапке.
Циодрас
да, в моем случае я хотел протестировать пакет, ссылаясь на его каталог сборки, а не устанавливая его ... (но пакет имел несколько внутренних .so с некоторыми взаимозависимостями ... различные обходные пути, но просто раздражающие)
Итан
0

Это указывает, что libcorona не установлен по правильному пути. Переместите каталог libcorona по правильному пути, проблема будет решена.

Рати
источник
Как это лучше, чем другие ответы?
Тото
@ В отличие от других ответов, вы в основном вручную устанавливаете файлы ... Хотя это не означает, что этот ответ лучше, но это вариант, который следует учитывать (люди делают это и в Windows, копируя библиотеки в system32 / sysWOW64, когда их приложения не могут их найти), не то, чтобы это рекомендовалось, потому что это настоятельно не рекомендуется.
Tcll