C ++静态链接的共享库 [英] C++ Statically linked shared library
问题描述
我有一个共享库使用的另一个应用程序超出了我的控制,需要* .so对象。我的库使用sqlite3,需要与它静态链接(我绝对需要一个自包含的二进制)。
I have a shared library used by a another application beyond my control which requires *.so objects. My library makes use of sqlite3 which needs to be statically linked with it (I absolutely need a self-contained binary).
当我尝试编译和链接我的库:
When I try to compile and link my library:
-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?
What is recompile with -fPIC related to? My code or CRT?
我已经尝试用-fPIC编译我的对象,结果相同。
I have already tried to compile my object with -fPIC with the same result.
谢谢。
EDIT:
问题似乎并不相关到SQLite3。
The problem does not seem to be related to SQLite3.
我写了一个简单的一行无用的库,它编译和链接如下:
I wrote a simple one-line-do-nothing library which compiles and links like this:
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或任何东西?
The problem seems to be related to CRT (crtbeginT.o). Am I supposed to recompile GCC --with-pic or anything?
推荐答案
您不应使用 -static
flag创建共享库时,用于创建静态链接的可执行文件。
You shouldn't use the -static
flag when creating a shared library, it's for creating statically linked executables.
如果您只有一个静态版本的库,使用 -lsqlite3
。但是如果同时存在动态版本(.so)和静态版本,链接器将更喜欢动态版本。
If you only have a static version of the library, you can just link it in using -lsqlite3
. But if there's both a dynamic version(.so) and a static version, the linker will prefer the dynamic one.
要指示链接器选择静态版本链接器 -Bstatic
标志,并使它切换回动态链接其他东西(如libc和动态运行时支持)与 -Bdynamic
。也就是说,您使用标志:
To instruct the linker to pick the static one, give the linker the -Bstatic
flag, and make it switch back to dynamic linking for other stuff (like libc and dynamic runtime support) with -Bdynamic
. That is, you use the flags:
-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic
或者,您只需指定.a文件的完整路径,例如 /usr/lib/libsqlite3.a
而不是任何编译器/链接器标志。
Alternativly, you can just specify the full path of the .a file, e.g. /usr/lib/libsqlite3.a
instead of any compiler/linker flags.
也可以使用 -l:libsqlite3.a
而不是 -lsqlite3
。这将强制使用库文件 libsqlite3.a
而不是 libsqlite3.so
,链接器默认使用。
With the GNU ld, you can also use -l:libsqlite3.a
instead of -lsqlite3
. This will force the use of the library file libsqlite3.a
instead of libsqlite3.so
, which the linker prefers by default.
请记住确保.a文件已使用 -fpic
标志编译,否则通常可以不会将其嵌入到共享库中。
Remember to make sure the .a file have been compiled with the -fpic
flag, otherwise you normally can't embed it in a shared library.
这篇关于C ++静态链接的共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!