【问题标题】:Why isn't DYLD_LIBRARY_PATH being propagated here?为什么 DYLD_LIBRARY_PATH 不在这里传播?
【发布时间】:2018-02-05 13:58:34
【问题描述】:

我正在尝试运行一个简单的 C++ 程序,该程序与我之前构建的 Boost.Thread 库的版本相关联。我似乎无法理解运行时库路径在 OS X 上的行为方式。

由于我的 Boost 库没有 RPATH-relative install name,我使用 DYLD_LIBRARY_PATH 环境变量来告诉动态链接器在运行时在哪里可以找到 libboost_thread.dylib

如果我直接在我的 (bash) shell 中运行程序,这会很好:

[~/git/project]$ echo $DYLD_LIBRARY_PATH
/Users/jasonr/git/project/boost/lib
[~/git/project]$ .sconf_temp/conftest_7
[~/git/project]$ # Program runs successfully; this is what I expect.

但是,这个程序是由我正在使用的类似autoconf 的框架作为一系列测试的一部分运行的。它使用sh -c 在子shell 中运行程序。如果我尝试这样做会发生以下情况:

[~/git/project]$ # Make sure the environment variable is exported to child shells.
[~/git/project]$ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH
[~/git/project]$ # Try to run it in a child shell.
[~/git/project]$ sh -c .sconf_temp/conftest_7
dyld: Library not loaded: libboost_thread.dylib
  Referenced from: /Users/jasonr/git/project/.sconf_temp/conftest_7
  Reason: image not found
Trace/BPT trap: 5

在这种情况下,就好像环境变量没有传播到dyld。为什么会出现这种情况?我更熟悉LD_LIBRARY_PATH 在 Linux 上的行为,(我认为)应该适用于上述示例。为了完成这项工作,我还需要做些什么吗?

【问题讨论】:

    标签: macos bash shell environment-variables


    【解决方案1】:

    您可能正在运行 El Capitan (OS X 10.11) 或更高版本。这是系统完整性保护的副作用。来自System Integrity Protection Guide: Runtime Protections的文章:

    当一个进程启动时,内核会检查主进程是否 可执行文件在磁盘上受到保护或使用特殊系统签名 权利。如果其中一个为真,则设置一个标志以表示它 受到保护以防修改。 …

    ... 任何动态链接器 (dyld) 环境变量,例如DYLD_LIBRARY_PATH,在 启动受保护的进程。

    所有系统提供的解释器,包括/bin/sh,都以这种方式受到保护。因此,当您调用 sh 时,所有 DYLD_* 环境变量都会被清除。

    您可以编写一个设置DYLD_LIBRARY_PATH 然后执行.sconf_temp/conftest_7 的shell 脚本。您可以使用 shell 解释器来执行它——事实上,你必须这样做——并且环境变量会很好,因为清除是在启动受保护的可执行文件时发生的。基本上,这种方法类似于您问题中的工作示例,但封装在 shell 脚本中。

    【讨论】:

    • 感谢您指出这一点。对于开发人员恕我直言,这是一个特别繁重的限制。正如您所指出的,我可以编写一个首先设置环境变量的 shell 脚本。但是,这需要我将值硬编码到脚本中,因为没有很好的方法将它们传达到相关脚本中(因为它们已被剥离出环境)。似乎关闭 SIP 是最简单的解决方法。
    猜你喜欢
    • 1970-01-01
    • 2020-08-31
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多