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}