Ste*_*ows 43 gcc visibility static-libraries
我有一个共享库项目,它由4个静态库(.a)和一个object(.o)文件构成.我正在尝试添加-fvisibility=hidden选项以将输出中的符号限制为仅使用__attribute__在源中标记的符号.
我已经-fvisibility=hidden为.so项目的编译选项(包括.o文件)和项目添加了选项.a.
目标文件中的符号将按照预期从最终中删除.so.但是,.a项目中的符号仍然在最终.so文件中.将-fvisibility=hidden选项添加到.solink命令无效.
我究竟做错了什么?
我的目的是从.so除了接口函数之外的所有符号中删除库.
编辑:我实际上使用版本地图来解决这个问题.但是,随着外部符号的更改,它需要继续维护版本脚本.接受的答案有更好的主意.
fon*_*ons 62
简单地传递-Wl,--exclude-libs,ALL给gcc
这将告诉链接器将静态库中的所有符号转换为隐藏.
--exclude-libs 还接受一个档案列表(即静态库名称),以便更精细地在哪些库中隐藏符号.
注意:这仅适用于使用GNU binutils(例如Linux)或支持链接器的系统--exclude-libs(例如,它不适用于OSX的ld64)
这是OS X问题的答案。
Mac ld不支持--exclude-libs,但它确实支持-exported_symbol sym,并且确实将其应用于静态库中的目标文件。而且,当您过滤到公共API时,白名单很小,足以将其拼写出来。
我在Makefile中结束了以下操作,-Wl,-exported_symbol,_api_func_1以为每个导出的符号生成一个标志:
SYMBOLS = api_func_1 api_func_2 api_func_3 api_func_4
SYMBOLS += api_func_5 # add more as necessary
COMMA = ,
LDFLAGS += $(addprefix -Wl$(COMMA)-exported_symbol$(COMMA)_,$(SYMBOLS))
# ...
libmyapi.so: # ...
$(CC) -shared -o $@ ... $(LDFLAGS)
Run Code Online (Sandbox Code Playgroud)
然后,在检测到系统具有哪个链接程序之后,可以在此标志版本与GNU ld版本之间进行if-gate操作。