我有相当大的 C++ 库和几个支持它的子库,我需要把整个东西变成一个 python 扩展。我使用 distutils 是因为它需要跨平台,但如果有更好的工具,我愿意接受建议。
有没有办法让 distutils 首先编译子库,然后在从主库创建扩展时链接它们?
我在我们的产品中使用了一个庞大的 C++ 库来做到这一点。有几种工具可以帮助您自动完成编写绑定的任务:最流行的是SWIG,它已经存在了一段时间,在很多项目中都使用过,并且通常效果很好。
SWIG 最大的问题(在我看来)是 SWIG 本身的 C++ 代码库,委婉地说真的相当笨拙。它是在 STL 之前编写的,并且有它自己的半动态类型系统,现在只是陈旧而摇摇欲坠。除非您不得不陷入困境并对核心进行一些修改(我曾经尝试添加 doxygen -> docstring 转换),否则这无关紧要,但如果您这样做了,祝您好运!人们还说 SWIG 生成的代码效率不高,这可能是真的,但对我来说,我从来没有发现 SWIG 调用自己足以成为担心它的瓶颈。
如果 SWIG 不能让你的船浮起来,你可以使用其他工具:boost.python也很流行,如果你已经在 C++ 代码中使用了 boost 库,它可能是一个不错的选择。缺点是编译时间很长,因为它几乎都是基于 c++ 模板的。
这两种工具都要求您预先做一些工作,以定义将要公开的内容以及如何完成。对于 SWIG,您提供的接口文件类似于 C++ 头文件,但被剥离了,并带有一些额外的指令来告诉 SWIG 如何翻译复杂类型等。编写这些接口可能很乏味,因此您可能希望查看pygccxml 之类的东西来帮助您为您自动生成它们。
该软件包的作者实际上编写了另一个您可能喜欢的扩展:py++。这个包做了两件事:它可以自动生成绑定定义,然后可以将其提供给 boost.python 以生成 python 绑定:基本上它是大多数人的完整解决方案。如果您没有特别特殊或难以满足的要求,您可能想从那里开始。
其他一些可能作为参考有用的问题:
您可能还会发现这个Python 绑定生成工具的比较很方便。正如亚历克斯在评论中指出的那样,它现在已经相当老了,但至少让你对风景有了一些了解......
在如何驱动构建方面,您可能希望查看一个更高级的构建工具 distutils:如果您想坚持使用 Python,我强烈推荐Waf作为框架(其他人会告诉您SCons是要走的路,但请相信我,它的速度非常慢:我已经去过那里又回来了!)......这需要一点学习,但是当你了解它时,它会非常强大。而且由于它是纯 Python,它将与您在构建过程中拥有的任何其他 Python 代码完美集成(例如,您最终使用 Py++)...