2010-09-29 8 views
63

Tengo 2 bibliotecas estáticas de Linux, creadas por ar cr, libabc.a y libxyz.a.
Quiero fusionarlos en una biblioteca estática libaz.a.
¿Cómo puedo hacer esto?Cómo fusionar dos bibliotecas estáticas "ar" en una

Quiero crear una biblioteca estática resultante de la fusión, para no dar dos bibliotecas de enlace definitivo de solicitudes

+6

Consulte también: [ 'solución basada en libtool'] (http: // stackoverflow. com/a/8170851/196561): 'libtool -static -o new.a old1.a old2.a' – osgx

+1

funciona perfecto, solo un poco de duda si esas bibliotecas tienen un archivo común.o (pero la funcionalidad es diferente) ¿Seguirá funcionando? – bindingofisaac

Respuesta

39

puede extraer el objeto tanto de los archivos .a y crear su archivo .a utilizando los extraídos .o s:

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

¡Peligro, Will Robinson! Esto funciona solo si los nombres de los miembros en libabc.a y libxyz.a no se superponen. De lo contrario, sobrescribirá uno y se perderá. –

+5

Además, 'libabc.a' puede contener objetos con el mismo nombre (originados en directorios diferentes) - ¡volver a ensamblar no funcionará! –

+6

'ar -c' no funcionó para mí (Ubuntu 14.04). Tengo 'ar: ninguna operación especificada'. Hice 'ar -qc' en su lugar y funcionó bien. – Max

6

Si simplemente como:

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

va perdido algunos archivos de objetos si t aquí son miembros con el mismo nombre en AA y BA así, es necesario extraer los miembros de diferentes archivos en diferentes carpetas:

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 

aún más, es Posible que hay varios miembros del mismo nombre en un archivo (diga en aa), si ejecuta ar x aa, obtendrá solo una para los miembros del mismo nombre.

La única manera de extraer todos los miembros del mismo nombre en un archivo es para especificar el número de socio por la opción '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 
... 

esto sería un trabajo tedioso, por lo que tendrá que escribir una script más sofisticado para hacer ese trabajo.

Una opcionales soluciones es que se puede combinar varios archivos en una sola biblioteca compartida:

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

esta manera, el enlazador se encargará de todas las cosas para usted!

+1

Samuel, gracias. Pero al combinar en la biblioteca compartida, todos los objetos deben compilarse con '-fPIC'. – osgx

72

Hay al menos tres formas de hacerlo nativamente. La primera y más portátil es usar libtool. Después de haber construido las otras bibliotecas también con libtool, se pueden combinar simplemente añadiendo las librerías .la a una variable libaz_la_LIBADD automake, o directamente desde un Makefile con algo como:

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

Los otros dos son al menos disponibles cuando se usa GNU ar. Puede usar un script de MRI (nombrado por ejemplo libaz.mri), tales como:

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

y luego ejecutar ar como:

ar -M <libaz.mri 

O puede utilizar una archivo delgada (opción -T), lo que permitirá la adición de otros archivos sin que ellos anidados en el interior, aunque la desventaja es que si desea distribuir la biblioteca estática, el objeto separado faltará:

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

Todos los métodos anteriores manejan con gracia los nombres de los miembros superpuestos de los archivos originales.

De lo contrario, tendría que descomprimir en diferentes directorios y volverá a empaquetar de nuevo, para evitar la sustitución de la superposición de nombres de los miembros:

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

Para aquellos que quieren un archivo normal (no delgado), una cosa simple que se puede hacer es crear un archivo delgado y luego convertirlo a un archivo normal. Algo así como: 'ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a \ naddlib libaz.a \ nsave \ nend' | ar -M'. Esto crea un 'libaz.a' fino y temporal, y luego convierte el archivo delgado en uno normal (para que pueda moverlo/distribuirlo). Esto también se maneja con gracia cuando los nombres de su biblioteca tienen caracteres especiales (espaciados, más o comas) (es decir, 'ar cqT libbundle.a libfoo ++. A 'libbar baz.a''). ¡Pero +1 de mí! – Cornstalks

+0

¿Cuál es la desventaja del primer ejemplo de script de MRI? –

+0

+1 para secuencias de comandos MRI! – scraimer

Cuestiones relacionadas