可以在 Mac OS X 上使用 DYLD_LIBRARY_PATH 吗?还有,它的动态库搜索算法是什么?

发布于 2024-09-07 05:02:35 字数 385 浏览 5 评论 0原文

我读到一些文章不鼓励使用 DYLD_LIBRARY_PATH,因为动态库的路径应该使用 -install_name、@rpath 和 @loader_path 来修复。

就制作一个同时在 Linux 和 Mac OS X 上运行的程序而言,Mac OS X 的 DYLD_LIBRARY_PATH 与 Linux 的 LD_LIBRARY_PATH 完全相同。而且,我们可以共享(几乎)相同的没有 -install_name 和 @rpath 的 make 文件。

  • 在 Mac OS X 上使用 DYLD_LIBRARY_PATH 可以吗?
  • 当二进制文件找不到动态库时,Mac OS X 的动态库搜索算法是什么?当前目录-> DYLD_LIBRARY_PATH 目录...?

I read some articles discouraging of the use of DYLD_LIBRARY_PATH, as the the path of dynamic library should be fixed using -install_name, @rpath, and @loader_path.

In terms of making a program that runs both on Linux and Mac OS X, DYLD_LIBRARY_PATH of Mac OS X does exactly what LD_LIBRARY_PATH of Linux. And, we can share (almost) the same make file that doesn't have the -install_name and @rpath.

  • Is this OK to use DYLD_LIBRARY_PATH on Mac OS X?
  • What's the dynamic library search algorithm with Mac OS X when the binary can't find the dynamic library? current directory -> DYLD_LIBRARY_PATH directories ... ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南风起 2024-09-14 05:02:35

正如您所注意到的,DYLD_LIBRARY_PATH 的行为类似于其他 *nix 上的 LD_LIBRARY_PATH。但是,您应该查看另一个名为 DYLD_FALLBACK_LIBRARY_PATH 的环境变量。

一般来说,这些(在 osx 和 linux 上)仅建议用于开发用途,因为当您使用不具有相同符号表的库覆盖时,它们可能会导致符号查找错误。一个很好的例子是当您尝试使用自定义安装覆盖 VecLib(例如 blas lapack)的默认安装时。如果设置了 DYLD_LIBRARY_PATH,这将导致链接到系统 VecLib 的应用程序中出现符号未找到错误,如果未设置,则相反(自定义应用程序中的符号查找错误)。这是由于系统 blas/lapack 不是 ATLAS 库的完整实现。

DYLD_FALLBACK_LIBRARY_PATH 不会产生这些问题。

将库安装到非标准位置时,DYLD_FALLBACK_LIBRARY_PATH 更加理智。这将在默认路径中提供的库中查找符号,如果在那里找不到该符号,则回退到指定的路径。

好处是,此过程不会在针对默认库编译的应用程序中导致符号查找错误。

一般来说,当库安装到非标准位置时,应该指定绝对路径,这可以消除动态查找的歧义。

As you've noted, DYLD_LIBRARY_PATH behaves like LD_LIBRARY_PATH on other *nix. However, there is another environment variable you should look at called DYLD_FALLBACK_LIBRARY_PATH.

In general, these are (both on osx and linux) suggested only for development use as they can cause symbol lookup errors when you override with a library that does not have the same symbol table. A good example of this is when you attempt to override the default install of VecLib (e.g. blas lapack) with a custom install. This will cause symbol not found errors in applications linked to the system VecLib if DYLD_LIBRARY_PATH is set and the reverse (symbol lookup errors in custom applications) if it is not. This is due to the system blas/lapack not being a full implementation of the ATLAS libs.

DYLD_FALLBACK_LIBRARY_PATH will not produce these problems.

When installing libraries to a non-standard location, DYLD_FALLBACK_LIBRARY_PATH is much more sane. This will look for symbols in libraries provided in the default paths and if the symbol is not found there, fall back to the specified path.

The benefit is that this process will not cause symbol lookup errors in applications compiled against the default libraries.

In general, when libraries are installed to non-standard locations absolute paths should be specified which negates the ambiguity of the dynamic lookup.

爱已欠费 2024-09-14 05:02:35

DYLD_LIBRARY_PATH 的行为与 LD_LIBRARY_PATH 不同。 OS X dlopen 文档 (https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/dlopen.3.html)指定提供绝对路径时,会首先查找在 DYLD_LIBRARY_PATH 指定的位置:

当路径包含斜杠但不是框架路径(即 dylib 的完整路径或部分路径)时,
dlopen() 搜索以下内容,直到找到兼容的 Mach-O 文件: $DYLD_LIBRARY_PATH(带有叶
name from path ),然后是提供的路径(使用当前工作目录作为相对路径),然后
$DYLD_FALLBACK_LIBRARY_PATH(带有路径中的叶名称)。

换句话说,如果将 DYLD_LIBRARY_PATH 设置为 /Hello,则以下两个 dlopen 调用:

dlopen("/Hello/libfoo.so", RTLD_NOW);
dlopen("/World/libfoo.so", RTLD_NOW);

都将解析为 /Hello/libfoo .so.这是相当违反直觉的,并且代表了一个安全漏洞。使用 dlopen 的软件无法保证它加载正确的库(也许在其自己的环境中覆盖 DYLD_LIBRARY_PATH ?)

DYLD_LIBRARY_PATH does not behave like LD_LIBRARY_PATH. The OS X dlopen documentation (https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/dlopen.3.html) specifies that when providing an absolute path, it will first look in locations specified by DYLD_LIBRARY_PATH:

When path contains a slash but is not a framework path (i.e. a full path or a partial path to a dylib),
dlopen() searches the following until it finds a compatible Mach-O file: $DYLD_LIBRARY_PATH (with leaf
name from path ), then the supplied path (using current working directory for relative paths), then
$DYLD_FALLBACK_LIBRARY_PATH (with leaf name from path ).

In other words, if you set DYLD_LIBRARY_PATH to /Hello, the following two dlopen calls:

dlopen("/Hello/libfoo.so", RTLD_NOW);
dlopen("/World/libfoo.so", RTLD_NOW);

will both resolve to /Hello/libfoo.so. This is quite counter-intuitive, and represents a security vulnerability. Software using dlopen has no way to guarantee it is loading the correct libraries (perhaps override DYLD_LIBRARY_PATH in its own environment?)

彼岸花ソ最美的依靠 2024-09-14 05:02:35

有关动态链接编辑器的环境变量以及它们如何影响动态库搜索的文档,man dyld

DYLD_LIBRARY_PATH

这是一个用冒号分隔的包含库的目录列表。动态链接器在搜索库的默认位置之前先搜索这些目录。它允许您测试现有库的新版本。

对于程序使用的每个库,动态链接器会依次在 DYLD_LIBRARY_PATH 中的每个目录中查找它。如果仍然找不到该库,则会依次搜索 DYLD_FALLBACK_FRAMEWORK_PATH 和 DYLD_FALLBACK_LIBRARY_PATH。

使用 otool(1) 的 -L 选项。发现可执行文件链接的框架和共享库
反对。

DYLD_FALLBACK_LIBRARY_PATH

这是一个用冒号分隔的包含库的目录列表。它用作安装路径中未找到的库的默认位置。默认情况下,它设置为 $(HOME)/lib:/usr/local/lib:/lib:/usr/lib。

DYLD_VERSIONED_LIBRARY_PATH

这是一个以冒号分隔的目录列表,其中包含潜在的覆盖库。动态链接器在这些目录中搜索动态库。对于找到的每个库,dyld 都会查看其 LC_ID_DYLIB 并获取 current_version 和安装名称。 Dyld 然后在安装名称路径中查找库。每当需要具有该安装名称的 dylib 时,都会在进程中使用 current_version 值较大的那个。这与 DYLD_LIBRARY_PATH 类似,只是它并不总是覆盖,而是仅在提供的库较新时覆盖。

For documentation on the dynamic link editor's environment variables and how they affect the search for dynamic libraries, man dyld.

DYLD_LIBRARY_PATH

This is a colon separated list of directories that contain libraries. The dynamic linker searches these directories before it searches the default locations for libraries. It allows you to test new versions of existing libraries.

For each library that a program uses, the dynamic linker looks for it in each directory in DYLD_LIBRARY_PATH in turn. If it still can't find the library, it then searches DYLD_FALLBACK_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH in turn.

Use the -L option to otool(1). to discover the frameworks and shared libraries that the executable is linked
against.

DYLD_FALLBACK_LIBRARY_PATH

This is a colon separated list of directories that contain libraries. It is used as the default location for libraries not found in their install path. By default, it is set to $(HOME)/lib:/usr/local/lib:/lib:/usr/lib.

DYLD_VERSIONED_LIBRARY_PATH

This is a colon separated list of directories that contain potential override libraries. The dynamic linker searches these directories for dynamic libraries. For each library found dyld looks at its LC_ID_DYLIB and gets the current_version and install name. Dyld then looks for the library at the install name path. Whichever has the larger current_version value will be used in the process whenever a dylib with that install name is required. This is similar to DYLD_LIBRARY_PATH except instead of always overriding, it only overrides is the supplied library is newer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文