2016-01-13 9 views
5

Ich habe eine Konfigurationsprüfung, die bestimmt, welche Flags basierend auf Plattform und Version an g ++ übergeben werden. Ich verwende normalerweise eine spätere Version von gcc als die native Installationsversion, um Zugriff auf C++ 14-Funktionen zu erhalten. Auf älteren Plattformen bedeutet dies, dass ich -D_GLIBCXX_USE_CXX11_ABI = 0 hinzufügen muss, um die ältere C++ - ABI zu verwenden, oder ich kann keine Verknüpfung mit Host-Versionen von C++ - Bibliotheken herstellen. Allerdings verwenden einige neuere Plattformen die neue ABI. In diesem Fall ist -D_GLIBCXX_USE_CXX11_ABI = 1 (oder gar nichts) erforderlich.Wie der C++ - ABI, der von der Systemversion von gcc auf der Zielplattform verwendet wird, getestet wird

Ich kann dies basierend auf der Version der Zielplattform (d. H. Die Ausgabe von lsb_release -a) tun, aber ich möchte eine allgemeinere Methode.

Ich denke, ich bin auf halbem Weg mit der Kompilierung eines C++ Hallo Welt-Programm mit dem nativen Compiler (im Gegensatz zu meinem späteren), aber ich kann nicht ganz herausfinden, wie die ABI-Version zu testen. Zum Beispiel

oder ähnlich auf die Version von libstdC++, die von dem Hello-Probe-Programm verwandt wird.

 
ldd ./hello | grep stdc++ | sed -e 's_.* /_/_' | cut -f 1 -d' ' |xargs strings | grep 

Hat jemand bessere Vorschläge?

update: In der Tat muss ich das überhaupt nicht tun. Mein echtes Problem war, dass ich eine ältere Version von libstdC++ hatte. Die Kompilation hat eine Version 6.0.20 gefunden und die Laufzeit hat eine inkompatible Version 6.0.19 (oder möglicherweise umgekehrt) gefunden. Ich hatte ein ungelöstes Symbol, das ich fälschlicherweise der ABI-Version vorwarf. Entgegen der landläufigen Meinung sind Nebenversionen von libstdC++ nicht immer binärkompatibel. Ich beabsichtige immer die exakt gleiche Version zur Laufzeit und zur Kompilierzeit zu verwenden (wenn nicht die native Host-Version verwendet wird).

+0

Ich habe die Frage nicht beantwortet, aber mein Problem gelöst, ist die Antwort nicht mehr wichtig für mich. Diese Frage kann geschlossen werden. –

+1

libstdC++ ist vorwärtskompatibel, ich bin nicht einmal sicher, ob sie irgendeiner Form der semantischen Versionierung folgen. Ich wette, wenn Sie mit 6.0.19 verbunden und den resultierenden Code mit 6.0.20 ausgeführt haben, würde es gut funktionieren. – rubenvb

+0

Während es beabsichtigt ist, wahr zu sein. Sie können immer noch Probleme haben. Ich habe einige (interne) Programme unter Verwendung einer späteren Version der Bibliothek, die auf subtile Weise fehlerkompatibel waren, gebrochen. Ich würde nicht riskieren wollen, ein Systemprogramm so zu brechen, als wäre es sehr schwer zu debuggen. Siehe auch http://stackoverflow.com/questions/25979778/forcing-or-preventing-use-of-a-particular-mino-version-of-libstdc –

Antwort

0

Entgegen der landläufigen Meinung sind kleinere Versionen von libstdC++ nicht immer binärkompatibel.

Sie sind in beiden Richtungen nicht binärkompatibel. libstdC++.so.6.0.20 kann verwendet werden, wenn libstdC++ .so.6.0.19 benötigt wird, aber nicht umgekehrt.

Allerdings war die C++ 11-Unterstützung vor GCC 5 noch experimentell (dh in Arbeit) und daher war der ABI der neuen C++ 11-Komponenten nicht stabil, so dass Sie C++ 11 nicht mischen können/C++ 14 Code kompiliert mit GCC 4.x und GCC 4.y oder GCC 4 und GCC 5. Für C++ 98 Code können Sie & frei mischen (verwenden Sie einfach die neuere libstdc++.so, weil es nur in einer Richtung kompatibel ist).

Die Einzelheiten der großen vor 11 Inkompatibilitäten ++ C bis GCC 5 bei https://gcc.gnu.org/wiki/Cxx11AbiCompatibility dokumentiert

Wie dem auch sei, die jetzt irrelevant Frage zu beantworten:

Ich glaube, ich bin auf halbem Weg gibt mit Kompilieren eines C++ Hallo Welt Programm mit dem nativen Compiler (im Gegensatz zu meiner später ein), aber ich nicht ganz herausfinden, wie die ABI-Version

sondieren Wenn Sie den nativen Compiler laufen kann dann weiß ich nicht sehen was Das Problem ist, überprüfen Sie einfach den Standardwert des Makros:

+0

Das fast richtig ist, aber für mich gcc 4.9.3 oder RHEL7 nativen 4.8 das Makro zu verwenden, scheint _GLIBCXX_ABI_TAG_CXX11 oder _CXXABI_FORCED_H zu sein: ' > echo„# include “| g ++ -x C++ -E -dM - | grep ABI #define _CXXABI_FORCED_H 1 #define __GXX_ABI_VERSION 1002 #define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) ' gcc6 auf der anderen Seite fügt auch: ' #define _GLIBCXX_USE_DUAL_ABI 1 #define _GLIBCXX_USE_CXX11_ABI 1 ' –

+0

Nein, das sind völlig verschiedene Makros. Weder GCC 4.9.3 noch 4.8 unterstützen die mit GCC 5.1 eingeführte [Dual ABI] (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html), so dass sie ** immer ** äquivalent zu 'sind _GLIBCXX_USE_CXX11_ABI = 0' –

+0

Wenn Sie RHEL verwenden, sollten Sie sich das [devtoolset] (https://access.redhat.com/documentation/de/red-hat-developer-toolset/) ansehen, das Ihnen einen Überblick gibt -date GCC, die Binärdateien erzeugt, die nur vom Host libstdC++ abhängen (und die auch den Systemstandards in Bezug auf 'std :: string' ABI entsprechen) –

Verwandte Themen