Si je compile un programme C++ sur ma machine et l'exécute sur un autre (avec un logiciel plus ancien), je reçois: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found
.
En fait, sur mon système, la glibc est plus récente (j’ai eu gcc-libs 4.5.1: libstdc ++. So.6.0.14) et strings /usr/lib/libstdc++.so.6 | grep GLIBCXX
imprime de GLIBCXX_3.4
à GLIBCXX_3.4.14
. Sur l’autre système, il n’imprime que jusqu’à GLIBCXX_3.4.8
(j’ai libstdc ++. So.6.0.8).
J'ai donc quelques questions:
Pourquoi mon éditeur de liens lie-t-il les fichiers binaires C++ à libstdc ++ version GLIBCXX_3.4.9
au lieu de GLIBCXX_3.4.14
?
Si je respectais mon binaire contre libstdc ++ version GLIBCXX_3.4
, je suppose qu'il fonctionnerait presque partout. Cela impliquerait-il une sorte de problème? (par exemple: utiliserait-il des implémentations d'algorithmes plus anciennes et donc pires?)
Si au lieu de cela je statiquement lie mon programme à ma libstdc ++, je suppose qu’il fonctionnera partout; le binaire sera beaucoup plus gros (~ 1MB) bien sûr, d'autres avantages/inconvénients?
Puis-je forcer l'éditeur de liens à lier mon binaire à une version donnée de libstdc ++?
Utilisez readelf -a
et objdump -x
pour inspecter les fichiers ELF de préférence à strings
.
En réalité, toutes les versions de GLIBCXX_ * ne s'appliquent pas à la bibliothèque entière, mais à chaque symbole (versioning de symbole, voir DSO-howto ). Ainsi, vous pouvez avoir, par exemple: std::char_traits<wchar_t>::eq@@GLIBCXX_3.4.5
et std::ios_base::Init::~Init()@@GLIBCXX_3.4
sur le même fichier de bibliothèque.
Le fait que votre programme ait besoin de GLIBCXX_3.4.9 signifie probablement qu'il a été lié à un symbole introduit/a changé la sémantique de GLIBCXX_3.4.9.
MODIFIER
Je viens de me rappeler que les bibliothèques liées de manière statique augmentent l'utilisation de la mémoire.