python - 如何安装 C++ 库的 python 绑定(bind)

标签 python swig setuptools distutils setup.py

想象一下,我们得到了库的完整 C++ 源代码,称为 MyAwesomeLib .目标是向 python 展示它的一些功能,因此我们使用 swig 创建一个包装器并生成一个名为 PyMyAwesomeLib 的 python 包。 .

现在的目录结构是这样的

root_dir
|-src/
|-lib/
|    |- libMyAwesomeLib.so
|    |- _PyMyAwesomeLib.so
|-swig/
|    |- PyMyAwesomeLib.py
|-python/
     |- Script_using_myawesomelib.py

到目前为止一切顺利。理想情况下,我们接下来要做的就是复制 lib/*.so swig/*.pypython/*.py进入site-packages中的对应目录以 pythonic 方式,即使用

python setup.py install

但是,当我尝试使用 setuptools 来实现这个简单的目标时,我感到非常困惑。和 distutils .这两个工具都通过内部系统处理 python 扩展的编译,其中源文件、编译器标志等使用 setup(ext_module=[Extension(...)]) 传递。 .但这很荒谬,因为 MyAsesomeLib具有基于 makefile 的功能齐全的构建系统。移植嵌入到 makefile 中的逻辑将是多余的,而且是完全没有必要的工作。

经过一些研究,似乎还有两个选项,我可以覆盖 setuptools.command.buildsetuptools.command.install使用现有的 makefile 并直接复制结果,或者我可以以某种方式让 setuptools知道这些文件并要求它在安装过程中复制它们。第二种方式更吸引人,但也是最让我头疼的。我尝试了以下选项但没有成功

  • package_data , 和 include_package_data不起作用,因为 *.so 文件不受版本控制,并且它们不在任何包内。
  • data_files似乎不起作用,因为文件仅在运行时包含在内 python setup.py sdist , 但在 python setup.py install 时被忽略.这与我想要的相反。 .so文件不应包含在源代码分发中,而是在安装步骤中复制。
  • MANIFEST.in由于与 data_files 相同的原因而失败.
  • eager_resources也不起作用,但老实说我不知道​​ eager_resources 之间的区别和 data_filesMANIFEST.in .

我认为这其实是一种常见的情况,希望有一个简单的解决办法。任何帮助将不胜感激。

最佳答案

Porting the logic embedded in makefiles would be redundant and completely un-necessary work.

不幸的是,这正是我必须做的。一段时间以来,我一直在为同样的问题而苦苦挣扎。

移植它实际上并不算太糟糕。 distutils does understand SWIG extensions , 但这是他们相当随意地实现的。运行 SWIG 会创建 Python 文件,当前的构建顺序假定在运行 build_ext 之前已经考虑了所有 Python 文件。那个并不难fix ,但令人恼火的是,他们声称支持 SWIG 而没有提及这一点。 Distutils 试图在编译时实现跨平台,因此使用它仍然有优势。

如果您不想移植整个构建系统,请使用系统的包管理器。许多复杂的库都这样做(但他们也尽力使用 setup.py)。例如,要在 Ubuntu 上获取 numpy 和 lxml,您只需执行以下操作: sudo apt-get install python-numpy python-lxml。没有点子。

我知道您宁愿编写一个安装文件也不愿与每个包管理器打交道,所以这可能不是很有帮助。

如果您尝试使用 setuptools 路线,我会遇到一个致命缺陷:依赖项。

例如,如果您要分发基于 SWIG 的项目,它将需要 libpython。如果他们没有,就会发生这样的错误:

#include <Python.h>
error: File not found

这对普通用户来说毫无帮助。

更糟糕的是,如果您需要共享库但用户的库已过时,用户可能会遇到一些疯狂的错误。您受制于他们的 C++ 编译器输出对 Google 友好的错误消息,以便他们可以解决问题。

长期的解决方案是让 setuptools/distutils 更好地检测非 python 库,希望与 Ruby 的 gem 一样好。我几乎不得不自己动手。例如,在这个 setup.py 中我正在努力,你可以在顶部看到一些功能,我一起破解了依赖性检测(仍然不适用于所有系统......绝对不是 Windows)。

关于python - 如何安装 C++ 库的 python 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29200348/

相关文章:

Python:从导入类调用方法

python - 使用 SWIG 绑定(bind) Python/C++ 模板

python - 完整的 setuptools 安装帮助 (Mac)

python-2.7 - 在 mac osx 10.9 上安装 pyobjc

python - 找出用于安装当前包的 Python?

Python - 解决内存泄漏问题

python - Django Rest Framework - 如何测试 ViewSet?

python - 使用 Google App Engine (Python) 的 PDF 缩略图

c++ - 将 SWIG 与 C++ 结合使用

c++ - Lua/SWIG 从 Lua 中包装用户数据