如何在pypi上放置一个swig / pybind11 C ++项目

时间:2017-03-07 19:11:15

标签: python swig pypi pybind11

我的代码包含pybind11swig,但似乎无法找到有关如何在pypi上正确获取该代码的文档,因此我可以pip install我的包。

Pybind11 seems to have issues that make it difficult to put code on pypi

我认为我想要的是为Linux和Linux构建二进制轮。 OSX,但我找不到太多关于此的文档。 Some people do this via travis and scripting我想?是否有即插即用方式为所有发行版制作轮子?

1 个答案:

答案 0 :(得分:3)

很奇怪,你还没有找到任何信息。 distutuis及其较大的兄弟setuptools提供Extension类,允许在安装之前构建二进制Python-C扩展模块,并且任何非Python文件都可以通过{{包含在分发中3}}文件。至于Pybind11,它是一个只有头的库,因此构建一个依赖于它的模块应该没有困难。但是,最好在你的发行版中包含Pybind11头文件(它是十几个不是很大的.h文件),因为据我所知,distutils / setuptools不支持二进制模块的预构建依赖项。 / p>

假设您的头文件(包括Pybind11)位于include目录中,而您的源文件位于src目录中。然后,您的setup.py文件应如下所示:

import os
from setuptools import setup
from setuptools.extension import Extension

this_dir = os.path.dirname(os.path.abspath(__file__))

foo = Extension(
    name='foo',
    include_dirs=[os.path.join(this_dir, 'include')],
    sources=[
        os.path.join(this_dir, 'src', 'foo.cpp'),
        os.path.join(this_dir, 'src', 'bar.cpp')
    ]
)

setup(
    name='foo',
    version='0.0.1',
    author='John Doe',
    description='foo module',
    long_description='blah, blah, blah...',
    url='http://example.com',
    classifiers=[
        # The list of PyPI classifiers
    ],
    ext_modules=[foo],
    zip_safe=False,
    include_package_data=True,
)

您可以添加其他参数,例如宏定义等。 您的MANIFEST.in应如下所示:

recursive-include src *.cpp
recursive-include include *.h

现在您可以按照此处所述发布您的软件包:MANIFEST.in我只能注意到他们关于使用twine的建议仅适用于HTTPS支持较差的古老Python发行版。

现在任何用户都可以通过键入pip install foo在他们的环境中安装您的软件包,只要他们安装了与他们的Python版本兼容的C / C ++编译器。这在Linux上通常没有问题(我不了解Mac),但可能是Windows上的PITA。因此,为了简化安装,您还可以按照上面的打包指南中的说明将预编译的轮子添加到源分发中。您可以使用某些CI(如Travis或Appveyor(基于Windows的CI))自动编译轮子并在PyPI上发布它们。如果PyPI有一个用于目标平台的轮子,它只需解压缩到用户的环境。否则,模块是从源代码编译的(同样,如果兼容的编译器可用,否则构建/安装将失败)。

我不熟悉SWIG,但正如https://packaging.python.org中所述,在编译期间将SWIG包装器转换为C代码也得到本机安装工具的支持。 SWIG包装文件也包含在MANIFEST.in

如果您的二进制Python模块依赖于某些外部预构建库(如Boost或OpenSSL),那么事情会很复杂。正如我所说,setuptools不支持预构建依赖项,并且在Windows上,例如,没有二进制库的中央存储库(尽管Microsoft正试图通过创建vcpkg来修改这种情况)。在这种情况下,您可以在包中包含所有内容,或者为尽可能多的平台提供静态编译的轮子,或以某种方式警告潜在用户他们需要在pip之前安装一些先决条件 - 安装二进制模块。