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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:27:18  来源:igfitidea点击:

C++ Statically linked shared library

c++static-librariescrtdynamic-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 -staticflag 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 -Bstaticflag, 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.ainstead of any compiler/linker flags.

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

With the GNU ld, you can also use -l:libsqlite3.ainstead of -lsqlite3. This will force the use of the library file libsqlite3.ainstead 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 -fpicflag, 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 sqlitelibrary 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 并且一切正常。