繁体   English   中英

Boost 不静态链接到 boost::python 共享对象

[英]Boost not statically linking in to boost::python shared object

我已经使用 boost::python 为我的应用程序创建了一个包装器。

到目前为止,这是有效的:(静态库/源代码的数量)-> python_mapping.so

通过这种方式,我的共享对象由许多静态库组成,包括 boost 本身(特别是 boost_thread)。 我认为这将包含我所有的应用程序信息,因为我已经静态链接了所有内容。

这编译得很好。

ldd python_mapping.so
        librt.so.1 => /lib64/librt.so.1 (0x00002b7cbad37000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b7cbaf40000)
        libm.so.6 => /lib64/libm.so.6 (0x00002b7cbb240000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b7cbb4c4000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b7cbb6d2000)
        libc.so.6 => /lib64/libc.so.6 (0x00002b7cbb8ed000)
        /lib64/ld-linux-x86-64.so.2 (0x000000327ee00000)

但是,当我运行我的示例 python 应用程序时,我得到这个运行时链接错误:未定义符号:_ZTIN5boost6detail16thread_data_baseE

似乎那些很好地链接到静态库的 boost 库实际上并不存在?

我在这方面取得了一些进展。 显然,我的共享对象不包含很多编译器认为没有被使用的符号(因为它从未见过我的 c++ 对象被创建,因为它们是通过实例化 Python 对象创建的)。

有一些像:

//This is a class only created in python
#include "CPlusPlusClass.h"

PythonClass
{
       public:
           PythonClass() { }
       private:
           CPlusPlusClass _cplusplus;
};

//PythonMappings for PythonClass

#python file
import python_mapping

pythonClass = python_mapping.PythonClass() #This fails saying it can't find the symbol for CPlusPlusClass

编译器将优化 CPlusCPlus 类,因为它从未看到它实际被使用,这完全令人讨厌。 它似乎确实保留了 PythonClass 本身(可能是因为 Python Boost 映射宏。

你可以通过几种方式解决这个问题:

  1. 使用以下链接链接所有库: -Xlinker --whole-archive
  2. 在共享对象中创建库的虚拟使用

我想知道是否有人能想到另一种解决方案,因为浏览所有可能的库并将它们添加到 --whole-archive 中真的很烦人。

好的,由于没有人回应,我发现最简单的(也是我所知道的唯一解决方案)是包含您拥有的每个静态库:

-Xlinker --whole-archive

当然,您可以动态链接您的库,这将要求您在执行 Python 应用程序时设置 LD_LIBRARY_PATH(尽管对于许多库来说这不是我的选择)。

因此,从这个意义上说,显式动态链接可能被认为是更优雅的解决方案。

除此之外,如果您的库使用其他库:

python_mapping.so -> 在utility1.a 中静态链接 -> 在utility2.a 中静态链接

如果您忘记在utility1.a中链接,运行python应用程序会让您知道它找不到符号,但是,它不会抱怨utility2.a,并且当它到达该部分时会出现奇怪的行为图书馆。 所以......小心并确保你已经明确地链接到一切。

您可以使用链接器参数 -rpath 在可执行文件中嵌入库搜索路径,包括“当前目录”(g++ -Wl,-rpath,.),以便您可以准确指定从何处加载共享库。 如果您将应用程序移动到其他 .so 文件未知的机器上,这会有所帮助。 您还必须移动您明确指定的 .so 文件。 这是静态链接和完全动态链接之间的折衷,因为您实际上不会与包装盒上的其他应用程序“共享” .so 文件(您带来了自己的副本),这是使用共享库节省内存的好处之一.

这篇文章主要是为了宣传很少使用但非常有用的 -rpath 参数。

暂无
暂无

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

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