You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何采集make编译过程的耗时、告警错误等指标(无GCC9环境)

低侵入采集编译指标方案(适配GCC < 9、CMake+Makefile场景)

不需要重定向全量make输出做复杂解析,全程不用修改项目原有CMake配置,侵入性接近为0。

1. 单目标构建耗时采集

核心用CMake原生支持的**编译器启动器(compiler launcher)**机制,在不改动编译逻辑的前提下,包装所有g++调用行为,独立统计每个编译/链接步骤的耗时:

  • 第一步,写一个轻量shell包装脚本,比如命名为cxx_build_wrapper.sh,内容如下:
#!/bin/bash
# 入参1:真实g++可执行文件路径,后续入参为CMake传给g++的原生编译参数
REAL_COMPILER=$1
shift

# 从g++参数中提取当前构建的目标输出路径,作为统计维度的唯一标识
TARGET_OUTPUT=""
params=("$@")
for ((idx=0; idx<${#params[@]}; idx++)); do
    if [[ "${params[idx]}" == "-o" ]]; then
        TARGET_OUTPUT="${params[idx+1]}"
        break
    fi
done

# 无-o参数的场景(比如查版本、编译参数探测)直接跳过统计
if [[ -z "$TARGET_OUTPUT" ]]; then
    exec "$REAL_COMPILER" "$@"
fi

mkdir -p ./build_metrics
START_TIME=$(date +%s.%N)
# 透传执行g++编译,将g++原生stderr输出单独留存,不干扰终端正常打印
"$REAL_COMPILER" "$@" 2> >(tee -a "./build_metrics/${TARGET_OUTPUT//\//_}.diag" >&2)
BUILD_EXIT_CODE=$?
END_TIME=$(date +%s.%N)

# 写入耗时统计,csv格式可直接导入表格/可视化工具处理
COST=$(echo "$END_TIME - $START_TIME" | bc -l)
echo "$TARGET_OUTPUT,$START_TIME,$END_TIME,$COST,$BUILD_EXIT_CODE" >> ./build_metrics/build_time.csv
exit $BUILD_EXIT_CODE
  • 第二步,给脚本加可执行权限:chmod +x cxx_build_wrapper.sh
  • 第三步,CMake配置阶段传入launcher参数即可,不需要改项目内任何CMakeLists代码:
# 提前创建构建目录和指标存储目录
mkdir -p build build_metrics
cd build
# 配置时指定launcher,把真实g++路径作为固定参数传给wrapper
cmake -DCMAKE_CXX_COMPILER_LAUNCHER="/absolute/path/to/cxx_build_wrapper.sh,$(which g++)" ..
# 正常执行make即可,所有编译步骤会自动被包装
make -j$(nproc)

这个方案统计的耗时是纯编译/链接步骤的实际执行时间,不会混入make本身的目录切换、任务调度等无关耗时,精度到纳秒级,后续如果换Ninja生成器也能直接复用。

2. 全量警告/错误采集(适配GCC 9以下版本)

不需要依赖-fdiagnostics-format=json特性,也不需要过滤make的无关输出:
wrapper脚本已经把每个g++进程的原生stderr输出单独存到了build_metrics目录下的.diag文件里,完全没有make打印的Entering directory、Building CXX object这类冗余内容。
所有版本GCC的诊断信息(错误、警告、备注)都遵循固定的行前缀格式:

<源文件路径>:<行号>:<列号>: <诊断级别>: <诊断内容>

其中诊断级别只有error、warning、note三类,直接用正则过滤就能拿到全量有效诊断信息,零误判:

# 汇总所有编译/链接阶段的错误、警告到统一文件
grep -rE ":[0-9]+:[0-9]+: (error|warning):" ./build_metrics/*.diag > ./build_metrics/all_issues.txt

如果需要按目标筛选问题,直接查对应目标的.diag文件即可。

可选增强

  • 如果需要采集编译各阶段(预处理/编译/汇编)的细分耗时,直接在wrapper里给g++追加-ftime-report参数,该参数的输出会自动存入对应.diag文件,解析即可拿到细分耗时。
  • 如果项目中有自定义命令直接调用g++、没有走CMake的CMAKE_CXX_COMPILER变量,可以把wrapper软链为g放到PATH优先级最高的目录,就能覆盖所有g调用场景。
  • 不需要持久化单目标日志的话,可以直接在wrapper里把诊断信息和耗时统一写入单一日志文件,省去事后汇总步骤。

内容的提问来源于stack exchange,提问作者ElCactouss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 05:00:57