2009-03-20 10 views
13

Supposons que j'ai trois C bibliothèques statiques dire libColor.a qui dépend de * libRGB. * Un qui à son tour dépend de libPixel.a. La bibliothèque libColor.a dit dépendre de la bibliothèque libRGB.a car il y a quelques références dans libColor.a à certains des symboles définis dans libRGB.a. Comment puis-je combiner toutes les bibliothèques ci-dessus à un nouveau libNewColor.a qui est indépendant? Indépendant signifie que la nouvelle bibliothèque doit avoir tous les symboles définis. Donc, tout en liant j'ai juste besoin de donner -lNewColor. La taille de la nouvelle bibliothèque devrait être minime à-dire qu'elle ne doit pas contenir de symboles dans libRGB.a qui n'est pas utilisé par libColor.a etc. J'ai essayé ma chance en utilisant différentes options ar commande (utilisée pour créer et mettre à jour des bibliothèques/archives statiques).Combinant les bibliothèques statiques

+0

Vous pouvez encore regarder http: // stackoverflow. com/questions/8170450/combiner-static-libraries/8170851 # 8170851 et utiliser libt ool – Bruce

+0

Notez que l'étape de minimisation n'est vraiment pas nécessaire. Avec les bibliothèques statiques, l'éditeur de liens n'obtient que les fichiers objets dont il a besoin, contrairement aux bibliothèques partagées qui incluent tout. Il y a des raisons et des avantages à chaque approche; ils sont juste différents. Et vous n'avez vraiment pas besoin de vous inquiéter pendant que vous travaillez avec des bibliothèques statiques. –

Répondre

11

1/Extrayez TOUS les fichiers objet de chaque bibliothèque (en utilisant ar) et essayez de compiler votre code sans les bibliothèques ou les fichiers objet. Vous obtiendrez probablement un chargement absolu de symboles indéfinis. Si vous n'obtenez pas de symboles indéfinis, passez à l'étape 5.

2/Saisissez le premier et recherchez le fichier objet correspondant à ce symbole (en utilisant nm). 3/Notez ce fichier objet puis compilez votre code, y compris le nouveau fichier objet. Vous obtenez une nouvelle liste de symboles non définis ou, s'il n'y en a pas, passez à l'étape 5.

4/Passez à l'étape 2.

5/Combiner tous les fichiers objets dans votre liste (le cas échéant) dans une seule bibliothèque (à nouveau avec ar).

Bang! Voilà. Essayez de lier votre code sans aucun des objets mais avec la nouvelle bibliothèque.

Tout cela pourrait être relativement facilement automatisé avec un script shell.

+2

Inutilement compliqué, vous pouvez simplement extraire tous les fichiers .o dans un .a grand, comme quand il est finalement lié dans un exécutable, l'éditeur de liens va rejeter tous ceux utilisés de toute façon – MarkR

+2

@MarkR, @AIB voulait la taille de la * bibliothèque * être minimal, pas la taille de l'exécutable. – paxdiablo

+0

Accepter, mais j'aimerais un oneliner qui fait cela. Comme passer quelques options à ld pour lier avec seulement les symboles nécessaires etc ... – AIB

5

Une bibliothèque statique n'est pas beaucoup plus qu'une archive de certains fichiers objets (.o). Ce que vous pouvez faire est d'extraire tous les objets dans les deux bibliothèques (en utilisant "ar x") et ensuite utiliser "ar" pour les lier ensemble dans une nouvelle bibliothèque.

15

Une petite fonction Permettent du archiveur GNU est le script d'archivage, il est une interface simple mais puissante, et il peut faire exactement ce que vous voulez, par exemple, si le script suivant est appelé script.ar:

CREATE libNewColor.a 
ADDLIB libColor.a 
ADDLIB libRGB.a 
ADDLIB libPixel.a 
SAVE 
END 

Ensuite, vous pouvez invoquer ar comme suit:

ar -M < script.ar 

et vous obtiendrez libNewColor.a qui contient tous les fichiers .o de libColor.a libRGB.a et libPixel.a.

En outre, vous pouvez également ajouter régulier.o fichiers aussi bien avec la commande ADDMOD:

CREATE libNewColor.a 
ADDLIB libColor.a 
ADDLIB libRGB.a 
ADDLIB libPixel.a 
ADDMOD someRandomCompiledFile.o 
SAVE 
END 

De plus, il est très facile de générer ces scripts dans Makefile, donc je crée généralement une règle de makefile un peu générique pour la création d'archives qui génère effectivement le script et invoque ar le scénario. Quelque chose comme ceci:

$(OUTARC): $(OBJECTS) 
    $(SILENT)echo "CREATE [email protected]" > $(ODIR)/$(ARSCRIPT) 
    $(SILENT)for a in $(ARCHIVES); do (echo "ADDLIB $$a" >> $(ODIR)/$(ARSCRIPT)); done 
    $(SILENT)echo "ADDMOD $(OBJECTS)" >> $(ODIR)/$(ARSCRIPT) 
    $(SILENT)echo "SAVE" >> $(ODIR)/$(ARSCRIPT) 
    $(SILENT)echo "END" >> $(ODIR)/$(ARSCRIPT) 
    $(SILENT)$(AR) -M < $(ODIR)/$(ARSCRIPT) 

Bien que maintenant que je regarde, je suppose que cela ne fonctionne pas si $ (objets) est vide (si vous voulez juste de combiner les archives sans l'ajout de fichiers d'objets supplémentaires) mais je le laisser comme un exercice pour le lecteur de résoudre cette question en cas de besoin ...: D

Voici les documents pour cette fonction:

https://sourceware.org/binutils/docs/binutils/ar-scripts.html#ar-scripts

+0

C'est génial! Sauf que tous les chemins/libs qui ont un + dans le nom cassent le script. Par exemple openssl a libncurses ++. A – Gregory

+0

Neat! C'est beaucoup plus facile que de déballer et de reconditionner vous-même des fichiers objets. – Thomas

+0

Notez que, pour une raison quelconque, -D ne fonctionne pas en combinaison avec -M. Donc, si vous voulez obtenir des résultats déterministes, vous avez toujours besoin de la route extract-then-archive. –

Questions connexes