build-acceleration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBuild Acceleration
构建加速
Purpose
目标
Guide agents through reducing C/C++ build times using caching (ccache/sccache), distributed compilation (distcc), unity/jumbo builds, precompiled headers, split-DWARF for faster linking, and include pruning with IWYU.
指导Agent通过缓存(ccache/sccache)、分布式编译(distcc)、Unity/Jumbo构建、预编译头、用于加快链接速度的Split-DWARF以及使用IWYU进行包含文件裁剪等方式,缩短C/C++项目的构建时间。
Triggers
触发场景
- "My C++ build is too slow — how do I speed it up?"
- "How do I set up ccache / sccache?"
- "How do precompiled headers work with CMake?"
- "How do I set up distributed compilation with distcc?"
- "How do I reduce link times with split-DWARF?"
- "How do I find which headers are slowing down compilation?"
- "我的C++构建速度太慢了——如何加快速度?"
- "如何配置ccache / sccache?"
- "预编译头如何与CMake配合使用?"
- "如何配置distcc实现分布式编译?"
- "如何使用Split-DWARF缩短链接时间?"
- "如何找出拖慢编译速度的头文件?"
Workflow
工作流程
1. Diagnose the bottleneck first
1. 首先诊断瓶颈
bash
undefinedbash
undefinedTime the full build
Time the full build
time cmake --build build -j$(nproc)
time cmake --build build -j$(nproc)
Find the slowest TUs (CMake ≥3.16 with --profiling-output)
Find the slowest TUs (CMake ≥3.16 with --profiling-output)
cmake -S . -B build -DCMAKE_CXX_FLAGS="-ftime-report"
cmake --build build 2>&1 | grep "Total" | sort -t: -k2 -rn | head -20
cmake -S . -B build -DCMAKE_CXX_FLAGS="-ftime-report"
cmake --build build 2>&1 | grep "Total" | sort -t: -k2 -rn | head -20
Ninja build timings (use ninja -j1 for serial timing)
Ninja build timings (use ninja -j1 for serial timing)
ninja -C build -j1 2>&1 | grep "^[" | sort -t" " -k2 -rn | head -20
undefinedninja -C build -j1 2>&1 | grep "^[" | sort -t" " -k2 -rn | head -20
undefined2. ccache — compiler cache
2. ccache — 编译器缓存
bash
undefinedbash
undefinedInstall
Install
apt-get install ccache # Ubuntu/Debian
brew install ccache # macOS
apt-get install ccache # Ubuntu/Debian
brew install ccache # macOS
Check hit rate
Check hit rate
ccache -s
ccache -s
Configure cache size (default 5GB)
Configure cache size (default 5GB)
ccache -M 20G
ccache -M 20G
Invalidate cache if needed
Invalidate cache if needed
ccache -C
CMake integration (recommended over prefix hacks):
```cmakeccache -C
CMake集成(推荐使用此方式而非前缀 hack):
```cmakeCMakeLists.txt
CMakeLists.txt
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
endif()
Key `~/.config/ccache/ccache.conf` options:
```ini
max_size = 20G
compression = true
compression_level = 6find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
endif()
`~/.config/ccache/ccache.conf`的关键配置项:
```ini
max_size = 20G
compression = true
compression_level = 6For CI: share cache across jobs
For CI: share cache across jobs
cache_dir = /shared/ccache
undefinedcache_dir = /shared/ccache
undefined3. sccache — cloud-compatible cache (Rust, C/C++)
3. sccache — 兼容云环境的缓存工具(支持Rust、C/C++)
bash
cargo install sccachebash
cargo install sccacheOr: brew install sccache
Or: brew install sccache
Set as compiler launcher
Set as compiler launcher
export RUSTC_WRAPPER=sccache # for Rust
export CMAKE_C_COMPILER_LAUNCHER=sccache # for CMake
export RUSTC_WRAPPER=sccache # for Rust
export CMAKE_C_COMPILER_LAUNCHER=sccache # for CMake
With S3 backend
With S3 backend
export SCCACHE_BUCKET=my-build-cache
export SCCACHE_REGION=us-east-1
sccache --start-server
sccache --show-stats
undefinedexport SCCACHE_BUCKET=my-build-cache
export SCCACHE_REGION=us-east-1
sccache --start-server
sccache --show-stats
undefined4. Precompiled headers (PCH)
4. 预编译头(PCH)
PCH compiles a large header once and reuses the binary form.
cmake
undefinedPCH会一次性编译大型头文件,并复用其二进制形式。
cmake
undefinedCMake ≥3.16 native PCH support
CMake ≥3.16 native PCH support
target_precompile_headers(mylib PRIVATE
<vector>
<string>
<unordered_map>
"myproject/common.h"
)
target_precompile_headers(mylib PRIVATE
<vector>
<string>
<unordered_map>
"myproject/common.h"
)
Share PCH across targets (avoids recompilation)
Share PCH across targets (avoids recompilation)
target_precompile_headers(myapp REUSE_FROM mylib)
```c
// Traditional: stdafx.h / pch.h approach
// All TUs include pch.h as the very first include
// pch.h includes heavy system headers
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>PCH is most effective when headers are large and stable (STL, Boost, Qt). Avoid PCH for frequently-changing project headers.
target_precompile_headers(myapp REUSE_FROM mylib)
```c
// Traditional: stdafx.h / pch.h approach
// All TUs include pch.h as the very first include
// pch.h includes heavy system headers
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>当头文件体积大且稳定时(如STL、Boost、Qt),PCH的效果最佳。对于频繁变更的项目头文件,建议避免使用PCH。
5. Unity / jumbo builds
5. Unity/Jumbo构建
Combine multiple files into one TU to reduce header parsing overhead and improve inlining.
.cppcmake
undefined将多个文件合并为一个TU,以减少头文件解析开销并提升内联优化效果。
.cppcmake
undefinedCMake ≥3.16 unity build
CMake ≥3.16 unity build
set_target_properties(mylib PROPERTIES UNITY_BUILD ON)
set_target_properties(mylib PROPERTIES UNITY_BUILD ON)
Control batch size (default 8 files per unity TU)
Control batch size (default 8 files per unity TU)
set_target_properties(mylib PROPERTIES UNITY_BUILD_BATCH_SIZE 16)
set_target_properties(mylib PROPERTIES UNITY_BUILD_BATCH_SIZE 16)
Exclude specific files from unity (e.g., if they have ODR issues)
Exclude specific files from unity (e.g., if they have ODR issues)
set_source_files_properties(problem.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
Manual unity file:
```cpp
// unity_build.cpp
#include "module_a.cpp"
#include "module_b.cpp"
#include "module_c.cpp"Watch out for: anonymous namespaces (each TU has its own), in headers, duplicate static variables.
using namespaceset_source_files_properties(problem.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
手动编写Unity文件:
```cpp
// unity_build.cpp
#include "module_a.cpp"
#include "module_b.cpp"
#include "module_c.cpp"注意事项:匿名命名空间(每个TU都有独立的匿名命名空间)、头文件中的、重复的静态变量。
using namespace6. split-DWARF — reduce link time
6. Split-DWARF — 缩短链接时间
Split DWARF puts debug info in sidecar files, dramatically reducing what the linker must process.
.dwobash
undefinedSplit-DWARF将调试信息存储在附属文件中,大幅减少链接器需要处理的数据量。
.dwobash
undefinedGCC / Clang
GCC / Clang
gcc -g -gsplit-dwarf -o prog main.c
gcc -g -gsplit-dwarf -o prog main.c
CMake global
CMake global
add_compile_options(-gsplit-dwarf)
add_compile_options(-gsplit-dwarf)
Combine .dwo files for distribution (optional)
Combine .dwo files for distribution (optional)
dwp -o prog.dwp prog # GNU dwp tool
Pair with `--gdb-index` for faster GDB startup:
```bash
gcc -g -gsplit-dwarf -Wl,--gdb-index -o prog main.cLink time comparison (large project, typical): full DWARF ~4×–6× longer link vs .
-g-gsplit-dwarfdwp -o prog.dwp prog # GNU dwp tool
搭配`--gdb-index`使用可加快GDB启动速度:
```bash
gcc -g -gsplit-dwarf -Wl,--gdb-index -o prog main.c链接时间对比(大型项目典型情况):使用生成完整DWARF调试信息的链接时间比使用长约4-6倍。
-g-gsplit-dwarf7. distcc — distributed compilation
7. distcc — 分布式编译
bash
undefinedbash
undefinedInstall on all machines
Install on all machines
apt-get install distcc
apt-get install distcc
Start daemon on worker machines
Start daemon on worker machines
distccd --daemon --allow 192.168.1.0/24 --jobs 8
distccd --daemon --allow 192.168.1.0/24 --jobs 8
Client: set DISTCC_HOSTS
Client: set DISTCC_HOSTS
export DISTCC_HOSTS="localhost/4 worker1/8 worker2/8"
make -j20 CC="distcc gcc"
export DISTCC_HOSTS="localhost/4 worker1/8 worker2/8"
make -j20 CC="distcc gcc"
CMake integration
CMake integration
set(CMAKE_C_COMPILER_LAUNCHER distcc)
set(CMAKE_CXX_COMPILER_LAUNCHER distcc)
Stack with ccache: `CC="ccache distcc gcc"` — ccache checks local cache first, falls back to distcc.set(CMAKE_C_COMPILER_LAUNCHER distcc)
set(CMAKE_CXX_COMPILER_LAUNCHER distcc)
与ccache结合使用:`CC="ccache distcc gcc"` — ccache先检查本地缓存,未命中时再使用distcc。8. Include pruning with IWYU
8. 使用IWYU进行包含文件裁剪
bash
undefinedbash
undefinedInstall
Install
apt-get install iwyu
apt-get install iwyu
Run via CMake
Run via CMake
cmake -S . -B build -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=iwyu
cmake --build build 2>&1 | tee iwyu.log
cmake -S . -B build -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=iwyu
cmake --build build 2>&1 | tee iwyu.log
Apply fixes automatically
Apply fixes automatically
fix_include < iwyu.log --nosafe_headers
See `skills/build-systems/include-what-you-use` for full IWYU workflow.
For ccache configuration options, see [references/ccache-config.md](references/ccache-config.md).fix_include < iwyu.log --nosafe_headers
完整的IWYU工作流请参考`skills/build-systems/include-what-you-use`。
关于ccache的配置选项,请参考[references/ccache-config.md](references/ccache-config.md)。Related skills
相关技能
- Use for CMake project structure
skills/build-systems/cmake - Use for IWYU header pruning
skills/build-systems/include-what-you-use - Use for Rust-specific build acceleration
skills/rust/rust-build-times - Use for split-DWARF internals
skills/debuggers/dwarf-debug-format
- 如需了解CMake项目结构,请使用技能
skills/build-systems/cmake - 如需了解IWYU头文件裁剪,请使用技能
skills/build-systems/include-what-you-use - 如需了解Rust专属构建加速,请使用技能
skills/rust/rust-build-times - 如需了解Split-DWARF内部原理,请使用技能
skills/debuggers/dwarf-debug-format