Esa publicación de blog es bastante inexacta.
Hasta donde yo sé, se han introducido cambios en C ++ ABI con cada lanzamiento importante de GCC (es decir, aquellos con componentes de números de primera o segunda versión diferentes).
No es verdad. Los únicos cambios de C ++ ABI introducidos desde GCC 3.4 han sido compatibles con versiones anteriores, lo que significa que C ++ ABI se ha mantenido estable durante casi nueve años.
Para empeorar las cosas, la mayoría de las principales distribuciones de Linux utilizan instantáneas de GCC y / o parchean sus versiones de GCC, lo que hace que sea prácticamente imposible saber exactamente con qué versiones de GCC puede estar tratando cuando distribuye binarios.
Las diferencias entre las versiones parcheadas de GCC de las distribuciones son menores y no cambian la ABI, por ejemplo, la 4.6.3 20120306 de Fedora (Red Hat 4.6.3-2) es compatible con ABI con las versiones anteriores de FSF 4.6.xy casi con certeza con cualquier 4.6. x de cualquier otra distro.
En GNU / Linux, las bibliotecas en tiempo de ejecución de GCC usan el control de versiones de símbolos ELF, por lo que es fácil verificar las versiones de símbolos que necesitan los objetos y las bibliotecas, y si tiene una libstdc++.so
que proporciona esos símbolos, funcionará, no importa si es una versión parcheada ligeramente diferente. de otra versión de tu distribución.
pero no se puede vincular dinámicamente ningún código C ++ (o cualquier código que utilice el soporte de tiempo de ejecución de C ++) para que esto funcione.
Esto tampoco es cierto.
Dicho esto, vincular estáticamente a libstdc++.a
es una opción para ti.
La razón por la que podría no funcionar si carga dinámicamente una biblioteca (usando dlopen
) es que los símbolos libstdc ++ de los que depende podrían no haber sido necesarios para su aplicación cuando la vinculó (estáticamente), por lo que esos símbolos no estarán presentes en su ejecutable. Eso se puede resolver vinculando dinámicamente la biblioteca compartida a libstdc++.so
(que es lo correcto de todos modos si depende de ello). La interposición de símbolos ELF significa que los símbolos que están presentes en su ejecutable serán utilizados por la biblioteca compartida, pero otros no presente en su ejecutable se encontrará en el que libstdc++.so
se vincule. Si su aplicación no se usa dlopen
, no necesita preocuparse por eso.
Otra opción (y la que prefiero) es implementar la más nueva libstdc++.so
junto con su aplicación y asegurarse de que se encuentre antes que el sistema predeterminado libstdc++.so
, lo que se puede hacer obligando al vinculador dinámico a buscar en el lugar correcto, ya sea utilizando $LD_LIBRARY_PATH
la variable de entorno en la ejecución. time, o estableciendo un RPATH
en el ejecutable en link-time. Prefiero usarlo RPATH
porque no depende de que el entorno esté configurado correctamente para que la aplicación funcione. Si vincula su aplicación con '-Wl,-rpath,$ORIGIN'
(tenga en cuenta las comillas simples para evitar que el shell intente expandirse $ORIGIN
), el ejecutable tendrá una RPATH
de las $ORIGIN
cuales le indica al vinculador dinámico que busque bibliotecas compartidas en el mismo directorio que el ejecutable. Si pones lo nuevolibstdc++.so
en el mismo directorio que el ejecutable se encontrará en tiempo de ejecución, problema resuelto. (Otra opción es poner el ejecutable /some/path/bin/
y el libstdc ++ más nuevo. Así, /some/path/lib/
y vincularlo con '-Wl,-rpath,$ORIGIN/../lib'
o cualquier otra ubicación fija relativa al ejecutable, y establecer el RPATH relativo a $ORIGIN
)
-static-libstdc++
opción no tendría sentido, simplemente usaría-static