Linux导出符号冲突相关问题总结
https://blog.csdn.net/tgxallen/article/details/61206766
在linux中使用动态链接库进行链接时出现冲突导致crash,查看原因是因为我们的动态连接库中使用的protubuf版本与对方使用的版本冲突。但是我们产品中的protubuf是以静态库的方式链入,怎么会出现版本冲突呢。谷歌了一下,究其原因是因为在Linux中会默认将所有导入的第三方库的接口一并导出,这使得产品先启动后再load我们的引擎的时候,我们的第三方库在使用接口的时候,使用的并不是我们自己版本的接口,而是产品使用的版本的接口。
如果想查看动态链接库导出符号表可以使用objdump工具,linux下 objdump -T xxxx.so > symbol.log 便可以查看所有动态链接库导出的接口。
在Linux中就需要去手动控制动态链接库或者静态链接库导出的接口。
在使用cmake编译的项目中,可以增加xxx.map与xxx.sym文件在CMakeList.txt中对导出函数进行控制。.map用于控制动态链接库导出符号,.sym文件文件用于控制静态链接库导出符号,同时在编译参数上也有区别,--retain-symbols-file 控制静态符号表,--version-script 控制动态符号表。所以举个例子:
假设libxxx.so为我们的动态链接库,export.map为控制动态链接库导出符号的文件,其中global区域代表我们想要导出的符号,local区域代表不想导出的符号,*号表示除了global中的符号全部不导出。
export.map文件内容如下:
libxxx.so
{
global:
xxx_initialize();
xxx_finalize();
local:
*;
}
假设libxxx.a为我们想导出的静态链接库,export.sym文件为控制静态链接库导出符号文件,文件中所列举的函数即为静态库需要导出的符号表。
接下来在编译的时候需要指定参数:
对于动态链接库:
CMakeList.txt中添加:
SET_TARGET_PROPERTIES (libxxx PROPERTIES LINK_FLAGS -Wl,--no-undefined,--version-script,${PROJECT_SOURCE_DIR}/xxx/export.map)
gcc编译时:
gcc -shared -o libxxx.so wl, --version-script=export.map
对于静态链接库:
CMakeList.txt中添加:
SET_TARGET_PROPERTIES (libxxx PROPERTIES LINK_FLAGS -Wl,--no-undefined,--retain-symbols-file,${PROJECT_SOURCE_DIR}/xxx/export.sym)
gcc编译时:
gcc -shared -o libxxx.so wl,--retain-symbols-file=export.sym
Linux动态链接库中使用第三方库的时候这点需要注意,稍不小心就会crash。