简体   繁体   中英

C++ Statically linked shared library

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, eg /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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM