Kompiluję program w języku C ++ przy użyciu g++
i ld
. mam.so
bibliotekę, z której chcę korzystać podczas łączenia. Jednak biblioteka o tej samej nazwie istnieje w programie /usr/local/lib
i ld
wybiera tę bibliotekę zamiast tej, którą bezpośrednio określam. Jak mogę to naprawić?
W poniższych przykładach mój plik biblioteki to /my/dir/libfoo.so.0
. Rzeczy, które próbowałem, ale nie działają:
- moje polecenie g ++ to
g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
- dodanie
/my/dir
na początku lub na końcu mojej$PATH
zmiennej en` - dodanie
/my/dir/libfoo.so.0
jako argumentu do g ++
libfoo.*
istnieją pliki i gdzie -.so
w / o.0
,.a
itp itd?Odpowiedzi:
Dodaj ścieżkę do miejsca, w którym znajduje się twoja nowa biblioteka
LD_LIBRARY_PATH
(ma nieco inną nazwę na Macu ...)Twoje rozwiązanie powinno działać z wykorzystaniem
-L/my/dir -lfoo
opcji, w czasie wykonywania użyj LD_LIBRARY_PATH, aby wskazać lokalizację biblioteki.Ostrożnie z użyciem LD_LIBRARY_PATH - w skrócie (z linku):
LUB
Użyj opcji rpath przez gcc do konsolidatora - ścieżka przeszukiwania biblioteki uruchomieniowej zostanie użyta zamiast szukać w standardowym katalogu (opcja gcc):
Jest to dobre rozwiązanie tymczasowe. Linker najpierw przeszukuje LD_LIBRARY_PATH w poszukiwaniu bibliotek, zanim zajrzy do standardowych katalogów.
Jeśli nie chcesz trwale aktualizować LD_LIBRARY_PATH, możesz to zrobić w locie z wiersza poleceń:
Możesz sprawdzić, o czym konsolidator bibliotek wie (przykład):
/sbin/ldconfig -p | grep libpthread libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0
Możesz też sprawdzić, której biblioteki używa Twoja aplikacja:
ldd foo linux-gate.so.1 => (0xffffe000) libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000) libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000) librt.so.1 => /lib/librt.so.1 (0xb7e65000) libm.so.6 => /lib/libm.so.6 (0xb7d5b000) libc.so.6 => /lib/libc.so.6 (0xb7c2e000) /lib/ld-linux.so.2 (0xb7fc7000) libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000) libz.so.1 => /lib/libz.so.1 (0xb7c18000)
źródło
LD_LIBRARY_PATH
jest przeszukiwany w czasie wykonywania, w czasie kompilacji, który chcesz ustawićLIBRARY_PATH
. Zobacz gcc.gnu.org/onlinedocs/gcc/Environment-Variables.htmlgcc myFile.c -o myFile.o -l myLibraryBaseName -Wl,-rpath,locationOfMyLibrary -L locationOfMyLibrary
To stare pytanie, ale chyba nikt o tym nie wspomniał.
Miałeś szczęście, że coś w ogóle się łączyło.
Musiałeś się zmienić
do tego:
Twój linker śledzi symbole, które musi rozwiązać. Jeśli najpierw czyta bibliotekę, nie ma żadnych potrzebnych symboli, więc ignoruje zawarte w niej symbole. Określ biblioteki po rzeczach, które muszą się do nich łączyć, aby twój linker miał symbole do znalezienia w nich.
Ponadto
-lfoo
powoduje, że wyszukuje konkretnie plik o nazwielibfoo.a
lublibfoo.so
w razie potrzeby. Nielibfoo.so.0
. Więcln
nazwij lub zmień nazwę biblioteki odpowiednio.Cytując stronę podręcznika gcc:
-l library ... It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
Dodanie pliku bezpośrednio do
g++
wiersza poleceń powinno zadziałać, chyba że oczywiście umieściłeś go wcześniejbar.cpp
, powodując, że linker ignoruje go z powodu braku jakichkolwiek potrzebnych symboli, ponieważ żadne symbole nie były jeszcze potrzebne.źródło
Określenie bezwzględnej ścieżki do biblioteki powinno działać poprawnie:
g++ /my/dir/libfoo.so.0 ...
Czy pamiętałeś, aby usunąć
-lfoo
raz dodaną ścieżkę bezwzględną?źródło
@
symboli wersjonowanych? Minimalny przykład: github.com/cirosantilli/cpp-cheat/blob/…Alternatywnie możesz użyć zmiennych środowiskowych
LIBRARY_PATH
iCPLUS_INCLUDE_PATH
, które odpowiednio wskazują, gdzie szukać bibliotek i gdzie szukać nagłówków (CPATH
również wykonają zadanie), bez określania opcji -L i -I.Edit:
CPATH
zawiera nagłówek z-I
iCPLUS_INCLUDE_PATH
z-isystem
.źródło
export LIBRARY_PATH = /path/to/lib
w tej samej sesji konsoli, w której kompilujeszJeśli ktoś jest używany do pracy z DLL w systemie Windows i chciałby pominąć numery wersji .so w linux / QT, dodanie
CONFIG += plugin
spowoduje usunięcie numerów wersji. Aby użyć bezwzględnej ścieżki do .so, przekazanie jej do linkera działa dobrze, jak wspomniał pan Klatchko.źródło