编译速度慢怎么优化 —— 手机上让 Clang 更快
先搞清楚慢在哪
编译慢的原因分三类,对应不同的优化手段:
| 类别 | 典型原因 | 优化方向 |
|---|---|---|
| 编译器配置 | Debug 模式没优化、标准库过重 | 调整编译参数 |
| 缓存缺失 | 第一次编译、缓存被清了 | 保持缓存、增量编译 |
| 项目本身 | 头文件过度包含、模板过多 | 拆分项目、前置声明 |
一、编译器层面优化
正确设置 Debug vs Release
Cxxdroid 编译时有「模式」可选:
- Debug:带调试符号(
-g)、无优化(-O0)——编译慢,但可以调试 - Release:无调试符号、开启优化(
-O2或-O3)——编译更快(不是更慢!)
很多人以为 Release 模式更慢,刚好相反——Clang 在 -O2 下编译速度更快(优化器比完整的 Debug 配置处理量更少),而且生成的可执行文件也更小、运行更快。
调试验完就切回 Release 模式编译。
统一 C++ 标准
在 CMakeLists.txt 里固定 C++ 标准,不要让编译器用默认值。默认值可能是 C++14 或更低,和你代码用的特性不匹配时编译器可能要做额外兼容处理。
set(CMAKE_CXX_STANDARD 17) # 推荐 C++17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
关闭不必要的警告
-Wall -Wextra -Wpedantic 会让编译器做更多检查。如果你不需要这些警告,可以暂时关掉(发布前再开)。
二、缓存层面优化
保持编译缓存
Cxxdroid 的编译器缓存(类似 ccache)只要你不清就一直积累。用得越久、缓存命中率越高、编译越快。
千万不要随便清理应用缓存——那是手动浪费自己的编译加速积累。
增量编译
增量编译是 Clang 自身的能力:只重新编译改过的文件。
一个 50 个源文件的项目,改了其中 1 个,Clang 只重编那 1 个——加上链接,可能只要原来时间的 1/50。
避免频繁全量重编
每次 Clean + Rebuild 都会让所有缓存失效、所有文件重新编译。除非修改了 CMakeLists.txt、编译器版本或库版本,否则不要 Clean。
三、项目结构优化
减少头文件包含
C++ 编译慢的第一大元凶:头文件过度包含。
Boost 的 #include <boost/asio.hpp> 单一个头文件展开可能超过 10 万行代码。每一个包含它的 .cpp 文件编译时都要重新展开这 10 万行——哪怕你根本没用到 Boost.Asio 的功能。
优化手法:
- 能前置声明(forward declare)就不 include 头文件
- 把
#include移到 .cpp 文件里,头文件尽量只依赖前置声明 - 用
#pragma once或 include guard 防止重复展开
拆分大文件
单个文件超过 1000 行时,考虑拆分成多个职责清晰的小文件。编译时只有改过的那个小文件需要重新处理。
模板轻量化
模板越多、越复杂(特别是模板元编程),编译越慢。能不用模板就不用,能用运行时多态就用运行时多态。
减少宏展开
宏 #define 嵌套层级过深也会拖慢编译。用 constexpr、inline 函数代替宏。
实际效果对比
假设编译一个包含 Boost + SDL2 + 10 个源文件的项目:
| 操作 | 预计耗时 |
|---|---|
| 第一次编译(缓存全空) | 15-30 秒 |
| 改 1 个文件后增量编译 | 2-5 秒 |
| 完全没改动但继续点编译(缓存全命中) | < 1 秒 |
| Clean 后重新全量编译 | 15-30 秒 |
关键结论:用得越多、缓存越满、编译越快。如果第一次编译慢,别急——第二次就会快很多。
手机硬件限制的现实
最后要说实话:手机 CPU 主频通常 2-3 GHz,比桌面 i5/i7 的 4-5 GHz 慢不少。再怎么优化,手机上编译一个大型项目(50+ 源文件 + Boost 依赖)终究比桌面慢。
务实策略:
- 手机上:写代码、跑小项目、快速验证思路
- 桌面上:写大项目、完整编译、深度调试
Cxxdroid 写的 CMakeLists.txt 和源码在 CLion / VS Code 上直接能用——两个环境无缝衔接。