2010-04-29 8 views
14

Ich portiere ein bestehendes System von Windows zu Linux. Der Build ist mit mehreren statischen Bibliotheken strukturiert. Ich stieß auf einen Verknüpfungsfehler, bei dem ein Symbol (definiert in libA) in einem Objekt von libB nicht gefunden werden konnte. Die Linker Linie sah aus wieWie rekursive Abhängigkeiten zwischen statischen Bibliotheken mit dem binutils Linker umgehen?

g ++ test_obj.o -La -LB -o Test

Das Problem ist natürlich von der Zeit ist, dass der Linker findet es das Symbol von Liba braucht, hat sie es schon vorbei, und nicht erneut scannen, so dass es einfach ausgeht, obwohl das Symbol für die Aufnahme da ist.

Meine ursprüngliche Idee war natürlich, einfach den Link (zu -lB -lA) zu tauschen, so dass libA anschließend gescannt wird, und alle in libB fehlenden Symbole, die in libA sind, werden abgeholt. Aber dann finde ich tatsächlich eine rekursive Abhängigkeit zwischen libA und libB! Ich gehe davon aus, dass der Visual C++ - Linker dies auf irgendeine Weise handhabt (wird es standardmäßig neu gescannt?).

Wege des Umgangs mit dieser Ich habe in Betracht gezogen:

  • Verwendung von Shared Objects. Leider ist dies aus der Perspektive der PIC-Kompliation unerwünscht (dies ist leistungsabhängiger Code und das Verlieren von% ebx, um den GOT zu halten, würde wirklich weh tun), und gemeinsame Objekte werden nicht benötigt.

  • Erstellen Sie ein Mega-Array aller Objekte und vermeiden Sie das Problem.

  • Strukturieren Sie den Code, um die rekursive Abhängigkeit zu vermeiden (was offensichtlich die richtige Sache ist, aber ich versuche, diesen Port mit minimalen Änderungen zu machen).

Haben Sie andere Ideen, um damit umzugehen? Gibt es eine Möglichkeit, den Binutils-Linker davon zu überzeugen, Rescans von Bibliotheken durchzuführen, die er bereits angesehen hat, wenn ein Symbol fehlt?

Antwort

18

Genau dies tun:

g++ test_obj.o -lA -lB -lA  -o test 

Wenn der Linker den ersten Liba auf der Kommandozeile liest, wird es das Objekt/Symbole in verwerfen, dass niemand auf noch abhing, z.B. Alle Symbole libB benötigt, aber nicht test_obj.o. Du machst es einfach wieder libA, und es wird auch diese Symbole aufnehmen.

+2

Diese Frage die Antwort ist so ein großartiges Beispiel für eine elegante Lösung, die Sie starrte in das Gesicht ... Es liest sich fast wie die Pointe eines Witzes ...:) – dicroce

10

Während @nos eine einfache Lösung bietet, skaliert es nicht, wenn mehrere Bibliotheken beteiligt sind und die gegenseitigen Abhängigkeiten komplexer sind. Um die Probleme zu lösen ld bietet --start-group archives --end-group.

In Ihrem speziellen Fall:

g++ test_obj.o --start-group -lA -lB --end-group -o test 
+0

g ++ test_obj.o -Wl, - Startgruppe -lA -lB -Wl, - Endgruppe -o Test – yokto