2009-03-20 12 views
13

Angenommen, ich habe drei C statischen Bibliotheken sagen libColor.a die davon abhängt, * libRGB. * A, die wiederum hängt von libPixel.a. Die Bibliothek libColor.a wird gesagt, auf Bibliothek libRGB.a abzuhängen, da es einige Referenzen in libColor.a sind auf einige Symbole definiert in libRGB.a. Wie kombiniere ich alle oben genannten Bibliotheken zu einem neuen libNewColor.a, die unabhängig ist?Kombination statischen Bibliotheken

Unabhängig bedeutet, dass in der neuen Bibliothek alle Symbole definiert sein müssen. Also während der Verknüpfung muss ich nur -lNewColor geben. Die Größe der neuen Bibliothek sollte minimal sein, dh es keine Symbole in libRGB.a enthalten soll, die nicht von verwendet wird libColor.a usw. ich mein Glück mit verschiedenen Optionen versucht, in ar Befehl (zum erstellen und aktualisieren Sie statische Bibliotheken/Archive).

+0

Sie können alternativ unter http aussehen: // Stackoverflow. com/questions/8170450/kombinieren-static-libraries/8170851 # 8170851 und libt verwenden ool – Bruce

+0

Beachten Sie, dass der Minimierungsschritt wirklich nicht notwendig ist. Bei statischen Bibliotheken greift der Linker im Gegensatz zu gemeinsam genutzten Bibliotheken, die alles enthalten, nur die benötigten Objektdateien. Für jeden Ansatz gibt es Gründe und Vorteile. sie sind einfach anders. Und Sie brauchen sich keine Sorgen zu machen, wenn Sie mit statischen Bibliotheken arbeiten. –

Antwort

11

1/Extrahieren Sie alle Objektdateien aus jeder Bibliothek (mit ar) und versuchen Sie, Ihren Code ohne die Bibliotheken oder eine der Objektdateien zu kompilieren. Sie erhalten wahrscheinlich eine absolute Ladung unbestimmter Symbole. Wenn Sie keine undefinierten Symbole erhalten, fahren Sie mit Schritt 5 fort.

2/Ergreifen Sie die erste und finden Sie heraus, welche Objektdatei dieses Symbol erfüllt (mit nm).

3/Schreiben Sie diese Objektdatei auf und kompilieren Sie dann Ihren Code, einschließlich der neuen Objektdatei. Sie werden eine neue Liste von undefinierte Symbole erhalten oder, wenn es keine ist, gehen 5.

4/Gehen Sie zu Schritt 2.

zu Schritt 5/Kombinieren Sie alle Objektdateien in der Liste (falls vorhanden) in eine einzelne Bibliothek (wieder mit ar).

Bang! Hier hast du es. Versuchen Sie, den Code ohne die Objekte mit die neue Bibliothek zu verknüpfen.

Diese ganze Sache könnte relativ leicht mit einem Shell-Skript automatisiert werden.

+2

Unnötig kompliziert, Sie könnten einfach alle .o-Dateien in eine große .a-Datei extrahieren, wenn sie schließlich in eine ausführbare Datei eingebunden ist, wird der Linker alle unbenutzten E-Mails verwerfen – MarkR

+2

@MarkR, @AIB wollte die Größe der * Bibliothek * minimal sein, nicht die Größe der ausführbaren Datei. – paxdiablo

+0

Ich akzeptiere es, obwohl ich einen Oneliner lieben würde, der das macht. Wie einige Optionen an LD weitergeben, um nur mit den benötigten Symbolen usw. zu kommunizieren ... – AIB

5

Eine statische Bibliothek ist nicht viel mehr als ein Archiv einiger Objektdateien (.o). Was Sie tun können, ist, alle Objekte in den zwei Bibliotheken zu extrahieren (mit "ar x") und dann "ar" zu verwenden, um sie in einer neuen Bibliothek zu verknüpfen.

15

Ein wenig gebrauchtes Merkmal des GNU Archivierungs ist der Archiv-Skript, es ist eine einfache, aber leistungsfähige Schnittstelle ist, und es kann genau das tun, was Sie wollen, zum Beispiel, wenn Sie das folgende Skript script.ar aufgerufen:

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

Dann könnten Sie ar aufrufen wie folgt:

ar -M < script.ar 

und Sie würden libNewColor.a erhalten, die alle die .o-Dateien von libColor.a libRGB.a und libPixel.a enthält.

Zusätzlich können Sie auch regelmäßig hinzufügen.o Dateien als auch mit dem ADDMOD Befehl:

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

Des Weiteren ist es super einfach diese Skripte in Makefiles zu erzeugen, so dass ich eine etwas allgemeine Make-Datei Regel Archiven der Regel schafft für die Erstellung, die tatsächlich das Skript erzeugt und ruft ar auf dem Skript. Etwas wie folgt aus:

$(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) 

Obwohl jetzt, dass ich es sehe ich denke, es ist nicht, wenn $ (Objekte) funktioniert leer ist (dh, wenn Sie nur wollen, Archive kombinieren, ohne zusätzliche Objektdateien hinzufügen) aber ich werde lassen Sie es als eine Übung für den Leser, dass Problem zu beheben, wenn nötig ...: D

Hier ist die Dokumentation für diese Funktion:

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

+0

Das ist großartig! Außer dass alle Pfade/libs, die ein + im Namen haben, das Skript brechen. Zum Beispiel hat openssl libncurses ++. A – Gregory

+0

Ordentlich! Dies ist viel einfacher als das Entpacken und Neupacken von Objektdateien. – Thomas

+0

Beachten Sie, dass -D in Kombination mit -M nicht funktioniert. Wenn Sie also deterministische Ergebnisse erhalten möchten, benötigen Sie weiterhin die Route extrahieren, dann archivieren. –

Verwandte Themen