Comment savoir avec certitude quelle bibliothèque C utilisateur est utilisée par mon système? Les raisons possibles pour avoir besoin de ces informations incluent:
J'envisage de télécharger un paquet source gigantesque qui, j'en suis sûr, effectuera les vérifications appropriées et répertorie une version de bibliothèque mininum, mais je préfère me préserver d'un problème en vérifiant d'abord si cela fonctionnera.
Je suis préoccupé par la compatibilité ABI avec certains fichiers binaires tiers que je veux essayer d'installer en dehors du système de gestion des paquets du système.
J'ai un paquet source dont la documentation mentionne le besoin d'une version minimale de la bibliothèque de mon système, mais le processus de construction n'effectue aucune vérification.
Je construis un compilateur croisé ciblant un système spécifique et je ne veux pas risquer de problèmes de compatibilité .
la source
ldd
. Je ne sais pas siotool --version
peut être considéré comme donnant les mêmes informations.Réponses:
Les systèmes GNU / Linux utilisent généralement soit glibc (famille Fedora / Redhat, Arch), soit son cousin proche, eglibc (famille Debian / Ubuntu); puisque eglibc est maintenant en train de fusionner de nouveau dans glibc ( voir EGLIBC 2.19 - Branchée sous "Actualités" ), dans un avenir proche, ils seront tous de nouveau glibc.
Le moyen le plus simple de vérifier la version exacte est de demander
ldd
qui est livré avec la bibliothèque C.Sur Fedora 20:
C'est glibc 2.18.
Sur Raspbian (port Debian 7 pour le SoC ARMv6 Broadcom):
C'est eglibc 2.13.
Si, pour une raison quelconque, vous avez mélangé et mis en correspondance certaines parties ou si vous n’êtes pas sûr de
ldd
votre choix, vous pouvez interroger directement la bibliothèque C.Aucun de ceux-ci n'est exécutable, mais ils fournissent un indice sur l'endroit où en trouver un.
Cependant, ce n'est pas forcément si facile, car la bibliothèque C n'a pas besoin de résider quelque part
whereis
pour la trouver.Malheureusement, la page de manuel ne fournit pas de numéro de version.
ldd
reste pratique, car tout exécutable fonctionnel lié dynamiquement sur le système (par exemple, presque tout dedans/usr/bin
) sera lié à la bibliothèque C.libc.so.6
est sur la troisième ligne.la source
/lib/`uname -m`*
chemin. Donc , de manière portable serait:find /lib/`uname -m`* /usr/lib* -executable -name "*libc.so*" | xargs --version
. Merci pour la bonne explication.Un système n'est pas limité à une seule bibliothèque C. La plupart, cependant, n'utilisent principalement qu'un seul, qui sera également celui utilisé par le compilateur par défaut. Et puisque vous téléchargez le code source à compiler, c’est celui qui vous intéresse.
Commencez avec un programme trivial:
compilez-le à l'aide du compilateur que vous allez utiliser pour le code source, puis utilisez-le
ldd
pour savoir où se trouve la bibliothèque C:Vous avez maintenant le chemin de la bibliothèque C. Vous pouvez le rechercher dans votre gestionnaire de paquets pour trouver le paquet (par exemple,
dpkg -S /lib/x86_64-linux-gnu/libc.so.6
ourpm -q -f /lib/x86_64-linux-gnu/libc.so.6
).Au moins dans le cas de eglibc / glibc, vous pouvez le lancer:
Enfin, vous pouvez voir si vous pouvez obtenir des indices
objdump -p /lib/x86_64-linux-gnu/libc.so.6
en consultant la section des définitions de version :Notez que le symbole GLIBC_2.18 a le numéro de version le plus récent parmi les symboles répertoriés et que la version de la bibliothèque est bien 2.18. C'est eglibc, cependant (il est compatible binaire avec glibc 2.18, il utilise donc les mêmes versions de symboles).
Vous pouvez également essayer d'utiliser
strings
pour trouver quelque chose à ce sujet. Vous voudrez spécifier une longueur minimale (-n
) plus longue ou utiliser grep pour rechercher quelque chose:les deux travaillent pour cet eglibc.
REMARQUE: L'utilitaire de paquet Debian
dpkg-shlibdeps
utiliseobjdump
sous le capot, ainsi que les informations de symbole stockées dans les paquets de la bibliothèque Debian, pour déterminer les versions minimales des dépendances requises par les paquets binaires Debian au moment de la construction. Fondamentalement, il examine les symboles exportés par le paquet binaire Debian, puis recherche les versions minimales des bibliothèques contenant ces symboles.la source
La réponse évidente, bien que pas la plus complète, consiste à vérifier votre gestionnaire de paquets, par exemple:
(Malheureusement, glibc n'a pas de
.pc
fichier pkconfig , il enpkgconfig --modversion glibc
va de même pour les non-coureurs.) Voir aussi l'excellentegetconf
suggestion de @Gnouc .Le cas le plus simple, avec gcc + glibc, et celui que j’utilise le plus souvent en premier lieu, consiste simplement à exécuter
libc.so
, comme indiqué dans certaines des autres réponses données ici. Il n'est pas nécessaire de passer des arguments, il affiche sa version par défaut. Cela fonctionne aussi loin que glibc-2.1 (les défauts de segmentation de glibc-2.0, bien que vous ayez déjà pu vérifier leglibcbug
script (maintenant abandonné) pour confirmer la version). Cette méthode fonctionne également avec les versions récentes (> 0.9.15) de musl-libc (qui vient de passer à 1.0 aujourd'hui, le 20 mars). Cela ne fonctionne pas avec uClibc, il segfaults.Un moyen simple de dire exactement ce que vous
gcc
allez faire est de compiler:(avec glibc,
<stdio.h>
comprend<features.h>
qui définit les macros GLIBC pertinentes, vous avez besoin<gnu/libc-version.h>
pour les déclarations de fonction.)Cela intercepte des cas plus complexes (plusieurs bibliothèques et / ou plusieurs compilateurs), en supposant que vous utilisiez le bon compilateur (et les bons indicateurs) bien sûr. (Je suppose que cela ne fera pas la distinction entre eglibc et glibc proprement dit.)
Si vous êtes certain d’utiliser glibc (ou eglibc),(désolé, ce n’est pas correct).ld
la version sera également confirméeSi
__GNU_LIBRARY__
n'est pas défini, vous obtiendrez des erreurs, alors il est temps pour le plan B.gcc -dumpmachine
peut aider, par exemple pour uclibc, il a un-uclibc
suffixe, comme vous le pouvezgcc -dumpspecs | grep dynamic-linker
. Cela peut aussi impliquer l’ABI.gcc -print-file-name=libc.so
vous dira quel fichier le compilateur utilisera pour "-lc
", il s'agit certainement d'un script d'éditeur de liens au sein de votre installation gcc, que vous pouvez lire en texte brut. Cela montrera le chemin exact pourlibc.so
. Cela fonctionnera également si vous passez des drapeaux tels que-m32
ou-m64
.Dans le cas où vous utilisez uclibc (tel qu'il est utilisé par OpenWRT et plus), il définit
__UCLIBC_MAJOR__
,__UCLIBC_MINOR__
et__UCLIBC_SUBLEVEL__
ainsi que__UCLIBC__
dans<features.h>
, il est donc facile à détecter en utilisant une variation mineure sur l'extrait de code ci - dessus C. Dans un souci de compatibilité, uClibc peut également définir les macros GNU / GLIBC telles qu’utilisées ci-dessus, il prétend actuellement être glibc-2.2. Il ne met pas en œuvre actuellement lesgnu_get_libc_X()
fonctions, mais il ne mettre en œuvre cegetconf
qui peut aussi induire en erreur (je soupçonne qu'il renvoie une réponse vide pourgetconf GNU_LIBC_VERSION
ma construction env boude aujourd'hui , donc je ne peux pas confirmer.)Dans le cas peu probable où vous utiliseriez dietlibc , l'exécution
diet -v
affichera la version.(FWIW, depuis plusieurs années avec le logiciel en utilisant autoconf j'ai eu plus de problèmes avec décochée-pour
gcc
et lesg++
exigences qu'avec le check-pour les fonctions de la glibc.)la source
GNU libc (ce que la plupart des distributions Linux utilisent sous une forme ou une autre) fait tout son possible pour maintenir une compatibilité ascendante stricte. Vous ne devriez donc rencontrer de problèmes que si vous essayez de lancer un binaire trop nouveau sur une ancienne version (ou une distribution "entreprise", ils gèlent normalement les versions, en particulier celles de base comme la bibliothèque C, rétroportant les correctifs tout en conservant une compatibilité binaire considérable) . Je pense que vous êtes beaucoup plus susceptible de rencontrer des problèmes avec d'autres bibliothèques (C ++ avait quelques modifications d'API / ABI dans la mémoire récente, d'autres bibliothèques ne se soucient tout simplement pas de la compatibilité avec les versions antérieures).
Malheureusement, le seul moyen de le savoir est d'essayer.
la source
(Ceci est essentiellement la même chose que la réponse de goldilocks mais avec quelques explications supplémentaires sur ce qui se passe sous le capot.)
La bibliothèque principale partagée pour GNU libc
libc.so.6
(sous Linux; Hurd a un nom différent de SONAME) a la propriété inhabituelle (pour les bibliothèques partagées) que vous pouvez appeler en tant qu'exécutable. Si vous le faites, il affiche le type de choses que les utilitaires GNU impriment généralement lorsqu’ils sont exécutés--version
, comme ceci:Mais bien sûr, le répertoire où
libc.so.6
vit n'est pas$PATH
, vous devez donc savoir où le chercher. Il pourrait être/lib
,/lib64
,/usr/lib
ou quelque chose d' encore farfelue (comme dans ce cas). Commodément,ldd
vous dira:Pour que cela fonctionne, vous devez bien sûr connaître le chemin complet d'un exécutable binaire lié dynamiquement. L’
sh
exécutable est garanti/bin
(car de nombreux#!
scripts l’attendent) et ne peut pas être lui-même un#!
script. Cela pourrait être lié statiquement, mais je n'ai pas rencontré de système qui le fasse depuis de nombreuses années.Je ne sais pas ce que vous faites si vous utilisez uClibc ou musl ou quelque chose de plus exotique.
la source
$ ldd $(which sh) | grep libc
. : DUne autre façon de l'obtenir:
la source