使用python的setuptools/setup.py编译和安装C可执行文件?

Dav*_*lis 10 python setuptools setup.py python-3.x

我有一个python模块,调用从C源构建的外部二进制文件.

该外部可执行文件的源代码是我的python模块的一部分,以.tar.gz文件的形式发布.

有没有解压缩的方法,然后编译外部可执行文件,并使用setuptools/setup.py安装它?

我想要达到的目标是:

  • 将二进制文件安装到虚拟环境中
  • 使用管理编译/安装二进制的setup.py install,setup.py build等等.
  • 制作我的python模块的二进制部分,以便它可以作为一个轮子分发而没有外部依赖

Dav*_*lis 7

最后通过修改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})
Run Code Online (Sandbox Code Playgroud)

现在,当python setup.py install调用时,使用自定义CustomInstall类,然后在运行正常安装步骤之前编译并安装软件.

您也可以对您感兴趣的任何其他步骤执行类似操作(例如build/develop/bdist_egg等).

另一种方法是使compile_and_install_software()函数成为子类setuptools.Command,并为它创建一个完全成熟的setuptools命令.

这更复杂,但允许您执行诸如将其指定为另一个命令的子命令(例如,避免执行两次)以及在命令行上将自定义选项传递给它的操作.