2012-10-28 340 views
4

背景:将静态库链接到共享库?

我想将几个静态库链接到一个共享库。原因是我希望我的应用程序使用我测试过的特定lib版本。我不想将静态版本作为共享库发布到我的应用程序中。我已经创建了这个样本库和应用程序以尽可能简化。我想在链接过程中继续将共享库链接到应用程序。

问:

为什么我得到下列错误信息?我究竟做错了什么?也许这不是在Linux上做事的常用方式,但是可以这样做吗?这种提升是否具体?

----库

//example.cpp 
#include <boost/thread.hpp> 
void doit() 
{ 
    boost::thread t1; 
} 

#build script 
g++ -Wall -fPIC -I/usr/include -c example.cpp -o example.o 
g++ -shared /usr/lib/libboost_thread.a /usr/lib/libboost_system.a 
    example.o -o libexample.so 
#build OK. 

----样品应用

//main.cpp 
#include <iostream> 
void doit(); 
int main() 
{ 
    std::cout << "main\n"; 
    doit(); 
    return 0; 
}; 

#build script. 
g++ -Wall -c main.cpp -o main.o 
g++ libexample.so main.o -o main 

#error message. 
libexample.so: undefined reference to `boost::thread::thread()' 
libexample.so: undefined reference to `boost::thread::~thread()' 
collect2: ld returned 1 exit status 

所有的源代码位于同一目录中。 Boost安装在/ usr/lib和/ usr/include中。在Ubuntu 10.04机器上使用apt-get安装Boost版本1.40。

谢谢!

+0

不要这样做:静态库通常包含普通对象成员,而共享库包含与位置无关的代码。 –

+0

但是,如果我用-fPIC重新编译静态库,该怎么办?这会有帮助吗? – mantler

回答

1

我认为最简单的方法是使用--whole-archive链接器开关(关于此主题的更多SO问题,请参阅how to link static library into dynamic library in gcc)。

这样做的缺点是共享库将从Boost静态库中导出所有符号,如果您在也使用Boost的应用程序中使用.so(但是使用不同的版本或编译为不同的开关)。

因此,您需要使用版本脚本来隐藏从库中导出的内容(请参阅How to hide the exported symbols name within a shared library,也适用于链接器版本脚本的Google),只留下doit()可见。在你的情况,这样的版本脚本可能看起来像:

{ 
global: 
    doit*; 
local: 
    *; 
}  

你还需要确保你与链接的静态库编译-fPIC(这是不可能的,如果你不调整自己的建立旗帜),其他明智的你会在i386有性能损失,并且可能根本不会链接到amd64

+0

谢谢,我会试试这个。我只需要先下载并重新编译boost。 – mantler

+0

这个答案有点进一步解释:http://stackoverflow.com/a/2649792/602340 – matiu