Di mana executable mencari objek bersama saat runtime?

102

Saya mengerti bagaimana mendefinisikan termasuk objek yang dibagikan pada waktu penautan / kompilasi. Namun, saya masih bertanya-tanya bagaimana cara executable mencari objek yang dibagikan ( *.soperpustakaan) pada waktu eksekusi.

Misalnya, aplikasi saya a.outmemanggil fungsi yang ditentukan di lib.soperpustakaan. Setelah mengkompilasi, saya pindah lib.soke direktori baru di blog saya $HOME.

Bagaimana saya bisa mengatakan a.outuntuk mencarinya di sana?

rahmu
sumber

Jawaban:

102

The HOWTO shared library menjelaskan sebagian besar mekanisme yang terlibat, dan loader dinamis pengguna tersebut lebih rinci. Setiap varian unix memiliki caranya sendiri, tetapi sebagian besar menggunakan format yang dapat dieksekusi ( ELF ) yang sama dan memiliki penghubung dinamis yang serupa (diturunkan dari Solaris). Di bawah ini saya akan merangkum perilaku umum dengan fokus pada Linux; periksa manual sistem Anda untuk cerita lengkap.

Singkatnya, ketika sedang mencari perpustakaan dinamis ( .sofile) linker mencoba:

  • direktori yang tercantum dalam LD_LIBRARY_PATHvariabel lingkungan ( DYLD_LIBRARY_PATHpada OSX);
  • direktori yang tercantum dalam executable rPath ;
  • direktori pada jalur pencarian sistem, yang (setidaknya di Linux) terdiri dari entri di /etc/ld.so.confplus /libdan /usr/lib.

Rpath disimpan dalam executable (itu adalah atribut DT_RPATHatau DT_RUNPATHdinamis). Ini dapat berisi path absolut atau path yang dimulai dengan $ORIGINuntuk menunjukkan path relatif ke lokasi executable (misalnya jika executable berada di dalam /opt/myapp/bindan rpath-nya adalah $ORIGIN/../lib:$ORIGIN/../pluginsmaka dynamic linker akan mencari /opt/myapp/libdan /opt/myapp/plugins). Jalan biasanya ditentukan ketika dieksekusi dikompilasi, dengan -rpathopsi untuk ld, tetapi Anda dapat mengubahnya dengan chrpath.

Dalam skenario yang Anda jelaskan, jika Anda adalah pengembang atau pembuat paket aplikasi dan bermaksud untuk menginstalnya dalam …/bin, …/libstruktur, lalu tautkan dengan -rpath='$ORIGIN/../lib'. Jika Anda menginstal biner pra-dibangun di sistem Anda, letakkan perpustakaan di direktori di jalur pencarian ( /usr/local/libjika Anda adalah administrator sistem, atau direktori yang Anda tambahkan $LD_LIBRARY_PATH), atau coba chrpath.

Gilles
sumber
3
Pada beberapa sistem, /lib64dan /usr/lib64digunakan untuk binari 64 bit dan /libdan /usr/libdigunakan untuk binari 32 bit.
Mark Lakata
Mengapa jawaban yang benar ini tidak berbicara apa-apa tentang ldconfig ??
Loves Probability
1
@ LovesProbability Karena pertanyaannya adalah di mana executable mencari perpustakaan, yang tidak melibatkan ldconfig. ldconfigTerlibat ketika Anda menginstal perpustakaan.
Gilles
1
Perhatikan bahwa "jalur pencarian sistem" untuk *.soperpustakaan tidak sama dengan $PATH. Jalur pencarian seperti yang diberikan oleh @enzotib dalam jawaban mereka. Untuk mencetak jalur yang akan dicari, jalankan ldconfig -v 2>/dev/null | grep -v ^$'\t'.
Andrew Bate
bagi saya, untuk menjalankan ldconfig, saya perlu /sbin/ldconfigdan sihir Andrew Bate lainnya untuk menjalankannya non-root
Robert Lugg
16

Di Linux perilaku ini dijelaskan di ld(1)halaman manual

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.
enzotib
sumber
1
"Direktori default, biasanya / lib dan / usr / lib." -> bagaimana saya bisa mengetahui apakah sistem saya normal?
Thorsten Staerk
2
Pertanyaannya adalah tentang runtime dan bukan waktu tautan
Talespin_Kit
2

Saya yakin jawabannya di sini ldconfig.

ldconfig membuat tautan dan cache yang diperlukan ke pustaka bersama terbaru yang ditemukan di direktori yang ditentukan pada baris perintah, di file /etc/ld.so.conf, dan di direktori tepercaya (/ lib dan / usr / lib). Cache digunakan oleh run-time linker, ld.so atau ld-linux.so. ldconfig memeriksa header dan nama file dari perpustakaan yang dihadapinya saat menentukan versi mana yang harus memperbarui tautannya.

http://linux.die.net/man/8/ldconfig

Sean C.
sumber
0

Untuk menjalankan aplikasi, file /proc/1234/mapsberisi semua pustaka yang terhubung secara dinamis aktual.

Di mana 1234pid dari executable berjalan.

Linux mengikuti LD_LIBRARY_PATH dan variabel lainnya, seperti ditunjukkan dalam jawaban oleh Gilles.

pengguna138692
sumber
4
Sangat menyenangkan bahwa Anda mengkonfirmasi dalam kalimat kedua Anda bahwa jawaban Gilles membantu. Namun, bagian pertama tidak berkontribusi sama sekali untuk menjelaskan bagaimana cara mengetahui a.out di mana file-file itu, hanya dari mana didapatnya jika mereka sudah ditemukan. Semua dalam semua ini seharusnya hanya komentar, bukan jawaban.
Anthon