【问题标题】:Substitute for LD_PRELOAD or LD_LIBRARY_PATH替代 LD_PRELOAD 或 LD_LIBRARY_PATH
【发布时间】:2011-03-31 16:46:11
【问题描述】:

我正在一台我没有 root 访问权限的机器上进行一些 C 编程。我已经编译了一些我要链接的共享库,但是因为我无法在典型位置 (/usr/local/lib) 安装这些库,所以每次编译和运行时我都必须明确指定库的位置。编译时,这只是意味着将-L 标志添加到gcc 命令中,但是对于程序执行而言,这更烦人。要么我必须在每个会话中将非标准目录添加到LD_LIBRARY_PATH,要么我必须将LD_PRELOAD=/path/to/libs 添加到执行命令的开头。

有没有更好的方法在我没有 root 访问权限的机器上执行此操作?

顺便说一句,机器运行的是 Red Hat 4.1。

【问题讨论】:

  • 您可以使用-rpath 或类似选项对二进制文件中的库路径进行硬编码。
  • 等等.. Red Hat 4.1!?!在这种情况下,您可以根它并在系统范围内安装库...

标签: c shared-libraries dynamic-linking


【解决方案1】:

有几种解决方案,从好到坏:

  1. 使用$ORIGIN,例如gcc main.o -L../lib -lfoo -Wl,-rpath='$ORIGIN'/../lib
  2. 使用目标 RPATH,例如gcc main.o -L../LIB -lfoo -Wl,-rpath=/home/user/lib
  3. 从您的.bashrc.profile 设置LD_LIBRARY_PATH

解决方案 1 允许您将二进制文件安装在任何地方,只要您将二进制文件和库一起移动,例如my-app/bin/a.out 和 my-app/lib/{needed-shared-libs}.so。它还允许应用程序的多个版本及其共享库集。

如果您只需要一组共享库并且不希望移动它们,则解决方案 2 可以正常工作。

解决方案 3 会影响您运行的每个应用程序,并可能导致其中一些应用程序绑定到您的共享库而不是系统库。这可能会导致它们崩溃、因未解决的符号而失败,或者给您带来其他痛​​苦。更严重的是,问题只会发生在您身上,不会发生在其他人身上,因此您将很难获得帮助。

【讨论】:

    【解决方案2】:

    您可以将环境变量添加到您的.bashrc(或登录时您的 shell 来源的任何文件)。

    【讨论】:

    • 将 LD_LIBRARY_PATH 添加到您的 .bashrc 是不合适的,因为它仅与单个应用程序相关。当 OP 有两个版本的可执行文件并与两个不同版本的共享库捆绑在一起时会发生什么?
    【解决方案3】:

    如果您在编译和链接程序时设置环境变量LD_RUN_PATH,那么该搜索路径将被烘焙到可执行文件中,动态链接器将在运行时搜索它。

    【讨论】:

    • 使用标志比使用环境变量更好:显式 > 隐式。
    【解决方案4】:

    使用 LD_LIBRARY_PATH 或 LD_PRELOAD 几乎可以做到这一点。要解决此问题,请将您的程序从 myprog 重命名为 myprog-exe,并创建一个类似于 myprog 的 shell 脚本:

    #!/bin/sh
    export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
    `dirname $0`/myprog-exe
    

    这样,当有人运行 myprog 时,它会真正运行 shell 脚本,然后运行 ​​myprog。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 2019-04-06
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多