【问题标题】:How do I get rid of LD_LIBRARY_PATH at run-time?如何在运行时摆脱 LD_LIBRARY_PATH?
【发布时间】:2011-01-29 20:49:19
【问题描述】:

我正在构建一个使用 Intel 的 IPP 库的 C++ 应用程序。该库默认安装在 /opt 中,并且需要您设置 LD_LIBRARY_PATH 来编译和运行您的软件(如果您选择共享库链接,我这样做了)。我已经修改了我的configure.ac/Makefile.am,以便在编译时不需要设置该变量,但在运行时仍然找不到共享库;我该怎么做?

我正在使用g++ 使用-Wl, -R/path/to/libdir 标志进行编译

更新 1: 实际上我的二进制程序有一些正确链接的 IPP 库,但只有一个没有:

$ ldd myprogram
linux-vdso.so.1 =>  (0x00007fffa93ff000)
libippacem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippacem64t.so.6.0 (0x00007f22c2fa3000)
libippsem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippsem64t.so.6.0 (0x00007f22c2d20000)
libippcoreem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippcoreem64t.so.6.0 (0x00007f22c2c14000)
[...]
libiomp5.so => not found
libiomp5.so => not found
libiomp5.so => not found

图书馆当然在那里:

$ locate libiomp5.so
/opt/intel/ipp/6.0.2.076/em64t/sharedlib/libiomp5.so

【问题讨论】:

  • 我可能需要将问题更改为其他问题,但我需要建议,我缺乏想法
  • 嗯,我想知道那个人也缺少版本号扩展是否是巧合 - 也许 IPP 只是没有安装自己吗?
  • 我想知道丢失的库是否不是您的程序引用的,而是您引用的库?
  • @Richard:这是一个非常好的想法。您可以使用 LD_RUN_PATH 或适当的链接器选项编译 IPP(或其他 IPP 相关库)。
  • @Richard:你可能是对的,我记得读过类似的东西,libiomp5.so 是来自英特尔的线程库(MKL 的 IIRC 部分)。问题是我无法重新编译 IPP,因为它们不是 OSS...

标签: c++ g++ shared-libraries autotools intel-ipp


【解决方案1】:

/path/to/lib 是指包含库的目录的路径,还是实际文件的路径?

给定目录参数的-R 选项被ld 视为-rpath,这是您真正想要的选项。它将给定目录添加到运行时库搜索路径。只要您给它目录而不是文件名,那应该可以。我对此相当有信心,我自己做过,因为这是 libtool 给出的提示之一:

库已安装在:

/path/to/library-directory

如果您碰巧想链接已安装的库 在给定目录 LIBDIR 中,您必须使用 libtool,并且 指定库的完整路径名,或使用 `-LLIBDIR' 在链接期间标记并至少执行以下操作之一:

  • 将 LIBDIR 添加到“LD_LIBRARY_PATH”环境变量 执行期间
  • 将 LIBDIR 添加到 `LD_RUN_PATH' 环境变量 链接期间
  • 使用 `-Wl,-rpath -Wl,LIBDIR' 链接器标志
  • 让您的系统管理员将 LIBDIR 添加到 `/etc/ld.so.conf'

(我将其粘贴在这里,因为可以想象其他选项之一可能更可取 - 例如 LD_RUN_PATH 可以节省您对 makefile 的修改)

【讨论】:

  • 我修改了问题以更好地指定我确实指向一个目录。将该选项添加到链接阶段确实在编译时解决了问题,但运行时仍然不起作用。当然我做了make clean && make 以确保我已经更新了二进制文件......
  • 你可以试试LD_RUN_PATH路线,以防万一?
【解决方案2】:

正如 Richard Pennington 所建议的,我的应用程序不直接使用缺少的库,但我使用的共享库会使用它。由于我无法重新编译 IPP,我的问题的解决方案是在编译时添加 -liomp5,使用链接器的 -R 选项。这实际上添加了 libiomp5.so 的 rpath 来解决问题!

【讨论】:

    【解决方案3】:

    您可以通过在二进制文件上运行ldd 命令或readelf 命令来检查库的路径是否从您的-R 标志中获取。 LD_LIBRARY_PATH 环境变量是一个覆盖变量,因此通常不需要。

    【讨论】:

      【解决方案4】:

      如果可能,您应该使用 -R 选项。

      如果不是,请重命名您的可执行文件并创建一个运行您的可执行文件的启动脚本,并在其中为该范围设置 LD_LIBRARY_PATH。

      根据平台,您可以通过 /etc/ld.so.conf.d(想到 Redhat/Fedora)修改 ld.so.conf,这使得从部署场景中“更容易”部署对 ld.so 的更改。

      【讨论】:

      • 你看已经发布的信息了吗? OP is 使用-R 选项;问题是它没有按预期工作。修改 ld.so.conf 就像设置 LD_LIBRARY_PATH 一样,但更糟糕的是 - 它适用于所有事物,而不仅仅是这个程序,而且以始终需要 root 的方式进行部署并不容易。
      • 另外,虽然包装脚本可以工作,但它不仅不优雅,而且在某些不太可能但可能的情况下,它可能会出现问题 - 如果相关程序启动其他程序,它们将继承该环境变量,并且您再次对 LD_LIBRARY_PATH 的常见问题持开放态度。
      • 我并不是说它们是很好的解决方案,但如果最终用户安装的运行时组件是依赖项并且未明确添加到系统的查找方法中,那么您的选择将非常有限。基本上只有两种方法可以找到默认值之外的动态库——更新 ld.so,或者以某种形式使用 LD_LIBRARY_PATH(或 LD_RUN_PATH)。
      【解决方案5】:

      除了此处发布的所有有用提示之外..您不是在尝试在 32 位系统上使用 64 位特定库(反之亦然,取决于其他条件),是吗?

      【讨论】:

        【解决方案6】:

        重击:

        export LD_LIBRARY_PATH=/path/to/lib
        

        tcsh:

        setenv LD_LIBRARY_PATH /path/to/lib
        

        【讨论】:

        • 问题是如何必须设置 LD_LIBRARY_PATH,而不是如何设置它。这是一个非常合理的问题,因为设置 LD_LIBRARY_PATH 可能非常邪恶。
        【解决方案7】:

        尝试通过ld.so.conf 配置您的ldconfig,使其默认搜索您的/opt/... 目录。

        【讨论】:

        • 这不是一个可行的选择,它就像设置 LD_LIBRARY_PATH,但可能不太便携。此外,它还需要一项管理任务,这并不能解决主要问题,即尽可能轻松地让下一个用户/开发人员运行该软件。
        猜你喜欢
        • 1970-01-01
        • 2010-09-09
        • 2018-10-05
        • 1970-01-01
        • 1970-01-01
        • 2017-01-24
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多