如何跨多架构部署Python扩展(共享库)?
问题:跨平台分发C编译的Python共享库,无需自定义加载器的方案?
背景
- 可将C代码编译为符合Python识别规则的共享库,已成功将
foo.c编译为foo.so,Python中import foo可正常运行。 - 目标是分发适配Linux、Mac、Windows的共享库集合,让
import foo自动加载对应平台的库,且不暴露foo.c源码。
理想目录结构
mypkg/ ┠─ __init__.py ┠─ foo.so (Linux) ┠─ foo.dylib (Mac) ┖─ foo.dll (Windows)
当前问题
期望from mypkg import foo自动匹配对应平台的库,但Mac环境下会错误加载foo.so并报错:
ImportError: dlopen(/.../mypkg/foo.so, 0x0002): tried: '/.../mypkg/foo.so' (not a mach-o file)
补充说明
不采用PyPI/pip/wheel分发的原因:代码并非运行在标准python.exe进程中。
主程序是支持C插件的C程序,通过自研C插件初始化Python环境(调用Py_Initialize()等接口),将原C API暴露为Python接口,该插件可查找、加载并执行Python插件(无法独立运行),此流程已验证正常工作。
当前需解决的核心场景:Python插件如何引用共享库形式的Python模块,执行流程如下:
main.c -> 1) InitPython 2) PyImport_Import("plugins/a.py") 3) PyImport_Import("plugins/b.py") -> import mypkg.foo ...
若mypkg/foo.py为纯Python代码可正常运行,但foo为共享库时,Linux和Mac都要求命名为foo.so,无法直接以b.py + mypkg/*的形式分发插件。
已尝试pip install --target=plugins foo.whl,同时正在测试一种自定义加载机制(mypkg/foo.py代码如下),目前看似可行,仍在验证:
import os import platform _system = platform.system() from importlib.machinery import ExtensionFileLoader from importlib.utils import spec_from_file_location filename = f'{os.path.dirname(__file__)}/foo.{_system.lower()}.so' _loader = ExtensionFileLoader('foo', filename) _spec = spec_from_file_location('foo', filename) _mod = _loader.create_module(_spec) _loader.exec_module(_mod) from foo import *
核心提问
是否存在无需编写自定义模块加载器的模式/命名方案?
内容的提问来源于stack exchange,提问作者pbuck
相关产品推荐
相关产品推荐

