Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self-contained shared library

I need to create a shared library whose own dependencies including libc/libstdc++ have to be statically linked to it to produce a self-contained binary. I tried to do this

g++ -c -fpic -o foo.o foo.cpp
g++ -static -shared -o foo.so foo.o

which fails with:

/usr/bin/ld.bfd.real: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.2.0/crtbeginT.o: relocation R_X86_64_32 against `__TMC_END__' can not be      used when making a shared object; recompile with -fPIC
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/5.2.0/crtbeginT.o: could not read symbols: Bad value
collect2: error: ld returned 1 exit status

Can somebody tell me what I am doing wrong?

like image 215
user10602 Avatar asked Nov 20 '15 12:11

user10602


People also ask

What is the difference between shared library and static?

Static libraries take longer to execute, because loading into the memory happens every time while executing. While Shared libraries are faster because shared library code is already in the memory. In Static library no compatibility issue has been observed.

What is meant by shared library?

A shared library or shared object is a file that is intended to be shared by multiple programs. Symbols used by a program are loaded from shared libraries into memory at load time or runtime.

How does shared library work?

Simply put, A shared library/ Dynamic Library is a library that is loaded dynamically at runtime for each application that requires it. Dynamic Linking doesn't require the code to be copied, it is done by just placing name of the library in the binary file.


1 Answers

You can use the -static-libstdc++ option to link libstdc++ statically. You probably shouldn't link statically to libc (or libgcc, which you can link statically with -static-libgcc should you need to) if you're making a dynamic library; you'll want to pick up the libc version of the application that loads your shared library.

Other options controlling static linking can be found in the GCC manual. You may also be able to achieve the desired results by passing arguments to the linker (-Wl,<argument>, or calling ld directly). The LD manual lists the permitted options.


Example:

I wrote the following code

#include <iostream>

extern "C" void do_something() {
    std::cout << "Doing something!\n";
}

and compiled it to a .o file as follows:

g++ -fPIC -c -o tmp.o tmp.cpp

I then produced two shared libraries from it. One with -static-libstdc++, and one without:

g++ -shared -o tmp-shared.so tmp.o
g++ -shared -static-libstdc++ -o tmp-static.so tmp.o

For comparison, ldd tmp-shared.so:

linux-vdso.so.1 =>  (0x00007fffc6dfd000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b708cb43000)
libm.so.6 => /lib64/libm.so.6 (0x00002b708ce4c000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b708d0cf000)
libc.so.6 => /lib64/libc.so.6 (0x00002b708d2dd000)
/lib64/ld-linux-x86-64.so.2 (0x00000035c6c00000)

and ldd tmp-static.so:

linux-vdso.so.1 =>  (0x00007fff99bfd000)
libm.so.6 => /lib64/libm.so.6 (0x00002acbec030000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002acbec2b3000)
libc.so.6 => /lib64/libc.so.6 (0x00002acbec4c1000)
/lib64/ld-linux-x86-64.so.2 (0x00000035c6c00000)
like image 149
Andrew Avatar answered Oct 13 '22 03:10

Andrew