RedHat 5下GCC编译C++程序(Sconscript配置)遇__gcov_init隐藏符号错误
我来帮你搞定这个链接错误问题,我之前在RHEL5环境下用GCC和Scons做覆盖率测试时也碰到过类似的情况~
首先,咱们先揪出问题的核心原因:你遇到的hidden symbol '__gcov_init...' is referenced by DSO错误,主要是因为Sconscript的参数配置有两处关键问题,再加上可能的链接顺序或依赖库编译问题导致的。
1. 修正Scons的参数变量名错误
你写的CCFLAG和LINKFLAG是单数,但Scons里对应的正确变量名是复数形式:CCFLAGS(编译参数)和LINKFLAGS(链接参数)。单数的变量名Scons根本不会识别,相当于你之前加的覆盖率参数完全没生效!
2. 正确配置编译与链接参数
把编译和链接的覆盖率参数整理成正确的格式,建议用列表一次性添加,既清晰又避免重复:
编译配置(替换你原来的代码)
env.Append(CCFLAGS=['-fprofile-arcs', '-ftest-coverage', '--coverage'])
小贴士:在RHEL5的GCC(一般是4.x版本)里,
--coverage其实已经包含了-fprofile-arcs和-ftest-coverage,所以也可以简化成env.Append(CCFLAGS=['--coverage'])
链接配置(替换你原来的代码)
env.Append(LINKFLAGS=['-fprofile-arcs', '--coverage', '-lgcov'])
这里要注意-lgcov的位置,必须放在链接参数的最后——链接器是按顺序处理库的,需要让它在处理完所有目标文件后再加载gcov库,才能正确解析__gcov_init这类符号。
3. 处理依赖动态库(DSO)的情况
如果你的程序依赖了自己编译的动态共享库,那这些库也必须用同样的覆盖率参数(--coverage)编译。否则动态库会尝试引用主程序中被标记为隐藏的__gcov_init符号,就会触发你看到的错误。
4. 清理旧产物重新构建
最后,一定要先清理之前编译的目标文件和可执行文件,再重新构建,避免旧的未包含覆盖率信息的文件干扰:
scons -c && scons
按照上面的步骤调整后,这个链接错误应该就能解决了~
内容的提问来源于stack exchange,提问作者renjana

