Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > 0d5cd12c82d627a82c59047e1ba7b8a9 > files > 400

howto-html-fr-9.0-0.2mdk.noarch.rpm

<HTML>
<HEAD>
<TITLE>Edition de liens</TITLE>
</HEAD>
<BODY>
<H1>6. <A NAME="s6"></A>Edition de liens</H1>
<P>
<A HREF="GCC-HOWTO.html#toc6">Contenu de cette section</A></P>

<P> Entre les deux formats de binaires incompatibles, 
biblioth&egrave;ques statiques et dynamiques, on peut comparer l'op&eacute;ration
d'&eacute;dition de lien en fait &agrave; un jeu ou l'on se demanderait qu'est-ce 
qui se passe lorsque je lance le programme ? Cette section n'est
pas vraiment simple...</P>
<P></P>
<P> Pour dissiper la confusion qui r&egrave;gne, nous allons nous baser sur
ce qui se passe lors d'ex&eacute;cution d'un programme, avec le chargement
dynamique. Vous verrez &eacute;galement la description de l'&eacute;dition
de liens dynamiques, mais plus tard. Cette section est
d&eacute;di&eacute;e &agrave; l'&eacute;dition de liens qui intervient &agrave; la fin de la compilation.</P>
<P></P>
<H2>6.1 <A NAME="ss6.1"></A> Biblioth&egrave;ques partag&eacute;es contre biblioth&egrave;ques statiques</H2>

<P> La derni&egrave;re phase de construction d'un programme est de r&eacute;aliser
l'&eacute;dition de liens, ce qui consiste &agrave; assembler tous les morceaux 
du programme et de chercher ceux qui sont manquants. Bien &eacute;videment,
beaucoup de programmes r&eacute;alisent les m&ecirc;mes op&eacute;rations comme 
ouvrir des fichiers par exemple, et ces pi&egrave;ces qui r&eacute;alisent ce genre
d'op&eacute;rations sont fournies sous la forme de biblioth&egrave;ques. Sous Linux,
ces biblioth&egrave;ques peuvent &ecirc;tre trouv&eacute;es dans les r&eacute;pertoires 
<CODE>/lib</CODE> et<CODE>/usr/lib/</CODE> entre autres.</P>
<P>
<A NAME="index.65"></A> 
 
<A NAME="index.66"></A> 
 </P>
<P>Lorsque vous utilisez une biblioth&egrave;que statique, l'&eacute;diteur de liens
cherche le code dont votre programme a besoin et en effectue
une copie dans le programme physique g&eacute;n&eacute;r&eacute;. Pour les biblioth&egrave;ques
partag&eacute;es, c'est le contraire : l'&eacute;diteur de liens laisse du code
qui lors du lancement du programme chargera automatiquement la 
biblioth&egrave;que. Il est &eacute;vident que ces biblioth&egrave;ques permettent
d'obtenir un ex&eacute;cutable plus petit; elles permettent &eacute;galement
d'utiliser moins de m&eacute;moire et moins de place disque. Linux
effectue par d&eacute;faut une &eacute;dition de liens dynamique s'il peut trouver
les biblioth&egrave;ques de ce type sinon, il effectue une &eacute;dition de liens
statique. Si vous obtenez des binaires statiques alors que vous les 
voulez dynamiques v&eacute;rifiez que les biblioth&egrave;ques existent 
(<CODE>*.sa</CODE> pour le format a.out, et <CODE>*.so</CODE> pour le format ELF) et 
que vous poss&eacute;dez les droits suffisants pour y acc&eacute;der (lecture).</P>
<P>Sous Linux, les biblioth&egrave;ques statiques ont pour nom <CODE>libnom.a</CODE>, 
alors que les biblioth&egrave;ques dynamiques sont appel&eacute;es 
<CODE>libnnom.so.x.y.z</CODE> o&ugrave; <CODE>x.y.z</CODE> repr&eacute;sente le num&eacute;ro de 
version. Les biblioth&egrave;ques dynamiques ont souvent des liens logiques qui
pointent dessus, et qui sont tr&egrave;s importants. Normalement, les biblioth&egrave;ques
standards sont livr&eacute;es sous la double forme dynamique
et statique.</P>
<P>Vous pouvez savoir de quelles biblioth&egrave;ques dynamiques un programme a besoin
en utilisant la commande <CODE>ldd</CODE> (<EM>List Dynamic Dependencies</EM>)
<BLOCKQUOTE><CODE>
<PRE>
$ ldd /usr/bin/lynx
        libncurses.so.1 =&gt; /usr/lib/libncurses.so.1.9.6
        libc.so.5 =&gt; /lib/libc.so.5.2.18
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>Cela indique sur mon syst&egrave;me que l'outil <CODE>lynx</CODE> (outil WWW) 
a besoin des biblioth&egrave;ques dynamiques <CODE>libc.so.5</CODE> (la biblioth&egrave;que C)
et de <CODE>libncurses.so.1</CODE> (n&eacute;cessaire pour le contr&ocirc;le du terminal). 
Si un programme ne poss&egrave;de pas de d&eacute;pendances, <CODE>ldd</CODE> indiquera
`<EM>statically linked</EM>' (&eacute;dition de liens statique).</P>
<P></P>

<A NAME="index.69"></A> <A NAME="index.68"></A> <A NAME="index.67"></A> <H2>6.2 <A NAME="ss6.2"></A> A la recherche des fonctions... ou dans quelle biblioth&egrave;que se trouve la fonction <CODE>sin()</CODE> ?')   </H2>

<P> <CODE>nm </CODE><EM>nomdebiblioth&egrave;que</EM> vous donne tous les symboles r&eacute;f&eacute;renc&eacute;s dans
la biblioth&egrave;que. Cela fonctionne que cela soit du code statique ou dynamique.
Supposez que vous vouliez savoir o&ugrave; se trouve d&eacute;finie la fonction
<CODE>tcgetattr()</CODE> :
<BLOCKQUOTE><CODE>
<PRE>
$ nm libncurses.so.1 |grep tcget
         U tcgetattr
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>La lettre <CODE>U</CODE> vous indique que c'est ind&eacute;fini (<EM>Undefined</EM>)
--- cela indique que la biblioth&egrave;que ncurses l'utilise mais ne la d&eacute;finit pas.
Vous pouvez &eacute;galement faire :</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
$ nm libc.so.5 | grep tcget
00010fe8 T __tcgetattr
00010fe8 W tcgetattr
00068718 T tcgetpgrp
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>La lettre `<CODE>W</CODE>' indique que le symbole est d&eacute;fini mais de telle
mani&egrave;re qu'il peut &ecirc;tre surcharg&eacute; par une autre d&eacute;finition de la fonction
dans une autre biblioth&egrave;que (W pour <EM>weak</EM> : faible).
Une d&eacute;finition normale est marqu&eacute;e par la lettre `<CODE>T</CODE>' 
(comme pour <CODE>tcgetpgrp</CODE>).</P>
<P>
<A NAME="index.70"></A> 
 </P>
<P>La r&eacute;ponse &agrave; la question situ&eacute;e dans le titre est 
<CODE>libm.(so|a)</CODE>.  Toutes les fonctions d&eacute;finies dans le fichier
d'en-t&ecirc;te <CODE>&lt;math.h&gt;</CODE> sont impl&eacute;ment&eacute;es dans la
biblioth&egrave;que math&eacute;matique donc vous devrez effectuer l'&eacute;dition de liens
gr&acirc;ce &agrave; <CODE>-lm</CODE>.</P>
<P></P>
<P></P>

<H2>6.3 <A NAME="ss6.3"></A> Trouver les fichiers</H2>

<P></P>
<P>Supposons que vous ayez le message d'erreur suivant de la part
de l'&eacute;diteur de liens :</P>
<P><CODE>ld: Output file requires shared library `libfoo.so.1`</CODE></P>
<P></P>
<P> La strat&eacute;gie de recherche de fichiers de ld ou de ses copains
diff&egrave;re de la version utilis&eacute;e, mais vous pouvez &ecirc;tre s&ucirc;r 
que les fichiers situ&eacute;s dans le r&eacute;pertoire <CODE>/usr/lib</CODE> 
seront trouv&eacute;s. Si vous d&eacute;sirez que des fichiers situ&eacute;s &agrave; un endroit
diff&eacute;rent soient trouv&eacute;s, il est pr&eacute;f&eacute;rable d'ajouter l'option
<CODE>-L</CODE> &agrave; gcc ou ld.</P>
<P></P>
<P> Si cela ne vous aide pas clairement, v&eacute;rifiez que vous avez le bon
fichier &agrave; l'endroit sp&eacute;cifi&eacute;. Pour un syst&egrave;me a.out,
effectuer l'&eacute;dition de liens avec <CODE>-ltruc</CODE> implique que ld recherche
les biblioth&egrave;ques  <CODE>libtruc.sa</CODE> (biblioth&egrave;ques partag&eacute;es), et si elle
n'existe pas, il recherche <CODE>libtruc.a</CODE> (statique).  Pour le format
ELF, il cherche <CODE>libtruc.so</CODE> puis <CODE>libtruc.a</CODE>.  
<CODE>libtruc.so</CODE> est g&eacute;n&eacute;ralement un lien symbolique vers
<CODE>libtruc.so.x</CODE>.</P>
<P></P>

<H2>6.4 <A NAME="ss6.4"></A> Compiler votre propre biblioth&egrave;que</H2>

<H3>Num&eacute;ro de la version</H3>

<P> Comme tout programme, les biblioth&egrave;ques ont tendance &agrave; avoir quelques
bogues qui sont corrig&eacute;s au fur et &agrave; mesure. De nouvelles 
fonctionnalit&eacute;s sont ajout&eacute;es et qui peuvent changer l'effet
de celles qui existent ou bien certaines anciennes peuvent &ecirc;tres supprim&eacute;es.
Cela peut &ecirc;tre un probl&egrave;me pour les programmes qui les utilisent.</P>
<P>Donc, nous introduisons la notion de num&eacute;ro de version. Nous
r&eacute;pertorions les modifications effectu&eacute;es dans la biblioth&egrave;ques
comme &eacute;tant soit mineures soit majeures. Cela signifie qu'une 
modification mineure ne peut pas modifier le fonctionnement d'un
programme (en bref, il continue &agrave; fonctionner comme avant). Vous pouvez
identifier le num&eacute;ro de la version de la biblioth&egrave;que en regardant
son nom (en fait c'est un mensonge pour les biblioth&egrave;ques ELF... mais
continuez &agrave; faire comme si !) : <CODE>libtruc.so.1.2</CODE> a pour version
majeure 1 et mineure 2.  Le num&eacute;ro de version mineur peut &ecirc;tre
plus ou moins &eacute;lev&eacute; --- la biblioth&egrave;que C met un num&eacute;ro de patch,
ce qui produit un nom tel que <CODE>libc.so.5.2.18</CODE>, et c'est &eacute;galement
courant d'y trouver des lettres ou des blancs soulign&eacute;s ou tout
autre caract&egrave;re ASCII affichable.</P>
<P>Une des principales diff&eacute;rences entre les formats ELF et a.out
se trouve dans la mani&egrave;re de construire la biblioth&egrave;que partag&eacute;e.
Nous traiterons les biblioth&egrave;ques partag&eacute;es en premier car c'est plus
simple.</P>
<P></P>
<A NAME="index.71"></A> <H3>ELF, qu'est-ce que c'est ? </H3>

<P> ELF (<EM>Executable and Linking Format</EM>) est format de binaire
initialement con&ccedil;u et d&eacute;velopp&eacute; par USL (<EM>UNIX System Laboratories</EM>)
et utilis&eacute; dans les syst&egrave;mes Solaris et System R4. En raison de sa
facilit&eacute; d'utilisation par rapport &agrave; l'ancien format dit a.out qu'utilisait
Linux, les d&eacute;veloppeurs de GCC et de la biblioth&egrave;que C ont d&eacute;cid&eacute; 
l'ann&eacute;e derni&egrave;re de basculer tout le syst&egrave;me sous le format ELF. ELF
est d&eacute;sormais le format binaire standard sous Linux.</P>
<P></P>
<H3>ELF, le retour !</H3>

<P> Ce paragraphe provient du groupe '/news-archives/comp.sys.sun.misc'.</P>
<P>
<BLOCKQUOTE>
ELF (<EM>Executable Linking Format</EM>) est le " nouveau et plus
performant " format de fichier introduit dans SVR4. ELF est beaucoup
plus puissant que le sacro-saint format COFF, dans le sens o&ugrave; il
est extensible. ELF voit un fichier objet comme une longue
liste de sections (plut&ocirc;t qu'un tableau de taille fixe 
d'&eacute;l&eacute;ments). Ces sections, &agrave; la diff&eacute;rence de COFF ne se trouvent
pas &agrave; un endroit constant et ne sont pas dans un ordre
particulier, etc. Les utilisateurs peuvent ajouter une nouvelle
section &agrave; ces fichiers objets s'il d&eacute;sirent y mettre de nouvelles
donn&eacute;es. ELS poss&egrave;de un format de d&eacute;bogage plus puissant
appel&eacute; DWARF (<EM>Debugging With Attribute Record Format</EM>) - 
par encore enti&egrave;rement g&eacute;r&eacute; par Linux (mais on y travaille !). 
Une liste cha&icirc;n&eacute;e de " DWARF DIEs " (ou <EM>Debugging Information 
Entries</EM> - NdT... le lecteur aura s&ucirc;rement not&eacute; le jeu de mot
assez noir : dwarf = nain; dies = morts) forment la section <EM>.debug</EM>
dans ELF. Au lieu d'avoir une liste de petits enregistrements  d'information
de taille fixes, les DWARF DIEs contiennent chacun une longue liste
complexe d'attributs et sont &eacute;crits sous la forme d'un arbre de donn&eacute;es.
Les DIEs peuvent contenir une plus grande quantit&eacute; d'information
que la section <EM>.debug</EM> du format COFF ne le pouvait (un peu comme
les graphes d'h&eacute;ritages du C++).
</BLOCKQUOTE>

<BLOCKQUOTE>
Les fichiers ELF sont accessibles gr&acirc;ce &agrave; la biblioth&egrave;que d'acc&egrave;s 
de SVR4 (Solaris 2.0 peut-&ecirc;tre ?), qui fournit une interface simple
et rapide aux parties les plus complexes d'ELF. Une des aubaines que
permet la biblioth&egrave;que d'acc&egrave;s ELF est que vous n'avez jamais besoin
de conna&icirc;tre les m&eacute;andres du format ELF. Pour acc&eacute;der &agrave; un fichier Unix,
on utilise un Elf *, retourn&eacute; par un appel &agrave; elf_open(). Ensuite,
vous effectuez des appels &agrave; elf_foobar() pour obtenir les diff&eacute;rents
composants au lieu d'avoir &agrave; triturer le fichier physique 
sur le disque (chose que beaucoup d'utilisateurs de COFF ont fait...).
</BLOCKQUOTE>
</P>
<P>Les arguments pour ou contre ELF, et les probl&egrave;mes li&eacute;s
&agrave; la mise &agrave; jour d'un syst&egrave;me a.out vers un syst&egrave;me ELF sont d&eacute;crits 
dans le ELF-HOWTO et je ne veux pas effectuer de copier coller ici
(NdT: ce HowTo est &eacute;galement traduit en fran&ccedil;ais).
Ce HowTo se trouve au m&ecirc;me endroit que les autres.</P>
<P></P>
<H3>Les biblioth&egrave;que partag&eacute;es ELF</H3>

<P> Pour construire <CODE>libtruc.so</CODE> comme une biblioth&egrave;que dynamique,
il suffit de suivre les &eacute;tapes suivantes :</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libtruc.so.1 -o libtruc.so.1.0 *.o
$ ln -s libtruc.so.1.0 libtruc.so.1
$ ln -s libtruc.so.1 libtruc.so
$ LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>Cela va g&eacute;n&eacute;rer une biblioth&egrave;que partag&eacute;e appel&eacute;e <CODE>libtruc.so.1.0</CODE>, 
les liens appropri&eacute;s pour ld (<CODE>libtruc.so</CODE>) et 
le chargeur dynamique (<CODE>libtruc.so.1</CODE>) pour le trouver. 
Pour tester, nous ajoutons le r&eacute;pertoire actuel &agrave; la 
variable d'environnement <CODE>LD_LIBRARY_PATH</CODE>.</P>
<P>
<A NAME="index.72"></A> 
 </P>
<P>Lorsque vous &ecirc;tes satisfait et que la biblioth&egrave;que fonctionne, vous
n'avez plus qu'&agrave; la d&eacute;placer dans le r&eacute;pertoire par exemple, 
<CODE>/usr/local/lib</CODE>, et de recr&eacute;er les liens appropri&eacute;s. Le lien
de <CODE>libtruc.so.1</CODE> sur <CODE>libtruc.so.1.0</CODE> est enregistr&eacute; par 
<CODE>ldconfig</CODE>, qui sur bon nombre de syst&egrave;mes est lanc&eacute; lors 
du processus d'amor&ccedil;age. Le lien <CODE>libfoo.so</CODE> doit &ecirc;tre mis &agrave; jour
&agrave; la main. Si vous faites attention lors de la mise &agrave; jour de la
biblioth&egrave;que la chose la plus simple &agrave; r&eacute;aliser est de cr&eacute;er le lien
<CODE>libfoo.so -> libfoo.so.1</CODE>, pour que ldconfig conserve les liens
actuels. Si vous ne faites pas cela, vous aurez des probl&egrave;mes plus
tard. Ne me dites pas que l'on ne vous a pas pr&eacute;venu !</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
$ /bin/su
# cp libtruc.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libtruc.so.1 libtruc.so )
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P></P>
<A NAME="index.74"></A> <A NAME="index.73"></A> <H3>Les num&eacute;ros de version, les noms et les liens  </H3>

<P> Chaque biblioth&egrave;que poss&egrave;de un nom propre (<EM>soname</EM>).  
Lorsque l'&eacute;diteur de liens en trouve un qui correspond &agrave; un nom
cherch&eacute;, il enregistre le nom de la biblioth&egrave;que dans le code binaire
au lieu d'y mettre le nom du fichier de la biblioth&egrave;que. Lors de
l'ex&eacute;cution, le chargeur dynamique va alors chercher un fichier ayant
pour nom le nom propre de la biblioth&egrave;que, et pas le nom du fichier
de la biblioth&egrave;que. Par exemple, une biblioth&egrave;que ayant pour nom
<CODE>libtruc.so</CODE> peut avoir comme nom propre <CODE>libbar.so</CODE>, et tous
les programmes li&eacute;s avec vont alors chercher <CODE>libbar.so</CODE> 
lors de leur ex&eacute;cution.</P>
<P></P>
<P>Cela semble &ecirc;tre une nuance un peu pointilleuse mais c'est la clef
de la compr&eacute;hension de la coexistence de plusieurs versions
diff&eacute;rentes de la m&ecirc;me biblioth&egrave;que sur le m&ecirc;me syst&egrave;me.
On a pour habitude sous Linux d'appeler une biblioth&egrave;que 
<CODE>libtruc.so.1.2</CODE> par exemple, et de lui donner comme
nom propre <CODE>libtruc.so.1</CODE>.  Si cette biblioth&egrave;que est rajout&eacute;e
dans un r&eacute;pertoire standard (par exemple dans <CODE>/usr/lib</CODE>), 
le programme <CODE>ldconfig</CODE> va cr&eacute;er un lien symbolique
entre <CODE>libtruc.so.1 -> libtruc.so.1.2</CODE> pour que l'image
appropri&eacute;e soit trouv&eacute;e lors de l'ex&eacute;cution. Vous aurez &eacute;galement besoin
d'un lien symbolique  <CODE>libtruc.so -> libtruc.so.1</CODE> pour que ld
trouve le nom propre lors de l'&eacute;dition de liens.</P>
<P> Donc, lorsque vous corrigez des erreurs dans la biblioth&egrave;que ou
bien lorsque vous ajoutez de nouvelles fonctions (en fait, pour
toute modification qui n'affecte pas l'ex&eacute;cution des programmes d&eacute;j&agrave;
existants), vous reconstruisez la biblioth&egrave;que, conservez le nom propre
tel qu'il &eacute;tait et changez le nom du fichier. Lorsque vous effectuez des 
modifications que peuvent modifier le d&eacute;roulement des programmes
existants, vous pouvez tout simplement incr&eacute;menter le nombre situ&eacute; 
dans le nom propre --- dans ce cas, appelez la nouvelle version de la
biblioth&egrave;que <CODE>libtruc.so.2.0</CODE>, et donnez-lui comme nom propre
<CODE>libtruc.so.2</CODE>.  Maintenant, faites pointer le lien de 
<CODE>libfoo.so</CODE> vers la nouvelle version et tout est bien dans
le meilleur des mondes !</P>
<P>Il est utile de remarquer que vous n'&ecirc;tes pas oblig&eacute; de nommer 
les biblioth&egrave;ques de cette mani&egrave;re, mais c'est une bonne convention.
Elf vous donne une certaine libert&eacute; pour nommer des biblioth&egrave;ques
tant et si bien que cela peut perturber certains utilisateurs, mais cela
ne veut pas dire que vous &ecirc;tes oblig&eacute; de le faire.</P>
<P>R&eacute;sum&eacute; : supposons que choisissiez d'adopter la m&eacute;thode traditionnelle
avec les mises &agrave; jour majeures qui peuvent ne pas &ecirc;tre compatibles
avec les versions pr&eacute;c&eacute;dentes et les mises &agrave; jour mineures qui ne posent
pas ce probl&egrave;me. Il suffit de cr&eacute;er la biblioth&egrave;que de cette mani&egrave;re :</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
gcc -shared -Wl,-soname,libtruc.so.majeur -o libtruc.so.majeur.mineur
</PRE>
</CODE></BLOCKQUOTE>

et tout devrait &ecirc;tre parfait !</P>
<P></P>
<H3>a.out.  Le bon vieux format </H3>

<P> La facilit&eacute; de construire des biblioth&egrave;que partag&eacute;es est la 
raison principale de passer &agrave; ELF. Ceci dit, il est toujours possible
de cr&eacute;er des biblioth&egrave;ques dynamiques au format a.out. R&eacute;cup&eacute;rez 
le fichier archive 
<A HREF="ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz">ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz</A>

et lisez les 20 pages de documentation que vous trouverez dedans
apr&egrave;s l'avoir d&eacute;sarchiv&eacute;. Je n'aime pas avoir l'air d'&ecirc;tre aussi
partisan, mais il est clair que je n'ai jamais aim&eacute; ce format :-).</P>
<P></P>
<A NAME="index.76"></A> <A NAME="index.75"></A> <H3>ZMAGIC contre QMAGIC  </H3>

<P> QMAGIC est le format des ex&eacute;cutables qui ressemble un peu aux vieux
binaires a.out (&eacute;galement connu comme ZMAGIC), mais qui laisse
la premi&egrave;re page libre. Cela permet plus facilement de r&eacute;cup&eacute;rer
les adresses non affect&eacute;es (comme NULL) dans l'intervalle
0-4096 (NdT : Linux utilise des pages de 4Ko).</P>
<P>Les &eacute;diteurs de liens d&eacute;suets ne g&egrave;rent que le format ZMAGIC, ceux
un peu moins rustiques g&egrave;rent les deux, et les plus r&eacute;cents uniquement
le QMAGIC. Cela importe peu car le noyau g&egrave;re les deux types.</P>
<P>La commande <CODE>file</CODE> est capable d'identifier si un programme est
de type QMAGIC.</P>
<P></P>
<H3>Gestion des fichiers</H3>

<P>Une biblioth&egrave;que dynamique a.out (DLL) est compos&eacute;e de 
deux fichiers et d'un lien symbolique. Supposons que l'on
utilise la biblioth&egrave;que <EM>truc</EM>, les fichiers seraient
les suivants : <CODE>libtruc.sa</CODE> et <CODE>libtruc.so.1.2</CODE>; et le 
lien symbolique aurait pour nom <CODE>libtruc.so.1</CODE> et pointerait
sur le dernier des fichiers. Mais &agrave; quoi servent-ils ?</P>
<P>Lors de la compilation, <CODE>ld</CODE> cherche <CODE>libtruc.sa</CODE>.  
C'est le fichier de description de la biblioth&egrave;que : il contient
toutes les donn&eacute;es export&eacute;es et les pointeurs vers les fonctions
n&eacute;cessaires pour l'&eacute;dition de liens.</P>
<P>Lors de l'ex&eacute;cution, le chargeur dynamique cherche <CODE>libtruc.so.1</CODE>.
C'est un lien symbolique plut&ocirc;t qu'un r&eacute;el fichier pour que les
biblioth&egrave;ques puissent &ecirc;tre mise &agrave; jour sans avoir &agrave; casser les
applications qui utilisent la biblioth&egrave;que. Apr&egrave;s la mise &agrave; jour, 
disons que l'on est pass&eacute; &agrave; la version <CODE>libfoo.so.1.3</CODE>,
le lancement de ldconfig va positionner le lien. Comme 
cette op&eacute;ration est atomique, aucune application fonctionnant 
n'aura de probl&egrave;me.</P>
<P>Les biblioth&egrave;ques DLL (Je sais que c'est une tautologie... mais pardon !) 
semblent &ecirc;tre tr&egrave;s souvent plus importantes que leur &eacute;quivalent
statique. En fait, c'est qu'elles r&eacute;servent de la place pour les
extensions ult&eacute;rieures sous la simple forme de trous qui sont
fait de telle mani&egrave;re qu'ils n'occupent pas de place disque (NdT : 
un peu comme les fichiers <CODE>core</CODE>). Toutefois, un
simple appel &agrave; <CODE>cp</CODE> ou &agrave; <CODE>makehole</CODE> les remplira...
Vous pouvez effectuer une op&eacute;ration de <CODE>strip</CODE> apr&egrave;s la construction
de la biblioth&egrave;que, comme les adresses sont &agrave; des endroits fixes.
<B>Ne faites pas la m&ecirc;me op&eacute;ration avec les biblioth&egrave;ques ELF !</B></P>
<P></P>
<H3>" libc-lite " ?</H3>

<P> Une " libc-lite " (contraction de <EM>libc</EM> et <EM>little</EM>)
est une version &eacute;pur&eacute;e et r&eacute;duite de la biblioth&egrave;que 
libc construite de telle mani&egrave;re qu'elle puisse tenir sur 
une disquette avec un certain nombre d'outil Unix.
Elle n'inclut pas curses, dbm, termcap, ... 
Si votre <CODE>/lib/libc.so.4</CODE> est li&eacute;e avec une biblioth&egrave;que de ce genre
il est tr&egrave;s fortement conseill&eacute; de la remplacer avec une version compl&egrave;te.</P>
<P></P>
<H3>Edition de liens : probl&egrave;me courants </H3>

<P> Envoyez-les moi ! </P>
<P>
<DL>
<P></P>
<DT><B> Des programmes statiques lorsque vous les voulez
partag&eacute;s</B><DD><P>
<A NAME="index.77"></A> 
 
<A NAME="index.78"></A> 
 </P>
<P>V&eacute;rifiez que vous avez les bons liens pour que <CODE>ld</CODE> puisse
trouver les biblioth&egrave;ques partag&eacute;es. Pour ELF cela veut dire que
<CODE>libtruc.so</CODE> est un lien symbolique sur son image,
pour a.out un fichier <CODE>libtruc.sa</CODE>.  Beaucoup de personnes
ont eu ce probl&egrave;me apr&egrave;s &ecirc;tre pass&eacute;s des outils ELF 2.5 &agrave; 2.6 
(<CODE>binutils</CODE>) --- la derni&egrave;re version effectue une recherche
plus intelligente pour les biblioth&egrave;ques dynamiques et donc ils 
n'avaient pas cr&eacute;&eacute; tous les liens symboliques n&eacute;cessaires.
Cette caract&eacute;ristique avait &eacute;t&eacute; supprim&eacute;e pour des raisons de compatibilit&eacute;
avec d'autres architectures et parce qu'assez souvent cela ne marchait
pas bien. En bref, cela posait plus de probl&egrave;mes qu'autre chose.</P>
<P></P>
<DT><B> Le programme `mkimage' n'arrive pas &agrave; trouver libgcc</B><DD><P>
<A NAME="index.79"></A> 
 </P>
<P>Comme <CODE>libc.so.4.5.x</CODE> et suivantes, libgcc n'est pas une 
biblioth&egrave;que partag&eacute;e. Vous devez remplacer les `<CODE>-lgcc</CODE>' 
sur la ligne de commande par 
<CODE>`gcc -print-libgcc-file-name`</CODE> (entre quotes)</P>
<P>Egalement, d&eacute;truisez tous les fichiers situ&eacute;s dans <CODE>/usr/lib/libgcc*</CODE>.
C'est important.</P>
<P></P>
<DT><B> Le message <CODE>__NEEDS_SHRLIB_libc_4 multiply defined</CODE></B><DD><P>Sont une cons&eacute;quence du m&ecirc;me probl&egrave;me.</P>
<P></P>
<DT><B> Le message ``Assertion failure'' appara&icirc;t lorsque vous reconstruisez une
DLL</B><DD><P>Ce message &eacute;nigmatique signifie qu'un &eacute;l&eacute;ment de votre table <EM>jump</EM>
a d&eacute;pass&eacute; la table car trop peu de place &eacute;tait r&eacute;serv&eacute;e dans le fichier 
<CODE>jump.vars</CODE> file.  Vous pouvez trouver le(s) coupable(s) en lan&ccedil;ant 
la commande <CODE>getsize</CODE> fournie dans le paquetage tools-2.17.tar.gz. 
La seule solution est de passer &agrave; une nouvelle version majeure,
m&ecirc;me si elle sera incompatible avec les pr&eacute;c&eacute;dentes.</P>
<P></P>
<DT><B> <CODE>ld: output file needs shared library libc.so.4</CODE> </B><DD><P>Cela arrive lorsque vous effectuez l'&eacute;dition de liens avec des biblioth&egrave;ques
diff&eacute;rentes de la libc (comme les biblioth&egrave;ques X) et que vous utilisez
l'option <CODE>-g</CODE> sans utiliser l'option <CODE>-static</CODE>.</P>
<P>Les fichiers <CODE>.sa</CODE> pour les biblioth&egrave;ques dynamiques ont un symbole
non r&eacute;solu <CODE>_NEEDS_SHRLIB_libc_4</CODE> qui est d&eacute;fini dans 
<CODE>libc.sa</CODE>.  Or, lorsque vous utilisez <CODE>-g</CODE> vous faites l'&eacute;dition
de liens avec <CODE>libg.a</CODE> ou <CODE>libc.a</CODE> et donc ce symbole n'est jamais 
d&eacute;fini.</P>
<P>Donc, pour r&eacute;soudre le probl&egrave;me, ajoutez l'option <CODE>-static</CODE> 
lorsque vous compilez avec l'option <CODE>-g</CODE>, ou n'utilisez pas
<CODE>-g</CODE> lors de l'&eacute;dition de liens !</P>
</DL>
</P>
<P></P>
<P></P>

<HR>
<P>
Chapitre <A HREF="GCC-HOWTO-7.html">suivant</A>,
Chapitre <A HREF="GCC-HOWTO-5.html">Pr&eacute;c&eacute;dent</A>
<P>
Table des mati&egrave;res de <A HREF="GCC-HOWTO.html#toc6">ce chapitre</A>,
 <A HREF="GCC-HOWTO.html#toc">Table des mati&egrave;res</A> g&eacute;n&eacute;rale</P>
<P>
<A HREF="GCC-HOWTO.html">D&eacute;but</A> du document,
 <A HREF="#0"> D&eacute;but de ce chapitre</A></P>
</BODY>
</HTML>