Saya sedang menyusun program c ++ menggunakan g++
dan ld
. Saya memiliki .so
perpustakaan yang ingin saya gunakan selama menautkan. Namun, perpustakaan dengan nama yang sama ada di dalamnya /usr/local/lib
, dan ld
memilih perpustakaan itu daripada yang saya tentukan secara langsung. Bagaimana cara memperbaikinya?
Untuk contoh di bawah ini, file perpustakaan saya adalah /my/dir/libfoo.so.0
. Hal-hal yang saya coba yang tidak berhasil:
- perintah g ++ saya adalah
g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
- menambahkan
/my/dir
ke awal atau akhir$PATH
variabel en` saya - menambahkan
/my/dir/libfoo.so.0
sebagai argumen ke g ++
libfoo.*
file ada dan di mana -.so
w / o.0
,.a
, dll?Jawaban:
Tambahkan jalur ke tempat perpustakaan baru Anda berada
LD_LIBRARY_PATH
(memiliki nama yang sedikit berbeda di Mac ...)Solusi Anda harus bekerja dengan menggunakan
-L/my/dir -lfoo
opsi, pada waktu proses gunakan LD_LIBRARY_PATH untuk menunjuk ke lokasi perpustakaan Anda.Hati-hati dengan menggunakan LD_LIBRARY_PATH - singkatnya (dari tautan):
ATAU
Gunakan opsi rpath melalui gcc ke linker - jalur pencarian pustaka runtime, akan digunakan alih-alih mencari di dir standar (opsi gcc):
Ini bagus untuk solusi sementara. Linker terlebih dahulu mencari pustaka LD_LIBRARY_PATH sebelum melihat ke direktori standar.
Jika Anda tidak ingin memperbarui LD_LIBRARY_PATH secara permanen, Anda dapat melakukannya dengan cepat di baris perintah:
Anda dapat memeriksa apa yang diketahui linker perpustakaan tentang penggunaan (contoh):
/sbin/ldconfig -p | grep libpthread libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0
Dan Anda dapat memeriksa perpustakaan mana yang digunakan aplikasi Anda:
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)
sumber
LD_LIBRARY_PATH
dicari saat runtime, pada waktu kompilasi yang ingin Anda setelLIBRARY_PATH
. Lihat gcc.gnu.org/onlinedocs/gcc/Environment-Variables.htmlgcc myFile.c -o myFile.o -l myLibraryBaseName -Wl,-rpath,locationOfMyLibrary -L locationOfMyLibrary
Ini adalah pertanyaan lama, tapi sepertinya tidak ada yang menyebutkan ini.
Anda beruntung karena semuanya terhubung.
Anda perlu berubah
untuk ini:
Linker Anda melacak simbol yang perlu diselesaikan. Jika ia membaca pustaka terlebih dahulu, ia tidak memiliki simbol yang diperlukan, jadi ia mengabaikan simbol di dalamnya. Tentukan pustaka setelah hal-hal yang perlu ditautkan ke mereka sehingga penaut Anda memiliki simbol untuk ditemukan di dalamnya.
Juga,
-lfoo
buat itu mencari file bernamalibfoo.a
ataulibfoo.so
sesuai kebutuhan. Tidaklibfoo.so.0
. Begitu jugaln
nama atau ganti nama perpustakaan sebagai appopriate.Untuk mengutip halaman manual 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.
Menambahkan file secara langsung ke
g++
baris perintah seharusnya sudah bekerja, kecuali tentu saja, Anda meletakkannya sebelumnyabar.cpp
, menyebabkan linker mengabaikannya karena tidak memiliki simbol yang diperlukan, karena belum ada simbol yang diperlukan.sumber
Menentukan jalur absolut ke perpustakaan seharusnya berfungsi dengan baik:
g++ /my/dir/libfoo.so.0 ...
Apakah Anda ingat untuk menghapus
-lfoo
setelah Anda menambahkan jalur absolut?sumber
@
simbol berversi? Contoh minimal: github.com/cirosantilli/cpp-cheat/blob/…Sebagai alternatif, Anda bisa menggunakan variabel lingkungan
LIBRARY_PATH
danCPLUS_INCLUDE_PATH
, yang masing-masing menunjukkan di mana mencari perpustakaan dan di mana mencari header (CPATH
juga akan melakukan pekerjaan itu), tanpa menentukan opsi -L dan -I.Edit:
CPATH
menyertakan tajuk dengan-I
danCPLUS_INCLUDE_PATH
dengan-isystem
.sumber
export LIBRARY_PATH = /path/to/lib
dalam sesi konsol yang sama di mana Anda mengompilasiJika salah satu digunakan untuk bekerja dengan DLL di Windows dan ingin melewati nomor versi .so di linux / QT, menambahkan
CONFIG += plugin
akan menghilangkan nomor versi. Untuk menggunakan jalur absolut ke .so, memberikannya ke linker berfungsi dengan baik, seperti yang disebutkan oleh Tn. Klatchko.sumber