wol*_*box 5 c++ python python-extensions pybind11
我正在尝试创建和分发(使用 pip)一个 Python 包,其中包含 Python 代码和使用 Pybind11(使用 Visual Studio 2019)编译为 .pyd 文件的 C++ 代码。我还想包含.pyi 存根文件,用于 VScode 和其他编辑器。我找不到太多关于正确执行此操作的文档。
我希望能够像平常一样通过 pip 安装包,并from mymodule.mysubmodule import myfunc像普通的 Python 包一样编写等,包括使用我编写的 .pyi 文件自动完成、类型注释、VScode 智能感知等。
我的 C++ 代码位于多个 cpp 和头文件中。它使用一些标准库和一些外部库(例如boost)。它定义了一个模块和 2 个子模块。我希望能够在 Windows 和 Linux 上以及 x86 和 x64 上分发它。我目前的目标是 Python 3.9 和 c++17 标准。
我应该如何构建和分发这个包?我是否包含 c++ 源文件,并创建一个类似于Pybind11 示例的 setup.py ?如果是这样,我如何包含外部库?如何构建 .pyi 存根文件?这是否意味着尝试安装我的软件包的人也需要 C++ 编译器?
或者,我应该将我的 c++ 编译为每个平台和架构的 .pyd/.so 文件吗?如果是这样,有没有办法指定通过 pip 安装哪个?再说一次,我将如何构建 .pyi 存根?
.pyi存根pybind11问题提到了几个为二进制模块生成存根的工具(1、2 )。可能还有更多,但我不知道其他人。不幸的是,两者都远非完美,因此您可能仍然需要手动检查和调整生成的存根。
.pyi存根的分布修正存根后,您只需将这些.pyi文件与指示文件一起包含在您的分发中(例如,在轮子中或作为源)py.typed,或者将它们作为独立包单独分发(例如mypackage-stubs)。
Wheels 允许您的库的用户以二进制形式安装它,即无需编译。Wheels 使用较旧的编译器来兼容更多的系统/平台,因此您可能会在使用 C++17 库时遇到一些问题。(C++11 已经足够老了,轮子应该没有问题)。
为各种平台构建轮子是乏味的,pybind11 的python_example使用cibuildwheels包来做到这一点,如果你已经在使用 CI,我会推荐这条路线。
如果目标平台缺少轮子,pip 将尝试从源安装。这需要已安装您正在使用的编译器和第三方库。
如果您的设置很复杂并且需要许多第三方库,那么可能值得编写一个conda 配方并使用conda-forge生成包的二进制版本。Conda 优于 pip,因为它也可以管理非 python 依赖项。