2013-03-10 11 views
6

Ich baue eine gemeinsame Bibliothek (wir nennen es "foo"), die eine andere Bibliothek verwendet (wir nennen es "bar"). "bar" verwendet einige Funktionen von OpenSSL.Fehler, die sich auf eine Reihe offener OpenSSL-Symbole beziehen, die eindeutig existieren?

Hier ist das Problem.

"bar" wurde als statische Bibliothek kompiliert und es scheint, dass OpenSSL auch war. Also, wenn ich die Bibliothek ("foo") verknüpfen, schließe ich das:

  • Objektdateien für "foo"
  • statische Bibliothek libbar.a
  • OpenSSL statische Bibliotheken libcrypto.a und libssl.a

Der Build-Befehl sieht in etwa so aus:

g++ -Wl,-soname,libfoo.so -shared file1.o file2.o libbar.a \ 
    libcrypto.a libssl.a -o libfoo.so 

Allerdings Ich bekomme eine Menge von Fehlern:

ld: ./obj/libbar.a(file1.c.o): in function initialize_openssl: 
    ssl.c:117: error: undefined reference to 'SSL_library_init' 

den folgenden Befehl ausführen:

nm libssl.a | grep SSL_library_init 

erzeugt die folgende Ausgabe:

00000000 T SSL_library_init 

So offensichtlich es ist nichts falsch mit den OpenSSL-Bibliotheken ist. Was könnte möglicherweise so etwas verursacht haben? Hier sind die drei Befehle verwendet OpenSSL bauen:

export cross=arm-linux-androideabi- 
./Configure android --prefix=~/openssl-arm 
make CC="${cross}gcc" AR="${cross}ar r" RANLIB="${cross}ranlib" 

Der Übersetzungsvorgang ohne Fehler abgeschlossen, so bin ich völlig verwirrt.

Warum erhalte ich Linker-Fehler, die sich auf eine Reihe von OpenSSL-Symbolen beziehen, die eindeutig existieren?

Antwort

3

Das Problem wurde durch die Reihenfolge der Bibliotheken im Link-Befehl verursacht. Die Reihenfolge libcrypto.a und libssl.a wurde geändert, alle Symbole wurden aufgelöst.

GCC verwendet LD standardmäßig, und es ist ein Single-Pass-Linker. Wenn Sie zwei Bibliotheken haben, wie libssl und libcrypto, die in einer bestimmten Reihenfolge verknüpft sind, bedeutet das, dass libssl von Symbolen aus libcrypto abhängt. Daher muss libssl vor libcrypto (oder libcrypto muss libssl folgen). Es sollte keine Überraschung sein libssl verlässt sich auf libcrypto seit libcrypto bietet die Crypto von libssl verwendet.

+1

Ich vermute, weil der Compiler/Linker die Symbole in einer linearen Reihenfolge lernen und wenn eine Out-of-Order-Bedingung passiert, dann barfs. Es könnte sogar umgekehrt linear sein (antizipierender Balken abhängig von foo und Ihre Abhängigkeitskonstruktionen werden rückwärts gebaut). – RobotHumans