2015-10-16 22 views
8

Ho un modulo Python che chiama un binario esterno, costruito dalla sorgente C.Compilare e installare l'eseguibile C usando python's setuptools/setup.py?

L'origine di tale eseguibile esterno è parte del mio modulo python, distribuito come file .tar.gz.

C'è un modo di decomprimere, quindi compilare quell'eseguibile esterno e installarlo utilizzando setuptools/setup.py?

Quello che mi piacerebbe realizzare è:

  • installazione che binario in ambienti virtuali
  • gestire la compilazione/installazione del binario utilizzando setup.py install, setup.py build ecc
  • rendendo la parte binaria del mio modulo python, in modo che possa essere distribuito come una ruota senza dipendenze esterne
+0

Hai risolto questo problema? Se sì, puoi condividere la tua soluzione? Grazie –

+0

ho fatto alla fine, aggiungerò una risposta a breve. –

risposta

3

risolto alla fine modificando setup.py per aggiungere ulteriori gestori per i comandi che hanno eseguito l'installazione.

Un esempio di setup.py che fa questo potrebbe essere:

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}) 

Ora, quando python setup.py install si chiama, il CustomInstall classe personalizzata viene utilizzato, questo allora compila e installa il software prima della normale vengono eseguiti installare passi.

Puoi anche fare simili per tutti gli altri passaggi che ti interessano (ad esempio build/develop/bdist_egg ecc.).

Un'alternativa è rendere la funzione compile_and_install_software() una sottoclasse di setuptools.Command e creare un comando setuptools completo per esso.

Questo è più complicato, ma consente di fare cose come specificarlo come sottocomando di un altro comando (ad esempio evitare di eseguirlo due volte) e di passare le opzioni personalizzate ad esso nella riga di comando.

Problemi correlati