usr/bin/ld:找不到 -l <nameOfTheLibrary>
- 2024-09-30 15:23:00
- admin 原创
- 168
问题描述:
我正在尝试编译我的程序但返回了此错误:
usr/bin/ld: cannot find -l<nameOfTheLibrary>
在我的 makefile 中,我使用命令g++
并链接到我的库,这是指向位于其他目录中的库的符号链接。
请问是否可以添加选项使其工作?
解决方案 1:
要弄清楚链接器正在寻找什么,请以详细模式运行它。
例如,我在尝试编译支持 ZLIB 的 MySQL 时遇到了这个问题。我在编译过程中收到了如下错误:
/usr/bin/ld: cannot find -lzlib
我谷歌了一下,发现问题不大,人们会说要确保<library>.so
文件确实存在,如果不存在,则创建指向版本文件的符号链接,例如。zlib.so.1.2.8
但是,当我检查时,zlib.so
确实存在。所以,我想,这肯定不是问题所在。
我在互联网上看到另一篇帖子,建议使用以下命令运行 make LD_DEBUG=all
:
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
瞧!
解决方案 2:
如果您的库名称是 saylibxyz.so
并且它位于路径上,则说:
/home/user/myDir
然后将其链接到你的程序:
g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
解决方案 3:
似乎没有任何答案可以解决初学者经常遇到的无法安装所需库的问题。
在 Debianish 平台上,如果libfoo
缺少,你可以经常使用以下命令安装它:
apt-get install libfoo-dev
-dev
软件包的版本是开发工作所必需的,即使是编译源代码以链接到库这样简单的开发工作。
软件包名称有时需要一些修饰(libfoo0-dev
没有 foo-dev
前缀的lib
?等),或者您可以简单地使用发行版的软件包搜索来准确找出哪些软件包提供了特定的文件。
(如果有多个,您需要找出它们之间的区别。选择最酷或最受欢迎的是一种常见的捷径,但对于任何严肃的开发工作来说,这不是一个可接受的程序。)
对于其他架构(最显著的是 RPM),适用类似的程序,尽管细节会有所不同。
解决方案 4:
编译时间
当 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
选项获取的库名称在开头和结尾不带lib
“and ”。.so
注意 2:在某些情况下,库文件名后面跟着其版本,例如
libswift.so.1.2
。在这些情况下,g++ 也无法找到库文件。解决此问题的一个简单方法是创建一个libswift.so.1.2
名为的符号链接libswift.so
。
运行时
当您将应用程序链接到共享库时,要求该库在您运行应用程序时保持可用。在运行时,您的应用程序(实际上是动态链接器)会在 中查找其库LD_LIBRARY_PATH
。它是一个存储路径列表的环境变量。
示例:在我们的示例中libswift.so
,动态链接器无法找到libswift.so
in LD_LIBRARY_PATH
(指向默认搜索路径)。要修复此问题,您应该将路径附加到该变量libswift.so
中。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor
解决方案 5:
g++
在使用via make
define进行编译时,LIBRARY_PATH
使用该选项更改 Makefile 可能不合适-L
。我已将额外的库放入其中,/opt/lib
因此我执行了以下操作:
$ export LIBRARY_PATH=/opt/lib/
然后运行make
并成功编译和链接。
要使用共享库运行程序,定义:
$ export LD_LIBRARY_PATH=/opt/lib/
在执行程序之前。
解决方案 6:
首先,你需要知道的命名规则lxxx
:
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst
lc
手段libc.so
,lltdl
手段libltdl.so
,lXtst
手段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
解决方案 7:
编译程序时,必须提供库的路径;在 g++ 中使用 -L 选项:
g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
解决方案 8:
我在装有 Centos 7.8 的新 VM 上编译 LXC 时遇到了这个问题。我尝试了上述所有方法,但都失败了。有人建议-static
从编译器配置中删除该标志,但我不想更改任何东西。
唯一有帮助的就是安装glibc-static
并重试。希望这对某人有帮助。
解决方案 9:
这是我的笔记本电脑的 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 已成功安装!
解决方案 10:
检查你的库的位置,例如 lxxx.so:
locate lxxx.so
如果不在/usr/lib
文件夹中,请输入以下内容:
sudo cp yourpath/lxxx.so /usr/lib
完毕。
解决方案 11:
除了已经给出的答案之外,还可能存在 .so 文件,但命名不正确。或者可能存在 .so 文件,但它属于另一个用户/root。
问题一:名称不当
如果您要链接文件,-l<nameOfLibrary>
则库文件名必须采用以下格式:lib<nameOfLibrary>
如果您只有<nameOfLibrary>.so
文件,请重命名!
问题 2:错误的所有者
要验证这不是问题 - 请执行
ls -l /path/to/.so/file
如果该文件属于 root 或其他用户,则需要执行
sudo chown yourUserName:yourUserName /path/to/.so/file
解决方案 12:
-static
如果符号链接指向动态库 .so,但由于遗留原因出现在链接标志中,也可能会出现此错误。如果是这样,请尝试将其删除。
解决方案 13:
我尝试链接到的库原来有一个非标准名称(即没有以“lib”为前缀),所以他们建议使用这样的命令来编译它 -
gcc test.c -Iinclude lib/cspice.a -lm
解决方案 14:
我遇到了同样的错误信息。
我将其构建cmocka
为 aso
并尝试将其链接到我的可执行文件。但ld
总是出现以下抱怨:
/usr/bin/ld:找不到-lcmocka
cmocka
事实证明,构建后生成了3个文件:
库文件
libcmocka.so.0
libcmocka.so.0.7.0
1 和 2 是符号链接,只有 3 是真实文件。
我只将 1 复制到了我的库文件夹,但ld
找不到 3。
我复制全部 3 个之后,ld
就可以了。
解决方案 15:
我正在使用它g++
进行链接,对于我来说,链接器选项在整个命令行中的位置有所不同。
以下命令产生链接器错误:
# Wrong order!
g++ \n -L/some/lib/path -lz -lboost_system -lboost_iostreams -lboost_program_options \n -o myBinary fileA.o fileB.o fileC.o
相反,我必须将链接器选项放在和目标文件之后-o
:
# Correct order.
g++ \n -o myBinary fileA.o fileB.o fileC.o \n -L/some/lib/path -lz -lboost_system -lboost_iostreams -lboost_program_options
请注意,文档指出,顺序对于-l
选项很重要:
在命令中写入此选项的位置有所不同;链接器会按照指定的顺序搜索和处理库和目标文件。因此,“foo.o -lz bar.o”会在文件 foo.o 之后但在 bar.o 之前搜索库“z”。如果 bar.o 引用“z”中的函数,则可能不会加载这些函数。
这意味着,所需的实际位置可能取决于您想要进行的实际链接。
此外,这似乎也适用于-L
选项。例如,在我的代码中,我必须允许静态链接。对于静态链接命令,我必须将选项放在-L
之前-o
,而-l
选项则放在命令的最后面。
解决方案 16:
当我使用 Golang C FFI 和 Rust extern C 时,对我来说微妙的事情是:
尽管结果.so
库可能被称为类似的东西libmy_project.so
,但指定的文件名-L
实际上应该只包含l
而不是lib
,如下所示:
#cgo LDFLAGS: -L. -lmy_project.so // -> Good
#cgo LDFLAGS: -L. -libmy_project.so // -> Erro: No such file or directory
ld -lib_name --verbose
运行@dcarrith answer中的命令时可以注意到
那东西浪费了我太多时间,希望它能有所帮助
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件