Wie kann ich sicher sagen, welche userland C-Bibliothek mein System verwendet? Mögliche Gründe für die Verwendung dieser Informationen sind:
Es gibt ein gigantisches Quellcode-Paket, das ich herunterladen möchte. Ich bin sicher, dass es ordnungsgemäße Überprüfungen durchführt und eine Mini-Bibliotheksversion auflistet.
Ich bin besorgt über die ABI-Kompatibilität mit einigen Binärdateien von Drittanbietern, die ich außerhalb des Paketverwaltungssystems des Systems installieren möchte.
Ich habe ein Quellpaket, dessen Dokumentation die Notwendigkeit einer Mindestversion der Systembibliothek erwähnt, aber der Erstellungsprozess führt keine Überprüfungen durch.
Ich erstelle einen Cross-Compiler für ein bestimmtes System und möchte keine Probleme mit der Vorwärtskompatibilität riskieren .
quelle
ldd
. Ich bin mir nicht sicher, obotool --version
dies als die gleiche Information angesehen werden kann.Antworten:
GNU / Linux-Systeme verwenden normalerweise entweder glibc (Fedora / Redhat-Familie, Arch) oder seinen nahen Verwandten eglibc (Debian / Ubuntu-Familie). da eglibc nun wieder in glibc zusammengeführt wird ( siehe EGLIBC 2.19 Branch Created under "News" ), werden sie in naher Zukunft alle wieder glibc sein.
Am einfachsten können Sie die genaue Version überprüfen, indem Sie fragen
ldd
, welche Version mit der C-Bibliothek geliefert wird.Auf Fedora 20:
Das ist glibc 2.18.
Auf Raspbian (Debian 7-Port für ARMv6 Broadcom SoC):
Das ist eglibc 2.13.
Wenn Sie aus irgendeinem Grund einige Teile gemischt und abgeglichen haben oder sich nicht sicher sind
ldd
, können Sie die C-Bibliothek direkt abfragen.Keines davon ist ausführbar, aber es gibt einen Hinweis darauf, wo es zu finden ist.
Es ist jedoch nicht unbedingt so einfach, weil die C-Bibliothek sich nicht irgendwo aufhalten muss,
whereis
um sie zu finden.Leider enthält die Manpage keine Versionsnummer.
ldd
Es ist immer noch praktisch, da jede funktionierende, dynamisch verknüpfte ausführbare Datei auf dem System (z. B. fast alles in/usr/bin
) mit der C-Bibliothek verknüpft wird.libc.so.6
ist in der dritten Zeile.quelle
/lib/`uname -m`*
path. So tragbare Art und Weise wäre:find /lib/`uname -m`* /usr/lib* -executable -name "*libc.so*" | xargs --version
. Danke für die nette Erklärung.Ein System ist nicht auf eine C-Bibliothek beschränkt. Die meisten verwenden jedoch in erster Linie nur einen, der auch vom Standard-Compiler verwendet wird. Und da Sie Quellcode zum Kompilieren herunterladen, ist dies derjenige, um den Sie sich kümmern.
Beginnen Sie mit einem einfachen Programm:
Kompilieren Sie es mit dem Compiler, den Sie für den Quellcode verwenden möchten, und ermitteln Sie dann
ldd
, wo sich die C-Bibliothek befindet:Sie haben jetzt den Pfad zur C-Bibliothek. Sie können dies in Ihrem Paketmanager nachschlagen, um das Paket zu finden (z . B.
dpkg -S /lib/x86_64-linux-gnu/libc.so.6
oderrpm -q -f /lib/x86_64-linux-gnu/libc.so.6
).Zumindest im Fall von eglibc / glibc können Sie es ausführen:
Schließlich können Sie
objdump -p /lib/x86_64-linux-gnu/libc.so.6
im Abschnitt mit den Versionsdefinitionen nachsehen , ob Sie Hinweise darauf erhalten können :Beachten Sie, dass das GLIBC_2.18-Symbol die neueste Versionsnummer unter den aufgelisteten Symbolen hat und die Bibliotheksversion in der Tat 2.18 ist. Es ist jedoch eglibc (es soll mit glibc 2.18 binär kompatibel sein, daher werden die gleichen Symbolversionen verwendet).
Sie könnten auch versuchen
strings
, etwas darüber herauszufinden. Sie möchten eine längere minimale Länge angeben (-n
) oder mit grep nach etwas suchen:beide arbeiten für diese eglibc.
HINWEIS: Das Debian-Paket-Dienstprogramm
dpkg-shlibdeps
verwendetobjdump
unter der Haube zusammen mit den in Debian-Bibliothekspaketen gespeicherten Symbolinformationen, um die Mindestversionen von Abhängigkeiten zu bestimmen, die von binären Debian-Paketen zum Zeitpunkt der Erstellung benötigt werden. Im Grunde betrachtet es die vom Debian-Binärpaket exportierten Symbole und findet dann die Mindestversionen der Bibliotheken, die diese Symbole enthalten.quelle
Die naheliegende, wenn auch nicht die umfassendste Antwort ist die Überprüfung Ihres Paketmanagers, z
(Leider hat glibc keine pkconfig-
.pc
Datei,pkgconfig --modversion glibc
ist also kein Runner.) Siehe auch @ Gnoucs exzellentergetconf
Vorschlag.Der einfachste Fall mit gcc + glibc und der, den ich meistens zuerst benutze, ist, einfach auszuführen
libc.so
, wie in einigen anderen Antworten hier beschrieben. Es müssen keine Argumente übergeben werden, die Version wird standardmäßig ausgegeben. Dies funktioniert bis zu glibc-2.1 (glibc-2.0-seg-Fehler), obwohl Sie vor langer Zeit das (inzwischen zurückgezogene)glibcbug
Skript überprüfen konnten , um die Version zu bestätigen. Diese Methode funktioniert auch mit neueren (> 0.9.15) Versionen von musl-libc (die heute, am 20. März, erst 1.0 waren). Es funktioniert nicht mit uClibc, es segfaults.Eine einfache Möglichkeit, genau zu sagen, was Sie
gcc
tun werden, ist das Kompilieren:(mit glibc,
<stdio.h>
enthält ,<features.h>
welche die entsprechenden GLIBC Makros definiert, müssen Sie<gnu/libc-version.h>
für die Funktionsdeklarationen.)Dies erfasst komplexere Fälle (mehrere Bibliotheken und / oder mehrere Compiler), vorausgesetzt, Sie verwenden natürlich den richtigen Compiler (und die richtigen Flags). (Ich vermute, es wird jedoch nicht zwischen eglibc und glibc unterscheiden.)
Wenn Sie sicher sind Sie verwenden glibc (oder eglibc) , dann(sorry, das ist nicht richtig).ld
wird auch die Version bestätigenWenn
__GNU_LIBRARY__
es nicht definiert ist, werden Sie Fehler bekommen, dann ist es Zeit für Plan B.gcc -dumpmachine
kann helfen, zB für Uclibc hat es ein-uclibc
Suffix, wie kanngcc -dumpspecs | grep dynamic-linker
. Dies kann auch die ABI implizieren.gcc -print-file-name=libc.so
wird Ihnen sagen, welche Datei der Compiler für "-lc
" verwenden wird. Dies ist mit ziemlicher Sicherheit ein Linker-Skript in Ihrer gcc-Installation, das Sie als Klartext lesen können. Das zeigt den genauen Pfad zulibc.so
. Dies funktioniert auch, wenn Sie Flags wie-m32
oder übergeben-m64
.Für den Fall , verwenden Sie uclibc ( und wurden von OpenWRT und mehr), es definiert
__UCLIBC_MAJOR__
,__UCLIBC_MINOR__
und__UCLIBC_SUBLEVEL__
als auch__UCLIBC__
in<features.h>
, so dass es leicht ist erkannt eine kleinere Variante des obigen C - Code - Snippet verwenden. Im Interesse der Kompatibilität kann uClibc auch die oben verwendeten GNU / GLIBC-Makros definieren, die derzeit als glibc-2.2 bezeichnet werden. Dabei spielt es keine derzeit die Umsetzunggnu_get_libc_X()
Funktionen, aber es nicht implementieren ,getconf
die auch die Irre führen kann (ich vermute , es gibt eine leere Antwortgetconf GNU_LIBC_VERSION
, mein Build env schmollt heute so kann ich nicht bestätigen.)In dem unwahrscheinlichen Fall, dass Sie dietlibc verwenden , wird beim Ausführen
diet -v
die Version angezeigt.(FWIW, über mehrere Jahre hinweg hatte ich mit Software, die Autoconf verwendet, mehr Probleme mit ungeprüften Funktionen
gcc
undg++
Anforderungen als mit auf glibc geprüften Funktionen.)quelle
GNU libc (was die meisten Linux-Distributionen in der einen oder anderen Form verwenden) ist sehr bemüht, um eine strikte Abwärtskompatibilität zu gewährleisten. Daher sollten Sie nur dann auf Probleme stoßen, wenn Sie versuchen, eine zu neue Binärdatei auf einer alten Version auszuführen (oder auf einer "Enterprise" -Distribution, die normalerweise Versionen einfriert, insbesondere Basisversionen wie die C-Bibliothek, Backporting-Fixes und strenge Binärkompatibilität). . Ich glaube, dass Sie viel häufiger auf Probleme mit anderen Bibliotheken stoßen (C ++ hatte einige API / ABI-Änderungen im letzten Speicher, einige andere Bibliotheken kümmern sich einfach nicht um die Abwärtskompatibilität).
Leider ist der einzige Weg, um sicher herauszufinden, zu versuchen.
quelle
(Dies ist im Wesentlichen dasselbe wie die Antwort von Goldlöckchen, aber mit einer weiteren Erklärung dessen, was unter der Haube vor sich geht.)
Die gemeinsam
libc.so.6
genutzte Kernbibliothek für GNU libc (unter Linux; Hurd hat einen anderen SONAME) hat die ungewöhnliche Eigenschaft (für gemeinsam genutzte Bibliotheken), dass Sie sie als ausführbare Datei aufrufen können. Wenn Sie dies tun, wird die Art von Dingen gedruckt, die GNU-Dienstprogramme normalerweise drucken, wenn sie mit ausgeführt--version
werden:Aber natürlich ist das Verzeichnis, in dem sich das
libc.so.6
Leben befindet, nicht vorhanden.$PATH
Sie müssen also wissen, wo Sie danach suchen müssen. Es könnte sein , in/lib
,/lib64
,/usr/lib
oder etwas noch wackier (wie in diesem Fall). Günstigerweiseldd
werden Sie sagen:Damit dies funktioniert, müssen Sie natürlich den vollständigen Pfadnamen einer dynamisch verknüpften ausführbaren Binärdatei kennen. Die
sh
ausführbare Datei befindet sich garantiert in/bin
(da dies von so vielen#!
Skripten erwartet wird) und kann selbst kein#!
Skript sein. Es könnte statisch verknüpft sein, aber ich bin seit vielen Jahren nicht mehr auf ein System gestoßen, das dies tat.Ich weiß nicht, was du machst, wenn du mit uClibc oder Musl oder etwas Exotischerem unterwegs bist.
quelle
$ ldd $(which sh) | grep libc
. : DEin anderer Weg, um es zu bekommen:
quelle