Linux 导出符号冲突相关问题总结:在 linux 中使用动态链接库进行链接时出现冲突导致崩溃,查看原因是因为我们的动态连接库中使用的 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 动态链接库中使用第三方库的时候这点需要注意,稍不小心就会崩溃。
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/03-13/18658195.html