您的位置:首页 > 运维架构 > Linux

Linux导出符号冲突相关问题总结

2017-03-10 20:37 3951 查看
在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文件为控制静态链接库导出符号文件,文件中所列举的函数即为静态库需要导出的符号表。
libxxx.a
{
xxxx_initialize();
xxxx_finalize();
}


接下来在编译的时候需要指定参数:
对于动态链接库:

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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: