为什么 DYLD_LIBRARY_PATH 不在这里传播? [英] Why isn't DYLD_LIBRARY_PATH being propagated here?

查看:21
本文介绍了为什么 DYLD_LIBRARY_PATH 不在这里传播?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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.

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

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.

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

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

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

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?

推荐答案

大概您正在运行 El Capitan (OS X 10.11) 或更高版本.这是系统完整性保护的副作用.来自 系统完整性保护指南:运行时保护 文章:

Presumably, you are running El Capitan (OS X 10.11) or later. 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. …

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

… Any dynamic linker (dyld) environment variables, such as DYLD_LIBRARY_PATH, are purged when launching protected processes.

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

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.

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆