web-dev-qa-db-fra.com

Un bon moyen de lier une bibliothèque statique à l'aide de GCC

Pourquoi certaines bibliothèques statiques (lib * .a) peuvent-elles être liées de la même manière que les bibliothèques partagées (lib * .so) sont liées (commutateur ld -l), mais certaines ne le peuvent pas?

On m'a toujours appris que toutes les bibliothèques, statiques ou non, peuvent être liées avec -l ..., mais j'ai jusqu'à présent rencontré une seule bibliothèque (GLFW), qui ne fait que répandre des erreurs de lien "référence non définie" si je essayez de le lier de cette façon.

Selon la réponse sur cette question , la manière "correcte" de lier des bibliothèques statiques est de les inclure directement, avec mes propres fichiers objets, plutôt que d'utiliser -l. Et, dans le cas de la bibliothèque GLFW, cela résout certainement le problème. Mais toutes les autres bibliothèques statiques que j'utilise fonctionnent très bien lorsqu'elles sont liées avec -l.

Alors:

  • Qu'est-ce qui pourrait empêcher cette bibliothèque de fonctionner lorsqu'elle est liée plutôt que incluse directement? Si je connaissais la cause, je pourrais peut-être éditer et recompiler la bibliothèque pour résoudre le problème.
  • Est-il vrai que vous n'êtes pas censé lier des bibliothèques statiques de la même manière que vous liez des bibliothèques partagées? (Et si non, pourquoi pas?)
  • L'éditeur de liens est-il toujours en mesure d'éliminer les fonctions de bibliothèque inutilisées de l'exécutable de sortie lorsque la bibliothèque est directement incluse de cette manière?
22
Nairou

Merci pour les réponses! Il s'avère que le problème était dû à l'ordre des liens. Apparemment, si vous utilisez une bibliothèque qui à son tour a d'autres dépendances de bibliothèque, ces autres dépendances doivent être listées après la bibliothèque, pas avant comme je l'avais fait. J'ai appris quelque chose de nouveau!

25
Nairou

La bonne façon de lier une bibliothèque statique utilise -l, mais cela ne fonctionne que si la bibliothèque peut être trouvée sur le chemin de recherche. Si ce n'est pas le cas, vous pouvez ajouter le répertoire à la liste en utilisant -L ou nommer le fichier par son nom, comme vous le dites.

La même chose est vraie pour les bibliothèques partagées, en fait, bien qu'elles soient plus susceptibles d'être trouvées, peut-être.

6
ams

Avez-vous pris soin d'indiquer à GCC le chemin de votre bibliothèque (en utilisant -L)? En utilisant uniquement -l, GCC ne pourra lier que les bibliothèques disponibles dans les répertoires standard.

-L[path] -l[lib]
5
Vincent L.

La raison est historique. L'outil "ar" était à l'origine l'outil d'archivage de fichiers sur PDP11 unix, bien qu'il ait ensuite été entièrement remplacé par "tar" à cet effet. Il stocke des fichiers (fichiers objets, dans ce cas) dans un package. Et il y a une extension séparée contenant la table des symboles à utiliser par l'éditeur de liens. Il est possible si vous gérez manuellement des fichiers dans l'archive que la table des symboles peut devenir obsolète.

La réponse courte est que vous pouvez utiliser l'outil "ranlib" sur n'importe quelle archive pour recréer la table des symboles. Essayez ça. Plus largement, essayez de comprendre d'où viennent les bibliothèques corrompues et corrigez cela.

1
Andy Ross