这是 macOS 上的一个常见误解 - macOS 上的库不仅仅通过名称引用,而是通过绝对路径引用。由于这个原因,安装在 /opt/local 中的 MacPorts OpenSSL 不满足 PyPy 附带的库的要求,因为它需要 /usr/local/opt/openssl 中的库。
几天前,我在 macports-users 列表中引用了我自己的一封电子邮件,其中解释了详细信息:
macOS 库是使用其绝对路径从二进制文件中引用的。
在技术层面上,当您在命令行上使用例如 -lcurl 链接二进制文件时,链接器将在您在命令行上提供的搜索路径中找到 libcurl.dylib(应该是 -L/opt/ local/lib 用于 MacPorts)。然后它将从文件中读取库 id。对于我们的 MacPorts 的 libcurl 示例,这是:
$> otool -D /opt/local/lib/libcurl.dylib
/opt/local/lib/libcurl.4.dylib
然后,此路径将被复制到链接的二进制文件中。您可以使用 MacPorts curl 二进制文件来验证这一点:
$> otool -L /opt/local/bin/curl | grep libcurl
/opt/local/lib/libcurl.4.dylib (compatibility version 10.0.0, current version 10.0.0)
当您运行 /opt/local/bin/curl 时,加载程序会读取此表并使用其绝对路径定位此文件。设置 DYLD_LIBRARY_PATH 会覆盖此设置并尝试在 DYLD_LIBRARY_PATH 中给定的目录中找到具有给定基本名称的文件,但如果库和二进制文件已正确构建(并且未移动),则永远不必设置它。
当然,这会使您的二进制文件不可重定位。如果要重定位二进制文件,可以使用特殊变量@loader_path、@executable_path 和@rpath 来使用相对路径。请参阅 dylibbundler 端口,如果您使用 -headerpad_max_install_names 链接器标志(MacPorts 默认情况下)构建二进制文件,它会在很大程度上自动执行此操作。
要解决您的问题,您可以设置 DYLD_FALLBACK_LIBRARY_PATH 并希望这些库是二进制兼容的(它们可能兼容也可能不兼容)或使用install_name_tool -change
(它们的作用相同,但在文件而不是环境中)。但是,您应该询问为您提供此二进制文件的人,他们希望您如何运行它以及从何处获得匹配的 OpenSSL 库。