2013-05-02 12 views
6

Próbuję skompilować projekt. Kompiluje się pomyślnie. Komenda make kończy działanie z kodem stanu 0 i nie wyświetlają się żadne błędy.ldd mówi, że biblioteka nie została znaleziona przez kompilację zakończoną pomyślnie

Jednak projekt nie działa, a po uruchomieniu ldd -d <file> pokazuje, że mam dwie biblioteki, które nie zostały znalezione.

>ldd -d output_file.so 
    linux-gate.so.1 => (0xf77e0000) 
    libvstdlib_srv.so => not found 
    libtier0_srv.so => not found 
    libm.so.6 => /lib/libm.so.6 (0xf7760000) 
    libdl.so.2 => /lib/libdl.so.2 (0xf775b000) 
    libc.so.6 => /lib/libc.so.6 (0xf75a9000) 
    /lib/ld-linux.so.2 (0x46e4a000) 
undefined symbol: pfVectorNormalize  (output_file.so) 
undefined symbol: _Z12VectorAnglesRK6VectorR6QAngle  (output_file.so) 
undefined symbol: pfSqrt  (output_file.so) 
undefined symbol: __cxa_guard_acquire (output_file.so) 
undefined symbol: __cxa_guard_release (output_file.so) 
undefined symbol: _Z6ConMsgPKcz (output_file.so) 
undefined symbol: Warning  (output_file.so) 
undefined symbol: __dynamic_cast  (output_file.so) 
undefined symbol: _Z11ConColorMsgRK5ColorPKcz (output_file.so) 
undefined symbol: Error (output_file.so) 
undefined symbol: AssertValidStringPtr (output_file.so) 
undefined symbol: _AssertValidWritePtr (output_file.so) 
undefined symbol: _AssertValidReadPtr (output_file.so) 
undefined symbol: _ZTVN10__cxxabiv121__vmi_class_type_infoE  (output_file.so) 
undefined symbol: _ZTVN10__cxxabiv120__si_class_type_infoE  (output_file.so) 
undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE (output_file.so) 
undefined symbol: __gxx_personality_v0 (output_file.so) 

Te dwie biblioteki są ustawione linki jako symboliczne do rzeczywistej lokalizacji pliku:

... 
lrwxrwxrwx 1 Andy Andy 62 May 2 12:30 libtier0_srv.so -> /home/dev/sdks/hl2sdk-ob-valve/lib/linux/libtier0_srv.so 
lrwxrwxrwx 1 Andy Andy 64 May 2 12:30 libvstdlib_srv.so -> /home/dev/sdks/hl2sdk-ob-valve/lib/linux/libvstdlib_srv.so 
-rw-r--r-- 1 Andy Andy 5444 May 2 11:53 Makefile 
... 

istota run komenda gcc jest

gcc -I/home/dev/sdks/hl2sdk-ob-valve/public/game/server -I. -I.. -ICEntity -Isdk -I/home/dev/project1/hl2sdk-ob-valve/public -I/home/dev/sdks/hl2sdk-ob-valve/public/engine -I/home/dev/sdks/hl2sdk-ob-valve/public/tier0 -I/home/dev/sdks/hl2sdk-ob-valve/public/tier1 -I/home/dev/sdks/hl2sdk-ob-valve/public/mathlib -I/home/dev/project1/mmsource-central/core -I/home/dev/project1/mmsource-central/core/sourcehook -I/home/dev/project1/sourcemod-central/public -I/home/dev/project1/sourcemod-central/public/sourcepawn -I/home/dev/project1/sourcemod-central/core project1_output/sdk/smsdk_ext.o project1_output/extension.o project1_output/CTrackingProjectile.o project1_output/CSentryRocket.o project1_output/CProjectileRocket.o project1_output/CProjectileArrow.o project1_output/CProjectileFlare.o project1_output/CProjectilePipe.o project1_output/CProjectileSyringe.o project1_output/CEntity/CEntity.o project1_output/CEntity/CEntityManager.o project1_output/CEntity/CPlayer.o /home/dev/project1/hl2sdk-ob-valve/lib/linux/tier1_i486.a libvstdlib_srv.so libtier0_srv.so -m32 -lm -ldl -static-libgcc -shared -o project1_output/output_file.so

Moje pytania są następujące: 1.) Dlaczego nie znaleziono tych dwóch bibliotek, mimo że są one połączone symbolicznie? 2.) Niezdefiniowane symbole są częścią pakietu mathlib, zawartego w poleceniu gcc. -I/home/dev/sdks/hl2sdk-ob-valve/public/mathlib Dlaczego byłyby one niezdefiniowane, mimo że zostały uwzględnione?

c++ nie jest moim ulubionym językiem i wiem wystarczająco dużo o plikach Makefile, aby być niebezpiecznym, ale tak naprawdę nie naprawiać niczego, więc przepraszam, jeśli to nie jest wystarczająca informacja. Mogę zapewnić więcej w razie potrzeby.

+1

Na marginesie, czy SDK _really_ znajduje się w '/ dev'? –

+0

@JoachimIsaksson Nie! Ukrywałem ścieżki i nawet nie myślałem o '/ dev'. Zaktualizowałem pytanie, aby użyć '/ home/dev', więc to nikogo nie myli. – Andy

Odpowiedz

5

Pliki biblioteki są udostępnionymi obiektami, co oznacza, że ​​nie zostaną rozwiązane przed uruchomieniem. Aby je znaleźć (przy założeniu, że Linux lub inny wariant Uniksa) będziesz musiał dodać ścieżkę do bibliotek do swojej LD_LIBRARY_PATH (jest jeszcze inna ścieżka env, którą można użyć, ale nie mogę o niej teraz myśleć), a następnie ldd powinien być w stanie znaleźć bibliotekę.

2

Jako że wspomniano o diverscuba23, musisz dodać ścieżkę, na której znajduje się twoja biblioteka, do swojej LD_LIBRARY_PATH. Łatwym, a nie trwałym sposobem na osiągnięcie tego jest określenie go po uruchomieniu programu w taki sposób:

LD_LIBRARY_PATH =.:$LD_LIBRARY_PATH ./yourProgram 

W tym przypadku biblioteka musiałaby być w tym samym katalogu, w którym jest uruchomiony program.

11

Po prostu natknąłem się na to, miałem ten sam problem, ale inne rozwiązanie.

Używanie LD_LIBRARY_PATH będzie działać. I to jest w porządku, jeśli chodzi o własne testy w środowisku kompilacji, ale powinieneś tego unikać, poza tym takim przypadkiem. Oto artykuł przez kogoś, kto wie o wiele więcej niż ja o tym, dlaczego LD_LIBRARY_PATH jest zły:

http://xahlee.info/UnixResource_dir/_/ldpath.html

Co się stało jest, jak widać również z faktu, że ustawienie LD_LIBRARY_PATH pracował, jest to, że w czasie wykonywania Twój program nie może znaleźć udostępnionej biblioteki libtier0_srv.so. Zamiast globalnie ustawiając zmienną dla wszystkich programów, aby najpierw spojrzeć na /home/dev/sdks/hl2sdk-ob-valve/lib/linux/, należy dodać katalog do ścieżki wyszukiwania biblioteki uruchomieniowej. Można to zrobić poprzez przepuszczenie opcję

-rpath /home/dev/sdks/hl2sdk-ob-valve/lib/linux/

do ld łącznik.Można to zrobić za pomocą polecenia gcc pan pisał, dodając opcję

-Wl,-rpath,/home/dev/sdks/hl2sdk-ob-valve/lib/linux/,

który mówi gcc przekazać opcję wyżej ld.

+0

Tak, to jest lepsze niż podejście "młotem" do ustawiania zmiennej środowiskowej. – drlolly

Powiązane problemy