usr / bin / ld: không thể tìm thấy -l <nameOfTheL Library>


443

Tôi đang cố gắng biên dịch chương trình của mình và nó trả về lỗi này:

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

trong tệp thực hiện của tôi, tôi sử dụng lệnh g++và liên kết đến thư viện của mình, đây là một liên kết tượng trưng đến thư viện của tôi nằm trên một thư mục khác.

Có một tùy chọn để thêm vào để làm cho nó hoạt động không?


1
Cần thêm thông tin. Lệnh nào bạn đã phát hành để biên dịch chương trình của bạn? Bạn có thể sử dụng make -n mục tiêu của mình để thực hiện chỉ cần in các lệnh mà nó thường gọi
djf

Đăng makefile hoặc lệnh bạn thực thi.
Ortwin Angermeier

Lệnh của tôi là cái này: g ++ - <tùy chọn> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheL Library> -l <nameOfTheL Library> -lpthread -o myexe
ZoOo

4
Là thư viện bạn muốn liên kết với được xây dựng với cùng kiến ​​trúc (ví dụ: 32/64 bit)? Là thư viện bạn muốn liên kết với một thư viện tùy chỉnh? Tên thư viện quan trọng, vì nó phải bắt đầu bằng lib <name> khi sử dụng -lkhóa chuyển (ví dụ: libpthread.so bạn đã liên kết với).
Ortwin Angermeier

1
Vấn đề là ở liên kết tượng trưng của tôi trên thư viện không tốt! Cảm ơn bạn đã giúp đỡ !
ZoOo

Câu trả lời:


196

Nếu tên thư viện của bạn được nói libxyz.sovà nó nằm trên đường dẫn, hãy nói:

/home/user/myDir

sau đó để liên kết nó với chương trình của bạn:

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog

11
thư viện của tôi không phải là một cái động (.so) mà là một cái tĩnh (.a). Có vấn đề đến từ đó?
ZoOo

3
@ZoOo không bình thường, trình liên kết có thể hoạt động với một trong hai
djf

7
một cách khác để liên kết thư viện của bạn là bạn có thể chỉ định trực tiếp tên của thư viện với đường dẫn đầy đủ, như g ++ .. /path/mylib.a
Saurabh Bhola

2
Có nhưng nó vẫn không hoạt động. Thư viện của tôi là một liên kết tượng trưng, ​​tôi nghĩ vấn đề đến từ đó bởi vì khi tôi sử dụng thư viện trong thư mục khác thì nó hoạt động!
ZoOo

2
Là liên kết tượng trưng của bạn chính xác trỏ đến thư viện tại vị trí thực tế ??. bạn có thể đăng đầu ra của "ll" trên liên kết tượng trưng không.
Saurabh Bhola

450

Để tìm ra những gì trình liên kết đang tìm kiếm, hãy chạy nó trong chế độ dài dòng.

Ví dụ, tôi gặp phải vấn đề này trong khi cố gắng biên dịch MySQL với hỗ trợ ZLIB. Tôi đã nhận được một lỗi như thế này trong quá trình biên dịch:

/usr/bin/ld: cannot find -lzlib

Tôi đã thực hiện một số Google và tiếp tục gặp các vấn đề khác nhau cùng loại mà mọi người sẽ nói để đảm bảo tệp .so thực sự tồn tại và nếu không, thì hãy tạo một liên kết tượng trưng cho tệp được phiên bản, ví dụ: zlib. so.1.2.8. Nhưng, khi tôi kiểm tra, zlib.so DID tồn tại. Vì vậy, tôi nghĩ, chắc chắn đó không phải là vấn đề.

Tôi đã xem qua một bài đăng khác trên Internets được đề xuất để thực hiện với LD_DEBUG = all:

LD_DEBUG=all make

Mặc dù tôi đã nhận được TON đầu ra gỡ lỗi, nhưng nó không thực sự hữu ích. Nó thêm nhiều nhầm lẫn hơn bất cứ điều gì khác. Vì vậy, tôi đã định bỏ cuộc.

Sau đó, tôi đã có một bản hùng ca. Tôi nghĩ rằng để thực sự kiểm tra văn bản trợ giúp cho lệnh ld:

ld --help

Từ đó, tôi tìm ra cách chạy ld trong chế độ dài dòng (hãy tưởng tượng rằng):

ld -lzlib --verbose

Đây là đầu ra tôi nhận được:

==================================================
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...

Vì vậy, để cuối cùng sửa nó để tôi có thể biên dịch MySQL với phiên bản ZLIB của riêng tôi (chứ không phải là phiên bản đi kèm):

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

Voila!


60
Cảm ơn, điều này rất hữu ích. Đối với những người khác sử dụng gcc để biên dịch và liên kết chương trình của họ (thay vì sử dụng ld trực tiếp), bạn có thể thêm -Xlinker --verbosevào các đối số dòng lệnh của gcc để chuyển tùy chọn này sang ld.

5
Điều này cũng giúp tôi. Makefile tôi đã chỉ mong đợi các thư viện tĩnh nên nó được sử dụng -Wl,-Bstatic. Điều này giới hạn tìm kiếm chỉ các tệp .a. Tùy chọn verbose cho thấy rõ điều này. Khi tôi xóa -Wl,-Bstaticthư viện chia sẻ cũng được tìm kiếm.
micah94

2
Tôi đang ở trên FreeBSD 10. LLVM Clang cc mới lấy một đối số của biểu mẫu -Wl,--verbosevà chuyển --verboseđến trình liên kết.
Christian Campbell

7
Bây giờ đó là những gì tôi gọi là một câu trả lời hoàn hảo! Cảm ơn rất nhiều. Nó tiết kiệm rất nhiều thời gian. Chỉ để thêm để giúp một người như tôi. Nó có thể được sử dụng để gỡ lỗi các vấn đề liên quan đến đường dẫn là tốt. Đảm bảo bạn kiểm tra đường dẫn bằng -L <đường dẫn đến thư mục> bằng lệnh, ld -L <path> -l <tên thư viện> --verbose
sbhatt

2
@EdwardBlack Xem câu trả lời này . Về cơ bản, đối với gcc, chỉ cần thêm -Wl,--verboseđể truyền verbose cho trình liên kết.
chembrad

46

Dường như không có bất kỳ câu trả lời nào giải quyết vấn đề người mới bắt đầu rất phổ biến về việc không cài đặt thư viện cần thiết ở nơi đầu tiên.

Trên nền tảng Debianish, nếu libfoobị thiếu, bạn có thể thường xuyên cài đặt nó với một cái gì đó như

apt-get install libfoo-dev

Các -devphiên bản của gói là cần thiết cho việc phát triển, thậm chí công việc phát triển tầm thường như soạn thảo mã nguồn để liên kết đến thư viện.

Tên gói đôi khi sẽ yêu cầu một số trang trí ( libfoo0-dev? Không foo-devlibtiền tố? V.v.) hoặc bạn có thể chỉ cần sử dụng tìm kiếm gói của distro để tìm ra chính xác gói nào cung cấp một tệp cụ thể.

(Nếu có nhiều hơn một, bạn sẽ cần tìm hiểu sự khác biệt của chúng là gì. Chọn thứ hay nhất hoặc phổ biến nhất là một phím tắt phổ biến, nhưng không phải là một quy trình chấp nhận được cho bất kỳ công việc phát triển nghiêm túc nào.)

Đối với các kiến ​​trúc khác (đáng chú ý nhất là RPM) các quy trình tương tự được áp dụng, mặc dù các chi tiết sẽ khác nhau.


3
Điều này chỉ giúp tôi với một vấn đề tôi gặp phải với một máy chủ mới và Perl. apt-get install libperl-devsắp xếp nó cho tôi Cảm ơn :)
Andrew Newby

1
Điều này! Không cần phải gây rối với Makefile
Byron Whitlock

Đây có lẽ là giải pháp phổ biến nhất và giúp tôi biên dịch xương rồng trên CentOS 7. Một cách đơn giản đã yum install openssl-develgiải quyết nó.
djluko

1
Đây là cách khắc phục tốt nhất nếu bạn thấy symlink kết thúc bằng .so bị thiếu, nhưng bạn có một symlink như libfoo.so.6 -> libfoo.so.6.0.2 (ví dụ), thay vì tạo liên kết tượng trưng bằng tay. (có nghĩa là bạn đã cài đặt gói libfoo, nhưng không phải libfoo-dev)
dmaestro12

39

Thời gian biên dịch

Khi g ++ nói cannot find -l<nameOfTheLibrary>, nó có nghĩa là g ++ đã tìm kiếm các tập tin lib{nameOfTheLibrary}.so, nhưng nó không thể tìm thấy nó trong đường dẫn tìm kiếm thư viện chia sẻ, mà theo điểm mặc định /usr/lib/usr/local/libvà ở một nơi khác có thể.

Để giải quyết vấn đề này, bạn nên cung cấp tệp thư viện ( lib{nameOfTheLibrary}.so) trong các đường dẫn tìm kiếm đó hoặc sử dụng -Ltùy chọn lệnh. -L{path}nói với g ++ (thực tế ld) để tìm các tệp thư viện trong đường dẫn {path}ngoài các đường dẫn mặc định.

Ví dụ: Giả sử bạn có thư viện tại /home/taylor/libswift.sovà bạn muốn liên kết ứng dụng của mình với thư viện này. Trong trường hợp này, bạn nên cung cấp g ++ với các tùy chọn sau:

g++ main.cpp -o main -L/home/taylor -lswift
  • Lưu ý 1 : -ltùy chọn lấy tên thư viện mà không có lib.soở đầu và cuối của nó.

  • Lưu ý 2 : Trong một số trường hợp, tên tệp thư viện được theo sau bởi phiên bản của nó libswift.so.1.2. Trong những trường hợp này, g ++ cũng không thể tìm thấy tệp thư viện. Một cách giải quyết đơn giản để khắc phục điều này là tạo ra một liên kết tượng trưng để libswift.so.1.2được gọi libswift.so.


Thời gian chạy

Khi bạn liên kết ứng dụng của mình với thư viện dùng chung, thư viện yêu cầu phải có sẵn bất cứ khi nào bạn chạy ứng dụng. Trong thời gian chạy, ứng dụng của bạn (thực sự là trình liên kết động) tìm kiếm các thư viện của nó LD_LIBRARY_PATH. Đó là một biến môi trường lưu trữ một danh sách các đường dẫn.

Ví dụ: Trong trường hợp của chúng tôi libswift.soVí dụ, mối liên kết động không thể tìm thấy libswift.sotrong LD_LIBRARY_PATH(mà điểm đến đường dẫn tìm kiếm mặc định). Để khắc phục sự cố, bạn nên nối biến đó với đường dẫn libswift.sođang ở.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor

Cảm ơn bài viết của bạn! Tôi đã bỏ qua tất cả các câu trả lời cho đến lúc tôi sao chép .socác tập tin vào /usr/lib, nhưng nó trở nên thú vị đối với tôi liệu có exportgiúp được gì không. Mặc dù quá trình cài đặt sau khi maketiếp tục lâu hơn, một lỗi khác xảy ra. Lần này, .so.0không tìm thấy tệp, nhưng cả hai .so.so.0tệp đều nằm trong thư mục nơi tôi đã xây dựng gói phụ thuộc từ nguồn. Bạn có thể giúp với điều đó?
A.Ametov

33

Trong quá trình biên dịch với định nghĩa g++thông qua nếu có thể không phù hợp để thay đổi Makefile với tùy chọn. Tôi đã đặt thêm thư viện của mình vào nên tôi đã làm:makeLIBRARY_PATH-L/opt/lib

$ export LIBRARY_PATH=/opt/lib/

và sau đó chạy makeđể biên dịch và liên kết thành công.

Để chạy chương trình với thư viện dùng chung, hãy xác định:

$ export LD_LIBRARY_PATH=/opt/lib/

trước khi thực hiện chương trình.


14

Trước tiên, bạn cần biết quy tắc đặt tên của lxxx:

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

lcphương tiện libc.so, lltdlphương tiện libltdl.so, lXtstphương tiện libXts.so.

Vì vậy, nó là lib+ lib-name+.so


Khi chúng tôi biết tên, chúng tôi có thể sử dụng locateđể tìm đường dẫn của lxxx.sotệp này .

$ 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

Nếu bạn không thể tìm thấy nó, bạn cần cài đặt nó bằng cách yum(Tôi sử dụng CentOS). Thông thường bạn có tệp này, nhưng nó không liên kết đến đúng nơi.


Liên kết nó đến đúng nơi, thường là /lib64hoặc/usr/lib64

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

Làm xong!

tham chiếu: https://i-pogo.blogspot.jp/2010/01/usrbinld-cannot-find-lxxx.html


4
locateChỉ hoạt động nếu nó được cài đặt và chạy thường xuyên. Một cách giải quyết khác là chạy findtrên toàn bộ đĩa của bạn, nhưng tất nhiên, nó sẽ mất thời gian. Nếu bạn thấy mình làm điều đó thường xuyên, hãy xem xét việc cài đặt locatechỉ để giảm chi phí (tương tác, con người) của hoạt động này.
tripleee

5

Khi bạn biên dịch chương trình của mình, bạn phải cung cấp đường dẫn đến thư viện; trong g ++, sử dụng tùy chọn -L:

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar

1
Thuộc tính nào chúng ta phải thay đổi ccmakeđể Makefiletạo ra với cờ được liên kết? Tôi muốn liên kết -lARToolkitPluscờ của tôi với một con đường.
Shashwat

2

Lỗi này cũng có thể được đưa ra nếu liên kết tượng trưng đến một thư viện động, .so, nhưng vì lý do di sản -staticxuất hiện giữa các cờ liên kết. Nếu vậy, hãy thử loại bỏ nó.


2

Kiểm tra vị trí thư viện của bạn, ví dụ lxxx.so:

locate lxxx.so

Nếu nó không có trong /usr/libthư mục, gõ này:

sudo cp yourpath/lxxx.so /usr/lib

Làm xong.


4
Bạn cần thận trọng trong việc sao chép thư viện vào thư mục hệ thống.
Paul Floyd

2

Ngoài các câu trả lời đã được đưa ra, cũng có thể xảy ra trường hợp tệp * .so tồn tại nhưng không được đặt tên đúng. Hoặc có thể xảy ra trường hợp tệp * .so tồn tại nhưng nó thuộc sở hữu của người dùng / root khác.

Vấn đề 1: Tên không đúng

Nếu bạn đang liên kết tệp như -l<nameOfLibrary> tên tệp thư viện PHẢI có dạng lib<nameOfLibrary> Nếu bạn chỉ có <nameOfLibrary>.sotệp, hãy đổi tên tệp!

Vấn đề 2: Chủ sở hữu sai

Để xác minh rằng đây không phải là vấn đề - hãy làm

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

Nếu tệp được sở hữu bởi root hoặc người dùng khác, bạn cần phải làm

sudo chown yourUserName:yourUserName /path/to/.so/file

1

Thư viện mà tôi đang cố liên kết hóa ra có một tên không chuẩn (nghĩa là không có tiền tố là 'lib'), vì vậy họ đã khuyến nghị sử dụng một lệnh như thế này để biên dịch nó -

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


Chỉ tiền tố với "lib" để có được một tên tiêu chuẩn đã sửa cho tôi
el_technic0

1

Đây là thông tin Ubuntu của máy tính xách tay của tôi.

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

Tôi sử dụng định vị để tìm các tệp .so cho boost_filesystem và boost_system

locate libboost_filesystem
locate libboost_system

Sau đó liên kết các tệp .so đến / usr / lib và đổi tên thành .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

Làm xong! Gói Velocyto.R đã được cài đặt thành công!


1

Tôi gặp thông báo lỗi tương tự.

Tôi đã xây dựng cmockanhư một sovà cố gắng liên kết nó với thực thi của tôi. Nhưng ldluôn luôn phàn nàn dưới đây:

/ usr / bin / ld: không thể tìm thấy -lcmocka

Hóa ra có 3 tệp được tạo sau khi cmockađược xây dựng:

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

1 và 2 là các liên kết ký hiệu và chỉ có 3 là tệp thực.

Tôi chỉ sao chép 1 vào thư mục thư viện của mình, nơi ldkhông tìm thấy 3.

Sau khi tôi sao chép cả 3, ldhoạt động.


Bạn có thể cung cấp nói xin vui lòng bạn muốn nói đến thư mục nào trong "thư mục thư viện của tôi" không?
A.Ametov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.