【问题标题】:Package shared object (library) with Python Egg / Wheel用 Python Egg / Wheel 打包共享对象(库)
【发布时间】:2018-01-24 16:00:43
【问题描述】:

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

  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 中的另一个共享库调用的。

【问题讨论】:

    标签: python shared-libraries setuptools


    【解决方案1】:

    如果你想硬编码共享库的位置,你可以使用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=目录

    将目录添加到运行时库搜索路径。这用于 将 ELF 可执行文件与共享对象链接。所有 -rpath 参数 被连接起来并传递给运行时链接器,运行时链接器使用它们来 在运行时定位共享对象。 -rpath 选项也用于 明确定位共享对象需要的共享对象 包含在链接中

    如果不能选择更新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
    

    在 StackOverflow 上有很多关于如何做到这一点的示例,还有很多关于操作库搜索路径的附加信息/示例。

    【讨论】:

    • 这是很好的信息,对我有很大帮助,但我仍然有疑问:运行时库搜索路径的默认值是多少?对我来说,安排它使库位于默认位置比尝试更改此设置更容易。 (2) 我尝试将库放在ld 可以找到它的地方:这并没有帮助 Python 找到它。 (3) 如何手动加载?我查看了 Cthon 生成的wrapped.py,但它太神秘了/我不确定它到底是做什么的。
    • 对上述问题的答案添加到原始答案中。
    • 我想我应该说,看起来这里的解决方案可能变得比他们需要的更复杂。查看一个已安装的 python 项目,其中包含多个共享库。查看__init__.py 文件,您可以获得一些加载子组件的示例,这些示例可能对您有用。
    • 最后,我认为问题出在特定的链接器上,它在创建共享库时还将搜索路径编码到被链接到正在编译的库中的库中,这就是为什么放例如,/usr/lib 中的共享对象不起作用。最后,我通过硬编码所需的库位置并让安装脚本将其移动到那里来使它工作。当然,这使得它不能跨平台,也不能安装在自定义位置......(续)
    • setuptools 的文档真的很糟糕,即使有可能以某种方式编写更通用的设置脚本,它肯定从未提到过。至于“其他项目和他们的__init__.py - 我已经做到了......这是一个可怕的混乱,它只在某些时候有效。大多数需要额外共享库的Python项目在Windows或@ 987654341@,或使用pip --user 或使用不同的setup.py install 选项......这是一个非常糟糕的基础设施规划......
    猜你喜欢
    • 2013-07-03
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    相关资源
    最近更新 更多