GNU/Linux >> Belajar Linux >  >> Linux

Untuk apa opsi 'soname' untuk membangun perpustakaan bersama?

soname digunakan untuk menunjukkan kompatibilitas api biner apa yang didukung perpustakaan Anda.

SONAME digunakan pada waktu kompilasi oleh linker untuk menentukan dari file perpustakaan apa versi perpustakaan target yang sebenarnya. gcc -lNAME akan mencari libNAME .so tautkan atau file lalu tangkap SONAME-nya yang tentunya akan lebih spesifik ( ex tautan libnuke.so ke libnuke.so.0.1.4 yang berisi SONAME libnuke.so.0 ).

Pada saat dijalankan, ini akan ditautkan dengan ini kemudian diatur ke bagian dinamis ELF NEEDED , maka perpustakaan dengan nama ini ( atau tautan ke sana ) harus ada. Saat Run time SONAME diabaikan, jadi hanya tautan atau keberadaan file yang cukup.

Catatan:SONAME diterapkan hanya pada waktu link/build dan bukan pada waktu proses.

Pustaka 'SONAME' dapat dilihat dengan 'objdump -p file |grep SONAME'.'NEEDED' dari binari dapat dilihat dengan 'objdump -p file |grep NEEDED'.

[EDIT] PERINGATAN Berikut adalah komentar umum, bukan yang diterapkan di linux. Lihat di bagian akhir.

Misalkan Anda memiliki pustaka dengan nama libnuke.so.1.2 dan Anda mengembangkan pustaka libnuke baru :

  • jika perpustakaan baru Anda adalah perbaikan dari sebelumnya tanpa perubahan api, Anda harus tetap menggunakan soname yang sama, tingkatkan versi nama file. yaitu file akan menjadi libnuke.so.1.2.1 tetapi soname akan tetap menjadi libnuke.so.1.2.
  • jika Anda memiliki perpustakaan baru yang hanya menambahkan fungsi baru tetapi tidak merusak fungsionalitas dan masih kompatibel dengan sebelumnya, Anda ingin menggunakan soname yang sama dari sebelumnya ditambah akhiran baru seperti .1. yaitu file dan soname akan menjadi libnuke.so.1.2.1. Program apa pun yang ditautkan dengan libnuke.1.2 akan tetap berfungsi dengan yang itu. Program baru yang ditautkan dengan libnuke.1.2.1 hanya akan berfungsi dengan yang itu (sampai subversi baru datang seperti libnuke.1.2.1.1 ).
  • jika pustaka baru Anda tidak kompatibel dengan libnuke apa pun :libnuke.so.2
  • jika perpustakaan baru Anda kompatibel dengan versi lama:libnuke.so.1.3 [ yaitu masih kompatibel dengan libnuke.so.1 ]

[EDIT] untuk menyelesaikan :kasing linux.

Dalam kehidupan nyata linux SONAME sebagai bentuk spesifik :lib[NAME][API-VERSION].so.[major-version]major-version hanya satu nilai integer yang meningkat pada setiap perubahan pustaka utama.API-VERSION kosong secara default

ex libnuke.so.0

Kemudian nama file asli termasuk versi minor dan subversi ex :libnuke.so.0.1.5

Menurut saya, tidak memberikan soname adalah praktik yang buruk karena mengganti nama file akan mengubah perilakunya.


Anda membuat pustaka dinamis bernama libx.1.0.0 dalam tradisi penamaan libname.{a}.{b}.{c}

{a} stand for primary version, should changes when APIs changes(which making things incompatible).
{b} stand for sub version, should changes by adding APIs.
{c} stand for mirror version, should changes by bug fixing or optimizing

Sekarang Anda merilis libx.1.2.0, dan Anda perlu mendeklarasikan bahwa libx.1.2.0 kompatibel dengan libx.1.0.0 karena hanya menambahkan fungsi dan eksekusi orang tidak akan macet, cukup tautkan seperti dulu dengan:

Menyetel libx.1.0.0 dan libx.1.2.0 agar memiliki soname yang sama, misalnya libx.1

Inilah yang dilakukan soname.


Berikut adalah contoh yang mendukung jawaban Johann Klasek.

Singkatnya, SONAME diperlukan pada saat dijalankan. Pada waktu kompilasi, hanya diperlukan nama linker atau nama asli (mis. g++ main.cpp -L. -ladd atau g++ main.cpp -L. -l:libadd.so.1.1 ). Definisi nama penghubung dan nama asli mengikuti HOWTO Perpustakaan Program:3. Perpustakaan Bersama.

Pohon sumber:

├── add.cpp
├── add.h
├── main.cpp
└── Makefile

Makefile:

SOURCE_FILE=add.cpp
# main.cpp includes `add.h`, whose implementation is `add.cpp`
MAIN_FILE=main.cpp
SONAME=libadd.so.1
REAL_NAME=libadd.so.1.1
LINKER_NAME=libadd.so
OUTPUT_FILE=a.out

all:
   g++ -shared -fPIC -Wl,-soname,${SONAME} -o ${REAL_NAME} ${SOURCE_FILE}
   ln -s ${REAL_NAME} ${LINKER_NAME}
   g++ main.cpp -I. -L. -ladd -o ${OUTPUT_FILE} 
   # Same as `ldconfig -n .`, creates a symbolic link
   ln -s ${REAL_NAME} ${SONAME}
   #./a.out: error while loading shared libraries: libadd.so.1: cannot open 
   # shared object file: No such file or directory
   LD_LIBRARY_PATH=. ./${OUTPUT_FILE}
clean:
   rm ${SONAME} ${REAL_NAME} ${LINKER_NAME} ${OUTPUT_FILE}

Linux
  1. Bagaimana cara memeriksa pustaka bersama apa yang dimuat saat dijalankan untuk proses tertentu?

  2. Apa kata sandi root default untuk MySQL 5.7

  3. Apa alasan rmdir(1) dan rm(1) hidup berdampingan?

  1. Apa id partisi / tipe sistem file untuk UDF?

  2. Apa yang dimaksud dengan 'bidang' untuk perintah potong?

  3. Apa gunanya opsi -o dalam perintah useradd?

  1. Apa lokasi yang benar untuk variabel PS1 Shell?

  2. Berapa ukuran yang disarankan untuk partisi Linux /boot?

  3. Apa fasilitas syslog untuk log auditd?