如何提高基于PyO3的库在不同Python版本间的可移植性?
我在我的系统上用PyO3创建了一个库,使用的是Python 3.5.2。这个库的.so文件链接到了对应的libpython3.5m文件:
$ ldd my_library.so
linux-vdso.so.1 => (0x00007ffffc823000)
libpython3.5m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0 (0x00007fcac34b0000)
...
但是,如果我想在另一个系统上使用我的库,而那个系统的Python版本是不同的小版本(比如3.6.9或3.7.3),那么就找不到这个库:
$ ldd my_library.so
linux-vdso.so.1 (0x00007fffefaae000)
libpython3.5m.so.1.0 => not found
...
因此,我就不能使用我的库了:
$ python3
Python 3.6.9 (default, Apr 18 2020, 01:56:04)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_library
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: libpython3.5m.so.1.0: cannot open shared object file: No such file or directory
有没有办法让我这个库能更通用地链接到libpython,这样就能适应这些小版本的变化,或者至少允许向后兼容(在新版本上构建,但也能让旧版本的Python使用我的库)?或者我在运行时能做些什么,让这个库仍然可以正常工作?
相关问题:
- 暂无相关问题
1 个回答
2
Python 的扩展模块根本不应该链接到 libpython。这样做的话,Python 的符号会保持未解决状态,动态加载器会在加载这个模块的 Python 解释器中查找这些符号。这样一来,你甚至可以在一个静态链接的 Python 中使用你的模块!
rust-cpython 有一个 extension-module
的功能,而 PyO3 似乎也借鉴了这个功能。你可以在你的 Cargo.toml 文件中启用它:
[dependencies]
pyo3 = { version = ..., features = [ "extension-module" ] }