如何将静态库链接到共享库

时间:2015-01-28 07:51:28

标签: c++ linker ld

我正在尝试通过像

这样的命令将静态库链接到共享库
g++ -shared obj.o archive.a -o libLib.so

但是在运行时,我一直在得到未解析的系统,该系统应该在编译时从archive.a链接。我试过了

 g++ -shared obj.o -Wl,-Bstatic archive.a -Wl,-Bdynamic -o libLib.so

g++ -shared obj.o -Wl,-whole-archive archive.a -Wl,-no-whole-archive -o libLib.so

没有成功。我觉得我在这里缺少一些基本的东西......

1 个答案:

答案 0 :(得分:3)

你几乎不能(也就是从不)这样做。 Shared libraries应为position independent code,但静态库不是。{/ p>

如果您想将libaa链接到libfoo.so版本或获取共享(PIC)库libaa.so,则不是静态的(非) PIC)库libaa.a

因此,进入共享库foo1.cc的文件libfoo.so应编译为

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附加到上述命令。但是你不能将库链接到静态库,只需复制它们的成员。

但进入静态libfoo.a的文件只是编译为

g++ -Wall -O foo1.cc -o foo1.o

所以当你从foo1.o中提取libfoo.a成员时,它不是 PIC(效率非常低)

原则上,您可以将非PIC对象代码放在共享库中。在实践中,您永远不应该这样做,因为relocation的数量太大而无法实现共享库的目的。如果您这样做,文本内存将不会是可共享的,并且动态链接器将具有批次的重定位工作。

.so个共享对象中的代码应该是PIC,以允许ld.so在不同进程中的不同地址段mmap {/ 1}}。

因此,您可以找到一系列命令来将静态库链接到共享库,例如使用ar x libbar.a的所有成员提取,然后将所有这些提取的bar*.ofoo*.pic.o相关联,但这将是一个错误。不要将静态非PIC库或目标文件链接到PIC共享库。

有关详细信息(重点关注Linux),请阅读ld.so(8)ld(1)ELF wikipage,Levine's book: Linkers and loadersDrepper'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 源文件。功能