上下文:可以编译 C 代码,使其可以用作 python 模块。编译后的对象是一个具有特定命名的共享库,因此Python可以找到它并将其作为模块加载。
太棒了。我已经成功编译和测试了代码,使文件“foo.c”成为共享库“foo.so”,并且Python代码
import foo
可以工作。
目标是为 Mac、Linux 和 Windows 分发一组共享库,其中
import foo
加载适当的二进制共享库。
从概念上讲,我希望我的发行版包含一个包含三个文件的目录:
mypkg/
┠─ __init__.py
┠─ foo.so (linux)
┠─ foo.dylib (mac)
┖─ foo.dll (windows)
这样
from mypkg import foo
就会选择合适的库。
我不想想要分发源代码foo.c
。
问题是,Mac 会选择
.so
文件并抱怨:
ImportError: dlopen(/.../mypkg/foo.so, 0x0002): tried: '/.../mypkg/foo.so' (not a mach-o file)
是否有一种模式/命名方案允许这样做(无需编写自定义模块加载器)?
这是通过称为 Wheel 的二进制包分发格式来处理的:https://pythonwheels.com/
当今 Python 生态系统中几乎每个主要库都以轮子格式分发其代码,即使是那些不使用编译扩展的库。
如果您使用与 PEP-517 兼容的构建后端(Setuptools、Flit、Hatch、Poetry),构建轮子就像
pip install build && python -m build
一样简单。这将生成一个具有标准化文件名的轮文件,可以直接上传到 PyPI 进行分发。
但是,这不会处理多个平台的交叉编译。为此,您需要容器或虚拟机之类的东西,或者像cibuildwheel这样的工具。