2011-07-09 178 views
25

我有一个共享库被另一个应用程序超出了我的控制范围,它需要* .so对象。我的库使用sqlite3需要静态链接它(我绝对需要一个自包含的二进制文件)。C++静态链接共享库

当我尝试编译和链接我的图书馆:

-fpic -flto -pthread -m64 
-flto -static -shared 

我结束了以下错误:

/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC 
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value 
collect2: ld returned 1 exit status 

什么是重新编译-fPIC有关?我的代码或CRT?

我已经尝试用-fPIC编译我的对象,并得到相同的结果。

谢谢。

编辑:

似乎问题并不涉及到sqlite3的。

我写了编译和像这样的链接一个简单的线什么都不做的库:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -shared -o bar.so bar.o 

,但不喜欢这样的:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -static -shared -o bar.so bar.o 

的问题似乎与CRT (crtbeginT.o)。我应该重新编译GCC --with-pic或其他什么?

+0

这有点令人困惑。你是否试图将你的库链接到一个静态的sqlite库,或者你是否还想做其他的事情? – nos

+0

PIC =共享库所需的位置独立代码(在大多数体系结构上,我猜) – sehe

+0

@nos试图将我的共享库链接到sqlite3.a – Petr

回答

35

创建一个共享库时,不应使用-static标志,它是用于创建静态链接的可执行文件。

如果您只有一个库的静态版本,您可以使用链接它。但是,如果同时存在动态版本(.so)和静态版本,链接器将更喜欢动态版本。

要指示链接器选择静态链接器,请给链接器标记-Bstatic,并使其切换回其他东西(如libc和动态运行时支持)的动态链接,并使用-Bdynamic。也就是说,使用标志:

-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic 

Alternativly,你可以指定某文件,例如完整路径/usr/lib/libsqlite3.a而不是任何编译器/链接器标志。

使用GNU ld,您还可以使用-l:libsqlite3.a而不是。这将强制使用库文件libsqlite3.a而不是libsqlite3.so,默认情况下链接器首选。

请记住确保.a文件已使用-fpic标志进行编译,否则通常无法将其嵌入到共享库中。

+0

我在这里有同样的问题,不知道如何编译共享库,不会动态链接到像libc/libstdC++这样的分发依赖的工作人员 - “-Bstatic”确实提供动态链接的共享库。奇妙的是,在Windows上使用MinGW,我可以正确链接.dll与'-static'(取决于windows dll,但不是mingw的)。有没有办法链接.so静态? – Nick

+0

编号的unix共享库与Windows DLL工作非常不同。 – nos

+0

-l:libsqlite3.a技巧也适用于eclipse cdt。在Properties-> C/C++ Build-> Settings-> GCC C Linker-> Libraries中输入:libsqlite3.a,构建将静态链接到库。 – zztops

7

任何会以某种方式进入动态库的代码都应该是可重定位的。这意味着与.so链接的所有内容,无论是静态的还是动态的,都应该使用-fPIC进行编译。具体而言,静态sqlite库也应编译为-fPIC。什么PIC手段

详情请看这里:http://en.wikipedia.org/wiki/Position-independent_code

+0

我重新编译了sqlite3 --with-pic,但结果仍然相同... – Petr

+0

发布您执行的完整链接命令,以便我们可以进一步分析) – vines

+0

查看原文。 – Petr

0

我有同样的问题。显然静态不同于-Bstatic。我切换到-Bstatic,一切正常。