Wie füge ich zwei statische "ar" -Bibliotheken zu einer zusammen?

88

Ich habe 2 statische Linux - Bibliotheken, erstellt von ar cr, libabc.aund libxyz.a.
Ich möchte sie in einer statischen Bibliothek zusammenführen libaz.a.
Wie kann ich das machen.

Ich möchte eine zusammengeführte statische Bibliothek erstellen und nicht beide Bibliotheken der endgültigen Verknüpfung von Anwendungen zuordnen.

osgx
quelle
7
Siehe auch: libtool-basierte Lösung :libtool -static -o new.a old1.a old2.a
osgx
2
es funktioniert perfekt, nur ein kleiner Zweifel, ob diese Bibliotheken eine gemeinsame Datei haben.o (aber funktional sind sie unterschiedlich) wird es trotzdem funktionieren?
Bindingofisaac

Antworten:

58

Sie können das Objekt aus beiden .aDateien .aextrahieren und Ihre Datei mit den extrahierten .os erstellen :

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o
Codaddict
quelle
63
Gefahr, Will Robinson! Dies funktioniert nur, wenn sich die Namen der Mitglieder in libabc.a und libxyz.a nicht überschneiden. Andernfalls überschreiben Sie eine und sie geht verloren.
David Given
6
Darüber hinaus libabc.akönnen Objekte enthalten die gleichen Namen (entstandene Form verschiedene Verzeichnisse) mit - wieder zusammenbauen dann nicht funktioniert!
Igor R.
15
ar -chat bei mir nicht funktioniert (Ubuntu 14.04). Ich habe ar: no operation specified. Ich habe es ar -qcstattdessen getan und das hat gut funktioniert.
Max
ar t lib.a kann zum Anzeigen der Dateien in der Bibliothek verwendet werden, ohne die Dateien tatsächlich zu extrahieren.
Raj_gt1
Wie kann ich das in automake machen?
Shuva
117

Es gibt mindestens drei Möglichkeiten, dies nativ zu tun . Der erste und portabelste Weg ist die Verwendung von libtool. Nachdem Sie die anderen Bibliotheken ebenfalls mit libtool erstellt haben, können Sie sie kombinieren, indem Sie die .la-Bibliotheken zu einer automake libaz_la_LIBADD-Variablen hinzufügen oder direkt aus einem Makefile mit folgenden Elementen:

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

Die anderen beiden sind zumindest bei Verwendung von GNU ar verfügbar. Sie können ein MRT-Skript (z. B. libaz.mri) verwenden, z.

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

und dann ar ausführen als:

ar -M <libaz.mri

Oder Sie können ein Thin- Archiv (Option -T) verwenden, mit dem Sie andere Archive hinzufügen können, ohne sie darin zu verschachteln. Der Nachteil ist jedoch, dass das getrennte Objekt fehlt, wenn Sie die statische Bibliothek verteilen möchten:

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

Alle oben genannten Methoden behandeln überlappende Mitgliedsnamen aus den Originalarchiven ordnungsgemäß.

Andernfalls müssten Sie in verschiedene Verzeichnisse entpacken und erneut packen, um zu vermeiden, dass sich überlappende Mitgliedsnamen ersetzt werden:

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz
Guillem Jover
quelle
18
Für diejenigen, die ein normales Archiv (nicht dünn) möchten, können Sie einfach ein dünnes Archiv erstellen und es dann in ein normales Archiv konvertieren. So etwas wie : ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a\naddlib libaz.a\nsave\nend' | ar -M. Dadurch wird ein temporäres Thin erstellt libaz.aund das Thin-Archiv wird dann in ein normales umgewandelt (sodass Sie es verschieben / verteilen können). Dies funktioniert auch ordnungsgemäß, wenn Ihre Bibliotheksnamen Sonderzeichen (Abstände, Pluszeichen oder Kommas) enthalten (dh ar cqT libbundle.a libfoo++.a 'libbar baz.a'). Aber +1 von mir!
Cornstalks
Was ist der Nachteil des ersten Beispiels für ein MRT-Skript?
jb
Gute Antwort! Es ist gut, einige Optionen zu sehen, bei denen Sie nicht extrahieren und erneut erreichen müssen. Auch ich denke, @Cornstalks Idee ist gut. Vielleicht sollte die Antwort hinzugefügt werden?
Glühbirne1
Hey, wenn ich versuche, den Befehl zu verwenden, libtoolbekomme ich diese Fehler: libtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag' Irgendwelche Ideen, wie man das behebt?
Lars Nielsen
@ Guillem @ Cornstalks Tolle Antwort. Was passiert , wenn die --Wl,-whole-archiveOption im ursprünglichen Verknüpfungsbefehl für mehrere lib * .a erforderlich, und ich brauche alle lib * .a in kombinieren one.a. Funktioniert beim erneuten Verknüpfen --Wl,-whole-archivenicht mit one.a. Was ist dein Vorschlag? stackoverflow.com/questions/56323197/…
Codierer
10

Wenn Sie es einfach so machen:

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

Sie verlieren einige Objektdateien, wenn sich in aa und ba Mitglieder mit demselben Namen befinden. Daher müssen Sie Mitglieder verschiedener Archive in verschiedene Ordner extrahieren:

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

Darüber hinaus ist es möglich, dass sich in einem Archiv mehrere Mitglieder mit demselben Namen befinden (z. B. in aa). Wenn Sie ar x aa ausführen , erhalten Sie nur eines für Mitglieder mit demselben Namen.

Die einzige Möglichkeit, alle gleichnamigen Mitglieder in einem Archiv zu extrahieren, besteht darin, die Mitgliedsnummer mit der Option 'N' anzugeben:

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
...

Dies wäre eine mühsame Arbeit, daher müssen Sie ein ausgefeilteres Skript schreiben, um diesen Job zu erledigen.

Eine optionale Lösung besteht darin, dass Sie mehrere Archive in einer gemeinsam genutzten Bibliothek kombinieren können:

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

Auf diese Weise erledigt der Linker alle Dinge für Sie!

samuel.zzy220
quelle
1
Samuel, danke. Beim Kombinieren in eine gemeinsam genutzte Bibliothek sollten jedoch alle Objekte mit kompiliert werden -fPIC.
Osgx
0

Noch besser ist es, wenn Sie eine teilweise Verknüpfung für jede Bibliothek durchführen und diese ein Archiv der beiden resultierenden Objektdateien erstellen. Auf diese Weise funktioniert es wie gemeinsam genutzte Bibliotheken

Sie verknüpfen teilweise mit

gcc -r --nostdlib

Führen Sie das Programm entweder aus, anstatt es zu erstellen, oder nachdem Sie es erneut extrahiert haben

gcc -r --nostdlib $CFLAGS $OBJECTS_A -o $LIBNAME_A.o
gcc -r --nostdlib $CFLAGS $OBJECTS_B -o $LIBNAME_B.o

dann

ar -cr $LIBNAME_JOINED.a $LIBNAME_A.o $LIBNAME_B.o
Allan Jensen
quelle
Es ist nicht wirklich eine Frage zu beantworten - wie er nach Bibliotheken gefragt hat. Oft haben Sie nicht einmal Quellen für Bibliotheken angegeben oder möchten diese aus anderen Gründen vorgefertigt lassen.
Pholat
0
ar -x libx264.a
mkdir sub && cd sub
ar -m ../libx264.a `ar -t ../libx264.a |sort|uniq|grep "\.o"`
ar -x ../libx264.a

Jetzt haben Sie zwei Versionen von "macroblock-10.o"

Gesetz wey
quelle
0
ar crsT libaz.a libabc.a libxyz.a

Hier erstellen Sie ein Archiv von Archiven und "reduzieren" das Ergebnis mit dem T-Flag. Ich bin mir nicht sicher, wie es mit .o-Dateien mit demselben Namen funktionieren soll, die möglicherweise darin enthalten sind.

Evgeny Yashin
quelle