如何将gcc -fvisibility选项应用于静态库中的符号?

我有一个从4静态库( .a )和一个对象( .o )文件构build的共享库项目。 我正在尝试添加-fvisibility=hidden选项,以便将输出中的符号限制为仅在源中使用__attribute__标记的符号。

我已将-fvisibility=hidden选项添加到.so项目(涵盖.o文件)和.a项目的编译选项。

对象文件中的符号按照预期从最终的.so中移除。 但是, .a项目中的符号仍然位于最终的.so文件中。 将-fvisibility=hidden选项添加到.so链接命令不起作用。

我究竟做错了什么?

我的目的是从.so除去除库的接口函数外的所有符号。

编辑:我现在实际上使用版本地图来解决这个问题。 但是,随着外部符号的变化,它需要继续维护版本脚本。 接受的答案有一个更好的主意。

基本上,可见性是在链接期间处理的,而链接器似乎并没有将其强加在静态存档上。 在这里 ,我们提出了一个相关的问题(虽然不是重复的)。

我build议你做的是将你的链接阶段: gcc -shared -o mylib.so foo.o libbar.a成两个阶段的过程,你可以找回目标文件:

  • ar x libbar.a (可能进入一个合适的空目录)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o

只需将-Wl,--exclude-libs,ALL传递给gcc

这将告诉链接器将静态库中的所有符号转换为隐藏。

--exclude-libs还接受一个档案列表(即静态库名称),以便在哪些库中隐藏符号的细粒度。

注意:这只适用于使用GNU binutils(例如Linux)的系统或支持--exclude-libs的链接器(例如,它不适用于OSX的ld64)