提升不会静态链接到boost :: python共享对象

时间:2012-09-26 23:14:04

标签: c++ python boost static-linking

我使用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

似乎那些与静态库链接良好的提升库实际上并不存在?

嘿伙计们,我在这方面取得了一些进展。显然我的共享对象不包含编译器认为没有使用的很多符号(因为它从未看到我的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 Mapping宏。

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

  1. 将您的所有图书馆与-Xlinker --whole-archive
  2. 相关联
  3. 在共享对象中创建库的虚拟使用
  4. 我想知道是否有人能想到另一个解决方案,因为通过所有可能的库并使用--whole-archive

    添加它们真的很烦人

    谢谢!

2 个答案:

答案 0 :(得分:2)

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

-Xlinker --whole-archive

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

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

除此之外,如果您的图书馆使用其他图书馆:

python_mapping.so - > static1.a中的静态链接 - > static2.a

中的static链接

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

答案 1 :(得分:0)

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

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