在使用 SCons 和 GCC 进行编译时,可以通过以下方法在编译结束后自动统计错误和警告的总数:
在 SConstruct
文件中添加以下代码,利用 Python 捕获编译输出并分析:
import re
def build_stats(target, source, env):
# 执行原始编译命令并捕获输出
cmd = env["CCCOM"] # 获取原始编译命令
process = subprocess.Popen(
cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
)
output, _ = process.communicate()
# 统计错误和警告
errors = len(re.findall(r"berror:b", output))
warnings = len(re.findall(r"bwarning:b", output))
print(f"n编译结果:错误数 = {errors}, 警告数 = {warnings}")
# 返回原始退出码
return process.returncode
# 替换默认的编译命令
env = Environment()
env["CCCOM"] = build_stats # 替换 C 编译器命令
env["CXXCOM"] = build_stats # 替换 C++ 编译器命令
在 SConstruct
中添加以下代码,将编译输出重定向到文件:
# 强制所有输出到 build.log(包括屏幕)
env = Environment()
env.Append(CCCOM=' 2>&1 | tee -a build.log') # Linux/macOS
# env.Append(CCCOM=' 2>&1 | tee.exe -a build.log') # Windows 安装 tee 工具后
# 每次构建前清空日志
def clear_log():
if os.path.exists('build.log'):
os.remove('build.log')
clear_log()
在 SConstruct
末尾添加:
# 构建结束后统计日志
def print_stats():
try:
with open('build.log', 'r') as f:
content = f.read()
errors = content.count('error:')
warnings = content.count('warning:')
print(f"n统计结果:错误总数 = {errors}, 警告总数 = {warnings}")
except Exception as e:
print("无法读取日志文件:", str(e))
# 注册构建后钩子
from SCons.Script import AlwaysBuild
AlwaysBuild(print_stats)
# 启用 JSON 格式诊断
env = Environment(CCFLAGS=['-fdiagnostics-format=json'])
# 添加后处理脚本
import json
def parse_json_stats():
try:
with open('build.log', 'r') as f:
errors = 0
warnings = 0
for line in f:
try:
diag = json.loads(line)
if diag.get('kind') == 'error':
errors += 1
elif diag.get('kind') == 'warning':
warnings += 1
except:
pass
print(f"nJSON统计:错误 = {errors}, 警告 = {warnings}")
except Exception as e:
print("解析失败:", str(e))
AlwaysBuild(parse_json_stats)
scons -Q # -Q 安静模式,减少干扰输出
...(编译过程输出)...
统计结果:错误总数 = 2, 警告总数 = 15
-j
多线程编译,日志内容可能交错,但不影响关键字统计。tee
工具(Git Bash/Cygwin 自带)。berror:b
确保精确匹配编译器输出的关键字。这些方法可根据项目需求灵活组合使用,推荐方法2作为通用解决方案。
更多回帖