qu'est-ce que ranlib?

13

J'utilise un système MacOSX depuis un certain temps, mais j'ai récemment commencé à fouiller dans les tripes. J'ai trouvé un guide me disant d'exécuter «sudo ranlib /usr/local/lib/libjpeg.a» (installation de libjpeg). J'ai lu le manuel ranlib et j'ai essayé de le consulter en ligne. Je ne comprends tout simplement pas. Quelles ressources dois-je rechercher pour en savoir plus, ou quelqu'un peut-il donner une explication concise sur son utilisation? Merci d'avance!

Ying
la source

Réponses:

7

ranlibajoute ou met à jour des fichiers objets dans une bibliothèque statique . Les éditeurs de liens peuvent utiliser des bibliothèques statiques lors de la liaison afin de fournir les symboles dont le code a besoin pour fonctionner (par opposition au chargeur qui les recherche dans les bibliothèques dynamiques lors de l'exécution de l'exécutable).

Ignacio Vazquez-Abrams
la source
Salut Ignacio, merci pour la réponse. Est-ce à dire que si j'exécute ranlib sur une bibliothèque, il sera disponible à chaque fois qu'un éditeur de liens essaiera de le 'référencer'? Comment est-il retiré?
Ying
ranlibest utilisé pour créer et modifier les bibliothèques. C'est à l'éditeur de liens de les utiliser, généralement en passant l'emplacement et / ou le nom de la bibliothèque sur la ligne de commande. Voir les arguments -Let -lpour gcc pour plus de détails.
Ignacio Vazquez-Abrams
5
Mais ne fait pas ça non arplus? Quelle est la différence?
greatwolf
18

Cette description semble assez claire: http://sourceware.org/binutils/docs/binutils/ranlib.html

Donc, si vous archivez une collection de fichiers objets, dites:

$ ar r fruits.a apple.o orange.o pineapple.o

Puis en cours d'exécution

$ ranlib fruits.a

crée un index du contenu de fruits.a et stocke l'index dans fruits.a. Ceci est utile pour la liaison et au cas où les objets s'appelleraient.

Invité McGuesterson
la source
"ranlib génère un index du contenu d'une archive et le stocke dans l'archive". Cela ressemble plus à quelque chose à combiner taret je dirais pas très clair.
Codebling
9

ranlib génère un index du contenu d'une archive et le stocke dans l'archive. L'index répertorie chaque symbole défini par un membre d'une archive qui est un fichier objet déplaçable. Une archive avec un tel index accélère la liaison à la bibliothèque et permet aux routines de la bibliothèque de s'appeler sans égard à leur placement dans l'archive.

source: page de manuel ranlib

Albert
la source
2

ar

Sous Linux, arest l'archiveur GNU à usage général. (Il existe des variantes non GNU ardans d'autres systèmes d'exploitation de type Unix). Avec l'optionc

ar c... archive-name file...

Il crée une archive contenant des copies de file.... Le archive-nameconventionnellement, mais pas nécessairement, a l'extension .a(pour l' archive ). Chacun file...peut être n'importe quel type de fichier, pas nécessairement un fichier objet.

Lorsque les fichiers archivés sont tous des fichiers objets, il est généralement prévu d'utiliser l'archive pour fournir cette sélection de fichiers objets dans la liaison de programmes ou DSO (Dynamic Shared Objects). Dans ce cas archive-name, le préfixe sera également classiquement attribué lib, par exemple libfoo.a, afin qu'il puisse être découvert en tant que fichier d'entrée de l'éditeur de liens via l'option de l'éditeur de liens -lfoo.

Utilisé comme fichier d'entrée de l'éditeur de liens, il libfoo.aest normalement appelé bibliothèque statique . Cette utilisation est une source perpétuelle de confusion pour les programmeurs inexpérimentés, car elle les amène à penser qu'une archive libfoo.aest à peu près la même chose qu'un DSO libfoo.so, normalement appelé bibliothèque dynamique / partagée , et à construire de fausses attentes sur cette base. En fait, une "bibliothèque statique" et une "bibliothèque dynamique" ne sont pas du tout des choses similaires et sont utilisées dans la liaison de manières totalement différentes.

Une différence notable est qu'une bibliothèque statique n'est pas produite par l' éditeur de liens , mais par ar. Donc, aucun lien ne se produit, aucune résolution de symbole ne se produit. Les fichiers objets archivés sont inchangés: ils sont juste mis dans un sac.

Lorsqu'une archive est entrée dans le lien de quelque chose qui est produit par l'éditeur de liens - tel qu'un programme ou DSO - l'éditeur de liens regarde dans le sac pour voir s'il y a des fichiers objets qui fournissent des définitions pour les références de symboles non résolues qui se sont accumulées plus tôt dans la liaison. Si elle en trouve, il extrait les fichiers d'objets du sac et relie les dans le fichier de sortie, exactement comme s'ils ont été nommés individuellement dans la ligne de commande de liaison et l'archive ne mentionne pas du tout. Ainsi, le rôle entier d'une archive dans la liaison est comme un sac de fichiers objets à partir duquel l'éditeur de liens peut sélectionner ceux dont il a besoin pour poursuivre la liaison.

Par défaut, GNU arrend ses archives de sortie prêtes à être utilisées comme entrées de l'éditeur de liens. Il ajoute un "fichier" bidon à l'archive, avec un nom de fichier bidon magique, et dans ce fichier bidon, il écrit du contenu que l'éditeur de liens est capable de lire comme une table de recherche à partir des symboles globaux définis par n'importe quel fichier objet de l'archive. aux noms et positions de ces fichiers objets dans l'archive. Cette table de recherche permet à l'éditeur de liens de rechercher dans l'archive et d'identifier tous les fichiers d'objets qui définissent les références de symboles non résolues qu'il a en main.

Vous pouvez supprimer la création ou la mise à jour de cette table de recherche avec l' option q(= rapide ) - que vous avez en fait utilisée dans votre propre arexemple - et également avec l' option (majuscule) S(= pas de table de symboles ). Et si vous invoquez arpour créer ou mettre à jour une archive qui n'a pas de table de symboles (à jour) pour une raison quelconque, vous pouvez lui en donner une avec l' soption.

ranlib

ranlibne crée pas du tout de bibliothèques. Sous Linux, ranlibest un programme hérité qui ajoute une table de symboles (à jour) à une ararchive si elle n'en a pas. Son effet est exactement le même ar squ'avec GNU ar. Historiquement, avant arétait équipé pour générer une table de symboles elle-même, ranlibétait le kludge qui a injecté le fichier bidon magique dans une archive pour permettre à l'éditeur de liens de choisir des fichiers objet à partir de celui-ci. Dans les systèmes d'exploitation non GNU Unix, il ranlibpourrait encore être nécessaire à cet effet. Votre exemple:

ar qc libgraphics.a *.o
ranlib libgraphics.a

dit:

  • Créez libgraphics.aen ajoutant à une archive tous les *.ofichiers du répertoire courant, sans table de symboles.
  • Ajoutez ensuite une table de symboles à libgraphics.a

Sous Linux, cela a le même effet net que:

ar cr libgraphics.a *.o

En soi, ar qc libgraphics.a *.ocrée une archive que l'éditeur de liens ne peut pas utiliser, car il n'a pas de table de symboles.

ld

Votre exemple:

ld -r -o libgraphics.a *.o

est en fait assez peu orthodoxe. Ceci illustre l'utilisation assez rare de l' éditeur de liens , ldpour produire un fusionné fichier objet en reliant plusieurs fichiers d'entrée dans un seul fichier objet de sortie, dans laquelle la résolution des symboles a été fait dans la mesure du possible , étant donné les fichiers d'entrée. L' option -r(= relocatable ) demande à l'éditeur de liens de produire une cible de fichier objet (plutôt qu'un programme ou DSO) en liant les entrées autant que possible et de ne pas faire échouer le linkaqe si des références de symboles non définies restent dans le fichier de sortie. Cette utilisation est appelée liaison partielle .

Le fichier de sortie de ld -r ... est un fichier objet, pas une ar archive , et spécifier un nom de fichier de sortie qui ressemble à celui d'une ararchive n'en fait pas un. Votre exemple illustre donc une tromperie. Cette:

ld -r -o graphics.o *.o

serait véridique. Je ne sais pas quel pourrait être le but d'une telle tromperie, car même si un fichier objet ELF est appelé libgraphics.aet est entré dans une liaison soit par ce nom, soit par -lgraphicsl'éditeur de liens l'identifiera correctement en tant que fichier objet ELF , pas une ararchive, et le consommera comme il consomme n'importe quel fichier objet dans la ligne de commande: il le relie inconditionnellement au fichier de sortie, alors que le point d'entrée d'une archive authentique est de lier les membres de l'archive uniquement à condition qu'ils soient référencés . Peut-être avez-vous juste un exemple de lien mal informé ici.

Emballer...

En fait, nous n'avons vu qu'une seule façon de produire quelque chose qui est conventionnellement appelé une bibliothèque , et c'est la production d'une bibliothèque dite statique , en archivant certains fichiers objets et en mettant une table de symboles dans l'archive.

Et nous n'avons pas du tout vu comment produire l'autre type de chose le plus important que l'on appelle conventionnellement une bibliothèque , à savoir un objet partagé dynamique / bibliothèque partagée / bibliothèque dynamique.

Comme un programme, un DSO est produit par l'éditeur de liens . Un programme et un DSO sont des variantes du fichier binaire ELF que le chargeur du système d'exploitation comprend et peut utiliser pour assembler un processus en cours d'exécution. Habituellement , nous invoquons l'éditeur de liens via une une des interfaces de GCC ( gcc, g++, gfortran, etc.):

Lier un programme:

gcc -o prog file.o ... -Ldir ... -lfoo ...

Lier un DSO:

gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...

Les bibliothèques partagées et les bibliothèques statiques peuvent être proposées à l'éditeur de liens par le -lfooprotocole uniforme , lorsque vous liez un autre programme ou DSO. Cette option demande à l'éditeur de liens d'analyser ses répertoires de recherche spécifiés ou par défaut pour trouver libfoo.soou libfoo.a. Par défaut, une fois qu'il a trouvé l'un d'eux, il entrera ce fichier dans la liaison, et s'il trouve les deux dans le même répertoire de recherche, il préférera libfoo.so. Si libfoo.so, est sélectionné, l'éditeur de liens ajoute ce DSO à la liste des dépendances d'exécution de n'importe quel programme ou DSO que vous créez. Si libfoo.aest sélectionné, l'éditeur de liens utilise l'archive comme une sélection de fichiers objets à lier au fichier de sortie, si nécessaire, juste là et ensuite. Aucune dépendance d'exécution sur libfoo.alui-même est possible; il ne peut pas être mappé dans un processus; cela ne signifie rien pour le chargeur du système d'exploitation.

Copié à partir de https://stackoverflow.com/a/47924864/195787 .

Royi
la source