usr / bin / ld: tidak dapat menemukan -l <nameOfTheLibrary>

443

Saya mencoba mengkompilasi program saya dan mengembalikan kesalahan ini:

usr/bin/ld: cannot find -l<nameOfTheLibrary>

di makefile saya, saya menggunakan perintah g++dan tautan ke perpustakaan saya yang merupakan tautan simbolis ke perpustakaan saya yang terletak di direktori lain.

Apakah ada opsi untuk ditambahkan agar berhasil?

ZoOo
sumber
1
Perlu info lebih lanjut. Perintah apa yang Anda keluarkan untuk mengkompilasi program Anda? Anda dapat menggunakan make -n your-target untuk membuat hanya mencetak perintah yang biasanya dipanggil
djf
Poskan file makefile atau perintah yang Anda jalankan.
Ortwin Angermeier
perintah saya adalah ini: g ++ - <options> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheLibrary> -l <nameOfTheLibrary> -lpthread -o myexe
ZoOo
4
Apakah perpustakaan yang ingin Anda tautkan dibangun dengan arsitektur yang sama (mis. 32/64 bit)? Apakah perpustakaan yang ingin Anda tautkan dengan perpustakaan khusus? Nama pustaka penting, karena harus dimulai dengan lib <nama> saat menggunakan -lsakelar (mis. Libpthread.so yang sudah Anda tautkan).
Ortwin Angermeier
1
Masalahnya ada pada tautan simbolis saya di perpustakaan yang tidak bagus! Terima kasih atas bantuan Anda !
ZoOo

Jawaban:

196

Jika nama perpustakaan Anda diucapkan libxyz.sodan terletak di jalur, katakan:

/home/user/myDir

lalu menautkannya ke program Anda:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
Saurabh Bhola
sumber
11
perpustakaan saya bukan yang dinamis (.so) tetapi yang statis (.a). Apakah masalahnya berasal dari itu?
ZoOo
3
@ZoOo yang seharusnya tidak masalah, linker dapat bekerja dengan salah satunya
djf
7
Cara lain untuk menautkan perpustakaan Anda adalah Anda dapat secara langsung menentukan nama perpustakaan dengan jalur lengkap, seperti g ++ .. /path/mylib.a
Saurabh Bhola
2
Ya tapi masih tidak berhasil. Perpustakaan saya adalah tautan simbolis, saya pikir masalahnya berasal dari itu karena ketika saya menggunakan perpustakaan di direktori lain berfungsi!
ZoOo
2
Apakah tautan simbolis Anda dengan benar menunjuk ke perpustakaan di lokasi aktual ?? Anda dapat memposting output "ll" pada tautan simbolik.
Saurabh Bhola
450

Untuk mengetahui apa yang dicari oleh tautan, jalankan dalam mode verbose.

Misalnya, saya mengalami masalah ini ketika mencoba mengkompilasi MySQL dengan dukungan ZLIB. Saya menerima kesalahan seperti ini selama kompilasi:

/usr/bin/ld: cannot find -lzlib

Saya melakukan beberapa Googl'ing dan terus menemukan masalah yang berbeda dari jenis yang sama di mana orang akan mengatakan untuk memastikan file .so benar-benar ada dan jika tidak, kemudian buat symlink ke file versi, misalnya, zlib. jadi 1.2.2. Tapi, ketika saya periksa, zlib.so DID ada. Jadi, saya pikir, pasti itu bukan masalahnya.

Saya menemukan posting lain di Internet yang menyarankan untuk menjalankan make dengan LD_DEBUG = semua:

LD_DEBUG=all make

Meskipun saya mendapat TON hasil debugging, itu sebenarnya tidak membantu. Itu menambahkan lebih banyak kebingungan daripada yang lain. Jadi, saya hampir menyerah.

Kemudian, saya memiliki pencerahan. Saya pikir untuk benar-benar memeriksa teks bantuan untuk perintah ld:

ld --help

Dari situ, saya menemukan cara menjalankan ld dalam mode verbose (bayangkan itu):

ld -lzlib --verbose

Ini adalah output yang saya dapatkan:

==================================================
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib64/libzlib.a failed
attempt to open /usr/local/lib64/libzlib.so failed
attempt to open /usr/local/lib64/libzlib.a failed
attempt to open /lib64/libzlib.so failed
attempt to open /lib64/libzlib.a failed
attempt to open /usr/lib64/libzlib.so failed
attempt to open /usr/lib64/libzlib.a failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.so failed
attempt to open /usr/x86_64-linux-gnu/lib/libzlib.a failed
attempt to open /usr/local/lib/libzlib.so failed
attempt to open /usr/local/lib/libzlib.a failed
attempt to open /lib/libzlib.so failed
attempt to open /lib/libzlib.a failed
attempt to open /usr/lib/libzlib.so failed
attempt to open /usr/lib/libzlib.a failed
/usr/bin/ld.bfd.real: cannot find -lzlib

Ding, ding, ding ...

Jadi, untuk akhirnya memperbaikinya sehingga saya dapat mengkompilasi MySQL dengan versi ZLIB saya sendiri (bukan versi yang dibundel):

sudo ln -s /usr/lib/libz.so.1.2.8 /usr/lib/libzlib.so

Voila!

dcarrith
sumber
60
Terima kasih, ini sangat membantu. Untuk orang lain yang menggunakan gcc untuk mengkompilasi dan menautkan program mereka (daripada menggunakan ld secara langsung), Anda dapat menambahkan -Xlinker --verboseargumen baris perintah gcc agar meneruskan opsi ini ke ld.
5
Ini juga membantu saya. Makefile yang saya miliki hanya mengharapkan perpustakaan statis sehingga digunakan -Wl,-Bstatic. Ini membatasi pencarian hanya untuk file .a Opsi verbose menunjukkan ini dengan jelas. Setelah saya menghapus -Wl,-Bstaticperpustakaan bersama juga dicari.
micah94
2
Saya menggunakan FreeBSD 10. LLXM Clang cc baru mengambil argumen dari formulir -Wl,--verbosedan melewati --verboseke linker.
Christian Campbell
7
Nah, itu yang saya sebut jawaban sempurna! Terima kasih banyak. Ini menghemat banyak waktu. Hanya untuk menambah membantu orang seperti saya. Itu dapat digunakan untuk men-debug masalah yang berhubungan dengan jalur juga. Pastikan Anda memeriksa lintasan dengan -L <path to directory> dengan perintah, ld -L <path> -l <library name>
--verbose
2
@ EdwardBlack Lihat jawaban ini . Intinya, untuk gcc, tambahkan saja -Wl,--verbosepass verbose ke linker.
chembrad
46

Tampaknya tidak ada jawaban yang membahas masalah pemula yang sangat umum gagal menginstal perpustakaan yang diperlukan di tempat pertama.

Pada platform Debianish, jika libfootidak ada, Anda dapat sering menginstalnya dengan sesuatu seperti

apt-get install libfoo-dev

Itu -dev versi paket yang diperlukan untuk pekerjaan pembangunan, bahkan pekerjaan pembangunan sepele seperti kompilasi kode sumber untuk nge-link ke perpustakaan.

Nama paket terkadang membutuhkan beberapa dekorasi ( libfoo0-dev? foo-devTanpa libawalan? Dll), atau Anda dapat menggunakan pencarian paket distro Anda untuk mengetahui secara tepat paket mana yang menyediakan file tertentu.

(Jika ada lebih dari satu, Anda perlu mencari tahu apa perbedaannya. Memilih yang paling keren atau paling populer adalah jalan pintas yang umum, tetapi bukan prosedur yang dapat diterima untuk setiap pekerjaan pengembangan yang serius.)

Untuk arsitektur lain (terutama RPM) prosedur serupa berlaku, meskipun detailnya akan berbeda.

tripleee
sumber
3
Ini hanya membantu saya dengan masalah yang saya alami dengan server baru dan Perl. apt-get install libperl-devmengurutkannya untukku. Terima kasih :)
Andrew Newby
1
Ini! Tidak perlu dipusingkan dengan Makefile
Byron Whitlock
Ini mungkin solusi yang paling umum dan membantu saya mengkompilasi cacti-spine pada CentOS 7. Sederhana yum install openssl-develmenyelesaikannya.
djluko
1
Ini adalah perbaikan terbaik jika Anda menemukan symlink yang berakhiran .so hilang, tetapi Anda memiliki symlink seperti libfoo.so.6 -> libfoo.so.6.0.2 (misalnya), daripada membuat symlink dengan tangan. (artinya Anda memiliki paket libfoo diinstal, tetapi tidak libfoo-dev)
dmaestro12
39

Waktu kompilasi

Ketika g ++ mengatakan cannot find -l<nameOfTheLibrary>, itu berarti bahwa g ++ mencari file lib{nameOfTheLibrary}.so, tetapi tidak dapat menemukannya di jalur pencarian perpustakaan bersama, yang secara default menunjuk ke /usr/libdan /usr/local/libdan di tempat lain mungkin.

Untuk mengatasi masalah ini, Anda harus menyediakan file perpustakaan ( lib{nameOfTheLibrary}.so) di jalur pencarian tersebut atau menggunakan -Lopsi perintah. -L{path}memberitahu g ++ (sebenarnya ld) untuk menemukan file library di path {path}selain path default.

Contoh: Anggap Anda memiliki perpustakaan di /home/taylor/libswift.so, dan Anda ingin menautkan aplikasi Anda ke perpustakaan ini. Dalam hal ini, Anda harus menyediakan g ++ dengan opsi berikut:

g++ main.cpp -o main -L/home/taylor -lswift
  • Catatan 1 : -lopsi mendapatkan nama pustaka tanpa lib dan .sopada awal dan akhir.

  • Catatan 2 : Dalam beberapa kasus, nama file perpustakaan diikuti oleh versinya, misalnya libswift.so.1.2. Dalam kasus ini, g ++ juga tidak dapat menemukan file perpustakaan. Solusi sederhana untuk memperbaikinya adalah membuat tautan simbolis untuk libswift.so.1.2dipanggil libswift.so.


Runtime

Saat Anda menautkan aplikasi ke perpustakaan bersama, perpustakaan harus tetap tersedia setiap kali Anda menjalankan aplikasi. Di runtime aplikasi Anda (sebenarnya tautan dinamis) mencari pustaka di LD_LIBRARY_PATH. Ini adalah variabel lingkungan yang menyimpan daftar jalur.

Contoh: Dalam kasus kami libswift.somisalnya, linker dinamis tidak dapat menemukan libswift.sodi LD_LIBRARY_PATH(yang menunjuk ke jalur pencarian default). Untuk memperbaiki masalah, Anda harus menambahkan variabel dengan path libswift.sodi.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
kodok
sumber
Terima kasih untuk kiriman Anda! Saya telah mengabaikan semua jawaban sampai saat saya menyalin .sofile /usr/lib, tetapi menjadi menarik bagi saya apakah exportakan membantu. Meskipun proses instalasi setelah makeberlanjut lebih lama, kesalahan lain terjadi. Kali ini, .so.0file tidak ditemukan, tetapi keduanya .sodan .so.0file berada di direktori di mana saya telah membangun paket tergantung dari sumber. Bisakah Anda membantu dengan itu?
A.Ametov
33

Selama kompilasi dengan g++via makedefine LIBRARY_PATHjika mungkin tidak tepat untuk mengubah Makefile dengan -Lopsi. Saya telah memasukkan perpustakaan tambahan saya /opt/libjadi saya lakukan:

$ export LIBRARY_PATH=/opt/lib/

dan kemudian dijalankan makeuntuk kompilasi dan penautan yang berhasil.

Untuk menjalankan program dengan perpustakaan bersama tentukan:

$ export LD_LIBRARY_PATH=/opt/lib/

sebelum menjalankan program.

Finn Årup Nielsen
sumber
14

Pertama, Anda perlu tahu aturan penamaan lxxx:

/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst

lcberarti libc.so, lltdlberarti libltdl.so, lXtstberarti libXts.so.

Jadi, itu lib+ lib-name+.so


Setelah kita tahu namanya, kita bisa menggunakan locateuntuk mencari path lxxx.sofile ini .

$ locate libiconv.so
/home/user/anaconda3/lib/libiconv.so   # <-- right here
/home/user/anaconda3/lib/libiconv.so.2
/home/user/anaconda3/lib/libiconv.so.2.5.1
/home/user/anaconda3/lib/preloadable_libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2.5.1
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/preloadable_libiconv.so

Jika Anda tidak dapat menemukannya, Anda harus menginstalnya dengan yum(saya menggunakan CentOS). Biasanya Anda memiliki file ini, tetapi tidak terhubung ke tempat yang tepat.


Tautkan ke tempat yang tepat, biasanya itu /lib64atau/usr/lib64

$ sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/

Selesai!

ref: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html

Belter
sumber
4
locatehanya berfungsi jika diinstal dan berjalan secara teratur. Solusi kasar adalah untuk berjalan finddi seluruh disk Anda, tetapi tentu saja, itu akan memakan waktu. Jika Anda sering melakukannya, pertimbangkan untuk menginstal locatehanya untuk menurunkan biaya (interaktif, manusia) dari operasi ini.
tripleee
5

Ketika Anda mengkompilasi program Anda, Anda harus menyediakan jalur ke perpustakaan; di g ++ gunakan opsi -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
koan
sumber
1
Properti mana yang harus kita ubah ccmakeagar Makefiledibuat dengan bendera yang ditautkan? Saya ingin menautkan -lARToolkitPlusbenderaku ke jalur.
Shashwat
2

Kesalahan ini juga dapat terjadi jika tautan simbolik ke pustaka dinamis, .so, tetapi karena alasan lama -staticmuncul di antara bendera tautan. Jika demikian, coba hapus.

Vzbux
sumber
2

Periksa lokasi perpustakaan Anda, misalnya lxxx.so:

locate lxxx.so

Jika tidak ada di /usr/libfolder, ketikkan ini:

sudo cp yourpath/lxxx.so /usr/lib

Selesai

hua
sumber
4
Anda perlu berhati-hati dalam menyalin pustaka ke direktori sistem.
Paul Floyd
2

Terlepas dari jawaban yang telah diberikan, mungkin juga ada file * .so yang ada tetapi tidak dinamai dengan benar. Atau mungkin file * .so ada tetapi dimiliki oleh pengguna lain / root.

Edisi 1: Nama tidak benar

Jika Anda menautkan file itu -l<nameOfLibrary> maka nama file perpustakaan HARUS dalam bentuk lib<nameOfLibrary> Jika Anda hanya memiliki <nameOfLibrary>.sofile, ganti nama itu!

Edisi 2: Pemilik yang salah

Untuk memverifikasi bahwa ini bukan masalah - lakukan

ls -l /path/to/.so/file

Jika file tersebut dimiliki oleh root atau pengguna lain, Anda perlu melakukannya

sudo chown yourUserName:yourUserName /path/to/.so/file
pengguna13107
sumber
1

Perpustakaan yang saya coba taut ternyata memiliki nama yang tidak standar (mis. Tidak diawali dengan 'lib'), jadi mereka merekomendasikan menggunakan perintah seperti ini untuk mengkompilasinya -

gcc test.c -Iinclude lib/cspice.a -lm

Brian Burns
sumber
Hanya awalan dengan "lib" untuk mendapatkan nama standar yang memperbaikinya untuk saya
el_technic0
1

Berikut ini informasi Ubuntu dari laptop saya.

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:    18.04
Codename:   bionic

Saya menggunakan temukan untuk menemukan file .so untuk boost_filesystem dan boost_system

locate libboost_filesystem
locate libboost_system

Kemudian tautkan file .so ke / usr / lib dan ganti nama menjadi .so

sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 /usr/lib/libboost_filesystem.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 /usr/lib/libboost_system.so

Selesai! Paket R velocyto.R berhasil diinstal!

Shicheng Guo
sumber
1

Saya menemukan pesan kesalahan yang sama.

Saya membangunnya cmockasebagai sodan mencoba menautkannya ke executable saya. Tetapi ldselalu mengeluh di bawah ini:

/ usr / bin / ld: tidak dapat menemukan -lcmocka

Ternyata ada 3 file yang dihasilkan setelah cmockadibangun:

  1. libcmocka.so
  2. libcmocka.so.0
  3. libcmocka.so.0.7.0

1 dan 2 adalah tautan simbol dan hanya 3 yang merupakan file asli.

Saya hanya menyalin 1 ke folder perpustakaan saya, di mana ldgagal menemukan 3.

Setelah saya menyalin ketiga, ldberfungsi.

smwikipedia
sumber
Bisakah Anda memberikan say please folder apa yang Anda maksud di bawah "folder perpustakaan saya"?
A.Ametov