用 ccache 加速内核编译
~作为内核开发者,我最喜欢的就是在每一次做了少量修改后全量编译时摸鱼了~(不是)。其实每一次内核的编译都要等待很长时间,而且有一些场景还不能只做增量编译:
- 中间文件损坏:增量编译的过程中如果因为某些特殊原因(例如不耐烦按了 Ctrl+C,或者系统关机了)导致某些中间文件输出未遂,而 make 又以为它已经完成输出(make只看文件是否存在不验证文件内容),就会导致 vmlinux 会缺失部分内容。这时不想去查哪一个文件损坏了,最简单的办法就是
make clean删掉中间文件然后全量编译一遍; - LSP 支持:
bear -- make -j$(nproc)可以按照当前的编译命令生成compile_commands.json,方便 clangd 使用。(当然,也可以用scripts/clang-tools/gen_compile_commands.py,但是它导出的结果会存在对 clang 未知的编译器参数,有点难看)
anyway,为了减少等待编译的时间,我在偶然间发现了 ccache 这个编译器缓存工具。
使用方法
ccache 的实现原理是根据预处理后的源码、编译器版本、命令行参数算哈希,命中的情况下将之前生成的 .o 复制出来跳过编译。它支持两种使用方法:
前缀执行方法:
bashccache gcc -c example.c伪装执行方法:
bashcp ccache /usr/local/bin/ ln -s ccache /usr/local/bin/gcc ln -s ccache /usr/local/bin/g++ # 或者对不支持软链接的系统 cp ccache /usr/local/bin/gcc cp ccache /usr/local/bin/g++
伪装执行的方法可以更充分地拦截每一次编译。
在内核编译时,我们可以这样使用:
bash
# 将内核本体和 host 侧工具都用 ccache 缓存
make CC="ccache gcc" HOSTCC="ccache gcc" -j$(nproc)WARNING
由于第一次 ccache 需要构建缓存,所以反而会变得更慢。
TIP
虽然编译阶段会快不少,但是生成 BTF 的阶段和链接阶段还是会成为瓶颈。个人实测的最终节省的时间大约是 50% 左右。