2010-07-29 6 views
26

Avant aujourd'hui, j'avais toujours cru que l'ordre dans lequel les objets et les bibliothèques étaient transmis à g ++ pendant l'étape de liaison n'était pas important. Puis, aujourd'hui, j'ai essayé de lier le code C++ au code c. J'ai enveloppé tous les en-têtes C dans un bloc externe "C" mais l'éditeur de liens avait toujours des difficultés à trouver des symboles que je connaissais dans les archives d'objets C.g ++ dépendance de l'ordre de liaison lors de la liaison du code c au code C++

Perplexe, j'ai créé un exemple relativement simple pour isoler l'erreur de liaison mais à ma grande surprise, l'exemple le plus simple est lié sans aucun problème. Après un peu d'essai et d'erreur, j'ai trouvé qu'en émulant le modèle de liaison utilisé dans l'exemple simple, je pouvais obtenir le code principal pour lier OK. Le modèle a été code objet premier, objet archives deuxième exemple:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

Quelqu'un peut-il faire la lumière sur pourquoi cela pourrait être si ?. Je n'ai jamais vu ce problème lors de la liaison de code C++ ordinaire.

+0

Pour plus de détails, voir: http://stackoverflow.com/questions/1095298/gcc-c-linker-errors-undefined-reference -to-vtable-for-xxx-undefined-referen/1095321 # 1095321 –

Répondre

35

L'ordre que vous spécifiez les fichiers objets et les bibliothèques est TRÈS important dans GCC - si vous n'avez pas été mordu par cela avant d'avoir mené une vie charmée. L'éditeur de liens recherche les symboles dans l'ordre où ils apparaissent, donc si vous avez un fichier source qui contient un appel à une fonction de bibliothèque, vous devez le placer devant la bibliothèque, sinon l'éditeur de liens ne saura pas qu'il doit le résoudre. L'utilisation complexe des bibliothèques peut signifier que vous devez spécifier la bibliothèque plus d'une fois, ce qui est une douleur royale pour obtenir raison.

+0

Croyez-moi, je n'ai pas :-), existe-t-il de la documentation sur cette propriété? –

+0

Nous y voilà: http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html –

+0

Moi aussi, j'ai toujours trouvé que l'ordre des liens était critique; il peut être difficile de déterminer pourquoi des erreurs de lien se produisent, aussi, jusqu'à ce que vous deviniez que la commande est fausse ... –

6

Une bibliothèque statique est une collection de fichiers objets regroupés dans une archive. Lors de la liaison, l'éditeur de liens choisit uniquement les objets dont il a besoin pour résoudre les symboles actuellement non définis. Puisque les objets sont liés dans l'ordre donné sur la ligne de commande, les objets de la bibliothèque ne seront inclus que si la bibliothèque vient après tous les objets qui en dépendent. Donc, l'ordre des liens est très important; Si vous utilisez des bibliothèques statiques, vous devez faire attention à ne pas oublier les dépendances et ne pas introduire de dépendances cycliques entre les bibliothèques.

+0

Les dépendances cycliques sont correctes - cela signifie simplement que vous devez avoir une ligne de lien comme "' ao bo ao' ". – caf

+1

@caf: si les objets supplémentaires de la seconde inclusion de 'a' dépendent des objets dans' b' qui n'ont pas encore été inclus, alors ce n'est pas suffisant; vous devrez ajouter 'b' à la fin. Ce qui à son tour pourrait introduire plus de dépendances sur 'a'. Les dépendances cycliques ne sont donc pas vraiment «correctes», il est rare qu'elles soient assez pathologiques pour nécessiter plus d'une répétition. –

17

La commande de bibliothèque passée à gcc/g ++ est réellement importante. Si A dépend de B, A doit être listé en premier. La raison en est qu'elle optimise les symboles qui ne sont pas référencés, donc si elle voit la bibliothèque B en premier, et que personne ne l'a référencée à ce moment-là, elle ne liera rien du tout.

0

Vous pouvez utiliser archives --start-groupe --end-groupe et écrire les 2 bibliothèques dépendantes au lieu de archives

gcc main.o -L. -Wl, - start-group -lobj_A -lobj_b -Wl, - end-group