移除静态库中多余的符号
生成库的时候,只想暴露接口符号给调用者,其他的符号需要删除,怎么办?
方法1
#hidden符号增加local flag
objcopy --strip-uneeded --localize-hidden libxxx.a
#根据need_globals_symbols_list.txt,将其中所有符号设置为global
objcopy --globalize-symbols=need_globals_symbols_list.txt libxxx.a
#移除local符号
strip -x libxxx.a
#移除其他非local符号
strip -N sym_name libxxx.a
#保留某些符号
strip -s -K sym_name
#轻度混淆,重命名section和无法strip的symbol
objcopy --redefine-sym old_sym=new_sym libxxx.a
objcopy --rename-section old_sect=new_sect libxxx.a
这个方法适合没有源码的情况,缺点有:
1.原始库需要被删除的符号必须是hidden (即编译时参数 -fvisibility=hidden 或手动指定 __attribute((visibility("hidden"))) ),否则objcopy无法将其设置为local,也就无法被strip -x移除,当然用strip -N strip -s -K也可以,就是麻烦。
2.当原始库需要被删除的符号是内部调用的符号(例如source1.c 中调用了source2.c的函数),不管是不是hidden,此符号都处于relocation,无法被strip移除,只能--redefine-sym --rename-section一个个修改混淆。即便如此,该符号的地址依然存在,objdump nm都可以看到。
方法2
#源码里,需要暴露的符号用__attribute((visibility("default"))),编译时增加参数
gcc -c *.c -o output.o -fvisibility=hidden
#链接
ld -r output.o --gcsections --gc-keep-exported -o libxxx.o
gcc-ar rcs -o libxxx.o libxxx.a
缺点:
1.需要有源码
2.依然不会删除内部调用的符号