Comment puis-je savoir avec certitude quelle bibliothèque C userland mon système utilise? Les raisons possibles d'avoir besoin de cette information include:
Il y a un package source gigantesque que je suis en train de download et qui va sûrement faire des vérifications adéquates et qui répertorie une version mininum de la bibliothèque, mais je préfère me préoccuper en vérifiant d'abord si cela fonctionnera.
Je suis préoccupé par la compatibilité ABI avec certains binarys tiers que je veux essayer et installer en dehors du système de gestion des packages du système.
J'ai un package source dont la documentation mentionne la nécessité d'une version minimum de la bibliothèque de mon système, mais le process de construction n'effectue aucun contrôle.
Je construis un compilateur croisé ciblant un système spécifique et je ne veux pas risquer des problèmes de compatibilité .
Les systèmes GNU / Linux utilisent généralement soit la glibc (famille Fedora / Redhat, Arch) ou son cousin proche, eglibc (famille Debian / Ubuntu); puisque eglibc est maintenant en train d'être fusionné en glibc ( voir EGLIBC 2.19 Branch Created sous "News" ), dans un proche avenir, ils seront de nouveau glibc.
La façon la plus simple de vérifier la version exacte est de requestr à ldd
, ldd
avec la bibliothèque C.
Sur Fedora 20:
> ldd --version ldd (GNU libc) 2.18
C'est la glibc 2.18.
Sur Raspbian (port Debian 7 pour le SoC ARMv6 Broadcom):
> ldd --version ldd (Debian EGLIBC 2.13-38+rpi2) 2.13
C'est eglibc 2.13.
Si, pour une raison quelconque, vous avez mélangé et assorti certaines parties ou n'êtes pas sûr de ldd
, vous pouvez interroger la bibliothèque C directement.
> whereis libc.so libc: /usr/lib64/libc.a /usr/lib64/libc.so /usr/share/man/man7/libc.7.gz
Aucun de ceux-ci n'est exécutable, mais ils fournissent un indice sur l'endroit où en find un.
> $(find /usr/lib64/ -executable -name "*libc.so*") --version GNU C Library (GNU libc) stable release version 2.18, by Roland McGrath et al.
Cependant, ce n'est pas nécessairement si facile, car la bibliothèque C n'a pas à résider quelque part whereis
peut le find.
> whereis libc.so libc: /usr/share/man/man7/libc.7.gz
Malheureusement, la page de manuel ne fournit pas de numéro de version. ldd
toujours utile car tout exécutable lié dynamicment au système (par exemple, presque tout dans /usr/bin
) sera lié à la bibliothèque C.
> ldd /usr/bin/touch /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6eed000) librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xb6ed0000) libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6da1000) /lib/ld-linux-armhf.so.3 (0xb6efb000) libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6d82000)
libc.so.6
est sur la troisième ligne.
> /lib/arm-linux-gnueabihf/libc.so.6 --version GNU C Library (Debian EGLIBC 2.13-38+rpi2) stable release version 2.13, by Roland McGrath et al.
Un système n'est pas réellement limité à une bibliothèque C. La plupart, cependant, utilisent principalement un seul, qui sera également celui que le compilateur par défaut utilise. Et puisque vous téléchargez le code source pour comstackr, c'est celui qui vous préoccupe.
Commencez avec un programme sortingvial:
#include <stdio.h> int main() { printf("Hello, world\n"); return 0; }
comstackz-le en utilisant le compilateur que vous allez utiliser pour le code source, puis utilisez ldd
pour savoir où se trouve la bibliothèque C:
$ ldd ./libc-test linux-vdso.so.1 (0x00007fff2e5fe000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c8ad98000) /lib64/ld-linux-x86-64.so.2 (0x00007f8c8b171000)
Vous avez maintenant le path vers la bibliothèque C. Vous pouvez le searchr dans votre gestionnaire de packages pour find le package (par exemple, dpkg -S /lib/x86_64-linux-gnu/libc.so.6
ou rpm -q -f /lib/x86_64-linux-gnu/libc.so.6
).
Au less dans le cas de eglibc / glibc, vous pouvez l'exécuter:
$ /lib/x86_64-linux-gnu/libc.so.6 GNU C Library (Debian EGLIBC 2.18-4) stable release version 2.18, by Roland McGrath et al. Copyright (C) 2013 Free Software Foundation, Inc. ⋮
Enfin, vous pouvez voir si vous pouvez get des indices de objdump -p /lib/x86_64-linux-gnu/libc.so.6
, en regardant dans la section des définitions de version :
Version definitions: 1 0x01 0x0865f4e6 libc.so.6 2 0x00 0x09691a75 GLIBC_2.2.5 3 0x00 0x09691a76 GLIBC_2.2.6 ⋮ 21 0x00 0x06969197 GLIBC_2.17 GLIBC_2.16 22 0x00 0x06969198 GLIBC_2.18 GLIBC_2.17 23 0x00 0x0963cf85 GLIBC_PRIVATE GLIBC_2.18
Notez comment le symbole GLIBC_2.18 a le numéro de version le plus récent parmi les symboles listés, et la version de bibliothèque est en effet 2.18. Il est cependant eglibc (il a l'intention d'être binary compatible avec la glibc 2.18, donc il utilise les mêmes versions de symboles).
Vous pouvez également essayer d'utiliser des ssortingngs
pour find quelque chose à ce sujet. Vous voudrez spécifier une longueur minimale plus longue ( -n
) ou utiliser grep pour searchr quelque chose:
$ ssortingngs /lib/x86_64-linux-gnu/libc.so.6 | grep 'version [0-9]' $ ssortingngs /lib/x86_64-linux-gnu/libc.so.6 | grep -iC1 'copyright'
les deux travaillent pour cet eglibc.
REMARQUE: L'utilitaire de package Debian dpkg-shlibdeps
utilise objdump
sous le capot, avec les informations de symbole stockées dans les packages de la bibliothèque Debian pour déterminer les versions minimales des dependencies requirejses par les packages Debian binarys au moment de la construction. Fondamentalement, il regarde les symboles exportés par le package Debian binary, puis trouve les versions minimales des bibliothèques qui contiennent ces symboles.
La réponse évidente, bien que pas la plus complète, est de vérifier votre gestionnaire de packages, par exemple
rpm -qi glibc dpkg -l libc6
(Malheureusement, la glibc n'a pas de file pkconfig .pc
, donc pkgconfig --modversion glibc
est un non-runner.) Voir aussi l'excellente suggestion getconf
@ Gnouc.
Le cas le plus simple, avec gcc + glibc, et celui que j'utilise le plus souvent en premier est de simplement exécuter libc.so
, comme indiqué dans certaines des autres réponses ici. Il n'y a pas besoin de passer d'arguments, il sort sa version par défaut. Cela fonctionne jusqu'à la glibc-2.1 (glibc-2.0 seg-failles, bien que vous puissiez alors vérifier le script glibcbug
(maintenant retiré) pour confirmer la version). Cette méthode fonctionne aussi avec les versions récentes (> 0.9.15) de musl-libc (qui vient d'être 1.0 aujourd'hui, le 20 mars). Il ne fonctionne pas avec uClibc, il segfaults.
Une façon simple de dire exactement ce que votre gcc
va faire est de comstackr:
#include <gnu/libc-version.h> #include <stdio.h> int main(int argc, char *argv[]) { printf("%s %s\n",gnu_get_libc_version(),gnu_get_libc_release()); printf("glibc v%i %i.%i\n",__GNU_LIBRARY__,__GLIBC__,__GLIBC_MINOR__); return 0; }
(avec glibc, <stdio.h>
inclut <features.h>
qui définit les macros GLIBC pertinentes, vous devez <gnu/libc-version.h>
pour les déclarations de fonctions).
Ceci attrape des cas plus complexes (libc multiples, et / ou plusieurs compilateurs), en supposant que vous utilisez le bon compilateur (et les drapeaux) bien sûr. (Je soupçonne qu'il ne fera pas la distinction entre eglibc et glibc proprement dit.)
Si vous êtes certain que vous utilisez glibc (ou eglibc), (désolé, ce n'est pas correct). ld
confirmera également la version
Si __GNU_LIBRARY__
n'est pas défini, vous obtiendrez des erreurs, alors il est time pour le plan B.
gcc -dumpmachine
peut aider, par exemple pour uclibc il a un suffixe -uclibc
, comme gcc -dumpspecs | grep dynamic-linker
gcc -dumpspecs | grep dynamic-linker
. Cela peut également impliquer l'ABI.
gcc -print-file-name=libc.so
vous dira quel file le compilateur utilisera pour " -lc
", il s'agit presque certainement d'un script de binding dans votre installation de gcc, que vous pouvez lire en text brut. Cela montrera le path exact vers libc.so
Cela fonctionnera également si vous passez des drapeaux comme -m64
ou -m64
.
Dans le cas où vous utilisez uclibc (utilisé par OpenWRT et plus), il définit __UCLIBC_MAJOR__
, __UCLIBC_MINOR__
et __UCLIBC_SUBLEVEL__
ainsi que __UCLIBC__
dans <features.h>
, donc il est facilement détecté en utilisant une variation mineure sur l'extrait de code C ci-dessus. Dans l'intérêt de la 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 gnu_get_libc_X()
pas actuellement les fonctions gnu_get_libc_X()
, mais il implémente getconf
qui peut aussi induire en erreur (je soupçonne qu'il renvoie une réponse vide pour getconf GNU_LIBC_VERSION
, ma build env est boude aujourd'hui donc je ne peux pas confirmer).
Dans le cas improbable où vous utilisez dietlibc , l' option running diet -v
affichera la version.
(FWIW, sur plusieurs années avec un logiciel utilisant autoconf J'ai eu plus de problèmes avec les exigences gcc
et g++
non vérifiées qu'avec les fonctionnalités de glibc vérifiées).
GNU libc (ce que la plupart des dissortingbutions Linux utilisent sous une forme ou une autre) fait de grands efforts pour garder une rétrocompatibilité ssortingcte. Donc, vous ne devriez rencontrer des problèmes que si vous tentez d'exécuter un nouveau binary sur une ancienne version (ou une dissortingbution "d'entreprise", normalement les versions de base, comme la bibliothèque C, . Je pense que vous êtes beaucoup plus susceptible de rencontrer des problèmes avec d'autres bibliothèques (C ++ a eu quelques changements d'API / ABI dans la memory récente, d'autres bibliothèques ne se soucient pas de la rétrocompatibilité).
Malheureusement, la seule façon de le savoir est d'essayer.
(C'est essentiellement la même chose que la réponse de Goldilocks mais avec plus d'explications sur ce qui se passe sous le capot.)
La librairie partagée principale pour GNU libc, libc.so.6
(sur Linux, Hurd a un SONAME différent), possède la propriété inhabituelle (pour les bibliothèques partagées) que vous pouvez l'appeler en tant qu'exécutable. Si vous le faites, il imprime le genre de choses que les utilitaires GNU impriment généralement lorsqu'ils sont exécutés avec --version
, comme ceci:
$ /lib/x86_64-linux-gnu/libc.so.6 GNU C Library (Debian EGLIBC 2.18-4) stable release version 2.18, by Roland McGrath et al. Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Comstackd by GNU CC version 4.8.2. Comstackd on a Linux 3.12.6 system on 2014-03-02. Available extensions: crypt add-on version 2.1 by Michael Glad and others GNU Libidn by Simon Josefsson Native POSIX Threads Library by Ulrich Drepper et al BIND-8.2.3-T5B libc ABIs: UNIQUE IFUNC For bug reporting instructions, please see: <http://www.debian.org/Bugs/>.
Mais bien sûr, le directory où libc.so.6
réside n'est pas dans $PATH
, vous devez donc savoir où le searchr. Il pourrait être dans /lib
, /lib64
, /usr/lib
, ou quelque chose encore plus wackier (comme dans ce cas). Idéalement, ldd
vous dira:
$ ldd /bin/sh | grep libc libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5660b93000)
Pour que cela fonctionne, bien sûr, vous devez connaître le path d'access complet d'un exécutable binary lié dynamicment. L'exécutable sh
est garanti dans /bin
(parce que tant de scripts #!
attendent), et ne peut pas être lui-même un #!
scénario. Il pourrait être lié statiquement, mais je n'ai pas rencontré un système qui a fait cela dans de nombreuses années.
Je ne sais pas ce que vous faites si vous courez avec uClibc ou Musl ou quelque chose de plus exotique.
Une autre façon de l'get:
getconf GNU_LIBC_VERSION