Linux 如何将静态库嵌入到共享库中?

Linux 如何将静态库嵌入到共享库中?,linux,linker,static-linking,dynamic-linking,undefined-symbol,Linux,Linker,Static Linking,Dynamic Linking,Undefined Symbol,在linux上,我试图创建一个共享库libbar.so,它嵌入了一个商业静态库(许可是可以的)。商业库有4个版本:libfoo-seq.a、libfoo-mt.a、libfoo-seq.so和libfoo-mt.so(它们都提供相同的符号,只是代码是顺序/多线程的,库是静态/共享的)。在这四个库中,我希望我的代码始终使用顺序foo库,因此当我创建libbar.so时,我将我的对象文件和libfoo seq.a链接在一起 问题是,在我的libbar.so被读入时,我库的用户可能已经读入了libfo

在linux上,我试图创建一个共享库libbar.so,它嵌入了一个商业静态库(许可是可以的)。商业库有4个版本:libfoo-seq.a、libfoo-mt.a、libfoo-seq.so和libfoo-mt.so(它们都提供相同的符号,只是代码是顺序/多线程的,库是静态/共享的)。在这四个库中,我希望我的代码始终使用顺序foo库,因此当我创建libbar.so时,我将我的对象文件和libfoo seq.a链接在一起

问题是,在我的libbar.so被读入时,我库的用户可能已经读入了libfoo-mt.so,因此libfoo中的所有符号在libbar.so被读入时已经存在,因此我对foo中函数的调用被解析为多线程版本


我想知道如何解决这个问题?当我编译创建我的对象文件时,以及当我将我的对象文件与libfoo seq.a链接以创建libbar时,我需要使用什么样的魔旗呢?

您可以通过版本脚本在libbar中隐藏libfoo的符号:

$ cat libbar.map
{
  global: libbar_*;
  local: libfoo_*;
};
$ gcc ... -o libbar.so -Wl,--version-script=libbar.map

我的理解是,有了它,libfoo的函数嵌入到我的libbar.so中,在外面就看不到了。但这只是等式的一个方面。我还需要,如果libfoo的函数已经通过打开libfoo-mt.so被拉入,那么它们就不会“渗透”到libbar.so中,所以当它被打开时,libbar.so仍然会使用libfoo seq.a中的函数。这部分也是真的吗?是的,如果libfoo的符号被隐藏(通过上面的脚本),您的库将不再尝试从外部导入它们(因此它们不会被覆盖)。您可以通过
readelf-hS--dyn-syms
验证libfoo的二进制接口。听起来不错,我今天晚些时候会试试。同时。。。您知道在Windows和AIX上的等价物吗…:-)?Windows不应存在此问题(默认情况下,符号已隐藏在那里,除非您使用
declspec(dllexport)
标记它们)。没有AIX专业知识,但如果我读得正确,它支持Linux等版本脚本。您的解决方案确实有效,谢谢。但对于我的情况,我发现了一个更简单的方法:只需在链接行中添加“-exclude libs ALL”,这将使所有嵌入的静态libs都成为本地的。