[英]How to install python binding of a C++ library
成像我們獲得了一個名為MyAwesomeLib
的庫的C ++源代碼。 目標是將其部分功能暴露給python,因此我們使用swig創建一個包裝器並生成一個名為PyMyAwesomeLib
的python包。
目錄結構現在看起來像
root_dir
|-src/
|-lib/
| |- libMyAwesomeLib.so
| |- _PyMyAwesomeLib.so
|-swig/
| |- PyMyAwesomeLib.py
|-python/
|- Script_using_myawesomelib.py
到現在為止還挺好。 理想情況下,我們接下來要做的就是將lib/*.so
swig/*.py
和python/*.py
以pythonic方式復制到site-packages
中的相應目錄中,即使用
python setup.py install
但是,當我嘗試使用setuptools
和distutils
實現這個簡單的目標時,我感到非常困惑。 這兩個工具都通過內部系統處理python擴展的編譯,其中源文件,編譯器標志等使用setup(ext_module=[Extension(...)])
傳遞。 但這很荒謬,因為MyAsesomeLib
有一個基於makefile的功能完備的構建系統。 移植嵌入在makefile中的邏輯將是多余的並且是完全不必要的工作。
經過一些研究,似乎還有兩個選項,我可以覆蓋setuptools.command.build
和setuptools.command.install
來使用現有的makefile並直接復制結果,或者我可以以某種方式讓setuptools
知道這些文件並詢問它在安裝過程中復制它們。 第二種方式更具吸引力,但它讓我頭疼。 我嘗試了以下選項但沒有成功
package_data
和include_package_data
不起作用,因為* .so文件不受版本控制,並且它們不在任何包內。 data_files
似乎不起作用,因為文件僅在運行python setup.py sdist
時包含,但在python setup.py install
時被忽略。 這與我想要的相反。 .so
文件不應包含在源代碼發行版中,而是在安裝步驟中復制。 MANIFEST.in
失敗的原因與data_files
相同。 eager_resources
也不起作用,但說實話,我不知道eager_resources
和data_files
或MANIFEST.in
之間的區別。 我認為這實際上是一種常見的情況,我希望有一個簡單的解決方案。 任何幫助將不勝感激。
移植嵌入在makefile中的邏輯將是多余的並且是完全不必要的工作。
不幸的是,這正是我必須要做的。 我一直在努力解決同樣的問題。
移植它實際上並不是太糟糕。 distutils確實理解SWIG擴展 ,但這是他們相當隨意地實現的。 運行SWIG創建Python文件,當前構建順序假定在運行build_ext
之前已考慮所有Python文件。 那個並不難解決 ,但是他們聲稱支持SWIG而不提這個就很煩人。 Distutils在編譯時試圖成為跨平台的,因此使用它仍然是一個優勢。
如果您不想移植整個構建系統,請使用系統的包管理器。 許多復雜的庫都這樣做(但他們也嘗試使用setup.py)。 例如,要在Ubuntu上獲取numpy和lxml,你只需要: sudo apt-get install python-numpy python-lxml
。 沒有點子。
我意識到你寧願寫一個設置文件,而不是處理每個包管理器,所以這可能不是很有幫助。
如果你試圖去setuptools路線,我遇到了一個致命的缺陷:依賴。
例如,如果您要分發基於SWIG的項目,那么它將需要libpython。 如果他們沒有,會發生這樣的錯誤:
#include <Python.h>
error: File not found
這對普通用戶來說非常無益。
更糟糕的是,如果您需要共享庫但用戶的庫已過期,則用戶可能會遇到一些瘋狂的錯誤。 您可以使用他們的C ++編譯器來輸出Google友好的錯誤消息,以便他們能夠解決這個問題。
長期解決方案是讓setuptools / distutils更好地檢測非python庫,希望與Ruby的gem一樣好。 我幾乎不得不自己動手。 例如,在我正在開發的這個setup.py中 ,你可以看到頂層的一些函數我一起入侵以進行依賴項檢測(仍然無法在所有系統上運行......絕對不是Windows)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.