Bagaimana Anda menentukan lokasi perpustakaan ke biner? (linux)

34

Untuk pertanyaan ini saya akan menggunakan contoh spesifik, tetapi ini benar-benar digeneralisasi ke hampir semua biner di linux yang sepertinya tidak dapat menemukan 'pustaka dependennya. Jadi, saya punya program yang tidak akan berjalan karena perpustakaan yang hilang:

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

LDD menyoroti masalah ini:

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)

Namun, corona diinstal:

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

Bagaimana cara memberi tahu biner tempat mencari pustaka "hilang"?

Mala
sumber

Jawaban:

43

Untuk sekali saja, atur variabel LD_LIBRARY_PATHke daftar direktori yang dipisahkan oleh titik dua untuk dicari. Ini analog dengan PATHuntuk executable, kecuali bahwa direktori sistem standar juga dicari setelah yang ditentukan melalui lingkungan.

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

Jika Anda memiliki program yang menyimpan perpustakaan di lokasi yang tidak standar dan tidak dapat menemukannya sendiri, Anda dapat menulis skrip wrapper:

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

Daftar direktori sistem standar disimpan di /etc/ld.so.conf. Sistem terbaru memungkinkan file ini untuk memasukkan file lain; jika milik Anda berisi sesuatu seperti include /etc/ld.so.conf.d/*.conf, buat file baru bernama /etc/ld.so.conf.d/mala.confberisi direktori yang ingin Anda tambahkan. Setelah Anda mengubah /etc/ld.so.confatau file yang disertakan, jalankan /sbin/ldconfigagar perubahan Anda diterapkan (ini memperbarui cache).

( LD_LIBRARY_PATHjuga berlaku untuk banyak penyatuan lainnya, termasuk FreeBSD, NetBSD, OpenBSD, Solaris dan Tru64. HP-UX memiliki SHLIB_PATHdan Mac OS X memiliki DYLD_LIBRARY_PATH. /etc/ld.so.confMemiliki analog pada sebagian besar penyatuan tetapi lokasi dan sintaksis berbeda lebih luas.)

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Fantastis, terima kasih banyak. Saya tidak tahu tentang /etc/ld.so.conf, dan itu akan sangat berguna bagi saya di masa depan.
Mala
15

Jika Anda ingin menghindari LD_LIBRARY_PATH, Anda juga dapat melakukan ini, saat menautkan:

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

-Wl, ... digunakan untuk meneruskan perintah tambahan ke tautan, dan dalam kasus ini, dengan -R Anda memberi tahu tautan untuk menyimpan jalur ini sebagai "jalur pencarian default" untuk .so.

Saya menyimpan banyak tips kecil seperti ini di situs saya:

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

ttsiodras
sumber
Tetapi jika perpustakaan itu sendiri telah berbagi perpustakaan untuk mencari, jalan yang disimpan dalam biner tidak diterapkan secara rekursif ke pencarian sub-perpustakaan. Saya belum menemukan cara lain selain menetapkan LD_LIBRARY_PATH di lingkungan, yang kemudian diterapkan pada pencarian rekursif ...
Ethan
@Ethan: Benar. Tetapi yang juga benar adalah bahwa skenario biasa di mana Anda ingin "mengemas" pustaka bersama untuk beberapa biner, adalah di mana Anda menempatkan semuanya bersama-sama; misalnya /opt/mypackage/bin/someBinaryakan membutuhkan lib yang Anda simpan /opt/mypackage/lib/. Hampir semua SW eksklusif yang dipasang di bawah / opt mengikuti aturan ini - yang berarti bahwa cara yang ditunjukkan di atas akan mencakup semua pemasangan semacam itu. Mereka kemudian biasanya akan menambahkan juga symlink di bawah / usr / bin yang menunjuk ke biner di bawah / opt - mengetahui bahwa "jalur pencarian default" akan menemukan .sos di bawah /opt/.../libfolder yang sesuai .
ttsiodras
ya, dalam kasus saya, saya ingin menguji suatu paket dengan menautkan ke direktori build-nya daripada menginstalnya ... (tetapi paket tersebut memiliki beberapa internal .so dengan beberapa inter-dependensi ... berbagai solusi tetapi hanya mengganggu)
Ethan
0

Ini menunjukkan libcorona tidak diinstal di jalur yang benar. Pindahkan direktori libcorona ke jalur yang benar, masalahnya akan teratasi ..

Rathi
sumber
Bagaimana ini lebih baik daripada jawaban lain?
Toto
@Toto tidak seperti jawaban lain, pada dasarnya Anda menginstal file secara manual ... Meskipun itu tidak berarti jawaban ini lebih baik, tetapi itu adalah opsi yang harus dipertimbangkan (orang-orang melakukan ini di Windows juga dengan menyalin pustaka ke system32 / sysWOW64 ketika aplikasi mereka tidak dapat menemukannya), bukan direkomendasikan, karena sangat tidak disarankan.
Tcll