摆脱“gcc - /usr/bin/ld: warning lib not found”

31

我在链接过程中遇到了以下警告:

/usr/bin/ld: warning: libxxx.so.6, needed by /a/b/c/libyyy.so, not found (try using -rpath or -rpath-link)

将环境变量LD_LIBRARY_PATH设置为path_to_libxxx.so.6可以消除警告(添加-Lpath_to_libxxx.so.6没有帮助)。

我有一个单独的编译服务器,只编译生成二进制文件。二进制文件在其他服务器上执行,其中libxxx.so.6被二进制文件看到(使用ldd executable检查)。

是否有其他方法可以在编译时消除警告(我多次遇到这个问题,非常恼人)?

4个回答

48

您需要添加等效于 -L 的动态库:

-Wl,-rpath-link,/path/to/lib

这将导致连接器在非标准位置查找共享库,但仅用于验证链接是否正确。

如果您希望程序在运行时在该位置找到库,则有一个类似的选项可执行此操作:

-Wl,-rpath,/path/to/lib

但是,如果你的程序没有问题,不使用这个也可以。


6
确保所需库文件的路径已知于运行时链接器。这可以通过添加一个带有所需路径的文件到 /etc/ld.so.conf.d/ 中来完成。例如,/etc/ld.so.conf.d/foo 内容如下:
/usr/local/lib/foo/

如果您使用的是非常老的Linux版本,可能不支持/etc/ld.so.conf.d/目录,这种情况下您需要直接将路径添加到/etc/ld.so.conf文件中。完成后,您需要通过执行"ldconfig"命令来更新链接器的数据库。

我在编译服务器上没有根权限。该服务器仅用于编译,二进制文件不会在其上执行。第一个问题是为什么在链接时需要考虑运行时环境,第二个问题是如何消除警告。 - dimba
1
@dimba 你不必担心它。这只是一个警告,告诉你二进制文件无法在当前机器上运行。至于如何在链接时禁用警告而不使用rpath,我不知道。(通常情况下,除非您将库与可执行文件捆绑在一起,否则使用rpath不是一个好主意。)如果您没有root权限,则LD_LIBRARY_PATH是您唯一的选择。 - Nikos C.

2
我知道这篇文章有点旧了,但是这里有一个更好的解决方法

根本原因:

问题实际上发生在GCC调用LD开始解析库依赖关系时。GCC和LD都知道包含库的sysroot,但是LD可能缺少一个关键组件:/etc/ld.so.conf文件。以下是来自Raspberry PI系统的示例ld.so.conf文件:

include /etc/ld.so.conf.d/*.conf

/etc/ld.so.conf.d目录包含以下文件:

00-vmcs.conf: /opt/vc/lib

arm-linux-gnueabihf.conf:

/lib/arm-linux-gnueabihf /usr/lib/arm-linux-gnueabihf

libc.conf:

/usr/local/lib

通用解决方案

问题可以通过将LD配置文件复制到交叉工具链的LD可以找到它们的位置来轻松解决。然而,这里有一个陷阱:如果您的交叉工具链是使用MinGW构建的(大多数都是),那么它可能无法访问glob()函数,因此它将无法解析启用通配符的include语句,例如*.conf。这里的解决方法是手动组合/etc/ld.so.conf.d中所有.conf文件的内容,并将它们粘贴到/etc/ld.so.conf中:

*/opt/vc/lib

/lib/arm-linux-gnueabihf

/usr/lib/arm-linux-gnueabihf

/usr/local/lib*

创建正确文件夹中的ld.so.conf文件后,您的工具链将能够自动解析所有共享库引用,您将不再看到该错误消息!


1
非常感谢,问题得到了干净利落的解决!值得一提的是,/etc/ld.so.conf 应该在工具链的_target_ sysroot中创建,而不是_host_ one中创建。 - Julien Ruffin
你好!您能详细解释一下“工具链的目标 sysroot”是什么吗?在我的应用程序中,工具链并不在 sysroot 中,它们在不同的路径中:
  • /path-to/sysroot
  • /path-to/toolchain
在 /path-to/sysroot/etc 下已经有了适当的 etc.ld.so.conf 文件,但我仍然遇到链接问题。请问我需要将 etc.ld.so.conf 文件放在 /path-to/toolchain 的哪个位置呢?
- user1011113

1
唯一使用命令行选项来消除这些警告的方法是使用 -L 标志,但奇怪的是它对您不起作用(也许您可以在此发布更多详细信息)。由于警告是由 ld 生成的,我们可以尝试使用 -Wl,option 来禁用链接器警告,但从 GNU ld 的文档中(链接),没有选项可以(停用)激活此警告。
因此,这使我们编写一个包装脚本来过滤掉这个警告或编译一个自定义版本的 ld。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接