103 votes

Comment fusionner deux bibliothèques statiques "ar" en une seule ?

J'ai 2 bibliothèques Linux statiques, créées par ar cr , libabc.a y libxyz.a .
Je veux les fusionner en une seule bibliothèque statique. libaz.a .
Comment puis-je le faire ?

Je veux créer une bibliothèque statique fusionnée, et non pas donner les deux bibliothèques au lien final des applications.

9 votes

Voir aussi : libtool -solution basée sur la technologie : libtool -static -o new.a old1.a old2.a

2 votes

Cela fonctionne parfaitement, juste un petit doute si ces bibliothèques ont un fichier .o commun (mais que les fonctionnalités sont différentes) cela fonctionnera-t-il toujours ?

0 votes

Libtool -static -o new.a old1.a old2.a ne fonctionne pas sous linux(centos 7)

137voto

Guillem Jover Points 71

Il y a au moins trois façons de procéder nativement . Le premier moyen et le plus portable est d'utiliser libtool. Après avoir construit les autres bibliothèques également avec libtool, vous pouvez les combiner simplement en ajoutant les librairies .la à une variable automake libaz_la_LIBADD, ou directement à partir d'un Makefile avec quelque chose comme :

libtool --mode=link cc -static -o libaz.la libabc.la libxyz.la

Les deux autres sont au moins disponibles lorsque vous utilisez GNU ar. Vous pouvez utiliser un MRI script (nommé par exemple libaz.mri), tel que :

create libaz.a
addlib libabc.a
addlib libxyz.a
save
end

et ensuite exécuter ar comme :

ar -M <libaz.mri

Ou vous pouvez utiliser un mince archive (option -T ), ce qui permettra d'ajouter d'autres archives sans qu'elles soient imbriquées à l'intérieur, bien que l'inconvénient soit que si vous voulez distribuer la bibliothèque statique, l'objet détaché sera absent :

ar -rcT libaz.a libabc.a libxyz.a

Toutes les méthodes ci-dessus gèrent gracieusement les noms de membres qui se chevauchent dans les archives originales.

Sinon, il faudrait déballer dans différents répertoires et remballer à nouveau, pour éviter de remplacer des noms de membres qui se chevauchent :

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz

20 votes

Pour ceux qui veulent une archive normale (et non pas légère), une chose simple à faire est de créer une archive légère, puis de la convertir en archive normale. Quelque chose comme : ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a\naddlib libaz.a\nsave\nend' | ar -M . Cela crée un mince temporaire libaz.a et convertit ensuite l'archive légère en archive normale (afin que vous puissiez la déplacer/distribuer). Cela permet également de gérer gracieusement les cas où les noms de vos bibliothèques contiennent des caractères spéciaux (espaces, plus, ou virgules) (par ex. ar cqT libbundle.a libfoo++.a 'libbar baz.a' ). Mais +1 de ma part !

1 votes

Quel est l'inconvénient du premier exemple d'IRM script donné ?

0 votes

Belle réponse ! C'est bien de voir des options qui ne nécessitent pas d'extraire et de ré-accrocher. Je pense aussi que l'idée de @Cornstalks est bonne. Peut-être devrait-elle être ajoutée à la réponse ?

66voto

codaddict Points 154968

Vous pouvez extraire l'objet à partir des deux .a et créez votre .a en utilisant le fichier .o s :

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o

69 votes

Danger, Will Robinson ! Ce travail uniquement si les noms des membres dans libabc.a et libxyz.a ne se chevauchent pas. Sinon, vous allez en écraser un et il sera perdu.

7 votes

D'ailleurs, libabc.a peut contenir des objets ayant le même nom (provenant de différents répertoires) -- le ré-assemblage ne fonctionnera pas alors !

18 votes

ar -c n'a pas fonctionné pour moi (Ubuntu 14.04). J'ai obtenu ar: no operation specified . J'ai fait ar -qc à la place et cela a bien fonctionné.

10voto

samuel.zzy220 Points 11

Si vous le faites simplement comme :

ar x a.a
ar x b.a
ar c c.a  *.o 

vous perdrez certains fichiers objets s'il y a des membres avec le même nom dans a.a et b.a Vous devez donc extraire les membres de différentes archives dans des dossiers différents :

ar x a.a && mv *.o a_objs
ar x b.a && mv *.o b_objs
ar c c.a a_objs/*.o b_objs/*.o

De plus, il est possible qu'il y ait plusieurs membres du même nom dans une archive (disons dans a.a), si vous exécutez ar x a.a vous n'en obtiendrez qu'un seul pour les membres du même nom.

La seule façon d'extraire tous les membres du même nom dans une archive est de spécifier le numéro du membre par l'option 'N' :

ar xN 1 a.a  xxx.c.o && mv xxx.c.o xxx.c.1.o
ar xN 2 b.a  xxx.c.o && mv xxx.c.o xxx.c.2.o
...

ce serait un travail fastidieux, vous devrez donc écrire un script plus sophistiqué pour faire ce travail.

Un en option est que vous pouvez combiner plusieurs archives en une seule bibliothèque partagée :

g++ -shared -o c.so -Wl,--whole-archive a.a b.a 

de cette façon le linker s'occupera de tout pour vous !

1 votes

Samuel, merci. Mais en combinant dans une bibliothèque partagée, tous les objets doivent être compilés avec le code suivant -fPIC .

6voto

Zac Points 570

L'option -c suggérée de ar me donne une erreur "ar : no operation specified". J'ai dû utiliser l'option 'r' (ar r libaz.a *.o a fonctionné pour moi). Ma version de ar est GNU ar 2.17.50.0.6-12.el5 20061020 (c'est une cible redhat 4).

La commande 'ar q' suggérée n'a pas fonctionné, car l'erreur suivante est apparue lors de l'enchaînement final :

libaz.a: could not read symbols: Archive has no index; run ranlib to add one

-1voto

Jichao Points 476

Ou vous pouvez simplement utiliser l'option "quick append" (man ar, regardez q ou r)

ar q libaz.a libabc.a libxyz.a

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X