使用 python 的 setuptools/setup.py 编译和安装 C 可执行文件?
Compiling & installing C executable using python's setuptools/setup.py?
我有一个 python 模块调用外部二进制文件,从 C 源代码构建。
该外部可执行文件的源代码是我的 python 模块的一部分,作为 .tar.gz 文件分发。
有没有办法解压缩,然后编译外部可执行文件,并使用 setuptools/setup.py 安装它?
我想实现的是:
- 将该二进制文件安装到虚拟环境中
- 使用
setup.py install
、setup.py build
等 管理二进制文件的 compilation/installation
- 制作我的 python 模块的二进制部分,以便它可以作为一个没有外部依赖项的轮子分发
最后通过修改 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
class,然后在正常安装步骤 运行 之前编译和安装软件。
您也可以对您感兴趣的任何其他步骤执行类似操作(例如 build/develop/bdist_egg 等)。
另一种方法是使 compile_and_install_software()
函数成为 setuptools.Command
的子 class,并为其创建一个完全成熟的 setuptools 命令。
这更复杂,但可以让您做一些事情,比如将它指定为另一个命令的子命令(例如避免执行两次),并在命令行上将自定义选项传递给它。
我有一个 python 模块调用外部二进制文件,从 C 源代码构建。
该外部可执行文件的源代码是我的 python 模块的一部分,作为 .tar.gz 文件分发。
有没有办法解压缩,然后编译外部可执行文件,并使用 setuptools/setup.py 安装它?
我想实现的是:
- 将该二进制文件安装到虚拟环境中
- 使用
setup.py install
、setup.py build
等 管理二进制文件的 compilation/installation
- 制作我的 python 模块的二进制部分,以便它可以作为一个没有外部依赖项的轮子分发
最后通过修改 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
class,然后在正常安装步骤 运行 之前编译和安装软件。
您也可以对您感兴趣的任何其他步骤执行类似操作(例如 build/develop/bdist_egg 等)。
另一种方法是使 compile_and_install_software()
函数成为 setuptools.Command
的子 class,并为其创建一个完全成熟的 setuptools 命令。
这更复杂,但可以让您做一些事情,比如将它指定为另一个命令的子命令(例如避免执行两次),并在命令行上将自定义选项传递给它。