为什么静态库可以依赖于共享库?

问题描述

据我所知,Linux 中的静态库不能依赖于共享库。但是,当我编译链接到 glog.a 和 gflags.a 的程序时,编译器报告以下错误

> /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libglog.a(libglog_la-utilities.o):
> In function `google::GetStackTrace(void**,int,int) [clone .part.7]':
> (.text+0xad): undefined reference to `_Ux86_64_getcontext'
> (.text+0xb8): undefined reference to `_ULx86_64_init_local'
> (.text+0xe7): undefined reference to `_ULx86_64_step' (.text+0x100):
> undefined reference to `_ULx86_64_get_reg' (.text+0x120): undefined
> reference to `_ULx86_64_step' collect2: error: ld returned 1 exit
> status

这个编译错误也通过链接 unwind.so解决。但是我觉得奇怪的是为什么libglog.a会依赖一个共享库?这不是不可能吗?

解决方法

此声明

Linux 中的静态库不能依赖于共享库

完全错误。

静态库只是目标文件的集合。

如果您可以使用从共享库导入的代码编译为 .o 文件,您可以将这些 .o 文件收集到库中,现在您有一个使用共享库导入的库图书馆。

与直接链接所有目标代码相比,静态库的唯一真正区别在于,该库包含一个符号索引,链接器使用该索引来决定需要链接库中的哪些目标文件。而直接传递给链接器的目标文件总是被链接进来。这对全局初始化器的行为有重要影响,而其他的影响很小。