Bu blog yazısı oldukça yanlış.
Bildiğim kadarıyla C ++ ABI değişiklikleri, GCC'nin her büyük sürümünde (yani farklı birinci veya ikinci sürüm numarası bileşenlerine sahip olanlar) tanıtıldı.
Doğru değil. GCC 3.4'ten bu yana sunulan tek C ++ ABI değişiklikleri geriye dönük uyumludur, yani C ++ ABI yaklaşık dokuz yıldır kararlıdır.
Sorunları daha da kötüleştirmek için, çoğu büyük Linux dağıtımı GCC anlık görüntülerini kullanır ve / veya GCC sürümlerini yamalar, bu da ikili dosyaları dağıtırken hangi GCC sürümleriyle uğraştığınızı tam olarak bilmeyi neredeyse imkansız hale getirir.
Dağıtımların yamalı GCC sürümleri arasındaki farklar küçüktür ve ABI değişmez, örneğin Fedora'nın 4.6.3 20120306 (Red Hat 4.6.3-2) yukarı akış FSF 4.6.x sürümleriyle ABI uyumludur ve neredeyse kesin olarak herhangi bir 4.6 ile uyumludur. diğer dağıtımlardan x.
GNU / Linux'ta GCC'nin çalışma zamanı kitaplıkları ELF sembol versiyonunu kullanır, bu nedenle nesneler ve kütüphaneler için ihtiyaç duyulan sembol versiyonlarını kontrol etmek kolaydır ve eğer libstdc++.so
bu sembolleri sağlayan bir şeye sahipseniz çalışır, biraz farklı bir yamalı versiyon olması fark etmez. dağıtımınızın başka bir sürümünden.
ancak C ++ kodu (veya C ++ çalışma zamanı desteğini kullanan herhangi bir kod) işe yarayacaksa dinamik olarak bağlanamaz.
Bu da doğru değil.
Bununla birlikte, statik olarak bağlantı kurmak libstdc++.a
sizin için bir seçenektir.
Bir kitaplığı dinamik olarak dlopen
yüklerseniz (kullanarak ) işe yaramamasının nedeni, bağlı olduğu libstdc ++ sembollerine, onu bağladığınızda (statik olarak) uygulamanız tarafından ihtiyaç duyulmamış olabilir, bu nedenle bu semboller çalıştırılabilir dosyanızda bulunmayacaktır. Bu, paylaşılan kitaplığa dinamik olarak bağlanarak çözülebilir libstdc++.so
(bu, buna bağlıysa yine de yapılacak doğru şeydir.) ELF simge enterpozisyonu, çalıştırılabilir dosyanızda bulunan sembollerin paylaşılan kitaplık tarafından kullanılacağı, ancak diğerlerinin kullanılmayacağı anlamına gelir. Yürütülebilir dosyanızda mevcut olan, libstdc++.so
bağlantı verdiği her yerde bulunacaktır . Uygulamanız kullanmıyorsa dlopen
, bunu önemsemenize gerek yoktur.
Başka bir seçenek (ve benim tercih ettiğim), libstdc++.so
uygulamanızın yanında yenisini dağıtmak ve varsayılan sistemden önce bulunmasını sağlamaktır; bu, libstdc++.so
dinamik bağlayıcıyı doğru yere bakmaya zorlayarak, ya $LD_LIBRARY_PATH
çalışma sırasında ortam değişkenini kullanarak yapılabilir . zaman veya RPATH
bağlantı zamanında çalıştırılabilir bir dosya ayarlayarak . RPATH
Uygulamanın çalışması için doğru ayarlanan ortama bağlı olmadığı için kullanmayı tercih ediyorum . Eğer birlikte uygulama bağlantı varsa '-Wl,-rpath,$ORIGIN'
(genişletmeye çalışırken kabuk önlemek için tek tırnak not $ORIGIN
ardından yürütülebilir sahip bir olacaktır) RPATH
ait $ORIGIN
olan kendisi yürütülebilir aynı dizinde paylaşılan kütüphaneler için görünüm dinamik bağlayıcı söyler. Daha yenisini koyarsanlibstdc++.so
çalıştırılabilir dosya ile aynı dizinde, çalışma zamanında bulunacaktır, sorun çözülmüştür. (Diğer bir seçenek olarak yürütülebilir koymaktır /some/path/bin/
öylesine. Ve daha yeni libstdc ++ /some/path/lib/
ile ve bağlantı '-Wl,-rpath,$ORIGIN/../lib'
yürütülebilir için başka bir sabit konum göreli veya ve rpath göre ayarlanır $ORIGIN
)
-static-libstdc++
seçeneğin bir anlamı olmayacağını ima etseydi, sadece kullanırdın-static