Dieser Blog-Beitrag ist ziemlich ungenau.
Soweit ich weiß, wurden C ++ ABI-Änderungen mit jeder Hauptversion von GCC eingeführt (dh mit unterschiedlichen Komponenten der ersten oder zweiten Versionsnummer).
Nicht wahr. Die einzigen seit GCC 3.4 eingeführten C ++ ABI-Änderungen waren abwärtskompatibel, was bedeutet, dass der C ++ ABI seit fast neun Jahren stabil ist.
Erschwerend kommt hinzu, dass die meisten großen Linux-Distributionen GCC-Snapshots verwenden und / oder ihre GCC-Versionen patchen, sodass es praktisch unmöglich ist, genau zu wissen, mit welchen GCC-Versionen Sie möglicherweise arbeiten, wenn Sie Binärdateien verteilen.
Die Unterschiede zwischen den gepatchten Versionen von GCC für Distributionen sind gering und ändern sich nicht an ABI. ZB Fedoras 4.6.3 20120306 (Red Hat 4.6.3-2) ist ABI-kompatibel mit den vorgelagerten FSF 4.6.x-Versionen und mit ziemlicher Sicherheit mit allen 4.6. x von jeder anderen Distribution.
Unter GNU / Linux verwenden die Laufzeitbibliotheken von GCC die ELF-Symbolversionierung, sodass Sie die von Objekten und Bibliotheken benötigten Symbolversionen leicht überprüfen können. Wenn Sie eine haben libstdc++.so
, die diese Symbole bereitstellt, funktioniert dies, spielt es keine Rolle, ob es sich um eine etwas andere gepatchte Version handelt von einer anderen Version Ihrer Distribution.
Es darf jedoch kein C ++ - Code (oder Code, der die C ++ - Laufzeitunterstützung verwendet) dynamisch verknüpft werden, wenn dies funktionieren soll.
Dies ist auch nicht wahr.
Das statische Verknüpfen mit libstdc++.a
ist jedoch eine Option für Sie.
Der Grund, warum es möglicherweise nicht funktioniert, wenn Sie eine Bibliothek dynamisch laden (mit dlopen
), ist, dass libstdc ++ - Symbole, von denen es abhängt, von Ihrer Anwendung möglicherweise nicht benötigt wurden, als Sie sie (statisch) verknüpft haben, sodass diese Symbole in Ihrer ausführbaren Datei nicht vorhanden sind. Dies kann durch dynamisches Verknüpfen der gemeinsam genutzten Bibliothek mit libstdc++.so
(was ohnehin das Richtige ist, wenn es davon abhängt) gelöst werden . ELF-Symbol-Interposition bedeutet, dass Symbole, die in Ihrer ausführbaren Datei vorhanden sind, von der gemeinsam genutzten Bibliothek verwendet werden, andere jedoch nicht Das in Ihrer ausführbaren Datei vorhandene Element befindet sich in dem libstdc++.so
Link, auf den es verweist. Wenn Ihre Anwendung nicht verwendet wird, müssen dlopen
Sie sich nicht darum kümmern.
Eine andere Option (und die, die ich bevorzuge) besteht darin, die neuere libstdc++.so
neben Ihrer Anwendung bereitzustellen und sicherzustellen, dass sie vor dem Standardsystem gefunden wird. Dies libstdc++.so
kann erreicht werden, indem der dynamische Linker gezwungen wird, an der richtigen Stelle zu suchen, entweder mithilfe der $LD_LIBRARY_PATH
Umgebungsvariablen bei run-. Zeit oder durch Festlegen einer RPATH
in der ausführbaren Datei zur Verbindungszeit. Ich bevorzuge die Verwendung, RPATH
da dies nicht davon abhängt, dass die Umgebung richtig eingestellt ist, damit die Anwendung funktioniert. Wenn Sie mit Ihrer Anwendung verknüpfen '-Wl,-rpath,$ORIGIN'
( man beachte die einfachen Anführungszeichen um die Schale zu verhindern versuchen , zu erweitern $ORIGIN
) die ausführbare Datei wird dann eine hat RPATH
von $ORIGIN
denen erzählt die dynamischen Linker Look für gemeinsam genutzte Bibliotheken im selben Verzeichnis wie die ausführbaren Datei selbst. Wenn Sie die neuere setzenlibstdc++.so
Im selben Verzeichnis wie die ausführbare Datei befindet sie sich zur Laufzeit. Das Problem wurde behoben. (Eine andere Möglichkeit besteht darin, die ausführbare Datei in /some/path/bin/
und die neuere libstdc ++ einzufügen. Also in /some/path/lib/
und mit '-Wl,-rpath,$ORIGIN/../lib'
einem anderen festen Speicherort in Bezug auf die ausführbare Datei zu verknüpfen und den RPATH in Bezug auf zu setzen. $ORIGIN
)