2015-10-16 107 views
8

我有一個python模塊,調用外部二進制文件,從C源構建。使用python的setuptools/setup.py編譯並安裝C可執行文件?

該外部可執行文件的源代碼是我的python模塊的一部分,以.tar.gz文件形式發佈。

有沒有解壓縮的方法,然後編譯該外部可執行文件,並使用setuptools/setup.py安裝它?

我想什麼來實現的是:

  • 安裝二進制到虛擬環境
  • 使用setup.py install管理編譯/安裝二進制的,setup.py build
  • 製作的二進制部分我python模塊,因此它可以作爲一個輪子分發而沒有外部依賴性
+0

你解決了這個問題嗎?如果是這樣,你能分享你的解決方案嗎?謝謝 –

+0

我在最後做了,我會盡快添加一個答案。 –

回答

3

最終通過修改setup.py爲安裝的命令添加額外的處理程序。

一個setup.py這不,這可能是的一個例子:

import os 
from setuptools import setup 
from setuptools.command.install import install 
import subprocess 

def get_virtualenv_path(): 
    """Used to work out path to install compiled binaries to.""" 
    if hasattr(sys, 'real_prefix'): 
     return sys.prefix 

    if hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix: 
     return sys.prefix 

    if 'conda' in sys.prefix: 
     return sys.prefix 

    return None 


def compile_and_install_software(): 
    """Used the subprocess module to compile/install the C software.""" 
    src_path = './some_c_package/' 

    # compile the software 
    cmd = "./configure CFLAGS='-03 -w -fPIC'" 
    venv = get_virtualenv_path() 
    if venv: 
     cmd += ' --prefix=' + os.path.abspath(venv) 
    subprocess.check_call(cmd, cwd=src_path, shell=True) 

    # install the software (into the virtualenv bin dir if present) 
    subprocess.check_call('make install', cwd=src_path, shell=True) 


class CustomInstall(install): 
    """Custom handler for the 'install' command.""" 
    def run(self): 
     compile_and_install_software() 
     super().run() 


setup(name='foo', 
     # ...other settings skipped... 
     cmdclass={'install': CustomInstall}) 

現在,當python setup.py install被調用時,自定義CustomInstall類使用時,該則編譯之前正常的安裝步驟運行安裝軟件。

您也可以對您感興趣的其他任何步驟(例如build/develop/bdist_egg等)進行類似操作。

另一種方法是使compile_and_install_software()函數成爲setuptools.Command的子類,併爲其創建完全成熟的setuptools命令。

這是比較複雜的,但可以讓你做一些事情,比如將其指定爲另一個命令的子命令(例如避免執行兩次),並在命令行中傳遞自定義選項。

相關問題