usr / bin / ld:找不到-l <nameOfTheLibrary>


443

我正在尝试编译我的程序,它返回此错误:

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

在我的makefile文件中,我使用命令g++并链接到我的库,这是到我的库的另一个目录的符号链接。

是否可以添加选项以使其正常工作?


1
需要更多信息。您发出了什么命令来编译程序?您可以使用make -n your-target使make只打印通常会调用的命令
djf

发布makefile或您执行的命令。
Ortwin Angermeier

我的命令是这个命令:g ++-<options> objetc1.o objetc2.o objetc3.o objetc4.o -L <pathOfTheLibrary> -l <​​nameOfTheLibrary> -lpthread -o myexe
ZoOo

4
您要链接的库是否具有相同的体系结构(例如32/64位)?您要链接到自定义库的库吗?库名称很重要,因为使用-l开关时必须以lib <name>开头(例如,libpthread.so,您已经在链接了)。
Ortwin Angermeier

1
问题出在我在图书馆的符号链接上,不好!谢谢你的帮助 !
ZoOo

Answers:


196

如果您的图书馆名称是say libxyz.so并且位于路径上,请说:

/home/user/myDir

然后将其链接到您的程序:

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

11
我的库不是动态库(.so),而是静态库(.a)。问题出在那吗?
ZoOo

3
@ZoOo通常不重要,链接器可以与任何一个配合使用
djf

7
链接库的另一种方法是,您可以直接使用完整路径指定库的名称,例如g ++ .. /path/mylib.a
Saurabh Bhola

2
是的,但是仍然不起作用。我的库是一个符号链接,我认为问题出在那,因为当我在其他目录中使用该库时,它可以工作!
ZoOo

2
您的符号链接是否正确指向实际位置的库??您可以在符号链接上发布“ ll”的输出吗?
Saurabh Bhola

450

要弄清楚链接程序在寻找什么,请在详细模式下运行它。

例如,当我尝试使用ZLIB支持编译MySQL时遇到了这个问题。我在编译期间收到这样的错误:

/usr/bin/ld: cannot find -lzlib

我做了一些Googl'ing操作,并不断碰到相同种类的不同问题,人们会说要确保.so文件确实存在,如果不存在,则创建指向版本文件的符号链接,例如zlib。所以1.2.8。但是,当我检查时,zlib.so DID存在。所以,我想,那肯定不是问题。

我在互联网上遇到了另一条建议使用LD_DEBUG = all运行make的帖子:

LD_DEBUG=all make

尽管我得到了大量调试信息,但实际上并没有帮助。它比其他任何事情都增加了混乱。所以,我正要放弃。

然后,我顿悟了。我认为实际上要检查ld命令的帮助文本:

ld --help

由此,我想出了如何在详细模式下运行ld(想象一下):

ld -lzlib --verbose

这是我得到的输出:

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

叮,叮...

因此,为了最终修复它,我可以使用自己的ZLIB版本(而不是捆绑版本)来编译MySQL:

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

瞧!


60
谢谢,这很有帮助。对于其他使用gcc编译和链接程序的人(而不是直接使用ld),您可以添加-Xlinker --verbose到gcc的命令行参数中,以使该选项传递给ld。

5
这也帮助了我。我的Makefile只希望使用静态库,因此可以使用-Wl,-Bstatic。这将搜索限制为仅.a文件。详细选项清楚地表明了这一点。一旦删除,-Wl,-Bstatic共享库也将被搜索。
micah94 2014年

2
我在FreeBSD 10上。新的LLVM Clang cc接受格式的自变量,-Wl,--verbose然后传递--verbose给链接器。
克里斯蒂安·坎贝尔

7
现在,这就是我所说的完美答案!非常感谢。它节省了很多时间。只是为了帮助像我这样的人。它也可以用于调试与路径相关的问题。确保使用命令ld -L <路径> -l <​​库名> --verbose使用-L <目录路径>检查该路径
sbhatt

2
@EdwardBlack参见此答案。本质上,对于gcc,只需添加-Wl,--verbose即可将详细信息传递给链接器。
chembrad 2015年

46

似乎没有任何答案可以解决非常常见的初学者问题,即首先无法安装所需的库。

在Debianish平台上,如果libfoo缺少该文件,则可以使用类似

apt-get install libfoo-dev

-dev开发工作,甚至是琐碎的开发工作,例如编译源代码以链接到库,都需要该软件包的版本。

软件包名称有时会需要一些修饰(libfoo0-devfoo-dev不带lib前缀吗?等),或者您可以简单地使用发行版的软件包搜索来精确地找出哪些软件包提供了特定文件。

(如果有多个,则需要找出它们之间的区别。选择最酷或最流行的方法是常见的捷径,但对于任何严肃的开发工作而言,这都不是可接受的过程。)

对于其他体系结构(最著名的是RPM),类似的过程适用,尽管细节会有所不同。


3
这只是帮助我解决了新服务器和Perl遇到的问题。 apt-get install libperl-dev为我整理了一下。谢谢:)
Andrew Newby

1
这个!无需弄乱Makefile
拜伦·惠特洛克

这可能是最常见的解决方案,并帮助我在CentOS 7上编译了cacti-spine yum install openssl-devel
djluko '17

1
如果找到以.so结尾的符号链接丢失,但是却有一个符号链接,例如libfoo.so.6-> libfoo.so.6.0.2(例如),而不是使用手。(这意味着您已安装软件包libfoo,但没有安装libfoo-dev)
dmaestro12

39

编译时间

当g ++表示时cannot find -l<nameOfTheLibrary>,表示g ++在寻找文件lib{nameOfTheLibrary}.so,但在共享库搜索路径中找不到该文件,该路径默认指向/usr/lib/usr/local/lib,可能指向其他位置。

要解决此问题,您应该lib{nameOfTheLibrary}.so在这些搜索路径中提供库文件()或使用-L命令选项。-L{path}告诉g ++(实际上是ld{path}在默认路径之外查找路径中的库文件。

例:假设您在处有一个库/home/taylor/libswift.so,并且想要将应用程序链接到该库。在这种情况下,您应该为g ++提供以下选项:

g++ main.cpp -o main -L/home/taylor -lswift
  • 注1-l option获得的库名不带 lib并且.so在开始和结尾处。

  • 笔记2:在某些情况下,例如,库文件名后跟版本libswift.so.1.2。在这些情况下,g ++也找不到该库文件。简单的解决方法来解决,这是创建符号链接到libswift.so.1.2名为libswift.so


运行

当您将应用程序链接到共享库时,需要在运行该应用程序时该库保持可用。在运行时,您的应用程序(实际上是动态链接器)在中查找其库LD_LIBRARY_PATH。这是一个环境变量,用于存储路径列表。

例如:在我们的情况下,libswift.so例如,动态链接器找不到libswift.soLD_LIBRARY_PATH(其指向默认搜索路径)。要解决此问题,您应该在路径中附加该变量libswift.so

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor

谢谢你的帖子!直到将.so文件复制到之前/usr/lib,我一直都忽略所有答案,但是对于我是否有export帮助变得很有趣。尽管安装过程make持续了更长的时间,但还是发生了另一个错误。这次, .so.0找不到文件,但是.so.so.0文件都在我从源代码构建依赖包的目录中。你能帮忙吗?
A.Ametov

33

在与编译g++通过make定义LIBRARY_PATH,如果它可能不适合与改变的Makefile -L选项。我已经放入了额外的库,/opt/lib所以我这样做了:

$ export LIBRARY_PATH=/opt/lib/

然后运行make以成功进行编译和链接。

要使用共享库运行程序,请定义:

$ export LD_LIBRARY_PATH=/opt/lib/

在执行程序之前。


14

首先,您需要了解以下命名规则lxxx

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

lc手段libc.solltdl手段libltdl.solXtst手段libXts.so

所以是lib+ lib-name+.so


知道名称后,就可以locate用来查找该lxxx.so文件的路径。

$ 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

如果找不到它,则需要通过以下方式进行安装yum(我使用CentOS)。通常您有此文件,但它没有链接到正确的位置。


它链接到正确的地方,通常是/lib64/usr/lib64

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

做完了!

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


4
locate仅在已安装并正常运行的情况下才能使用。一个粗略的解决方法是find在整个磁盘上运行,但是当然,这需要时间。如果您发现自己经常这样做,请考虑安装此产品locate,以降低此操作的成本(交互式,人工)。
三点

5

编译程序时,必须提供库的路径。在g ++中,使用-L选项:

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

1
我们必须更改哪个属性,ccmake以便Makefile使用链接标志创建?我想将我的-lARToolkitPlus标志链接到路径。
Shashwat 2014年

2

如果符号链接是指向动态库.so的,也可能引起此错误,但是由于传统原因-static,链接标志中会出现该错误。如果是这样,请尝试将其删除。


2

检查您的库的位置,例如lxxx.so:

locate lxxx.so

如果它不在/usr/lib文件夹中,请键入:

sudo cp yourpath/lxxx.so /usr/lib

做完了


4
在将库复制到系统目录时,需要格外小心。
保罗·弗洛伊德

2

除了已经给出的答案之外,*。so文件可能存在,但命名不正确。或者可能存在* .so文件,但该文件由另一个用户/ root拥有的情况。

问题1:名称不正确

如果要链接文件,-l<nameOfLibrary> 则库文件名必须采用以下格式:lib<nameOfLibrary> 如果只有<nameOfLibrary>.so文件,请重命名!

问题2:错误的所有者

要验证这不是问题,请执行

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

如果文件由root或其他用户拥有,则需要执行

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

1

我试图链接的库原来是一个非标准名称(即没有以“ lib”为前缀),因此他们建议使用类似这样的命令来编译它-

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


只给我加上“ lib”前缀才能为我固定一个标准名称
el_technic0 '19

1

这是我的笔记本电脑的Ubuntu信息。

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

我使用locate找到boost_filesystem和boost_system的.so文件

locate libboost_filesystem
locate libboost_system

然后将.so文件链接到/ usr / lib并重命名为.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

做完了!R软件包velocyto.R已成功安装!


1

我遇到了同样的错误消息。

我建立了cmocka一个,so并尝试将其链接到我的可执行文件。但ld总是在下面抱怨:

/ usr / bin / ld:找不到-lcmocka

事实证明,cmocka构建之后生成了3个文件:

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

1和2是符号链接,只有3是实际文件。

我只将1复制到了我的库文件夹中,在其中ld找不到3。

复制全部3个之后,即可ld正常工作。


您能否提供请说“我的图书馆文件夹”下的文件夹是什么?
A.Ametov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.