Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Code binaire de la bibliotheque standard

19 réponses
Avatar
candide
Bonjour,

Comment, en général, le code binaire de la bibliothèque standard apparait-il
dans le système de fichier ? sous la forme d'un seul (et assez gros ?) fichier
ou en plusieurs fichiers, chacun gérant les fonctions de chaque en-tête
(<stdlib.h>, <stdio.h>, etc), en supposant qu'il s'agisse de fichiers (je sais
que ce n'est pas nécessaire).

D'autre part, toujours en général, la bibliothèque standard est-elle statique ou
dynamique ? Sous Windows avec Mingw, il me semble que c'est un fichier
d'extension .a . Sous Linux et gcc, qu'en est-il ? De quel(s) fichier(s) (nom,
extension et répertoire) s'agit-il ?

Merci

10 réponses

1 2
Avatar
Mickaël Wolff
candide a écrit :
Comment, en général, le code binaire de la bibliothèque standard apparait-il
dans le système de fichier ?




Sous la forme d'un fichier :D Les fonctions de la bibliothèque
standard sont pour la plupart dans une bibliothèque nommée libc.so. La
plupart car il y a des exceptions, telles que les fonctions
mathématiques qui sont dans le fichier libm.so (c'est pour ça qu'il faut
lier avec l'argument -lm, regarde le manuel de abs). Ces fichiers sont
en fait les bibliothèques partagées. Lorsqu'un programme est exécuté,
les bibliothèques dont il a besoin sont chargées en mémoire. Il va s'en
dire que, si la bibliothèque est déjà chargée, l'OS ne recharge pas le
fichier.

Il y a aussi la forme statique, qui sont les fichiers que tu as
repéré suffixé par .a. Lorsque tu compiles en statique (flag -static de
ld), les fichiers objets (.o) contenus dans le fichier archive (.a) sont
inclus dans l'exécutable final. L'intérêt est que tu ne dépend pas des
bibliothèques installées sur le système. L'inconvénient, c'est le poids
du bestiaux, et l'emprunte mémoire.

MS Windows a des spécificités, que je ne connais pas bien. Les .so
n'y existent pas, ce sont des .dll, qui ont un fonctionnement
particulier. Il faut aussi parler des fichiers .lib nécessaire au liage
sous MS Windows.

Les fichiers .a sont des fichiers archive créés avec la commande ar,
contenant des fichiers objet (.o).
On créé une bibliothèque partagée avec la commande suivante par
exemple : cc -shared -Wl,-soname,libtoto.so -o libtoto.so toto.o

Sous Linux, les bibliothèques sont généralement rangées dans /lib/ et
/usr/lib/. Je te laisse chercher les archives ;) À noter que les
primitives système sont des symboles du noyau.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Seeking for a position <http://lupusmic.org/pro/>
Avatar
Mickaël Wolff
Petite rectification :

Mickaël Wolff a écrit :
telles que



certaines

fonctions mathématiques qui sont dans le fichier libm.so (c'est pour ça qu'il faut
lier avec l'argument -lm, regarde le manuel de



sin

). Ces fichiers sont en fait les bibliothèques partagées.


--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Seeking for a position <http://lupusmic.org/pro/>
Avatar
Eric Levenez
Le 01/02/09 14:52, dans <4985a8ed$0$24377$, « Mickaël
Wolff » a écrit :

candide a écrit :
Comment, en général, le code binaire de la bibliothèque standard apparait-il
dans le système de fichier ?



Sous la forme d'un fichier :D Les fonctions de la bibliothèque
standard sont pour la plupart dans une bibliothèque nommée libc.so. La
plupart car il y a des exceptions, telles que les fonctions
mathématiques qui sont dans le fichier libm.so (c'est pour ça qu'il faut
lier avec l'argument -lm, regarde le manuel de abs). Ces fichiers sont
en fait les bibliothèques partagées. Lorsqu'un programme est exécuté,
les bibliothèques dont il a besoin sont chargées en mémoire. Il va s'en
dire que, si la bibliothèque est déjà chargée, l'OS ne recharge pas le
fichier.



Pour compléter, sur Darwin et donc Mac OS X, les bibliothèques partagées
sont des .dylib. Toutes les fonctions standards sont dans libSystem, y
compris les fonctions mathématiques, il n'y a donc pas besoin du -lm des
autres Unix.

Il y a aussi la forme statique, qui sont les fichiers que tu as
repéré suffixé par .a. Lorsque tu compiles en statique (flag -static de
ld), les fichiers objets (.o) contenus dans le fichier archive (.a) sont
inclus dans l'exécutable final. L'intérêt est que tu ne dépend pas des
bibliothèques installées sur le système. L'inconvénient, c'est le poids
du bestiaux, et l'emprunte mémoire.



Un autre avantage des bibliothèque statique est la rapidité d'exécution car
les appels systèmes sont résolus un seul appel de fonction au lieu d'une
indirection généralement utilisée pour les bibliothèques dynamiques. Sur des
unix traditionnels, les programmes qui utilisent fortement les calculs
mathématiques, sont souvent linkés avec la bibliothèque mathématique
statique.

Les fichiers .a sont des fichiers archive créés avec la commande ar,
contenant des fichiers objet (.o).
On créé une bibliothèque partagée avec la commande suivante par
exemple : cc -shared -Wl,-soname,libtoto.so -o libtoto.so toto.o



Sous Darwin, Mac OS X, les bibliothèques partagées sont créées avec libtool.

Sous Linux, les bibliothèques sont généralement rangées dans /lib/ et
/usr/lib/. Je te laisse chercher les archives ;) À noter que les
primitives système sont des symboles du noyau.



Sous Darwin, Mac OS X, les bibliothèques peuvent, comme les exécutables,
contenir plusieurs architectures (ppc32, ppc64, i386, x86_64...) ce qui
simplifie grandement la distribution des logiciels.

--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Avatar
-ed-
On 1 fév, 14:07, candide wrote:
Bonjour,

Comment, en général, le code binaire de la bibliothèque standard ap parait-il
dans le système de fichier ? sous la forme d'un seul (et assez gros ?) fichier
ou en plusieurs fichiers,



Souvent 1 à 2 fichiers.

gcc/MingW : libc.



chacun gérant les fonctions de chaque en-tête
(<stdlib.h>, <stdio.h>, etc), en supposant qu'il s'agisse de fichiers (je sais
que ce n'est pas nécessaire).

D'autre part, toujours en général, la bibliothèque standard est-ell e statique ou
dynamique ? Sous Windows avec Mingw, il me semble que c'est un fichier
d'extension .a . Sous Linux et gcc, qu'en est-il ? De quel(s) fichier(s) (nom,
extension et répertoire) s'agit-il ?

Merci


Avatar
-ed-
On 1 fév, 14:07, candide wrote:
Bonjour,

Comment, en général, le code binaire de la bibliothèque standard ap parait-il
dans le système de fichier ? sous la forme d'un seul (et assez gros ?) fichier
ou en plusieurs fichiers, chacun gérant les fonctions de chaque en-tê te
(<stdlib.h>, <stdio.h>, etc), en supposant qu'il s'agisse de fichiers (je sais
que ce n'est pas nécessaire).



Généralement sous la forme de plusieurs fichiers.

Par exemple, avec gcc/MinGW, on a libc.a pour les fonctions autres que
celles de <math.h>, et libm.a pour celles-ci.

Ces .lib peuvent contenir soit tout le code (bibliothèque statiques,
comme sous DOS ou en embarqué), soit une simple interface permettant
de charger et d'accéder à une bibliothèque partagée généralemen t
fournie par le système :

Par exemple :

- Windows : msvcrt.dll (MicroSoft Visual C RunTime)
- GNU/Linux : libc.so (et libm.so ? à vérifier...)


D'autre part, toujours en général, la bibliothèque standard est-ell e statique ou
dynamique ? Sous Windows avec Mingw, il me semble que c'est un fichier
d'extension .a . Sous Linux et gcc, qu'en est-il ? De quel(s) fichier(s) (nom,
extension et répertoire) s'agit-il ?



Pour le répertoire, un simple grep te renseignera.
Avatar
-ed-
On 2 fév, 09:54, -ed- wrote:

Ces .lib peuvent contenir soit tout le code (bibliothèque statiques,



Ces .a ...
Avatar
candide
candide a écrit :

Comment, en général, le code binaire de la bibliothèque standard apparait-il
dans le système de fichier ?



J'ai posé cette question parce je souhaitais mener une petite expérience
didactique.

Je me rappelle que lors ma découverte du C il y a un peu plus de trois ans,
j'avais été très intrigué par les explications que j'avais lues dans mon livre
de C sur le processus de compilation et en particulier par le rôle du code
objet, des fichiers .a, des fichiers d'en-tête (que je considérais comme
binaires) et de l'édition de liens. D'ailleurs, j'ai mis fort longtemps à
comprendre que les messages que m'envoyait mon compilateur n'étaient pas tous de
même nature (erreur de compilation vs erreur de liaison).

Voilà pourquoi j'avais envie de faire l'expérience suivante :

1°) je crée un fichier source toto.c contenant un printf("Salut !n");
2°) je supprime (ou je déplace plutôt) le fichier de bibliothèque (libmachin.a
ou libmachin.so) contenant le code de printf()
3°) je tente de "compiler" toto.c : échec avéré par un message (pas d'exécutable).
4°) je place le fichier de bibliothèque libmachin.* dans le répertoire de toto.c
5°) je compile avec la commande adéquate : l'exécutable est produit.

Avec le recul, je me dis qu'on m'aurait présenté les choses ainsi, ça m'aurait
paru beaucoup plus clair et j'aurais compris beaucoup plus vite.

Maintenant, je me rends compte que dans mes implémentations, il y a une
multitude de fichiers .a (Mingw) ou .so gcc sous Linux) et que je ne sais même
pas lequel supprimer. Donc mon expérience va probablement tourner court surtout
que j'ai pas envie d'y passer des heures et des heures.

Si je lance en console:

$ nm a.out

je n'obtiens même pas mention du printf que j'avais dans toto.c, j'ai le symbole :

08049574 d p.5841
U puts@@GLIBC_2.0

donc je ne sais pas si je dois déduire que le fichier à déplacer est GLIBC_2.0.so .


Bref, tout ça pour dire aussi que le traitement livresque des langages de
programmation ne donne pas son côté tangible au langage.


Pendant que j'y suis, j'en profite pour poser la question technique suivante :

comment fait-on sous Linux pour fondre deux fichiers objets en un seul :
toto1.o +toto2.o = toto.o ? C'est possible ? (Naturellement, j'ai parcouru
longuement le manuel de gcc.)
Avatar
Marc Boyer
On 2009-02-02, candide wrote:
candide a écrit :

Comment, en général, le code binaire de la bibliothèque standard apparait-il
dans le système de fichier ?



J'ai posé cette question parce je souhaitais mener une petite expérience
didactique.

Je me rappelle que lors ma découverte du C il y a un peu plus de trois ans,
j'avais été très intrigué par les explications que j'avais lues dans mon livre
de C sur le processus de compilation et en particulier par le rôle du code
objet, des fichiers .a, des fichiers d'en-tête (que je considérais comme
binaires) et de l'édition de liens. D'ailleurs, j'ai mis fort longtemps à
comprendre que les messages que m'envoyait mon compilateur n'étaient pas tous de
même nature (erreur de compilation vs erreur de liaison).

Voilà pourquoi j'avais envie de faire l'expérience suivante :

1°) je crée un fichier source toto.c contenant un printf("Salut !n");
2°) je supprime (ou je déplace plutôt) le fichier de bibliothèque (libmachin.a
ou libmachin.so) contenant le code de printf()
3°) je tente de "compiler" toto.c : échec avéré par un message (pas d'exécutable).



Sauf que justement, si tu ne faisais que la phase de *compilation*
(option -c de gcc), ça devrait compiler sans aucun problème. C'est
*l'édition de lien* qui devrait planter.

4°) je place le fichier de bibliothèque libmachin.* dans le répertoire de toto.c
5°) je compile avec la commande adéquate : l'exécutable est produit.

Avec le recul, je me dis qu'on m'aurait présenté les choses ainsi, ça m'aurait
paru beaucoup plus clair et j'aurais compris beaucoup plus vite.



Pour toi, pourquoi pas.

Maintenant, je me rends compte que dans mes implémentations, il y a une
multitude de fichiers .a (Mingw) ou .so gcc sous Linux) et que je ne sais même
pas lequel supprimer. Donc mon expérience va probablement tourner court surtout
que j'ai pas envie d'y passer des heures et des heures.



Je comprends. D'ailleurs, je pense que le but c'est justement que ce soit
le compilo qui s'en débrouille, et pas le programmeur (en général).

Si je lance en console:

$ nm a.out

je n'obtiens même pas mention du printf que j'avais dans toto.c, j'ai le symbole :

08049574 d p.5841
U puts@@GLIBC_2.0



J'en déduit que le compilo a été intelligent, et qu'il a remplacé l'appel
à printf (grosse fonction) à un appel équivalent ici à puts.

donc je ne sais pas si je dois déduire que le fichier à déplacer est GLIBC_2.0.so .



Moi non plus. Ceci dit, je me demande même si la machine redémarrerait
bien si on déplacait la libc sans prévenir le reste du système.

Bref, tout ça pour dire aussi que le traitement livresque des langages de
programmation ne donne pas son côté tangible au langage.



Un langage est une chose, son implantation en est une autre.

Après, il est vrai qu'en 2008, il ne reste plus que deux familles d'OS,
les Win* et les Unix-like, et qu'on pourrait se contenter de décrire le
fonctionnement "habituel" sur ces deux familles d'OS là.

M'enfin bon, ça ne me semble pas très spécifique au C tout ça,
car il me semble qu'une fois qu'un OS a défini quelques politiques
de gestion de bibliothèques partagées, ce sont les langages/compilo/
interpéteurs/machines virtuelles qui se fondent dedans.

C'est vrai que le C a, sur les Unix-like, une place privilégiée
par rapport à l'OS ceci dit.

Marc Boyer
--
Au XXIème siècle, notre projet de société s'est réduit à un projet
économique...
Avatar
batyann811
candide wrote:


donc je ne sais pas si je dois déduire que le fichier à déplacer est GLIBC_2.0.so .




Chez moi c'est /lib/libc-2.3.5.so. Mais ne t'aventures pas à effacer ou
déplacer ce fichier car tu risques d'avoir de gros problèmes. Du genre
ne plus pouvoir lancer aucun programme qui serait lié avec cette
bibliothèque.

Pendant que j'y suis, j'en profite pour poser la question technique suivante :

comment fait-on sous Linux pour fondre deux fichiers objets en un seul :
toto1.o +toto2.o = toto.o ? C'est possible ? (Naturellement, j'ai parcouru
longuement le manuel de gcc.)



Oui c'est possible. http://www.trustonme.net/didactels/154.html
Avatar
candide
Marc Boyer a écrit :

3°) je tente de "compiler" toto.c : échec avéré par un message (pas d'exécutable).



Sauf que justement, si tu ne faisais que la phase de *compilation*
(option -c de gcc), ça devrait compiler sans aucun problème. C'est
*l'édition de lien* qui devrait planter.




Et c'est pourquoi, j'avais écrit compiler entre guillemets. C'est toute
l'ambiguïté de ce terme : quand on dit "compiler", et en particulier on
s'adresse à des débutants, le plus souvent cela signifie (préprocesseur +
compilateur + assembleur + éditeur de liens) autrement dit tout le cycle de
production depuis la source vers l'application, lequel doit rester transparent.




Maintenant, je me rends compte que dans mes implémentations, il y a une
multitude de fichiers .a (Mingw) ou .so gcc sous Linux) et que je ne sais même
pas lequel supprimer. Donc mon expérience va probablement tourner court surtout
que j'ai pas envie d'y passer des heures et des heures.



Je comprends. D'ailleurs, je pense que le but c'est justement que ce soit
le compilo qui s'en débrouille, et pas le programmeur (en général).



Oui mais mon but est de rendre les choses tangibles.

08049574 d p.5841
U puts@@GLIBC_2.0



J'en déduit que le compilo a été intelligent, et qu'il a remplacé l'appel
à printf (grosse fonction) à un appel équivalent ici à puts.



Oui, c'est c'est que j'ai compris en découvrant que mon printf avait été squeezé.



Moi non plus. Ceci dit, je me demande même si la machine redémarrerait
bien si on déplacait la libc sans prévenir le reste du système.



En principe oui, car le système (Ubuntu) fonctionnait au départ avant que
j'installe gcc et la lib C.


Bref, tout ça pour dire aussi que le traitement livresque des langages de
programmation ne donne pas son côté tangible au langage.



Un langage est une chose, son implantation en est une autre.

Après, il est vrai qu'en 2008, il ne reste plus que deux familles d'OS,
les Win* et les Unix-like, et qu'on pourrait se contenter de décrire le
fonctionnement "habituel" sur ces deux familles d'OS là.



Et après on adapterait un peu par induction assez facilement (je parle du point
de vue de la compréhension) à d'autres systèmes.

Vaut mieux une description "concrète" qui permet de comprendre d'autres
situations concrètes qu'une belle description abstraite prétendant tout
embrasser et qui ne permet pas de comprendre la moindre situation concrète
(syndrome Bourbaki). Hélas, beaucoup de livres/exposé/documentation sur C (et
d'autres questions que le C) sont fondés sur ce modèle-là.
1 2