【问题标题】:usr/bin/ld: cannot find -l<nameOfTheLibrary>usr/bin/ld: 找不到 -l<nameOfTheLibrary>
【发布时间】:2025-12-02 18:45:01
【问题描述】:

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

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

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

请问有没有可以添加的选项?

【问题讨论】:

  • 需要更多信息。你发出了什么命令来编译你的程序?您可以使用 make -n your-target 让 make 只打印它通常会调用的命令
  • 发布 makefile 或您执行的命令。
  • 我的命令是这个:g++ - objetc1.o objetc2.o objetc3.o objetc4.o -L -l -lpthread -o myexe
  • 您要链接的库是否使用相同的架构构建(例如 32/64 位)?您要与自定义库链接的库吗?库名称很重要,因为在使用 -l 开关时它必须以 lib 开头(例如,libpthread.so 你已经在链接)。
  • 问题出在我在图书馆的符号链接上,这不好!感谢您的帮助!

标签: c++ linux g++


【解决方案1】:

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

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

/usr/bin/ld: cannot find -lzlib

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

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

瞧!

【讨论】:

  • 谢谢,这很有帮助。对于其他使用 gcc 编译和链接他们的程序(而不是直接使用 ld)的人,您可以在 gcc 的命令行参数中添加 -Xlinker --verbose 以使其将此选项传递给 ld。
  • 这对我也有帮助。我的 Makefile 只需要静态库,所以它使用了-Wl,-Bstatic。这将搜索限制为仅 .a 文件。详细选项清楚地表明了这一点。一旦我删除了-Wl,-Bstatic,共享库也被搜索了。
  • 我在 FreeBSD 10 上。新的 LLVM Clang cc 采用 -Wl,--verbose 形式的参数并将 --verbose 传递给链接器。
  • 现在这就是我所说的完美答案!非常感谢。它节省了很多时间。只是为了帮助像我这样的人。它也可以用来调试路径相关的问题。确保使用 -L 命令检查路径, ld -L -l --verbose
  • @EdwardBlack 看到这个answer。本质上,对于 gcc,只需添加 -Wl,--verbose 即可将详细信息传递给链接器。
【解决方案2】:

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

/home/user/myDir

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

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

【讨论】:

  • 我的库不是动态库 (.so) 而是静态库 (.a)。问题出在哪里?
  • @ZoOo 这通常不重要,链接器可以使用任何一个
  • 另一种链接你的库的方法是你可以直接指定带有完整路径的库的名称,如 g++ .. /path/mylib.a
  • 是的,但它仍然不起作用。我的库是一个符号链接,我认为问题来自于此,因为当我在另一个目录中使用该库时它可以工作!
  • 您的符号链接是否正确指向实际位置的库??你能在符号链接上发布“ll”的输出吗?
【解决方案3】:

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

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

apt-get install libfoo-dev

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

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

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

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

【讨论】:

  • 这只是帮助我解决了我在使用新服务器和 Perl 时遇到的问题。 apt-get install libperl-dev 为我排序。谢谢:)
  • 这个!无需弄乱 Makefile
  • 这可能是最常见的解决方案,帮助我在 CentOS 7 上编译 cacti-spine。一个简单的yum install openssl-devel 解决了它。
  • 如果您发现缺少以 .so 结尾的符号链接,这是最好的解决方法,但是您有一个符号链接,例如 libfoo.so.6 --> libfoo.so.6.0.2(例如),而不是手动创建符号链接。 (意味着您安装了软件包 libfoo,但没有安装 libfoo-dev)
【解决方案4】:

编译时间

当 g++ 说 cannot find -l&lt;nameOfTheLibrary&gt; 时,表示 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 文件复制到/usr/lib 之前,我一直忽略所有答案,但是export 是否会有所帮助对我来说变得很有趣。尽管make 之后的安装过程持续了更长时间,但出现了另一个错误。这次没有找到.so.0 文件,但.so.so.0 文件都在我从源代码构建依赖包的目录中。你能帮忙吗?
【解决方案5】:

在通过make 使用g++ 编译期间,如果不适合使用-L 选项更改Makefile,则定义LIBRARY_PATH。我把我的额外库放在/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.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

    【讨论】:

    • locate 仅在安装并定期运行时才有效。一个粗略的解决方法是在整个磁盘上运行find,但当然,这需要时间。如果您发现自己经常这样做,请考虑安装 locate 以降低此操作的(交互式、人工)成本。
    • 谢谢你的回答让我知道出了什么问题。我创建了指向“丢失”libXXX.so 文件的软链接。例如:ln -s libasound.so.2 libasound.so
    【解决方案7】:

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

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

    【讨论】:

    • 我们必须更改ccmake 中的哪个属性,以便使用链接标志创建Makefile?我想将我的 -lARToolkitPlus 标志链接到路径。
    【解决方案8】:

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

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

    【讨论】:

    • 也救了我! :D
    【解决方案9】:

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

    locate lxxx.so
    

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

    sudo cp yourpath/lxxx.so /usr/lib
    

    完成。

    【讨论】:

    • 在将库复制到系统目录时需要谨慎。
    【解决方案10】:

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

    问题1:名称不正确

    如果您将文件链接为-l&lt;nameOfLibrary&gt; 那么库文件名的格式必须是lib&lt;nameOfLibrary&gt; 如果你只有&lt;nameOfLibrary&gt;.so 文件,重命名它!

    问题 2:错误的所有者

    要验证这不是问题 - 做

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

    如果文件归root或其他用户所有,则需要这样做

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

    【讨论】:

      【解决方案11】:

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

      【讨论】:

        【解决方案12】:

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

        【讨论】:

          【解决方案13】:

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

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

          【讨论】:

          • 仅以“lib”为前缀以获得为我修复的标准名称
          【解决方案14】:

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

          我将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 有效。

          【讨论】:

          • 你能说一下“我的图书馆文件夹”下的文件夹是什么意思吗?