Ubuntu 18.04动态库未包含静态库符号问题求助
解决Ubuntu 12.04与18.04间动态库符号缺失问题
这个问题的核心是GCC链接器在不同版本中的默认行为变化:Ubuntu 18.04使用的新版链接器(配合GCC 7.x)对静态库到动态库的符号打包做了体积优化,而Ubuntu 12.04的旧版链接器没有这个限制。
问题原因
在Ubuntu 12.04的旧版链接器中,把静态库(.a)链接到动态库(.so)时,链接器会默认将静态库的所有符号都打包进动态库。但Ubuntu 18.04的新版链接器为了减小动态库体积,默认只会将动态库自身直接引用到的静态库符号包含进去——如果你的动态库代码没有调用静态库的函数/符号,这些符号就会被链接器丢弃,导致nm -g无法看到它们。
解决方案:强制包含整个静态库的符号
修改你的动态库生成命令,用-Wl,--whole-archive和-Wl,--no-whole-archive包裹静态库文件,强制链接器将静态库的所有符号都加入到动态库中:
g++ -shared -I(include path) -L(other library path) -l(librarys) -o filename.so -Wl,-soname,filename.so -Wl,--whole-archive staticlib.a -Wl,--no-whole-archive
参数解释
-Wl,--whole-archive:告诉链接器,将后续的静态库文件中的所有符号都包含进输出文件,无论是否被动态库代码引用。-Wl,--no-whole-archive:恢复链接器的默认行为,避免影响后续可能添加的其他库(如果有的话)。
验证步骤
- 用修改后的命令重新生成动态库
filename.so - 再次执行
nm -g filename.so,你应该能看到静态库中的所有符号了,和Ubuntu 12.04中的输出一致。
额外说明
如果你的静态库编译时使用了-fvisibility=hidden选项,可能还需要添加-Wl,--export-dynamic参数确保符号被导出到动态符号表,但根据你的描述,Ubuntu 12.04能正常显示符号,所以这个情况大概率不存在。
内容的提问来源于stack exchange,提问作者chaitanya sonagara
相关产品推荐
相关产品推荐

