运行时链接器忽略 Solaris 上可执行文件中的 RPATH

发布于 2024-10-04 03:20:43 字数 2300 浏览 10 评论 0原文

我正在尝试在没有 root 权限的 Solaris 服务器上编译 samtools 。 Samtools 依赖于 zlib。本机上的系统 zlib 编译时不支持大文件,因此针对此版本编译 samtools 具有预期效果:samtools 只处理小文件。我需要它能够处理大文件。幸运的是,/usr/local/apps/zlib-1.2.5/ 中有一个由管理员编译的 zlib 版本,支持大文件。我可以通过将 -R /usr/local/apps/zlib-1.2.5/lib 添加到 CFLAGS 来对此进行编译,但这似乎不起作用。症状如下:

当我尝试运行 samtools 时,它崩溃并出现以下错误:

ld.so.1: samtools: fatal: relocation error: file samtools: symbol gzopen64: referenced symbol not found

如果我将 /usr/local/apps/zlib-1.2.5/ 添加到 LD_LIBRARY_PATH,则 samtools 可以正常工作。

使用 ldd 和 readelf 分析 samtools 会产生以下结果:

$ ldd -r samtools
        libnsl.so.1 =>   /usr/lib/libnsl.so.1
        libsocket.so.1 =>        /usr/lib/libsocket.so.1
        libresolv.so.2 =>        /usr/lib/libresolv.so.2
        libm.so.2 =>     /usr/lib/libm.so.2
        libcurses.so.1 =>        /usr/lib/libcurses.so.1
        libz.so =>       /usr/lib/libz.so
        libc.so.1 =>     /usr/lib/libc.so.1
        libmp.so.2 =>    /usr/lib/libmp.so.2
        libmd.so.1 =>    /usr/lib/libmd.so.1
        libscf.so.1 =>   /usr/lib/libscf.so.1
        libdoor.so.1 =>  /usr/lib/libdoor.so.1
        libuutil.so.1 =>         /usr/lib/libuutil.so.1
        libgen.so.1 =>   /usr/lib/libgen.so.1
        symbol not found: gzopen64              (samtools)

$ ldd -s samtools

   ...(snip)...

   find object=libz.so; required by samtools
    search path=/usr/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib  (LD_LIBRARY_PATH)
    trying path=/usr/lib/libz.so
        libz.so =>       /usr/lib/libz.so

   ...(snip)...

$ readelf -d samtools | grep RPATH
 0x0000000f (RPATH)                      Library rpath: [/usr/local/apps/zlib-1.2.5/lib:/usr/local/apps/gcc-4.5.1/lib]

因此 /usr/local/apps/zlib-1.2.5/lib 显然在二进制文件的 RPATH 中,据我了解应该在运行时搜索它共享库。但是,ldd -s 显示从未搜索过该目录。将此路径添加到 LD_LIBRARY_PATH 并重新运行 ldd 命令具有预期效果:搜索目录并找到正确版本的 libz。

那么如何强制 samtools 在运行时在 /usr/local/apps/zlib-1.2.5/lib 中搜索而不使用 LD_LIBRARY_PATH 呢?


编辑:文档此处似乎表明 -R 选项是正确的做法。但这不起作用。

I'm trying to compile samtools on a Solaris server where I do not have root. Samtools depends on zlib. The system zlib on this machine is not compiled with large file support, so compiling samtools against this version has the expected effect: samtools only handle small files. I need it to be able to handle large files. Luckily, there is a version of zlib compiled by the admin in /usr/local/apps/zlib-1.2.5/ with large file support. I can compile against this by adding -R /usr/local/apps/zlib-1.2.5/lib to CFLAGS, but this seems not to work. The symptoms are as follows:

When I try to run samtools, it crashes with this error:

ld.so.1: samtools: fatal: relocation error: file samtools: symbol gzopen64: referenced symbol not found

If I add /usr/local/apps/zlib-1.2.5/ to LD_LIBRARY_PATH, then samtools works fine.

Analyzing samtools with ldd and readelf yields the following:

$ ldd -r samtools
        libnsl.so.1 =>   /usr/lib/libnsl.so.1
        libsocket.so.1 =>        /usr/lib/libsocket.so.1
        libresolv.so.2 =>        /usr/lib/libresolv.so.2
        libm.so.2 =>     /usr/lib/libm.so.2
        libcurses.so.1 =>        /usr/lib/libcurses.so.1
        libz.so =>       /usr/lib/libz.so
        libc.so.1 =>     /usr/lib/libc.so.1
        libmp.so.2 =>    /usr/lib/libmp.so.2
        libmd.so.1 =>    /usr/lib/libmd.so.1
        libscf.so.1 =>   /usr/lib/libscf.so.1
        libdoor.so.1 =>  /usr/lib/libdoor.so.1
        libuutil.so.1 =>         /usr/lib/libuutil.so.1
        libgen.so.1 =>   /usr/lib/libgen.so.1
        symbol not found: gzopen64              (samtools)

$ ldd -s samtools

   ...(snip)...

   find object=libz.so; required by samtools
    search path=/usr/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib  (LD_LIBRARY_PATH)
    trying path=/usr/lib/libz.so
        libz.so =>       /usr/lib/libz.so

   ...(snip)...

$ readelf -d samtools | grep RPATH
 0x0000000f (RPATH)                      Library rpath: [/usr/local/apps/zlib-1.2.5/lib:/usr/local/apps/gcc-4.5.1/lib]

So /usr/local/apps/zlib-1.2.5/lib is clearly in the binary's RPATH, which I understand is supposed to be searched at runtime for shared libraries. However, ldd -s shows that this directory is never searched. Adding this path to LD_LIBRARY_PATH and re-running the ldd commands has the expected effect: the directory is searched and the correct version of libz is found.

So how can I force samtools to search in /usr/local/apps/zlib-1.2.5/lib at runtime without using LD_LIBRARY_PATH?


Edit: The documentation here would seem to indicate that the -R option is the correct thing to do. But it doesn't work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最美不过初阳 2024-10-11 03:20:43

我绝不是 Solaris 专家,但是这一行:

find object=libz.so; required by samtools
 search path=/usr/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib  (LD_LIBRARY_PATH)

似乎向我表明 LD_LIBRARY_PATH 已经设置,并且其中的 /usr/lib 路径正在占用优先于任何运行时链接器路径。如果 LD_LIBRARY_PATH 实际上存在,您可以取消设置它并查看是否可以解决该问题吗?

I'm by no means a Solaris expert, but this line:

find object=libz.so; required by samtools
 search path=/usr/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib  (LD_LIBRARY_PATH)

seems to indicate to me that LD_LIBRARY_PATH is already set, and the /usr/lib path in it is taking precedence over any runtime linker paths. Can you unset LD_LIBRARY_PATH if it is in fact present and see if that resolves it?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文