I'm trying to link a static library to a shared library via a command like
g++ -shared obj.o archive.a -o libLib.so
But at run time I keep getting unresolved system that should be link at compile time from archive.a. I've tried
g++ -shared obj.o -Wl,-Bstatic archive.a -Wl,-Bdynamic -o libLib.so
and
g++ -shared obj.o -Wl,-whole-archive archive.a -Wl,-no-whole-archive -o libLib.so
with no success. I feel like I'm missing something basic here...
You practically cannot (i.e. should never) do that. Shared libraries should be position independent code, but static libraries are not.
If you want to link libaa
into libfoo.so
build or get a shared (PIC) library libaa.so
, not a static (non-PIC) library libaa.a
So a file foo1.cc
going into a shared library libfoo.so
should be compiled as
g++ -c -fPIC -Wall -O foo1.cc -o foo1.pic.o
and the library will be linked as
g++ -shared foo1.pic.o foo2.pic.o -o libfoo.so
You could link another shared library libsmiling.so
into libfoo.so
e.g. by appending -lsmiling
to the above command. But you can't link libraries into static libraries, just copy their members.
But a file going into a static library libfoo.a
is just compiled as
g++ -Wall -O foo1.cc -o foo1.o
so when you extract that foo1.o
member from libfoo.a
it is not PIC (and that is very inefficient)
In principle you could put a non-PIC object code in a shared library. In practice, you should never do that, because the amount of relocation is so large that it defeats the purpose of shared libraries. If you did that, text memory won't be sharable and the dynamic linker would have a lot of relocation work.
Code inside .so
shared objects should be PIC to permit ld.so
to mmap
it at different address segments in different processes.
So you could find a sequence of commands to link a static library into a shared one, e.g. extract using ar x
all the members of the libbar.a
then link all these extracted bar*.o
with foo*.pic.o
but that would be a mistake. Don't link static non-PIC libraries or object files to PIC shared libraries.
For details (with a focus on Linux) read ld.so(8), ld(1), ELF wikipage, Levine's book: Linkers and loaders, Drepper's paper: How To Write Shared Libraries
PS. Some very few static libraries contain PIC code because they could be used to make shared libraries. For example my Debian provides the libc6-pic
package giving notably the /usr/lib/x86_64-linux-gnu/libc_pic.a
static PIC library -usable to build some variant of libc.so
-e.g. if I wanted to put my own malloc
in libc.so
! - without recompiling every glibc source file.