2013-03-10 15 views
6

Buduję wspólną bibliotekę (nazwiemy ją "foo"), która korzysta z innej biblioteki (nazwiemy ją "słupkiem"). "bar" korzysta z niektórych funkcji OpenSSL.Błędy odnoszące się do kilku nierozwiązanych symboli OpenSSL, które wyraźnie istnieją?

Oto, gdzie pojawia się problem.

"Pasek" został skompilowany jako biblioteka statyczna i wyglądałoby na to, że również OpenSSL. Więc kiedy odwołuje się do biblioteki ("foo"), I obejmują:

  • pliki wynikowe dla "foo"
  • statyczne biblioteki libbar.a
  • OpenSSL biblioteki statyczne libcrypto.a i libssl.a

polecenie kompilacji wygląda następująco:

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

Jednak Dostaję mnóstwo błędów:

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

uruchamiając następującą komendę:

nm libssl.a | grep SSL_library_init 

daje następujące dane wyjściowe:

00000000 T SSL_library_init 

Tak oczywiście nie ma nic złego z biblioteki OpenSSL. Co mogło spowodować coś takiego? Oto trzy polecenia używane do budowania OpenSSL:

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

Proces kompilacji zakończony bez żadnych błędów, więc jestem całkowicie niezrozumiałe.

Dlaczego otrzymuję błędy linkera, które odnoszą się do kilku symboli OpenSSL, które wyraźnie istnieją?

Odpowiedz

3

Problem został spowodowany kolejnością bibliotek w poleceniu link. Zmiana kolejności libcrypto.a i rozwiązała wszystkie symbole.

GCC domyślnie używa LD i jest to linker z pojedynczym przejściem. Jeśli masz dwie biblioteki, takie jak libssl i libcrypto połączone w określonej kolejności, oznacza to, że libssl zależy od symboli od libcrypto. Dlatego libssl musi poprzedzać libcrypto (lub libcrypto musi podążać za libssl). Nie powinno być niespodzianki. libssl polega na libcrypto, ponieważ libcrypto udostępnia kryptografię używaną przez libssl.

+1

Zgaduję, ponieważ kompilator/linker uczy się symboli w kolejności liniowej i jeśli stanie się warunek nie w porządku, to barfuje. Może nawet być odwrotno-liniowy (przewidujący pasek w zależności od foo i budowane konstrukcje zależności wstecz). – RobotHumans