563

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

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

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

请问有没有可以添加的选项让它工作?

4

14 回答 14

571

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

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

/usr/bin/ld: cannot find -lzlib

我做了一些谷歌搜索,并不断遇到相同类型的不同问题,人们会说要确保 .so 文件确实存在,如果不存在,则创建指向版本化文件的符号链接,例如 zlib。所以.1.2​​.8。但是,当我检查时, zlib.so 确实存在。所以,我想,这肯定不是问题。

我在 Internet 上看到另一个帖子,建议使用 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

瞧!

于 2014-02-08T15:04:05.317 回答
238

如果您的库名称是 saylibxyz.so并且它位于路径上,请说:

/home/user/myDir

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

g++ -L/home/user/myDir -lxyz myprog.cpp -o myprog
于 2013-05-23T09:33:31.203 回答
69

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

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

apt-get install libfoo-dev

包的-dev版本是开发工作所必需的,即使是一些琐碎的开发工作,例如编译源代码以链接到库。

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

(如果有多个,您需要找出它们的区别。挑选最酷或最流行的是一种常见的捷径,但对于任何严肃的开发工作来说,这不是一个可接受的过程。)

对于其他架构(尤其是 RPM),类似的程序也适用,但细节会有所不同。

于 2017-02-20T08:10:15.050 回答
60

编译时间

当 g++ 说cannot find -l<nameOfTheLibrary>时,这意味着 g++ 寻找文件lib{nameOfTheLibrary}.so,但它在共享库搜索路径中找不到它,默认情况下,它可能指向/usr/liband/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选项获取库名称,其开头和结尾没有 liband 。.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
于 2015-12-13T21:33:02.503 回答
39

在编译期间使用g++viamake定义LIBRARY_PATH是否不适合使用该-L选项更改 Makefile。我已经把我的额外图书馆放进去,/opt/lib所以我做了:

$ export LIBRARY_PATH=/opt/lib/

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

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

$ export LD_LIBRARY_PATH=/opt/lib/

在执行程序之前。

于 2015-09-10T12:50:06.553 回答
19

首先,您需要了解 的命名规则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

于 2017-11-10T09:11:24.573 回答
7

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

g++ myprogram.cc -o myprogram -lmylib -L/path/foo/bar
于 2013-05-23T09:22:56.460 回答
3

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

问题一:名称不当

如果您将文件链接为,-l<nameOfLibrary> 则库文件名必须采用以下形式lib<nameOfLibrary> 如果您只有<nameOfLibrary>.so文件,请重命名它!

问题 2:错误的所有者

要验证这不是问题 - 做

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

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

sudo chown yourUserName:yourUserName /path/to/.so/file
于 2018-05-22T02:21:06.570 回答
3

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

于 2019-06-12T20:12:53.743 回答
3

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

locate lxxx.so

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

sudo cp yourpath/lxxx.so /usr/lib

完毕。

于 2018-03-29T13:15:33.037 回答
2

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

唯一有帮助的是安装glibc-static并重试。希望对某人有所帮助。

于 2020-07-28T17:32:13.673 回答
2

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

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

于 2016-08-27T15:49:25.177 回答
2

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

于 2016-06-17T12:09:25.617 回答
1

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

我将其构建cmocka为 aso并尝试将其链接到我的可执行文件。但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就可以了。

于 2019-11-28T08:24:05.797 回答