2010-09-29 16 views
63

Ho 2 librerie linux statiche, create da , libabc.a e libxyz.a.
Voglio unirli in una libreria statica libaz.a.
Come posso fare questo.Come unire due librerie statiche "ar" in una

Voglio creare una libreria statica fusione, per non dare entrambe le librerie a collegamento finale delle applicazioni

+6

Consulta anche: [ 'soluzione libtool' basata] (http: // StackOverflow. it/a/8170851/196561): 'libtool -static -o new.a old1.a old2.a' – osgx

+1

funziona perfettamente, solo un piccolo dubbio se quelle librerie hanno file.o comune (ma le funzionalità sono saggie sono diverse) funzionerà ancora? – bindingofisaac

risposta

39

è possibile estrarre l'oggetto da entrambi i file .a e creare il file .a utilizzando i estratte .o s:

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

Pericolo, Will Robinson! Funziona solo se i nomi dei membri in libabc.a e libxyz.a non si sovrappongono. Altrimenti ne sovrascriverò uno e andrà perso. –

+5

Inoltre, 'libabc.a' può contenere oggetti aventi lo stesso nome (originato da diverse directory) - il riassemblaggio non funzionerà allora! –

+6

'ar -c' non ha funzionato per me (Ubuntu 14.04). Ho ottenuto "ar: nessuna operazione specificata". Ho fatto invece "ar -qc" e questo ha funzionato bene. – Max

6

Se semplicemente fate come:

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

si perso alcuni file oggetto se t qui ci sono i membri con lo stesso nome sia in AA e BA così, è necessario estrarre i membri di diversi archivi in ​​un'altra cartella:

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 

ulteriormente più, è posible che ci sono più membri dello stesso nome in un unico archivio (ad esempio in aa), se esegui ar x aa, ne riceverai solo uno per quei membri con lo stesso nome.

L'unico modo per estrarre tutti i membri della stesso nome in un unico archivio è quello di specificare il numero membro dall'opzione '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 
... 

questo sarebbe un lavoro noioso, in modo da avere per scrivere un script più sofisticato per fare quel lavoro.

Uno opzionali soluzioni è che è possibile combinare più archivi in ​​una libreria condivisa:

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

questo modo il linker si occuperà di tutte le cose per voi!

+1

Samuel, grazie. Ma nella combinazione nella libreria condivisa, tutti gli oggetti dovrebbero essere compilati con '-fPIC'. – osgx

72

Ci sono almeno tre modi per fare questo in modo nativo. Il primo e più portabile è usare libtool. Dopo aver costruito le altre librerie anche con libtool, è possibile combinarli semplicemente aggiungendo le librerie .la ad una variabile libaz_la_LIBADD automake, o direttamente da un Makefile con qualcosa di simile:

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

Gli altri due sono almeno disponibili quando si utilizza GNU ar. È possibile utilizzare uno script MRI (denominato ad esempio libaz.mri), come ad esempio:

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

e quindi eseguire ar come:

ar -M <libaz.mri 

Oppure si può utilizzare un sottile archivio (opzione -T), che consentirà di aggiungere altri archivi senza ottenere loro annidati all'interno, anche se il lato negativo è che se si desidera distribuire la libreria statica, mancherà l'oggetto distaccato:

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

Tutti i metodi sopra descritti gestiscono con garbo i nomi dei membri sovrapposti dagli archivi originali.

In caso contrario, sarebbe necessario scompattare in diverse directory e imballare ancora una volta, per evitare di sostituire i nomi dei membri che si sovrappongono:

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

Per coloro che desiderano un archivio normale (non sottile), una cosa semplice che è possibile fare è creare un archivio sottile, quindi convertirlo in un normale archivio. Qualcosa come: 'ar cqT libaz.a libabc.a libxyz.a && echo -e 'crea libaz.a \ naddlib libaz.a \ nsave \ nend' | ar -M'. Questo crea un temporaneo 'libaz.a', quindi converte l'archivio sottile in uno normale (in modo da poterlo spostare/distribuire). Questo anche con garbo quando i nomi delle tue librerie hanno caratteri speciali (spaziati, più o virgole) (ad esempio 'ar cqT libbundle.a libfoo ++. A 'libbar baz.a''). Ma +1 da parte mia! – Cornstalks

+0

Qual è lo svantaggio del primo esempio di script MRI fornito? –

+0

+1 per lo script MRI! – scraimer