【问题标题】:How to include external library with python wheel package如何在 python wheel 包中包含外部库
【发布时间】:2014-07-17 22:42:36
【问题描述】:

我想使用 cffi 模块在 Linux 上创建嵌入并使用外部库 (.so) 的 Python 包。

有没有标准的方法将 .so 文件包含到 python 包中?

该包将仅在内部使用,不会发布到 pypi。

我认为 Wheel 包是最好的选择 - 它们会创建特定于平台的包,其中所有文件都准备好复制,因此无需在目标环境上构建任何东西。

【问题讨论】:

  • 您是否尝试为您拥有的包创建轮子?很有可能,它会在其中包含所需的文件(但我不确定)。
  • 我尝试为包构建轮子 - 它包含由 cffi 创建的 .so 文件,该文件链接到外部库,但不链接到外部库本身。
  • 我想我会将 .so 库打包成 rpm 包(如果需要,这也可以让我从源代码重新编译它们)

标签: python shared-libraries python-wheel python-cffi


【解决方案1】:

您可以使用auditwheel 将外部库注入车轮:

auditwheel 修复:将这些外部共享库复制到轮子本身,并自动修改适当的 RPATH 条目,以便在运行时拾取这些库。这实现了类似于库已被静态链接而无需更改构建系统的结果。建议打包者捆绑,如静态链接,可能涉及版权问题。

您可以通过通常执行以下操作来预构建外部 c++ 库:

./configure && make && make install

这将生成一个my_external_library.so 文件并将其安装在适当的路径中。但是,您需要确保正确设置库路径,以便审计轮发现缺失的依赖项。

export LD_LIBRARY_PATH=/usr/local/lib

然后您可以通过执行以下命令来构建 python 轮:

python setup.py bdist_wheel

最后,您可以修复轮子,这会将my_external_library.so 注入到包中。

auditwheel repair my-python-wheel-1.5.2-cp35-cp35m-linux_x86_64.whl

我成功地将上述步骤应用于 python 库confluent-kafka-python,该库对librdkafka 具有必需的 c/c++ 依赖项。


注意:auditwheel 仅适用于 Linux。对于 MacOS,请参阅 delocate 工具。

【讨论】:

  • 感谢您的提示。 auditwheel 来自 pypa (Python Packaging Authority) - 他们应该知道自己在做什么 :)
  • 有人试过吗?制造特定于手臂的轮子有什么好处吗?
  • auditwheel 不是为了制造轮子,而是为了让它们符合manylinux。 arm 不是一个与 manylinux 兼容的平台,所以它不会帮助你。但是,例如,使用 setuptools 可以构建一个可能与某些外部事物相关联的非 manylinux 轮子。
【解决方案2】:

Wheels 是分发 Python 包的标准方式,但是当您的扩展模块依赖于其他 so 时,就会出现问题。这是因为使用了普通的 Linux 动态链接器,它只在 /usr/lib 或 /usr/local/lib 中查找。这是在virtualenv 中安装轮子时出现的问题。

据我所知,您有三种选择:

  • 静态链接,因此“包装器”不依赖于其他任何东西;
  • 使用ctypes 直接从Python 包装so;
  • 使用 Python 代码和包装器将分发分成一个轮子,以及一个单独的 RPM 或 DEB 以将其安装到 /usr/lib 或 /usr/local/lib。

如果您将依赖的so 作为要存储在/lib 中的数据文件并安装到根 Python 环境中(尚未尝试过),则轮可能可以工作,但这如果有人尝试将轮子安装到 virtualenv 中(确实尝试过),则会损坏。

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 2016-11-26
    • 2011-01-21
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多