Jak określić lokalizację bibliotek w pliku binarnym? (linux)

34

W tym pytaniu użyję konkretnego przykładu, ale tak naprawdę uogólnia on na prawie każdy plik binarny na Linuksie, który nie wydaje się znajdować swoich zależnych bibliotek. Mam więc program, który nie uruchomi się z powodu brakujących bibliotek:

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

ldd rzuca nieco światła na ten problem:

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)

Jednak corona jest zainstalowana:

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

Jak mam powiedzieć binarnemu, gdzie szukać „brakującej” biblioteki?

Mala
źródło

Odpowiedzi:

43

Dla jednorazowego ustawienia ustaw zmienną LD_LIBRARY_PATHna rozdzieloną dwukropkami listę katalogów do przeszukania. Jest to analogiczne jak w PATHprzypadku plików wykonywalnych, z tym że standardowe katalogi systemowe są dodatkowo przeszukiwane po katalogach określonych w środowisku.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Jeśli masz program, który utrzymuje biblioteki w niestandardowej lokalizacji i nie jest w stanie samodzielnie ich znaleźć, możesz napisać skrypt otoki:

#!/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 "$@"

Lista standardowych katalogów systemowych znajduje się w /etc/ld.so.conf. Najnowsze systemy pozwalają na dołączanie do tego pliku innych plików; jeśli twój zawiera coś podobnego include /etc/ld.so.conf.d/*.conf, utwórz nowy plik o nazwie /etc/ld.so.conf.d/mala.confzawierający katalogi, które chcesz dodać. Po zmianie /etc/ld.so.conflub dołączonym pliku, uruchom /sbin/ldconfigzmiany, aby zastosować (spowoduje to aktualizację pamięci podręcznej).

( LD_LIBRARY_PATHdotyczy również wielu innych unikatów, w tym FreeBSD, NetBSD, OpenBSD, Solaris i Tru64. HP-UX ma, SHLIB_PATHa Mac OS X ma DYLD_LIBRARY_PATH. /etc/ld.so.confma analogi na większości jednorożców, ale lokalizacja i składnia różnią się bardziej).

Gilles „SO- przestań być zły”
źródło
1
Fantastycznie, dziękuję bardzo. Nie miałem pojęcia o /etc/ld.so.conf i będzie mi to bardzo przydatne w przyszłości.
Mala
15

Jeśli chcesz uniknąć LD_LIBRARY_PATH, możesz to zrobić również podczas łączenia:

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

Opcja -Wl, ... służy do przekazywania dodatkowych poleceń do konsolidatora, aw tym przypadku za pomocą opcji -R nakazuje konsolidatorowi zapisanie tej ścieżki jako „domyślnej ścieżki wyszukiwania” .so.

W mojej witrynie przechowuję notatki z wielu małych wskazówek, takich jak ten:

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

ttsiodras
źródło
Ale jeśli sama biblioteka ma wspólne biblioteki do wyszukiwania, ścieżka rpath przechowywana w pliku binarnym nie jest stosowana rekurencyjnie do wyszukiwań podbiblioteki. Nie znalazłem sposobu na obejście tego poza ustawieniem LD_LIBRARY_PATH w środowisku, które następnie stosuje się do wyszukiwania rekurencyjnego ...
Ethan
@Ethan: True. Ale prawdą jest również to, że zwykłe scenariusze, w których chcesz „spakować” biblioteki współdzielone dla niektórych plików binarnych, to takie, w których umieściłeś je wszystkie razem; np. /opt/mypackage/bin/someBinarybędzie potrzebował bibliotek, które przechowujesz /opt/mypackage/lib/. Prawie wszystkie zastrzeżone oprogramowanie zainstalowane pod / opt działa zgodnie z tą zasadą - co oznacza, że ​​powyższy sposób obejmie wszystkie takie instalacje. Zazwyczaj dodają także dowiązanie symboliczne pod / usr / bin, które wskazuje na plik binarny pod / opt - wiedząc, że „domyślna ścieżka wyszukiwania” znajdzie .sos pod odpowiednim /opt/.../libfolderem.
ttsiodras
tak, w moim przypadku chciałem przetestować pakiet, łącząc się z jego katalogiem kompilacji, zamiast go instalować ... (ale pakiet miał kilka wewnętrznych .so z pewnymi wzajemnymi zależnościami ... różnorodne obejścia, ale tylko denerwujące)
Ethan
0

Oznacza to, że libcorona nie jest zainstalowana we właściwej ścieżce. Przenieś katalog libcorona do właściwej ścieżki, problem zostanie rozwiązany ..

Rathi
źródło
Jak to jest lepsze niż inne odpowiedzi?
Toto
@Toto w przeciwieństwie do innych odpowiedzi, w zasadzie ręcznie instalujesz pliki ... Chociaż nie oznacza to dokładnie, że ta odpowiedź jest lepsza, ale JEST to opcja, którą należy wziąć pod uwagę (ludzie robią to również w systemie Windows, kopiując biblioteki do system32 / sysWOW64, gdy ich aplikacje nie mogą ich znaleźć), nie jest to zalecane, ponieważ jest mocno odradzane.
Tcll