Ce billet de blog est assez inexact.
Autant que je sache, des changements ABI C ++ ont été introduits avec chaque version majeure de GCC (c'est-à-dire ceux avec différents composants de premier ou deuxième numéro de version).
Pas vrai. Les seuls changements ABI C ++ introduits depuis GCC 3.4 ont été rétrocompatibles, ce qui signifie que l'ABI C ++ est stable depuis près de neuf ans.
Pour aggraver les choses, la plupart des principales distributions Linux utilisent des instantanés GCC et / ou corrigent leurs versions GCC, ce qui rend pratiquement impossible de savoir exactement à quelles versions GCC vous pourriez avoir affaire lorsque vous distribuez des binaires.
Les différences entre les versions corrigées des distributions de GCC sont mineures et ne changent pas ABI, par exemple la version 4.6.3 20120306 de Fedora (Red Hat 4.6.3-2) est compatible ABI avec les versions amont de FSF 4.6.x et presque certainement avec n'importe quelle version 4.6. x de toute autre distribution.
Sur les bibliothèques d'exécution de GNU / Linux GCC utilisent la gestion des versions des symboles ELF, il est donc facile de vérifier les versions de symboles nécessaires aux objets et aux bibliothèques, et si vous avez un libstdc++.so
qui fournit ces symboles, cela fonctionnera, peu importe s'il s'agit d'une version corrigée légèrement différente d'une autre version de votre distribution.
mais aucun code C ++ (ou tout code utilisant le support d'exécution C ++) ne peut être lié dynamiquement si cela doit fonctionner.
Ce n'est pas vrai non plus.
Cela dit, la liaison statique vers libstdc++.a
est une option pour vous.
La raison pour laquelle cela peut ne pas fonctionner si vous chargez dynamiquement une bibliothèque (en utilisant dlopen
) est que les symboles libstdc ++ dont elle dépend n'ont peut-être pas été nécessaires à votre application lorsque vous l'avez liée (statiquement), donc ces symboles ne seront pas présents dans votre exécutable. Cela peut être résolu en liant dynamiquement la bibliothèque partagée à libstdc++.so
(ce qui est la bonne chose à faire de toute façon si cela en dépend.) L'interposition de symboles ELF signifie que les symboles présents dans votre exécutable seront utilisés par la bibliothèque partagée, mais d'autres non présent dans votre exécutable se trouve dans celui vers lequel libstdc++.so
il renvoie. Si votre application ne fonctionne pas, dlopen
vous n'avez pas besoin de vous en soucier.
Une autre option (et celle que je préfère) est de déployer le plus récent à libstdc++.so
côté de votre application et de vous assurer qu'il est trouvé avant le système par défaut libstdc++.so
, ce qui peut être fait en forçant l'éditeur de liens dynamique à chercher au bon endroit, soit en utilisant $LD_LIBRARY_PATH
la variable d'environnement lors de l'exécution. time, ou en définissant un RPATH
dans l'exécutable au moment de la liaison. Je préfère utiliser RPATH
car il ne dépend pas de la configuration correcte de l'environnement pour que l'application fonctionne. Si vous liez votre application avec '-Wl,-rpath,$ORIGIN'
(notez les guillemets simples pour empêcher le shell d' essayer d'élargir $ORIGIN
) puis l'exécutable aura un RPATH
de $ORIGIN
qui raconte l'éditeur de liens de dynamique pour rechercher des bibliothèques partagées dans le même répertoire que l'exécutable lui - même. Si vous mettez le plus récentlibstdc++.so
dans le même répertoire que l'exécutable, il se trouvera au moment de l'exécution, problème résolu. (Une autre option est de mettre l'exécutable dans /some/path/bin/
et le plus récent libstdc ++. So dans /some/path/lib/
et lier avec '-Wl,-rpath,$ORIGIN/../lib'
ou tout autre emplacement fixe par rapport à l'exécutable, et définir le RPATH par rapport à $ORIGIN
)
-static-libstdc++
option ne servirait à rien, vous utiliseriez simplement-static