用 Python Egg / Wheel 打包共享对象(库)

Package shared object (library) with Python Egg / Wheel

到目前为止我已经这样做了:

  1. 创建 MANIFEST.in 使用:include path/to/libfoo.so
  2. 创建了 setup.py,在调用 setupt.py install 后将 libfoo.so 放入 /usr/local/lib/python/site-packages/foo.egg/path/to/libfoo.so

当然,这无助于 Python 在 运行 需要时找到 libfoo。我需要做什么才能让 Python 真正找到这个图书馆?

备注

此库没有 Python 绑定,它只是一个包含一些本机代码的共享库。它是从位于 /usr/local/lib/python/site-packages/foo.egg/path/wrapped.cpython-36m-x86_64-linux-gnu.so.

的另一个共享库调用的

如果你想硬编码共享库的位置,你可以使用rpath选项。为此你会做类似的事情..

python setup.py build_ext --rpath=/usr/local/lib/python/site-packages/foo.egg/path/to

其中setup.py是用来构建wrapped.cpython-36m-x86_64-linux-gnu.so的脚本,rpathlibfoo.so的路径 当然你直接放这个应该可以在构建脚本中,取决于该过程的样子。

-rpath=dir

Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime. The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link

如果更新 wrapped.cpython-36m-x86_64-linux-gnu.so 的构建过程不是一个选项,我认为你唯一的选择是将 libfoo.so 放在加载库路径中的某处或手动添加位置 运行-时间。

回答您的一些后续问题...

系统加载库位置来自 /etc/ld.so.conf 并引用 ld.so.conf.d 目录中的位置。 ldconfig 命令根据此数据重建共享库的缓存,因此如果您进行更改,请务必调用此命令。

在命令行或 .bashrc 中,您可以使用 export LD_LIBRARY_PATH=.... 将其他目录添加到搜索路径。

您可以手动加载共享对象。请参阅 https://docs.python.org/2/library/ctypes.html 加载共享库

我自己没试过,但我读到如果你在你的 python 代码中手动加载一个从属共享库,然后导入更高级别的库,链接器就不必去出来并找到较低的那个,因为它已经加载了。这看起来像...

import ctypes
foolib = ctypes.CDLL('/full/path/to/libfoo.so')
import wrapped

Whosebug 上有许多关于如何执行此操作的示例,还有许多关于操作库搜索路径的其他 info/examples。