LD_LIBRARY_PATH a LIBRARY_PATH

159

Tworzę prosty program w C ++ i chcę tymczasowo zastąpić udostępnianą przez system bibliotekę współdzieloną jej nowszą wersją, na potrzeby programowania i testowania.

Próbowałem ustawić zmienną LD_LIBRARY_PATH, ale linker (ld) nie powiódł się z:

/ usr / bin / ld: nie można znaleźć -lyaml-cpp

Spodziewałem się, że to zadziała, ponieważ zgodnie ze stroną podręcznika ld:

Konsolidator używa następujących ścieżek wyszukiwania do zlokalizowania wymaganych bibliotek współdzielonych: ... W przypadku konsolidatora natywnego zawartość zmiennej środowiskowej „LD_LIBRARY_PATH” ...

Następnie spróbowałem ustawić LIBRARY_PATH i zadziałało.

Zgodnie z instrukcją GCC:

Wartość LIBRARY_PATH to rozdzielona dwukropkami lista katalogów, podobnie jak PATH. Po skonfigurowaniu jako natywny kompilator, GCC próbuje katalogów określonych w ten sposób podczas wyszukiwania specjalnych plików konsolidatora, jeśli nie może ich znaleźć za pomocą GCC_EXEC_PREFIX. Łączenie za pomocą GCC również używa tych katalogów podczas wyszukiwania zwykłych bibliotek dla opcji -l (ale katalogi określone przez -L są pierwsze).

Jak sugeruje podręcznik (GCC), LIBRARY_PATH działa, ponieważ łączę się z GCC.

Ale..

  • Skoro łączę się z gcc, dlaczego jest wywoływane ld, jak sugeruje komunikat o błędzie?
  • Jaki jest sens posiadania dwóch zmiennych w tym samym celu? Czy są jakieś inne różnice?
Georgios Politis
źródło

Odpowiedzi:

213

LIBRARY_PATH jest używany przez gcc przed kompilacją do przeszukiwania katalogów zawierających statyczne i współdzielone biblioteki, które muszą być połączone z twoim programem.

LD_LIBRARY_PATHjest używany przez program do przeszukiwania katalogów zawierających biblioteki współdzielone po pomyślnym skompilowaniu i dowiązaniu.

EDYCJA: Jak wskazano poniżej, Twoje biblioteki mogą być statyczne lub udostępniane. Jeśli jest statyczny, kod jest kopiowany do twojego programu i nie musisz szukać biblioteki po skompilowaniu i zlinkowaniu programu. Jeśli Twoja biblioteka jest udostępniana, musi być dynamicznie połączona z Twoim programem i wtedy właśnie LD_LIBRARY_PATHwchodzi w grę.

Naveen
źródło
14
I oczywiście LD_LIBRARY_PATH ma sens tylko w przypadku bibliotek dynamicznych
Alex Jasmin
2
Chodzi mi o to, że gdybym użył ld do łączenia (bezpośredniego), to zgodnie z podręcznikiem ld, LD_LIBRARY_PATH zostałaby wykorzystana do wyszukiwania katalogów zawierających biblioteki, które muszą być połączone z moim programem. Muszę czegoś tutaj przeoczyć ..
Georgios Politis
2
chyba że sam wywołasz ld i połączysz pliki obiektowe z bibliotekami, to „odziedziczy” ścieżkę, którą przekazuje do niego gcc. Możesz zastąpić standardowe gcc opcjami -Xlinker.
Naveen
5
W rzeczywistości LIBRARY_PATH jest używany do wyszukiwania katalogów zawierających biblioteki statyczne ORAZ dynamiczne, a nie tylko biblioteki statyczne.
particle128
3
Tak, to nieprawda - różnica polega na tym, że LIBRARY_PATHjest wyszukiwane biblioteki (statyczne lub dynamiczne) w czasie kompilacji, a w czasie wykonywaniaLD_LIBRARY_PATH - biblioteki dynamiczne. Oczywiście w czasie wykonywania nie musisz szukać bibliotek statycznych.
Timmmm
47

LD_LIBRARY_PATHjest przeszukiwany podczas uruchamiania programu, LIBRARY_PATHprzeszukiwany w czasie łączenia.

zastrzeżenie od komentarzy :

F'x
źródło
38
Uwaga: podczas łączenia bibliotek, ldsama w sobie nie szukać w bibliotekach albo LIBRARY_PATHalbo LD_LIBRARY_PATH. Dopiero gdy gccwywołuje ld, LIBRARY_PATHstaje się używane. (Nauczyłem się tego na
własnej skórze
1
@Rufflewind Interesujące, ale byłoby jeszcze bardziej, gdybyś podał jakieś referencje.
hmijail opłakuje resignees
W tym widoku rozróżnia się moment przeszukiwania bibliotek (czas łączenia a czas wykonywania), podczas gdy @Naveen rozróżnia typ wyszukiwanych bibliotek (statyczne i dynamiczne). Czy istnieją dwa widoki faktycznie identyczne (dynamiczny: czas wykonywania = statyczny: czas łącza), czy też istnieją ważne sytuacje, w których ta zgodność nie jest aktualna? Wydaje mi się, że pewna wiedza na temat bibliotek dynamicznych jest potrzebna również w czasie kompilacji.
XavierStuvw
13

Skoro łączę się z gcc, dlaczego jest wywoływane ld, jak sugeruje komunikat o błędzie?

gcc wywołuje wewnętrznie ld, gdy jest w trybie łączenia.

heroxbd
źródło