C++ 静态链接共享库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6634387/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Statically linked shared library
提问by Petr
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).
我有一个共享库被另一个超出我控制的应用程序使用,它需要 *.so 对象。我的库使用了需要与其静态链接的 sqlite3(我绝对需要一个独立的二进制文件)。
When I try to compile and link my library:
当我尝试编译和链接我的库时:
-fpic -flto -pthread -m64
-flto -static -shared
I end up with the following error:
我最终出现以下错误:
/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
What is recompile with -fPICrelated to? My code or CRT?
用 -fPIC 重新编译与什么有关?我的代码还是 CRT?
I have already tried to compile my object with -fPIC with the same result.
我已经尝试使用 -fPIC 编译我的对象,结果相同。
Thanks.
谢谢。
EDIT:
编辑:
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
but not like this:
g++ -c -fPIC -o bar.o bar.cpp
g++ -static -shared -o bar.so bar.o
该问题似乎与 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
The problem seems to be related to CRT (crtbeginT.o). Am I supposed to recompile GCC --with-pic or anything?
问题似乎与 CRT (crtbeginT.o) 有关。我应该重新编译 GCC --with-pic 还是什么?
回答by nos
You shouldn't use the -static
flag when creating a shared library, it's for creating statically linked executables.
-static
创建共享库时不应使用该标志,它用于创建静态链接的可执行文件。
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.
如果您只有该库的静态版本,则可以使用-lsqlite3
. 但是如果同时有动态版本 (.so) 和静态版本,链接器将更喜欢动态版本。
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:
要指示链接器选择静态链接器,请为链接器指定-Bstatic
标志,并使用-Bdynamic
. 也就是说,您使用以下标志:
-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic
Alternativly, you can just specify the full path of the .a file, e.g. /usr/lib/libsqlite3.a
instead of any compiler/linker flags.
或者,您可以只指定 .a 文件的完整路径,例如,/usr/lib/libsqlite3.a
而不是任何编译器/链接器标志。
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.
使用 GNU ld,您还可以使用-l:libsqlite3.a
代替-lsqlite3
. 这将强制使用库文件libsqlite3.a
而不是libsqlite3.so
,链接器默认情况下更喜欢使用 。
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.
请记住确保 .a 文件已使用该-fpic
标志编译,否则您通常无法将其嵌入共享库中。
回答by vines
Any code that will somehow make its way into a dynamic library should be relocatable. It means that everything that is linked with your .so, no matter statically or dynamically, should be compiled with -fPIC
. Specifically, static sqlite
library should also be compiled with -fPIC
.
任何以某种方式进入动态库的代码都应该是可重定位的。这意味着与您的 .so 链接的所有内容,无论是静态的还是动态的,都应该使用 .so 进行编译-fPIC
。具体来说,静态sqlite
库也应该用-fPIC
.
Details of what PIC means are here: http://en.wikipedia.org/wiki/Position-independent_code
PIC 含义的详细信息在这里:http: //en.wikipedia.org/wiki/Position-independent_code
回答by Dre
I had the same problem. Apparently -static is not the same as -Bstatic. I switched to -Bstatic and everything worked.
我有同样的问题。显然 -static 与 -Bstatic 不同。我切换到 -Bstatic 并且一切正常。