假设我有一个独立于任何 Python 机制构建的本机共享库(.dll 或 .so),以及一个使用 ctypes 与该库交互的 Python 模块。有没有办法可以将它们构建到 .whl 包中?如果是这样,怎么办?
假设这是可能的,我想我需要安装wheel包并使用
python setup.py bdist_wheel
但是我的setup.py需要是什么样子?
我想这样做,这样我就可以将各种平台的 Wheels 上传到私有包索引中,并能够 pip 安装适合我所在平台的合适的轮子。
这里有一个方法。例如,这使用 libeay32.dll 公开 md5 包。
项目结构为:
MD5
│ setup.py
│
└───md5
__init__.py
libeay32.dll
setup.py 是:
from setuptools import setup, Distribution
class BinaryDistribution(Distribution):
def has_ext_modules(foo):
return True
setup(
name='md5',
version='1.0',
description='MD5 Library',
packages=['md5'],
package_data={
'md5': ['libeay32.dll'],
},
distclass=BinaryDistribution
)
有几点需要注意:
Python ctypes 代码可以加载相对于自身的 DLL(此代码位于
__init.py__
):
lib_path = os.path.join(os.path.dirname(__file__), 'libeay32.dll')
lib = CDLL(lib_path)
使用 pip 安装“wheel”后,我可以运行
python setup.py bdist_wheel
来生成 dist\md5-1.0-cp34-none-win32.whl。我碰巧正在使用 cpython 3.4
,但如果您想要万向轮,您可以将 options={"bdist_wheel": {"universal": True}}
添加到设置调用中。
现在我可以创建并激活一个新的虚拟环境:
pip install md5-1.0-cp34-none-win32.whl
并使用我的包:
>>> import md5
>>> md5.digest('hello')
'8d11aa0625ce42cfe9429d5e93b5ab0a'
使用
cibuildwheel
,这是pypa
背后的团队pip
的解决方案。
cibuildwheel
可以用原生库构建wheel,它会自动修复像LD_LIBRARY_PATH
这样的问题,并将dll/so文件合并到bdistwheel中。