我正在尝试通过像
这样的命令将静态库链接到共享库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
没有成功。我觉得我在这里缺少一些基本的东西......
答案 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*.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 源文件。功能