2010-11-22 14 views
13

Wie das Projekt meines Teams entwickelt wird, generieren wir aus allen .o Objektdateien eine Shared Object-Bibliothek für unsere Anwendung. Meine Aufgabe (hoffentlich ist sie spezifisch genug, aber auch allgemein genug, um anderen nützlich zu sein!) Besteht darin, nur die Objektdateien einzubinden, die sich seit der letzten Erstellung der ausführbaren Datei geändert haben. Hier ist zum Beispiel die Befehlszeile, die ich verwende, um die .so:Inkrementelle Verknüpfung mit gcc unter Linux. Ist es möglich?

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o -o libMySharedLibrary.so 

zu erstellen, die wie erwartet funktioniert! :) Mein Ziel ist es, von nun an nur die geänderten Objektdateien einbinden zu können, um den gleichzeitigen Verknüpfungsprozess zu beschleunigen. Ein Beispiel Befehl wäre:

g++34 -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o -o libMySharedLibrary.so 

Welche libMySharedLibrary.so mit den neueren Objektdateien aktualisieren würde, während die älteren Objektdateien in libMySharedLibrary.so auch beibehalten wird. In Wirklichkeit, wenn ich libMySharedLibrary.so unter Verwendung des obigen Befehls erzeuge, ist die Dateigröße viel kleiner als die, wenn alle Objektdateien enthalten sind, so dass ich fast sicher sein kann, dass der obige Befehl nicht tut, was ich will.

Durch meine Forschung habe ich festgestellt, dass es eine -i Option für den Linker gibt, die die gleiche ist wie die -r Option, die scheint, alle Objektdateien in eine große Objektdatei auch zu kombinieren. Leider scheint das nicht das zu sein, was ich will.

Kurz gesagt, ich möchte nur die geänderten Objektdateien nach dem ursprünglichen Link einbinden, was zu einem schnelleren Verknüpfungsprozess für die zukünftigen Links führt. Gibt es eine Möglichkeit, dies zu tun?

EDIT: Ein Beispiel dafür, was ich mit -i/-r versucht habe:

Beispiel Befehl: g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject2.o MyObject3.o MyObject4.o -o AllMyObjects.o

ich den -nostdlib Tag hinzuzufügen hatte es bei mir von Schreien über, um es zu stoppen, und entfernt -shared weil gemeinsame Objekte mit dem Tag -r nicht zulässig sind.

Dieser Befehl scheint alle meine O-Dateien in eine große O-Datei zu knallen. Wenn ich also diese .o-Datei von nun an nur mit den geänderten .o-Dateien aktualisieren könnte, wäre das großartig. Nachdem AllMyObjects.o anfänglich erstellt wurde, habe ich diesen Befehl versucht: g++34 -Wl,-r -nostdlib -rdynamic -m64 -Wl,-rpath,'$ORIGIN' MyObject1.o MyObject3.o -o AllMyObjects.o, aber es würde auch eine viel kleinere (Dateigröße-weise) erstellen, also nehme ich an, dass es möglicherweise nicht alle Objektdateien haben kann. Ich glaube, das ist etwas, bei dem ich wahrscheinlich einen kleinen Fehler mache. Hat jemand einen Rat? Danke im Voraus.

+0

Dominiert die Linkphase wirklich Ihre inkrementellen Builds? Wenn nicht, warum? – dmckee

+0

Können Sie uns zeigen, was Sie mit '-i' /' -r' versucht haben? Es sieht so aus, als wäre es * die Option, die du haben willst, obwohl ich vermute, dass du auf Symbolkonflikte stoßen wirst (wenn man bedenkt, dass es keine Option zum Ersetzen gibt). –

+0

Die Linkphase ist nicht der zeitaufwendigste Teil meiner Builds. Dies ist jedoch die Aufgabe, die mein Teamleiter mir gestellt hat. Wir sind bereits gut darin, nur das zu kompilieren, was sich geändert hat. Derzeit kompilieren wir nur das, was sich geändert hat, und verbinden jedes einzelne Objekt erneut. –

Antwort

6

Es sieht aus, als ob Sie über -shared und -r nicht zusammen arbeiten. Ich war skeptisch, was Ihre alte GCC-Version, aber auch auf Ubuntu 10.10 ich das gleiche sehen:

$ ld -shared -r 
/usr/bin/ld.bfd.real: -r and -shared may not be used together 

Leider, das heißt, Sie in eine Sackgasse erreicht haben, wenn Sie absolut gemeinsame Objekte benötigen. Der binutils Linker implementiert es einfach nicht.

Wenn statische Bibliotheken eine Option für Sie sind, sind sie einfach Archive, die einfach mit dem ar Dienstprogramm bearbeitet werden können.

Andernfalls müssen Sie verschiedene Linker oder Compiler-Suites betrachten. Ich kann nicht garantieren, dass Sie dieses Feature finden, obwohl es exotisch erscheint.

+0

Ok. Vielen Dank für Ihre schnellen Antworten. Ich werde definitiv mit meinem Teamleiter sprechen und sehen, ob die Verwendung von statischen Bibliotheken eine Option wäre. Auch bei meinen Recherchen entdeckte ich einen alternativen Linker namens "Gold", der von Ian Lance Taylor bei google entwickelt wurde. Es wurde im März 2008 zu den Binutils hinzugefügt. Ich kann mir das auch anschauen. Ich hatte gehofft, dass es einen Weg geben würde, dies mit dem Standard-Linker zu tun, aber das scheint nicht der Fall zu sein. Nochmals vielen Dank für Ihre Hilfe! –

+3

Ich habe anscheinend "gold" installiert, aber "gold -shared -r" gibt das gleiche Ergebnis. –

+0

Haha, natürlich wäre das der Fall. :) Danke nochmal für deine Hilfe. –

3

Sie können das von Ihnen gewünschte Verhalten mit archive/static libraries erhalten, aber die anfängliche Verbindung dauert immer noch genauso lange.

Mit einer Archivdatei:

# Initially create the archive 
ar r libmylib.a <all object files> 

# Create your shared object (re-use this line after libmylib.a is updated) 
g++ -shared -rdynamic -m64 -Wl,-rpath,'$ORIGIN' libmylib.a -o libmylib.so  

# Update the archive file 
ar r libmylib.a updated1.o updated2.o 

Wie gesagt, es wird immer noch die gleiche Menge an Zeit in Anspruch nehmen zu verknüpfen tatsächlich die .so wie zuvor.

Verwandte Themen