usr/bin/ld:查找不到-l<

我试图编译我的程序,它返回这个错误:

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

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

是否有一个选项添加,使其工作,请?

1395608 次浏览

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

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

如果你的库名是libxyz.so,它位于路径上,说:

/home/user/myDir

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

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

要找出链接器正在寻找什么,请在verbose模式下运行它。

例如,我在尝试用ZLIB支持编译MySQL时遇到了这个问题。在编译过程中,我收到了这样一个错误:

/usr/bin/ld: cannot find -lzlib

我做了一些谷歌搜索,不断遇到不同的同类问题,人们会说,要确保.so文件确实存在,如果它不存在,那么就创建一个到版本文件的符号链接,例如,zlib.so.1.2.8。但是,当我检查时,zlib。确实存在。所以,我想,这肯定不是问题所在。

我在网上看到了另一篇文章,建议使用LD_DEBUG=all运行make:

LD_DEBUG=all make

虽然我得到了大量的调试输出,但实际上并没有什么帮助。这比其他任何事情都更让人困惑。所以,我打算放弃了。

然后,我有了一个顿悟。我想实际检查一下ld命令的帮助文本:

ld --help

由此,我想出了如何在verbose模式下运行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

瞧!

在使用g++通过make编译期间,如果使用# eyz3选项更改Makefile可能不合适,则定义LIBRARY_PATH。我把我的额外库在/opt/lib,所以我这样做:

$ export LIBRARY_PATH=/opt/lib/

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

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

$ export LD_LIBRARY_PATH=/opt/lib/

在执行程序之前。

编译时

当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.so

  • 注2:在某些情况下,库文件名后面跟着它的版本号,例如libswift.so.1.2。在这些情况下,g++也无法找到库文件。一个简单的解决方法是创建一个到libswift.so.1.2的符号链接,称为libswift.so


运行时

当你把你的应用链接到一个共享库时,它要求库在你运行应用时保持可用。在运行时,你的应用(实际上是动态链接器)在LD_LIBRARY_PATH中寻找它的库。它是一个存储路径列表的环境变量。

在我们的libswift.so示例中,动态链接器无法在LD_LIBRARY_PATH中找到libswift.so(指向默认搜索路径)。要解决这个问题,你应该将该变量与libswift.so所在的路径附加在一起。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/taylor

如果符号链接是指向动态库的,也会出现这个错误,.so,但是由于遗留的原因,-static出现在链接标志中。如果是,试着把它去掉。

我试图链接到的库有一个非标准的名称(即没有'lib'前缀),所以他们建议使用这样的命令来编译它-

# EYZ0

似乎没有任何答案可以解决初学者在第一时间未能安装所需库的常见问题。

在Debianish平台上,如果缺少libfoo,你可以经常用类似的东西来安装它

apt-get install libfoo-dev

开发工作需要包的-dev版本,即使是简单的开发工作,如编译源代码以链接到库。

包名有时需要一些修饰(libfoo0-dev?foo-dev没有lib前缀?或者你可以简单地使用发行版的包搜索来精确地找出哪些包提供了特定的文件。

(如果有不止一个,你需要找出它们之间的区别。选择最酷或最受欢迎的是一种常见的捷径,但对于任何严肃的开发工作来说都不是可接受的过程。)

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

首先,你需要知道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

# EYZ0

完成了!

裁判:# EYZ0

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

locate lxxx.so

如果不在/usr/lib文件夹中,输入以下内容:

sudo cp yourpath/lxxx.so /usr/lib

完成了。

除了已经给出的答案,也可能是*。因此文件存在,但没有正确命名。也可能是*。所以文件存在,但它由另一个用户/ root拥有。

名称不当

如果你将文件链接为-l<nameOfLibrary> 那么库文件名必须是lib<nameOfLibrary>的形式 如果你只有<nameOfLibrary>.so文件,重命名它!< / p >

错误的所有者

为了验证这不是问题-做

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

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

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

这是我笔记本电脑的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安装成功!

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

我构建了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工作。

我在使用Centos 7.8的新VM上编译LXC时遇到了这个问题。我尝试了以上所有的方法,但都失败了。有人建议从编译器配置中删除-static标志,但我不想改变任何东西。

唯一有帮助的是安装glibc-static并重试。希望这能帮助到别人。