Pourquoi l'ordre de '-l' option de gcc question?
Je suis en train de compiler un programme qui utilise udis86 de la bibliothèque. En fait, je suis en utilisant un exemple est donné dans le l'utilisateur manuel de l' de la bibliothèque. Mais lors de la compilation, il donne une erreur. Les erreurs que je reçois sont:
example.c:(.text+0x7): undefined reference to 'ud_init'
example.c:(.text+0x7): undefined reference to 'ud_set_input_file'
.
.
example.c:(.text+0x7): undefined reference to 'ud_insn_asm'
La commande que j'utilise est:
$ gcc -ludis86 example.c -o example
comme indiqué dans le manuel de manuel.
Clairement, l'éditeur de liens n'est pas en mesure de relier libudis de la bibliothèque. Mais si je change mon commandement:
$ gcc example.c -ludis86 -o example
Il commence à travailler. Donc peut plaire à quelqu'un d'expliquer quel est le problème avec la première commande?
- quelle version de gcc? Il peut être une version liées bug.
- Ce n'est pas un bug!! Version: gcc (Ubuntu/Linaro 4.4.4-14ubuntu5.1) 4.4.5
- double possible de l'éditeur de liens afin que GCC
Vous devez vous connecter pour publier un commentaire.
Parce que c'est la façon dont le lien entre l'algorithme utilisé par l'éditeur de liens GNU fonctionne (au moins quand il s'agit de lier les bibliothèques statiques). L'éditeur de liens est un seul passage de l'éditeur de liens et de ne pas revoir les bibliothèques une fois qu'ils ont vu.
Une bibliothèque est une collection (une archive), des fichiers objets. Lorsque vous ajoutez une bibliothèque à l'aide de la
-l
option, l'éditeur de liens n'est pas sans condition de prendre tous fichiers de l'objet à partir de la bibliothèque. Il faut seulement ces fichiers objets sont actuellement nécessaires, c'est à dire des fichiers qui permettent de résoudre certains actuellement en suspens (en cours) des symboles. Après cela, l'éditeur de liens en oublie complètement sur cette bibliothèque.La liste d'attente des symboles est constamment mis à jour par l'éditeur de liens que l'éditeur de liens de processus d'entrée les fichiers objets, l'un après l'autre de gauche à droite. Comme il traite chaque fichier objet, certains symboles se résolu et retiré de la liste, d'autres nouvellement découvert en suspens symboles ajoutés à la liste.
Donc, si vous inclus de la bibliothèque à l'aide de
-l
, l'éditeur de liens utilise la bibliothèque de résoudre autant actuellement dans l'attente de symboles qu'il le peut, et puis oublie complètement sur cette bibliothèque. Si il plus tard découvre tout à coup qu'elle a maintenant besoin de quelque autre objet fichier(s) à partir de cette bibliothèque, l'éditeur de liens ne sera pas un "retour" à la bibliothèque pour récupérer ces fichiers supplémentaires d'objets. Il est déjà trop tard.Pour cette raison, il est toujours une bonne idée d'utiliser
-l
option fin dans l'éditeur de liens de la ligne de commande, de sorte que par le temps que l'éditeur de liens obtient que-l
il peut déterminer de façon fiable l'objet sur lequel les fichiers dont il a besoin et dont il n'a pas besoin. Placer le-l
option en tant que premier paramètre à l'éditeur de liens en général n'a aucun sens: au tout début, la liste d'attente des symboles est vide (ou, plus précisément, consiste en un seul symbolemain
), ce qui signifie que l'éditeur de liens ne sera pas prendre quoi que ce soit à partir de la bibliothèque.Dans votre cas, votre fichier objet
example.o
contient des références à des symbolesud_init
,ud_set_input_file
etc. L'éditeur de liens doit recevoir le fichier de l'objet premier. Il va ajouter ces symboles à la liste d'attente des symboles. Après cela, vous pouvez utiliser-l
option pour ajouter le votre bibliothèque:-ludis86
. L'éditeur de liens de recherche de votre bibliothèque et de prendre tout ce qui résout ceux en attente de symboles.Si vous placez le
-ludis86
option en premier dans la ligne de commande, l'éditeur de liens efficacement ignorer votre bibliothèque, car au début il ne sait pas qu'il aura besoin deud_init
,ud_set_input_file
etc. Plus tard, lors du traitement deexample.o
il va découvrir ces symboles et les ajouter à l'attente de la liste des symboles. Mais ces symboles restent en suspens à la fin, depuis-ludis86
a déjà été traité (et, de fait, ignorées).Parfois, lorsque deux (ou plus) des bibliothèques se référer les uns aux autres dans la circulaire de la mode, on pourrait même besoin d'utiliser le
-l
option deux fois avec la même bibliothèque, pour donner de l'éditeur de liens deux chances de récupérer l'objet nécessaire fichiers de la bibliothèque.ld
. Voir--start-group
et--end-group
dans leld(1)
page de manuel. Il indique efficacement l'éditeur de liens de revisiter les archives du groupe.lld
de liaison de la LLVM projet ne pas mettre en œuvre POSIX comportement (voir @R..s'commentaire): ", Voici comment LLD approches du problème. Au lieu de mémoriser uniquement les symboles non définis, nous avons le programme de doctorat en droit, de sorte qu'il mémorise tous les symboles. Quand il voit un symbole non défini qui peut être résolu par l'extraction d'un fichier de l'objet à partir d'un fichier d'archive précédemment visité, il a immédiatement extrait le fichier et de faire un lien. C'est faisable parce que la LLD n'oublie pas les symboles qu'il ont vu dans les fichiers d'archive."J'ai frappé cette même question un moment de retour. Ligne de fond est que les outils gnu ne sont pas toujours "rechercher" dans la liste de la bibliothèque de résoudre les symboles manquants. De résoudre facilement les problèmes sont les suivants:
Il suffit de spécifier les libs et objs dans l'ordre de dépendance (comme vous l'avez découvert ci-dessus)
OU si vous avez une dépendance circulaire (où il fait référence à une fonction dans libB, mais libB référence à une fonction dans libA), puis il suffit de spécifier les libs sur la ligne de commande à deux reprises. C'est ce que la page de manuel suggère ainsi. E. g.
Utiliser le
-(
et-)
params pour spécifier un groupe d'archives qui ont de telles dépendances circulaires. Regardez l'éditeur de liens GNU manuel pour--start-group
et--end-group
. Voir ici pour plus de détails.Lorsque vous utilisez l'option 2 ou 3, vous êtes susceptible d'introduire une incidence sur les performances de la liaison. Si vos n'avez pas beaucoup de lien, il ne peut pas d'importance.
Ou de l'utilisation rescan
de pg 41 de Oracle Solaris 11.1 les Linkers et les Bibliothèques Guide: