如何将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)