linker - 如何调试“无法打开共享对象文件:没有这样的文件或目录”?
问题描述
在我们工作的项目中,我使用由另一个团队管理的构建系统,我遇到了一个问题,我能够编译和链接二进制文件,但是在执行它时,它抱怨无法加载共享对象文件,它不应该被链接到:
/home/me/build/bin/executable: error while loading shared libraries: libicui18n.so.52.1: cannot open shared object file: No such file or directory
奇怪的是,libicui18n.so.52.1
我什至可以在我的机器上找到的文件名的唯一实例是/opt/onlyoffice/desktopeditors/libicui18n.so.52.1
and /home/me/.local/opt/foxitsoftware/foxitreader/lib/libicui18n.so.52.1
,我绝对不会链接它,至少根据构建系统执行的链接器命令:
- 它不会作为任何显式
/absolute/path/to/libsomething.so.42.3
文件出现。 - 没有提供任何相关的
-L
选项。 - 没有任何相关内容作为
/absolute/path/to/libsomething.a
文件提供。 $LD_LIBRARY_PATH
或中没有任何相关内容$LIBRARY_PATH
。- 英特尔 Fortran 编译器没有理由将它们包含在默认路径中。
所以现在我想知道,还有什么libicui18n.so.52.1
可以链接到的,以及我如何去调试这样的问题。
解决方案
libicui18n.so.52.1 还可以如何链接
ELF 库可以独立于库本身的名称指定“在运行时应该使用什么名称” 。例子:
gcc -fPIC -shared -o libt.so t.c -Wl,--soname=libfoo.so.1.2.3
gcc main.c -L. -lt
./a.out
./a.out: error while loading shared libraries: libfoo.so.1.2.3: cannot open shared object file: No such file or directory
在这里,库以运行时需要的方式构建libfoo.so.1.2.3
,尽管不存在这样的库。由包装系统提供此类库(或符号链接)。
您可以检查一个库以查看它期望在运行时使用的名称,如下所示:
readelf -d libt.so | grep SONAME
0x000000000000000e (SONAME) Library soname: [libfoo.so.1.2.3]
您可以a.out
在运行时检查所需的库列表,如下所示:
readelf -d ./a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libfoo.so.1.2.3]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
我该如何调试这样的问题。
如上。您的下一个问题可能是“我该如何解决这个问题?”。
由于libicui18n.so.52.1
已安装,但未安装到动态链接器默认搜索的目录中,您所要做的就是告诉您的二进制文件将非标准/opt/onlyoffice/desktopeditors
目录添加到要搜索的目录列表中。
您可以通过添加-Wl,-rpath=/opt/onlyoffice/desktopeditors
到可执行文件的链接行来做到这一点。
您也可以添加/opt/onlyoffice/desktopeditors
到LD_LIBRARY_PATH
,但-Wl,-rpath
首选使用。
推荐阅读
- .net - 尝试确定 Webcore.exe 的进程 ID 时发生错误
- angular - 从下拉框中迭代的数组获取值的索引
- css - 现在我可以在移动的幻灯片上添加一个角三角形吗?
- r - 从列表中提取一组变量
- java - TornadoFX 窗口关闭时如何关闭整个应用程序?
- c# - 为文件夹中的所有文件设置使用命名空间
- html - 单击链接 href 目标 id 纯 css 时在滑块顶部停止滚动
- amazon-web-services - API 网关 - 端点请求随机超时
- wordpress - 发布时是否有任何方法可以在 wordpress 帖子中生成自动标题
- wordpress - 使用 Timber (Twig) 构建的 WordPress 网站是否可以使用 AMP