适用环境:Ubuntu 22.04 + ROS2 Humble
一、问题背景
ROS2 工作区一旦包含大量 C++ 包(SLAM、控制器、传感器驱动等),每次 colcon build 动辄耗时数分钟甚至十几分钟。主要痛点有两个:
- 重复编译:改了一个包,其余未改动的包却被重新编译
- 内存溢出 :
colcon默认并行编译所有包,包数多时极易把内存打爆,触发 OOM Killer,编译直接中断
本文给出两个针对性的解决方案。
二、ccache ------ 缓存编译结果,告别重复编译
原理
ccache 会把每次编译生成的 .o 文件按源码内容哈希缓存下来。下次编译时,若源码和编译参数完全相同,直接返回缓存结果,跳过实际编译,速度接近瞬间完成。
即使执行了 rm -rf build/,只要源码没变,ccache 依然命中缓存。
安装
bash
sudo apt install ccache
配置缓存目录和大小
写入 ~/.bashrc:
bash
export CCACHE_DIR="$HOME/.ccache"
export CCACHE_MAXSIZE="10G"
bash
source ~/.bashrc
缓存上限根据硬盘空间自行调整,10~20G 对大型 ROS2 工作区均够用。
全局永久生效(推荐)
colcon 支持通过 ~/.colcon/defaults.yaml 为所有工作区统一注入编译参数,无需每次手敲:
bash
mkdir -p ~/.colcon
cat > ~/.colcon/defaults.yaml << 'EOF'
build:
cmake-args:
- -DCMAKE_C_COMPILER_LAUNCHER=ccache
- -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- --no-warn-unused-cli
EOF
配置完成后,直接敲 colcon build 即可,ccache 自动接管所有 C/C++ 编译。
--no-warn-unused-cli说明 :工作区中若存在纯 Python 包(ament_python类型),CMake 会警告CMAKE_CXX_COMPILER_LAUNCHER未被使用。加上此参数可屏蔽该无害警告,保持输出整洁。
验证是否生效
bash
# 查看缓存命中统计
ccache -s
首次全量编译后再执行一次 colcon build,cache hit 数量应大幅上升,编译时间骤降。
bash
# 清零统计计数(不清除缓存内容)
ccache -z
三、控制并行数 ------ 防止编译时爆内存
问题原因
colcon 默认同时编译所有包,每个包又会启动多个编译线程,内存消耗随包数和线程数成倍放大。16G 内存的机器在编译 SLAM 相关工作区时经常 OOM。
解决方案
在 ~/.colcon/defaults.yaml 中追加并行控制参数:
yaml
build:
cmake-args:
- -DCMAKE_C_COMPILER_LAUNCHER=ccache
- -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- --no-warn-unused-cli
parallel-workers: 4 # 同时编译的包数,按内存酌情调整
cmake-args:
- -DCMAKE_BUILD_PARALLEL_LEVEL=4 # 每个包内部的并行线程数
注意 :
cmake-args在 YAML 中只能出现一次,需合并为同一个列表,完整写法见下方。
完整 ~/.colcon/defaults.yaml
yaml
build:
cmake-args:
- -DCMAKE_C_COMPILER_LAUNCHER=ccache
- -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- -DCMAKE_BUILD_PARALLEL_LEVEL=4
- --no-warn-unused-cli
parallel-workers: 4
| 参数 | 含义 |
|---|---|
parallel-workers |
colcon 同时构建的包数 |
CMAKE_BUILD_PARALLEL_LEVEL |
每个包内 make 使用的线程数 |
内存估算参考:parallel-workers × CMAKE_BUILD_PARALLEL_LEVEL × ~500MB,根据自身内存调整。32G 内存可适当放开到 8 × 8。
四、效果对比
| 场景 | 优化前 | 优化后 |
|---|---|---|
| 首次全量编译 | 基准 | 基准(建立缓存) |
| 未改动包的重新编译 | 与首次相当 | 接近 0 秒 |
| 清空 build/ 后重新编译 | 与首次相当 | 大幅缩短(命中缓存) |
| 大型工作区并行编译 | 易 OOM 中断 | 稳定完成 |
五、一键配置脚本
bash
#!/bin/bash
# 安装 ccache
sudo apt install -y ccache
# 写入环境变量
grep -qxF 'export CCACHE_DIR="$HOME/.ccache"' ~/.bashrc || \
echo 'export CCACHE_DIR="$HOME/.ccache"' >> ~/.bashrc
grep -qxF 'export CCACHE_MAXSIZE="10G"' ~/.bashrc || \
echo 'export CCACHE_MAXSIZE="10G"' >> ~/.bashrc
source ~/.bashrc
# 写入 colcon 全局配置
mkdir -p ~/.colcon
cat > ~/.colcon/defaults.yaml << 'EOF'
build:
cmake-args:
- -DCMAKE_C_COMPILER_LAUNCHER=ccache
- -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- -DCMAKE_BUILD_PARALLEL_LEVEL=4
- --no-warn-unused-cli
parallel-workers: 4
EOF
echo "配置完成,直接使用 colcon build 即可。"
保存为 setup_colcon_speedup.sh,chmod +x 后执行一次即可。
总结
- ccache:解决重复编译问题,改一个包只编译那一个包
- 并行数控制:解决大型工作区 OOM 问题,编译更稳定
~/.colcon/defaults.yaml:一次配置,所有工作区永久生效,colcon build无需带任何额外参数