【问题标题】:Compiling & installing C executable using python's setuptools/setup.py?使用 python 的 setuptools/setup.py 编译和安装 C 可执行文件?
【发布时间】:2016-01-15 02:07:46
【问题描述】:

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

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

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

我想要实现的是:

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

【问题讨论】:

  • 这个问题你解决了吗?如果是这样,你能分享你的解决方案吗?谢谢
  • 我最后做了,我会尽快添加答案。

标签: python python-3.x setuptools setup.py


【解决方案1】:

最终通过修改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 命令。

这更复杂,但可以让你做一些事情,比如将它指定为另一个命令的子命令(例如避免执行两次),并在命令行上将自定义选项传递给它。

【讨论】:

    猜你喜欢
    • 2015-03-02
    • 2011-08-09
    • 1970-01-01
    • 2013-12-05
    • 2013-05-20
    • 2013-07-22
    • 1970-01-01
    • 2014-04-16
    相关资源
    最近更新 更多