2015-10-16 2 views
8

У меня есть модуль python, который вызывает внешний двоичный код, построенный из источника C.Компиляция и установка C исполняемого файла с помощью pinton setuptools/setup.py?

Источник для этого внешнего исполняемого файла является частью моего модуля 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.

Это сложнее, но позволяет делать такие вещи, как указывать его как подкоманду другой команды (например, не выполнять ее дважды) и передавать в нее специальные параметры в командной строке.

Смежные вопросы