想象一下,我们得到了库的完整 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/*.py
和 python/*.py
进入site-packages
中的对应目录以 pythonic 方式,即使用
python setup.py install
但是,当我尝试使用 setuptools
来实现这个简单的目标时,我感到非常困惑。和 distutils
.这两个工具都通过内部系统处理 python 扩展的编译,其中源文件、编译器标志等使用 setup(ext_module=[Extension(...)])
传递。 .但这很荒谬,因为 MyAsesomeLib
具有基于 makefile 的功能齐全的构建系统。移植嵌入到 makefile 中的逻辑将是多余的,而且是完全没有必要的工作。
经过一些研究,似乎还有两个选项,我可以覆盖 setuptools.command.build
和 setuptools.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_files
或MANIFEST.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/