Wie finden Sie heraus, welche Version der libstdc ++ - Bibliothek auf Ihrem Linux-Computer installiert ist?

71

Ich habe folgenden Befehl gefunden: strings /usr/lib/libstdc++.so.6 | grep GLIBCvon hier . Es scheint zu funktionieren, aber dies ist eine Ad-hoc / heuristische Methode.

Gibt es einen bestimmten Befehl, mit dem die Bibliotheksversion von C ++ abgefragt werden kann? Oder ist die Methode, die ich gefunden habe, die akzeptierte Methode?

Trevor Boyd Smith
quelle

Antworten:

79

Um herauszufinden, welche Bibliothek verwendet wird, können Sie ausführen

 $ /sbin/ldconfig -p | grep stdc++
    libstdc++.so.6 (libc6) => /usr/lib/libstdc++.so.6

Die Liste der kompatiblen Versionen für libstdc ++ Version 3.4.0 und höher wird von bereitgestellt

 $ strings /usr/lib/libstdc++.so.6 | grep LIBCXX
 GLIBCXX_3.4
 GLIBCXX_3.4.1
 GLIBCXX_3.4.2
 ...

Für frühere Versionen ist das Symbol GLIBCPPdefiniert.

Der Datumsstempel der Bibliothek wird in einem Makro __GLIBCXX__oder __GLIBCPP__abhängig von der Version definiert:

// libdatestamp.cxx
#include <cstdio>

int main(int argc, char* argv[]){
#ifdef __GLIBCPP__
    std::printf("GLIBCPP: %d\n",__GLIBCPP__);
#endif
#ifdef __GLIBCXX__
    std::printf("GLIBCXX: %d\n",__GLIBCXX__);
#endif
   return 0;
}

$ g++ libdatestamp.cxx -o libdatestamp
$ ./libdatestamp
GLIBCXX: 20101208

Die Tabelle der Datenstempel der libstdc ++ - Versionen ist in der Dokumentation aufgeführt :

Dmitri Chubarov
quelle
9
Die Datenstempel sind fast völlig nutzlos. Ich weiß nicht, warum wir sie aufbewahren oder dokumentieren. Das Datum für GCC 4.6.3 ist beispielsweise später als 4.7.0, aber 4.7.0 verfügt über mehr Funktionen. Was nützt es also, das Veröffentlichungsdatum zu kennen?
Jonathan Wakely
Wie installiere ich diesen stringsBefehl? Aus welchem ​​Paket kommt?
Benutzer
@user stringsist ein Teil von GNU binutils.
Dmitri Chubarov
21

Was willst du genau wissen?

Der Soname der gemeinsam genutzten Bibliothek? Das ist Teil des Dateinamens libstdc++.so.6oder wird von angezeigt readelf -d /usr/lib64/libstdc++.so.6 | grep soname.

Die kleinere Revisionsnummer? Sie sollten dies erreichen können, indem Sie einfach überprüfen, auf was der Symlink verweist:

$ ls -l  /usr/lib/libstdc++.so.6
lrwxrwxrwx. 1 root root 19 Mar 23 09:43 /usr/lib/libstdc++.so.6 -> libstdc++.so.6.0.16

Das heißt, es ist 6.0.16, die 16. libstdc++.so.6Version der Version, die den GLIBCXX_3.4.16Symbolversionen entspricht.

Oder meinst du die Veröffentlichung, von der es kommt? Es ist Teil des GCC , so dass es die gleiche Version wie GCC ist, so dass , wenn Sie Ihr System geschraubt haben, indem unerreichte Versionen installieren g++und libstdc++.soSie können diese erhalten von:

$ g++ -dumpversion
4.6.3

Bei den meisten Distributionen können Sie auch einfach den Paketmanager fragen. Auf meinem Fedora-Host ist das so

$ rpm -q libstdc++
libstdc++-4.6.3-2.fc16.x86_64
libstdc++-4.6.3-2.fc16.i686

Wie bereits in anderen Antworten erwähnt, können Sie Releases Bibliotheksversionen zuordnen, indem Sie die ABI-Dokumente überprüfen

Jonathan Wakely
quelle
16

Der Mechanismus, den ich normalerweise verwende, ist eine Kombination aus dem Speichern readelf -Vder .gnu.versionInformationen aus libstdc ++ und einer Nachschlagetabelle, die dem größten GLIBCXX_extrahierten Wert entspricht.

readelf -sV /usr/lib/libstdc++.so.6 | sed -n 's/.*@@GLIBCXX_//p' | sort -u -V | tail -1

Wenn Ihre Version von sortzu alt ist, um die -VOption zu haben (die nach Versionsnummer sortiert ist), können Sie Folgendes verwenden:

tr '.' ' ' | sort -nu -t ' ' -k 1 -k 2 -k 3 -k 4 | tr ' ' '.'

anstelle von sort -u -V, um nach bis zu 4 Versionsziffern zu sortieren.

Im Allgemeinen sollte die Übereinstimmung mit der ABI-Version gut genug sein.

Wenn Sie jedoch versuchen, das aufzuspüren libstdc++.so.<VERSION>, können Sie eine kleine Bash verwenden, wie:

file=/usr/lib/libstdc++.so.6
while [ -h $file ]; do file=$(ls -l $file | sed -n 's/.*-> //p'); done
echo ${file#*.so.}

Für mein System ergab sich dies 6.0.10.

Wenn Sie jedoch versuchen, eine Binärdatei zu erhalten, die auf systemX kompiliert wurde, um auf systemY zu funktionieren, werden Sie mit solchen Dingen nur so weit kommen. In diesen Fällen müssen Sie eine Kopie von libstdc ++. Mit sich führen, die für die Anwendung verwendet wurde, und anschließend ein Skript ausführen, das Folgendes ausführt:

export LD_LIBRARY_PATH=<directory of stashed libstdc++.so>
exec application.bin "$@"

Im Allgemeinen wird das Problem behoben, dass die .so-Datei auf der Box nicht mit der Version aus der Anwendung kompatibel ist. Bei extremeren Unterschieden in der Umgebung füge ich normalerweise nur alle abhängigen Bibliotheken hinzu, bis die Anwendung ordnungsgemäß funktioniert. Dies ist das Linux-Äquivalent zum Umgehen dessen, was für Windows als DLL-Hölle angesehen wird .

Petesh
quelle
Können Sie identoder whatin der Bibliotheksdatei eingebettete Versionsinformationen finden?
David R Tribble
identWenn das lose Äquivalent von a verwendet wird strings -a <file> | grep '\$.*\$', whatwird das Äquivalent von verwendet strings -a <file> | fgrep '@(#)', von denen keines die Versionsinformationen der zugrunde liegenden Bibliothek bestimmt, wenn diese Zeichenfolgen nicht kompiliert sind. Wenn Sie versuchen, die Kompatibilität zu bestimmen, ist es viel sinnvoller, sich auf die ABI-Informationen zu verlassen Es wird im Allgemeinen in den Build eingekocht, während ident / welche Zeichenfolgen dazu neigen, weggelassen zu werden
Petesh