为什么这里不传播DYLD_LIBRARY_PATH? [英] Why isn't DYLD_LIBRARY_PATH being propagated here?
问题描述
由于我的Boost库没有一个 RPATH相对安装名称,我使用 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] $#程序运行成功;这是我的期望。
但是,该程序作为一系列测试的一部分运行,由我正在使用的autoconf
类框架。它使用 sh -c
在子shell中运行该程序。如果我尝试,会发生什么:
[〜/ git / project] $#确保环境变量导出为子炮弹。
[〜/ git / project] $ export DYLD_LIBRARY_PATH = $ DYLD_LIBRARY_PATH
[〜/ git / project] $#尝试在子shell中运行它。
[〜/ git / project] $ sh -c .sconf_temp / conftest_7
dyld:库未加载:libboost_thread.dylib
引用来自:/Users/jasonr/git/project/.sconf_temp / conftest_7
原因:图像未找到
跟踪/ BPT陷阱:5
在这种情况下,环境变量就不会传播到 dyld
。为什么会这样呢?我更熟悉Linux上的 LD_LIBRARY_PATH
的行为,我认为应该使用上面的例子。为了使这项工作有什么需要做的吗?
大概你正在运行El Capitan 10.11)。这是系统完整性保护的副作用。从系统完整性保护指南:运行时保护文章:
当进程启动时,内核检查主
可执行文件是否受保护磁盘或使用特殊系统
授权签署。如果两者都为真,则设置一个标志来表示
被保护以防修改。 ...
...任何动态链接器(
dyld
)
环境变量,如启动受保护的进程时,将清除DYLD_LIBRARY_PATH 。
所有系统提供包括 / bin / sh
在内的口译员受到这种保护。因此,当您调用 sh
时,将清除所有DYLD_ *环境变量。
您可以编写一个shell脚本,设置 DYLD_LIBRARY_PATH
,然后执行 .sconf_temp / conftest_7
。您可以使用shell解释器来执行 - 实际上,您必须 - 并且环境变量会很好,因为清除在受保护的可执行文件启动时发生。基本上,这种方法类似于您的问题中的工作示例,但封装在shell脚本中。
I have a simple C++ program that I'm trying to run that is linked against a version of the Boost.Thread library that I built previously. I seem to be having trouble understanding the way that runtime library paths behave on OS X.
Since my Boost library doesn't have an RPATH-relative install name, I'm using the DYLD_LIBRARY_PATH
environment variable to tell the dynamic linker where to find libboost_thread.dylib
at runtime.
This works fine if I run the program directly in my (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.
However, this program is run as part of a series of tests by an autoconf
-like framework that I'm using. It runs the program in a child shell using sh -c
. Here's what happens if I try that:
[~/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
It's as if the environment variable isn't propagated to dyld
in this case. Why would this occur? I'm more familiar with the behavior of LD_LIBRARY_PATH
on Linux, which (I think) should work with the above example. Is there something else I need to do in order to make this work?
Presumably, you are running El Capitan (OS X 10.11). It's a side effect of System Integrity Protection. From the System Integrity Protection Guide: Runtime Protections article:
When a process is started, the kernel checks to see whether the main executable is protected on disk or is signed with an special system entitlement. If either is true, then a flag is set to denote that it is protected against modification. …
… Any dynamic linker (
dyld
) environment variables, such asDYLD_LIBRARY_PATH
, are purged when launching protected processes.
All of the system-provided interpreters, including /bin/sh
, are protected in this fashion. Therefore, when you invoke sh
, all DYLD_* environment variables are purged.
You could write a shell script which sets DYLD_LIBRARY_PATH
and then executes .sconf_temp/conftest_7
. You can use the the shell interpreter to execute that — indeed, you must — and the environment variable will be fine, since the purging happens when a protected executable is started. Basically, this approach is analogous to the working example in your question, but encapsulated in a shell script.
这篇关于为什么这里不传播DYLD_LIBRARY_PATH?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!