Frage

Mein Projekt besteht aus einigen statischen Bibliotheken, die in einem letzten Schritt miteinander verbunden sind. Jetzt habe ich das Problem, dass die Link -Reihenfolge der Bibliothek ist wichtig (Andernfalls erhalte ich einen undefinierten Symbol -Linker -Fehler). Manchmal stoße ich auf das Problem, dass ich die verknüpften Bibliotheken neu sortieren muss (-lcommon -lsetup -lcontrol usw.). Im Moment ist es eine dumme Versuch und Irrtum: Wiederherstellen, Kompilieren, Überprüfen Sie Fehler, neu, sortieren, kompilieren und so weiter.

Also habe ich ein kleines Programm geschrieben, um mir die Abhängigkeiten zwischen den Bibliotheken zu zeigen, und generiert mir die Reihenfolge der Bibliotheken, um sie zu verknüpfen. Es liest sich in den definierten ('T', 'B', usw.) und undefinierten Symbolen ('u') von nm und entfernt die Schwache Symbole ('W', 'W', 'V' und 'V') aus der "undefinierten Symbolliste". Jetzt bestimmt es für jedes undefinierte Symbol der Bibliothek, das sie löst.

Aber mein Programm zeigt mir kreisförmige Abhängigkeiten ... was ist mein Fehler?

Wenn sie wirklich existieren, konnte ich überhaupt nicht verlinken ... also Was habe ich vermisst, als ich die NM -Ausgabe analysiere? Oder analysiert die NM -Ausgabe nicht so, um diese Abhängigkeiten zu erhalten?

libcommon.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
libhardware.a:
00000484 T _ZN15HardwareUnit23GetHardwareSerialNumberEv
libsecurityaccess.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
---
libhardware.a:
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
libsecurityaccess.a:
00004020 T _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
War es hilfreich?

Lösung

Eine weitere Option zum Verknüpfen von Bibliotheken mit kreisförmigen Abhängigkeiten besteht darin, eine spezielle Linkeroption dafür zu verwenden. Mann LD:

   -( archives -)
   --start-group archives --end-group
       The archives should be a list of archive files.  They may be either
       explicit file names, or -l options.

       The specified archives are searched repeatedly until no new
       undefined references are created.  Normally, an archive is searched
       only once in the order that it is specified on the command line.
       If a symbol in that archive is needed to resolve an undefined
       symbol referred to by an object in an archive that appears later on
       the command line, the linker would not be able to resolve that
       reference.  By grouping the archives, they all be searched
       repeatedly until all possible references are resolved.

       Using this option has a significant performance cost.  It is best
       to use it only when there are unavoidable circular references
       between two or more archives.

Es ist jedoch immer sauberer, die kreisförmigen Abhängigkeiten zu beseitigen.

Andere Tipps

Wenn Sie wirklich eine kreisförmige Abhängigkeitskette statischer Bibliotheken haben (und dies ist nicht aus Ihrer Paste klar; Sie zeigen nur eine nicht kreisförmige Abhängigkeit), gibt es zwei Optionen:

  1. Entfernen Sie die kreisförmige Abhängigkeit irgendwie; Sie können beispielsweise sicherstellen, dass Libcommon keine Symbole in libpthardware verweist.
  2. Extrahieren Sie die einzelnen .o -Dateien aus der .a -Bibliothek und verknüpfen Sie sie direkt. Dann ist die Verknüpfungsreihenfolge nicht mehr wichtig.

Bei 2. finden Sie es möglicherweise hilfreich, eine Teilverknüpfung zu verwenden, anstatt statische Bibliotheken zu erstellen. Auf Systemen mit GNU -Bintools kann dies erfolgen, indem Sie so etwas wie folgt:

ld -r -o libfoo.o foo.o bar.o

Dies ist, foo.o und bar.o zu einer einzigen .o -Datei zu kombinieren. Die Bestellung spielt keine Rolle. Sie können dann einfach libfoo.o als normale Objektdatei in Ihrem endgültigen Linkschritt verweisen.

Beachten Sie, dass dies dies tun kann stören die Fähigkeit des Linker, nicht referenzierte Teile der statischen Bibliothek zu verwerfen (Normalerweise erfolgt dies auf der Ebene von .o -Dateien innerhalb des .a, glaube ich). Wenn Sie alle oder die meisten dieser Bibliotheken verwenden, ist dies wahrscheinlich kein Problem. Wenn der Codespeicher jedoch ein Problem ist, möchten Sie sich möglicherweise untersuchen automatisch unbenutzten Code auf Funktionsebene verwerfen. Wenn Sie dies tun, passieren Sie --gc-sections und -s Nur am Finale Linkstufe (und vermeiden Sie dies, wenn Sie debuggen müssen!). Außerdem scheint die statische Verknüpfung mit Systembibliotheken bei modernen GCC nicht notwendig zu sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top