2017-03-07 105 views
1

我有代码包裹着两个pybind11swig,但似乎无法找到如何正确获取PyPI上的代码,所以我可以pip install我的包文档。如何把一大口/ pybind11 C++项目PyPI上

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

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

回答

1

很奇怪,你还没有找到任何信息。 distutuis及其更大的兄弟setuptools提供了Extension类,允许在安装之前构建二进制Python-C扩展模块,并且任何非Python文件都可以通过MANIFEST.in文件包含在发行版中。至于Pybind11,这是一个只有头文件的库,所以建立一个依赖它的模块应该没有困难。然而,最好在你的发行版中包含Pybind11头文件(大约有12个不是很大的文件),因为据我所知,distutils/setuptools不支持二进制模块的预构建依赖关系。

我们假设您的头文件(包括Pybind11)位于include dir中,并且您的源文件位于src dir中。然后你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 

现在,你可以发布你的包如下所述:https://packaging.python.org我只能指出,他们如何使用twine建议仅适用于HTTPS支持不好古Python发行有效。

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

我对SWIG并不熟悉,但如documentation所述,在编译过程中将SWIG包装转换为C代码时,本身也支持setuptools。 SWIG包装文件也包含在MANIFEST.in中。

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

+0

嗨罗马, 非常感谢这个伟大的答案!您是否介意阐述“distutils/setuptools不支持二进制模块的预构建依赖关系”。这可能正是我遇到的问题。 –

+0

pip在引擎盖下使用'setuptools',并且在下载软件包源代码(对于轮子,过程略有不同)下运行'python setup.py build install'。对于纯Python发行版,'build'意味着简单地将所有内容复制到'/ build/lib/目录中,但对于二进制模块,'build'步骤意味着使用编译器的实际构建。所以'install_requires ='只能在'install'步骤工作,并且据我所知,没有'build_requires'参数可以指定** build **依赖关系。 –

+0

实际上,在我正在使用的[setuptools](http://setuptools.readthedocs.io/en/latest/setuptools.html)中*有一个'setup_requires'。当我尝试在除我以外的其他平台上构建车轮时,我仍然收到[此错误](https://travis-ci.org/fraenkel-lab/pcst_fast/jobs/219742904),这是我不知道的。 –