Open chenpengcong opened 7 years ago
在学习别人代码过程中发现项目编译选项添加了-fvisibility=hidden,之前自己没用过这个编译选项,因此查阅资料学习
-fvisibility=hidden
fvisibility选项决定共享库中的符号是否是可见的。
-fvisibility=[default|internal|hidden|protected]
default意味着符号可见,hidden意味者不可见,internal和protected一般很少用
example
//foo.c #include "stdio.h" #include “foo.h” int global_var = 1; void foo() { printf("foo\n"); } //foo.h void foo(); extern int global_var;
$ gcc -fPIC -shared foo.c -o libfoo.so $ objdump -T libfoo.so
$ gcc -fPIC -shared foo.c -o libfoo.so
$ objdump -T libfoo.so
可以看到符号表中存在foo和global_var
加上编译选项-fvisibility=hidden
$ gcc -fPIC -shared -fvisibility=hidden foo.c -o libfoo.so $ objdump -T libfoo.so
$ gcc -fPIC -shared -fvisibility=hidden foo.c -o libfoo.so
可以看到符号表中不再存在foo和global_var,因此外部也就无法调用foo函数和使用全局变量global_var
PS:可以使用__attribute__ ((visibility("default")))指定符号可见性
__attribute__ ((visibility("default")))
static修饰的符号在符号表中也是不可见的,那么和fvisibility=hidden有什么区别呢
假如有一个函数用__attribute__((visibility("hidden")))修饰,那么在编译成动态共享库之后该函数是不可见的,但是如果该库由foo.o和bar.o链接而成的,那么该函数可以定义在foo.c,在bar.c中被调用,即隐藏的可见度适用于整个共享库,而不适用于组成它的单个编译单元。
__attribute__((visibility("hidden")))
而static修饰的函数只能在当前文件内被调用
参考: https://gcc.gnu.org/wiki/Visibility https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Code-Gen-Options.html https://stackoverflow.com/questions/17022983/is-it-possible-to-remove-symbols-from-a-shared-library-built-with-android-ndk https://stackoverflow.com/questions/14919528/what-is-the-practical-difference-between-a-static-function-and-a-function-with-t
背景:
在学习别人代码过程中发现项目编译选项添加了
-fvisibility=hidden
,之前自己没用过这个编译选项,因此查阅资料学习fvisibility选项
fvisibility选项决定共享库中的符号是否是可见的。
-fvisibility=[default|internal|hidden|protected]
default意味着符号可见,hidden意味者不可见,internal和protected一般很少用
example
$ gcc -fPIC -shared foo.c -o libfoo.so
$ objdump -T libfoo.so
可以看到符号表中存在foo和global_var
加上编译选项
-fvisibility=hidden
$ gcc -fPIC -shared -fvisibility=hidden foo.c -o libfoo.so
$ objdump -T libfoo.so
可以看到符号表中不再存在foo和global_var,因此外部也就无法调用foo函数和使用全局变量global_var
PS:可以使用
__attribute__ ((visibility("default")))
指定符号可见性设置不可见有什么好处
fvisibility=hidden和static有什么区别
static修饰的符号在符号表中也是不可见的,那么和fvisibility=hidden有什么区别呢
假如有一个函数用
__attribute__((visibility("hidden")))
修饰,那么在编译成动态共享库之后该函数是不可见的,但是如果该库由foo.o和bar.o链接而成的,那么该函数可以定义在foo.c,在bar.c中被调用,即隐藏的可见度适用于整个共享库,而不适用于组成它的单个编译单元。而static修饰的函数只能在当前文件内被调用
参考: https://gcc.gnu.org/wiki/Visibility https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Code-Gen-Options.html https://stackoverflow.com/questions/17022983/is-it-possible-to-remove-symbols-from-a-shared-library-built-with-android-ndk https://stackoverflow.com/questions/14919528/what-is-the-practical-difference-between-a-static-function-and-a-function-with-t