您实际上不能(即应该从不)这样做。 Shared libraries 应该是 position independent code,但静态库不是。
如果您想将libaa 链接到libfoo.so 构建或获取共享 (PIC) 库libaa.so,而不是静态(非PIC)库libaa.a
因此,进入共享库libfoo.so 的文件foo1.cc 应编译为
g++ -c -fPIC -Wall -O foo1.cc -o foo1.pic.o
库将链接为
g++ -shared foo1.pic.o foo2.pic.o -o libfoo.so
您可以将另一个共享库libsmiling.so 链接到libfoo.so,例如通过将-lsmiling 附加到上述命令。但是你不能将库链接到静态库中,只需复制它们的成员即可。
但是进入 static 库 libfoo.a 的文件只是编译为
g++ -Wall -O foo1.cc -o foo1.o
所以当你从libfoo.a 中提取foo1.o 成员时,它不是 PIC(效率非常低)
原则上,您可以将非 PIC 目标代码放入共享库中。在实践中,您永远不应该这样做,因为relocation 的数量如此之大以至于它违背了共享 库的目的。如果您这样做了,文本内存将无法共享,并且动态链接器将进行大量重定位工作。
.so 共享对象中的代码应该是 PIC,以允许 ld.so 到 mmap 它在不同进程的不同地址段。
因此,您可以找到一系列命令将静态库链接到共享库,例如使用ar x 提取libbar.a 的所有成员,然后将所有这些提取的bar*.o 与foo*.pic.o 链接,但这将是一个错误。不要将静态非 PIC 库或对象文件链接到 PIC 共享库。
有关详细信息(重点关注 Linux),请阅读 ld.so(8)、ld(1)、ELF wikipage、Levine's book: Linkers and loaders、Drepper's paper: How To Write Shared Libraries
PS。一些极少数静态库包含 PIC 代码,因为它们可用于制作共享库。例如,我的 Debian 提供了 libc6-pic 包,特别是提供了 /usr/lib/x86_64-linux-gnu/libc_pic.a 静态 PIC 库 - 可用于构建 libc.so 的某些变体 -e.g.如果我想将自己的malloc 放入libc.so! - 无需重新编译每个 glibc 源文件。