我正在开发一个C库(使用cmake作为构建系统)和一个用cython编写的相应python扩展。
构建过程由cmake进行,后者调用cython可执行文件以生成C文件。该文件被编译成python_library.so链接 针对本机library.so和其他依赖项。
该库可以正常工作,我可以将PYTHONPATH
设置到构建目录,运行python和import
并执行包装的python代码。
剩下的是关于如何安装/打包python模块的问题。
据我所知,创建python软件包的推荐方法是在setup.py
文件中使用setuptools / distutils。
当然可以在Extension
文件中定义C setup.py
(可选使用cython)。但是,我希望编译由cmake处理(它涉及一些依赖库等)
因此,基本上,我想告诉python,整个包是由现有的python_library.so文件定义的。那有可能吗?
注意:这里有一个related问题。但是OP 已经已经弄清楚了如何打包扩展。
答案 0 :(得分:1)
显然,这不是分发python软件包的最可靠的方法,因为它不适用于不同的操作系统,或者如果存在Python版本不匹配的话,可能会导致奇怪的结果-但这仍然是可能的。
让我们考虑以下文件夹结构:
/
|--- setup.py
|--- my_package
|------- __init__.py
|------- impl.pyx [needed only for creation of impl.so]
|------- impl-XXX.so [created via "cythonize -i impl.pyx"]
具有以下内容:
__ init __。py:
from .impl import foo
impl.pyx:
def foo():
print("I'm foo from impl")
setup.py:
from setuptools import setup, find_packages
kwargs = {
'name':'my_package',
'version':'0.1.0',
'packages':find_packages(),
#ensure so-files are copied to the installation:
'package_data' : { 'my_package': ['*.so']},
'include_package_data' : True,
'zip_safe' : False
}
setup(**kwargs)
现在,在调用python setup.py install
之后,该软件包已安装并可以使用:
>>> python -c "import my_package; my_package.foo()"
I'm foo from impl
注意:不要从带有安装文件的文件夹中调用测试,因为这样不能使用已安装的my_package
本地版本。
您可能想为不同的Python版本使用不同的二进制文件。可以为不同的Python版本编译相同的扩展名-您必须在生成的共享库中添加正确的后缀,例如:
可以使用
获得当前计算机上扩展名的后缀>>> import importlib
>>> importlib.machinery.EXTENSION_SUFFIXES
['.cp36-win_amd64.pyd', '.pyd']