我已经使用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本身(可能是因为PythonClass映射宏。
你可以用几种方法解决这个问题:
-Xlinker --whole-archive我想知道是否有人能想到另一种解决方案,因为浏览所有可能的库并将它们添加到-完整的存档中是非常烦人的。
发布于 2012-09-28 22:33:22
好的,由于没有人响应,我找到了最简单的(也是我所知道的唯一的解决方案)是将您拥有的每个静态库都包括在内:
-Xlinker --whole-archive当然,您可以动态链接库,这将要求您在执行python应用程序时设置LD_LIBRARY_PATH (尽管对于许多库来说,这不是一个选项)。
因此,在这个意义上,显式动态链接可能被认为是一个更优雅的解决方案。
除此之外,如果您的库使用其他库:
python_mapping.so ->静态链接实用程序1 a ->静态链接实用程序2.a
如果您忘记了在utility1.a中链接,运行python应用程序会让您知道它找不到符号,但是,它不会抱怨utility2.a,并且当它到达库的那个部分时会有奇怪的行为。所以..。要小心,并确保你已经明确地连接在每件事情上。
发布于 2013-06-21 16:07:57
可以使用链接器参数-rpath嵌入库搜索路径,包括可执行文件中的“当前目录”(g++ -Wl,-rpath,.)因此,您可以指定从何处加载共享库。如果您正在将应用程序移动到其他.so文件未知的机器,这将有所帮助。您还必须在您显式指定的.so文件上移动。这是静态链接和完全动态链接之间的折衷,因为您实际上不会与盒子上的其他应用程序“共享”.so文件(您自己带了副本),这是使用共享库节省内存的好处之一。
这篇文章主要是为了宣传很少使用的,但非常有用的-rpath参数。
https://stackoverflow.com/questions/12611845
复制相似问题