繁体   English   中英

与从python 3.5.2源构建的libpython3.5m.so相比,libpython3.so是什么?

[英]What is libpython3.so compared with libpython3.5m.so built from python 3.5.2 source?

在我的应用程序中,我使用boost_python和python 3.5.2。 全部由Ubuntu 14。

当我在Ubuntu中使用--with-shared选项从源代码构建Python 3.5.2时,我得到了libpython3.so (7.6kB)和libpython3.5m.so (12MB)。 我认为大的是真实的,小的可能是将呼叫转发到真实接口的东西。

由于boost_python可能假设客户端要链接到python( https://svn.boost.org/trac/boost/ticket/2615 ),所以我将libpython3.so与我的应用程序链接了。 但是,当我运行它时,出现了无法解析的符号错误。

ldd -r myappldd -r libboost_python.so都列出了所有未解析的python符号,这些符号可以在nm -D libpython3.5m.so找到。

# ldd -r lib/libboost_python3.so
    linux-vdso.so.1 => (0x00007ffe767fb000)
    libstdc+.so.6 => /usr/lib/x86_64-linux-gnu/libstdc+.so.6 (0x00007f130a7a3000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f130a58d000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f130a1c8000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1309ec2000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f130acf4000)
undefined symbol: PyExc_ImportError (lib/libboost_python3.so)
undefined symbol: PyProperty_Type (lib/libboost_python3.so)
undefined symbol: PyExc_StopIteration (lib/libboost_python3.so)
undefined symbol: PyBool_Type (lib/libboost_python3.so)
undefined symbol: PyExc_ValueError (lib/libboost_python3.so)
undefined symbol: PyList_Type (lib/libboost_python3.so)
undefined symbol: _Py_NotImplementedStruct (lib/libboost_python3.so)
undefined symbol: PyExc_TypeError (lib/libboost_python3.so)
undefined symbol: PyDict_Type (lib/libboost_python3.so)
...

libpython3.so依赖于libpython3.5m.so但本身没有这些符号。

我认为基于此,我应该将我的应用程序与libpython3.5m.so链接,而不是与libpython3.so 但是很奇怪的是,如果我使用LD_PRELOAD加载libpython3.so,那么这些符号可以在ldd -r libboost_python3.so中找到

# LD_LIBRARY_PATH=lib LD_PRELOAD=lib/libpython3.so ldd -r lib/libboost_python3.so
    linux-vdso.so.1 => (0x00007ffcb51f0000)
    lib/libpython3.so (0x00007f6f728e3000)
    libstdc+.so.6 => /usr/lib/x86_64-linux-gnu/libstdc+.so.6     (0x00007f6f725df000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6f723c9000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6f72004000)
    libpython3.5m.so.1.0 => lib/libpython3.5m.so.1.0 (0x00007f6f71ae1000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0     (0x00007f6f718c3000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6f715bd000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f6f72d32000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6f713b9000)
    libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f6f711b6000)

为什么要拥有libpython3.so以及如何使用它? 还是只直接使用libpython3.5m.so

libpython3.so库在那里支持PEP 384-定义稳定的ABI

从历史上看,Python不能保证次要版本之间(例如3.4和3.5之间)的C级ABI稳定性。 它们可能是源兼容的,但是某些结构可能会更改大小,或者结构成员会更改类型等。但是,ABI的某些部分已经成熟并且可以在更长的时间内保持稳定。

稳定的ABI PEP确定了Python C API的一个子集,如果开发人员致力于维护该子集的二进制兼容性,那么该子集不会对未来的Python开发施加不适当的限制。 如果程序或扩展将自身限制为仅使用此子集,则理论上可以在不重新编译的情况下跨不同的Python版本使用它。

使用稳定的ABI编译一些代码后,仍然存在如何链接到运行时的问题。 对于Python 3.5.x,您需要使用-lpython3.5m进行链接。 对于Python 3.6.x,您需要-lpython3.6m 这是libpython3.so进入的地方。

libpython3.so库仅具有一个用途:对于Python 3.5,它链接到libpython3.5m.so ,在3.6上它链接到libpython3.6m.so等。因此,如果扩展使用-lpython3链接,它将可以访问系统上安装的Python版本的运行时。

现在回到您的原始问题:除非您完全确定只使用稳定ABI中的功能(在您的情况下,这意味着确定libboost_python是否仅使用稳定ABI),那么您可能想要链接到版本化的libpython3.5m.so

如有疑问,最好链接到版本库:调试动态链接错误比由于ABI更改而引起的段错误要容易得多,如果您升级到更新版本的Python。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM