2017-03-07 102 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),這是我不知道的。 –