我使用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宏。
你可以通过以下几种方式解决这个问题:
-Xlinker --whole-archive
我想知道是否有人能想到另一个解决方案,因为通过所有可能的库并使用--whole-archive
添加它们真的很烦人谢谢!
答案 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参数。