macOS下为ctypes.util.find_library()指定路径

Specify a path for ctypes.util.find_library() under macOS

我想指定一个路径供ctypes.util.find_library()搜索。我该怎么做?

我想在 Python.

内完成

我正在使用 macOS。

如果我想从外部执行此操作 Python,我可以使用 LD_LIBRARY_PATH 指定位置。但是我已经读到我无法从 Python 中将此环境变量修改为 it is cached on Python's startup。修改值然后重新启动 Python 似乎是一个非常不可用的想法;例如,如果库是在执行过程中导入的,会发生什么情况?

我为什么要这样做?因为我想在 Windows 下工作的 Python 库中添加一个 MacOS 轮子。目前,他们将 DLL 打包到与 Python 源文件相同的目录中,并将该路径添加到 Windows' PATH 环境中,ctypes.util.find_library() 搜索——这是一种我无法使用的技术似乎在 Mac.

下复制

我试图理解 delocate。似乎声明 Python 库不依赖于任何共享对象。我怀疑这是因为动态库是使用 ctypes.util.find_library() 动态加载的,而不是在 Python.

中编译的代码

如有任何建议,我们将不胜感激!

尽管有一些环境变量(LD_LIBRARY_PATHDYLD_LIBRARY_PATH)会影响共享库的搜索路径,但当 Python 启动时,它们会被 Python 读取并修复向上。因此该选项被取消了。

相反,我们采用了 Python documentation 中暗示的方法:

If wrapping a shared library with ctypes, it may be better to determine the shared library name at development time, and hardcode that into the wrapper module instead of using find_library() to locate the library at runtime.

我们 hard-coded 每个操作系统所包含的库的名称,此外我们还为未包含这些库的操作系统提供了一个通用名称:

names = {
    "Windows": "libogg.dll",
    "Darwin": "libogg.0.dylib",
    "external": "ogg"
}

库加载代码检查是否可以为当前操作系统找到指定的库。如果不成功,将搜索 'external' 库。

库加载代码可以在PyOgg项目中找到;参见 Library.load()

此外,受 delocate project 的启发,我们需要编辑在某些动态库中找到的路径。例如,我们编辑 opusfile 二进制文件以指向我们包中的 ogg 二进制文件:

install_name_tool -change /usr/local/opt/libogg/lib/libogg.0.dylib @loader_path/libogg.0.dylib libopusfile.0.dylib

有关此过程的详细信息,请参阅 README file 与 PyOgg 项目中的 macOS 二进制文件相关联。

可以在 PyOgg 的 GitHub 页面 (#32) 上提出的问题中找到对该方法的进一步讨论。