it-swarm-tr.com

SO (paylaşılan nesne) numaraları nasıl çalışır?

Linux altındaki paylaşılan nesnelere "yani sayılar" kullandığını, yani paylaşılan bir nesnenin farklı sürümlerine farklı uzantılar verildiğini biliyorum, örneğin:

  • example.so.1
  • example.so.2

Ben bir fikir iki farklı dosya bir kütüphanede (Windows üzerinde "DLL Hell" aksine) bir sistemde var olabileceğini anlıyorum. Bunun pratikte nasıl çalıştığını bilmek ister misiniz? Çoğu zaman, example.so'nin example.so.2 ile sembolik bir bağlantı olduğunu görüyorum, burada .2 en son sürümdür. O halde example.so 'un eski bir sürümüne bağlı olarak bir uygulama onu nasıl doğru bir şekilde tanımlar? Hangi numaraların kullanılması gerektiğine dair herhangi bir kural var mı? Yoksa bu basit bir toplantı mı? Yazılım ikili dosyalarının sistemler arasında aktarıldığı Windows'tan farklı olarak, bir sistem paylaşılan bir nesnenin daha yeni bir sürümüne sahipse, kaynaktan derlenirken otomatik olarak eski sürüme bağlanır mı?

Bunun ldconfig ile ilgili olduğundan şüpheleniyorum, ancak nasıl yapılacağından emin değilim.

127
user119

İkili dosyalar, paylaşılan bir kütüphanenin hangi sürümüne bağımlı olduklarını bilir ve özellikle talep eder. Bağımlılıkları göstermek için ldd kullanabilirsiniz; ls için mayın:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

Gördüğünüz gibi, ör. libpthread.so.0, Yalnızca libpthread.so Değil.


Sembolik bağlantının nedeni bağlayıcıdır. Doğrudan libpthread.so İle bağlantı kurmak istediğinizde, gcc işaretini -lpthread Verir ve lib önekine ve .so otomatik olarak sonek. Bunu .so.0 Sonekine eklemesini söyleyemezsiniz, böylece sembolik bağlantı, bunu kolaylaştırmak için lib'in en yeni sürümüne işaret eder.

91
Michael Mrozek

Paylaşılan kitaplıklardaki sayılar, bir kitaplığın API'sını tanımlamak için Linux'ta kullanılan bir kuraldır. Genellikle biçim:

libFOO.so.MAJOR.MINOR

Ve fark ettiğiniz gibi, genellikle libFOO.so'dan libFOO.so.MAJOR.MINOR'a sembolik bir bağlantı vardır. ldconfig bu bağlantıyı en yeni sürüme güncellemekten sorumludur.

MAJOR genellikle API değiştiğinde (yeni giriş noktaları kaldırıldığında veya parametreler veya türler değiştiğinde) artar. MINOR tipik olarak hata düzeltme sürümleri için veya mevcut API'ları bozmadan yeni API'ler eklendiğinde artırılır.

Daha kapsamlı bir tartışma burada bulunabilir: Paylaşılan kütüphaneleri inceleme

61
miguel.de.icaza

Paylaşılan kitaplıklar aşağıdaki şemaya göre biçimlendirilmelidir:

blah.so.X.Y.Z

nerede

  • X = geriye doğru uyumsuz ABI sürümü
  • Y = geriye doğru uyumlu ABI sürümü
  • Z = Yalnızca dahili değişiklikler - ABI'de değişiklik yok

Genellikle ilk basamağı hello.so.1 Gibi görürsünüz, çünkü diğer basamaklar geriye dönük olarak uyumlu olduğu için ilk basamak kütüphanenin "versiyonunu" tanımlamak için gereken tek şeydir.

ldconfig bir sistemde hangi paylaşılan kitaplıkların bulunduğunu ve o kitaplığın yolunun nerede bulunduğunu gösteren bir tablo tutar. Bunu çalıştırarak doğrulayabilirsiniz:

ldconfig -p

Red Hat gibi bir şey için bir paket oluşturulduğunda, ikili dosyada çağrılan paylaşılan kütüphaneler aranacak ve RPM oluşturma zamanında paketin bağımlılıkları olarak eklenecektir. Bu nedenle, paketi yüklemeye gittiğinizde, yükleyici ldconfig öğesini işaretleyerek sisteme hello.so.1 Yüklenip yüklenmediğini arar.

Bir paketin bağımlılıklarını aşağıdaki gibi bir şey yaparak görebilirsiniz:

rpm -qpR hello.rpm

Bu sistem (Windows'tan farklı olarak), hello.so Sürümünün birden çok sürümünün bir sisteme yüklenmesine ve aynı anda farklı uygulamalar tarafından kullanılmasına izin verir.

25
ascotan

libNAME.so, -lNAME tarafından belirtilen bir kitaplığı ilk kez ararken derleyici/bağlayıcı tarafından kullanılan dosya adıdır. Paylaşılan bir kütüphane dosyasının içinde SONAME adlı bir alan bulunur. Bu alan, kitaplığın kendisi ilk kez oluşturma işlemi tarafından paylaşılan bir nesneye bağlandığında ayarlanır. Bu SONAME aslında, paylaşılan nesneye bağlı olarak bir bağlayıcının yürütülebilir dosyada depoladığı şeydir. Normalde SONAME, libNAME.so.MAJOR biçimindedir ve kütüphane, kendisine bağlı mevcut yürütülebilir dosyalarla uyumsuz hale geldiğinde ve kütüphanenin her iki ana sürümü de gerektiği gibi yüklenebilir (ancak geliştirme için yalnızca bir tane işaretlenecektir) Ayrıca, bir kütüphanenin küçük sürümleri arasında kolayca yükseltmeyi desteklemek için libNAME.so.MAJOR normalde libNAME.so.MAJOR.MINOR gibi bir dosyaya bağlantıdır. Yeni bir küçük sürüm kurulabilir ve tamamlandığında, eski küçük sürüme bağlantı, yeni küçük sürüme hemen yükseltilerek yeni yükseltmeleri kütüphaneyi kullanacak şekilde yükseltir. Ayrıca, Linux, GNU GCC, ld, sürüm komut dosyaları ve ELF ikili formatı - Nasıl çalışır?

20
penguin359