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
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 -fPIC related to? My code or CRT?
I have already tried to compile my object with -fPIC with the same result.
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
The problem seems to be related to CRT (crtbeginT.o). Am I supposed to recompile GCC --with-pic or anything?
You shouldn't use the -static
flag when creating a shared library, it's for creating statically linked executables.
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.
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
Alternativly, you can just specify the full path of the .a file, e.g. /usr/lib/libsqlite3.a
instead of any compiler/linker flags.
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.
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.
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
.
Details of what PIC means are here: http://en.wikipedia.org/wiki/Position-independent_code
I had the same problem. Apparently -static is not the same as -Bstatic. I switched to -Bstatic and everything worked.
精彩评论