封装SDK时如何隐藏内部符号
在封装SDK,对外提供API时。希望不暴露内部符号,免得产生冲突,给集成带来麻烦.本文演示了二种方法
原始工程
静态库(内部使用)
cat <<EOF | sudo tee internal_function.c
#include <stdio.h>
int internal_function()
{
printf("%s\n",__FUNCTION__);
}
EOF
gcc -c internal_function.c -o internal_function.o
ar rcs libinternal_function.a internal_function.o
nm libinternal_function.a | grep "internal_function" | grep "T"
#0000000000000000 T internal_function
动态库(外部使用)
cat <<EOF | sudo tee public_function.c
#include <stdio.h>
extern int internal_function();
int public_function()
{
printf("%s\n",__FUNCTION__);
internal_function();
}
EOF
gcc -fPIC -shared -o libpublic_function.so public_function.c libinternal_function.a
nm libpublic_function.so | grep -w "T"
#0000000000001164 T internal_function
#0000000000001139 T public_function
readelf -s libpublic_function.so | grep -w GLOBAL
# 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
# 6: 0000000000001139 43 FUNC GLOBAL DEFAULT 14 public_function
# 7: 0000000000001164 33 FUNC GLOBAL DEFAULT 14 internal_function
# 48: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.5
# 50: 0000000000001139 43 FUNC GLOBAL DEFAULT 14 public_function
# 52: 0000000000001164 33 FUNC GLOBAL DEFAULT 14 internal_function
可见 internal_function也对外暴露了,如果其它SDK中也有这样一个函数,后果很严重
方法一(-fvisibility=hidden):
静态库(内部使用)
cat <<EOF | sudo tee internal_function.c
#include <stdio.h>
int internal_function()
{
printf("%s\n",__FUNCTION__);
}
EOF
# 编译选项增加 -fvisibility=hidden -fvisibility-inlines-hidden
gcc -fvisibility=hidden -fvisibility-inlines-hidden \
-c internal_function.c -o internal_function.o
ar rcs libinternal_function.a internal_function.o
nm libinternal_function.a | grep -w "T"
#0000000000000000 T internal_function
动态库(外部使用)
cat <<EOF | sudo tee public_function.c
#include <stdio.h>
extern int internal_function();
# API增加 __attribute__ ((visibility ("default"))) 修饰
__attribute__ ((visibility ("default"))) int public_function()
{
printf("%s\n",__FUNCTION__);
internal_function();
}
EOF
#编译选项增加 -fvisibility=hidden -fvisibility-inlines-hidden
gcc -fvisibility=hidden -fvisibility-inlines-hidden \
-fPIC -shared -o libpublic_function.so public_function.c \
libinternal_function.a
nm libpublic_function.so | grep -w "T"
#0000000000001119 T public_function
readelf -s libpublic_function.so | grep -w GLOBAL
# 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
# 6: 0000000000001119 43 FUNC GLOBAL DEFAULT 14 public_function
# 49: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.5
# 51: 0000000000001119 43 FUNC GLOBAL DEFAULT 14 public_function
方法二(-Wl,-Bsymbolic -Wl,–exclude-libs,ALL):
静态库(内部使用)[无修改]
cat <<EOF | sudo tee internal_function.c
#include <stdio.h>
int internal_function()
{
printf("%s\n",__FUNCTION__);
}
EOF
gcc -c internal_function.c -o internal_function.o
ar rcs libinternal_function.a internal_function.o
nm libinternal_function.a | grep -w "T"
#0000000000000000 T internal_function
动态库(外部使用)
cat <<EOF | sudo tee public_function.c
#include <stdio.h>
extern int internal_function();
int public_function()
{
printf("%s\n",__FUNCTION__);
internal_function();
}
EOF
# 编译选项增加 -Wl,-Bsymbolic -Wl,--exclude-libs,ALL
gcc -Wl,-Bsymbolic -Wl,--exclude-libs,ALL \
-fPIC -shared -o libpublic_function.so public_function.c \
libinternal_function.a
nm libpublic_function.so | grep -w "T"
#0000000000001119 T public_function
readelf -s libpublic_function.so | grep -w GLOBAL
# 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
# 6: 0000000000001119 33 FUNC GLOBAL DEFAULT 14 public_function
# 51: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.5
# 53: 0000000000001119 33 FUNC GLOBAL DEFAULT 14 public_function