build-acceleration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Build 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
undefined
bash
undefined

Time 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
undefined
ninja -C build -j1 2>&1 | grep "^[" | sort -t" " -k2 -rn | head -20
undefined

2. ccache — compiler cache

2. ccache — 编译器缓存

bash
undefined
bash
undefined

Install

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):

```cmake
ccache -C

CMake集成(推荐使用此方式而非前缀 hack):

```cmake

CMakeLists.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 = 6
find_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 = 6

For CI: share cache across jobs

For CI: share cache across jobs

cache_dir = /shared/ccache
undefined
cache_dir = /shared/ccache
undefined

3. sccache — cloud-compatible cache (Rust, C/C++)

3. sccache — 兼容云环境的缓存工具(支持Rust、C/C++)

bash
cargo install sccache
bash
cargo install sccache

Or: 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
undefined
export SCCACHE_BUCKET=my-build-cache export SCCACHE_REGION=us-east-1 sccache --start-server
sccache --show-stats
undefined

4. Precompiled headers (PCH)

4. 预编译头(PCH)

PCH compiles a large header once and reuses the binary form.
cmake
undefined
PCH会一次性编译大型头文件,并复用其二进制形式。
cmake
undefined

CMake ≥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
.cpp
files into one TU to reduce header parsing overhead and improve inlining.
cmake
undefined
将多个
.cpp
文件合并为一个TU,以减少头文件解析开销并提升内联优化效果。
cmake
undefined

CMake ≥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),
using namespace
in headers, duplicate static variables.
set_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 namespace
、重复的静态变量。

6. split-DWARF — reduce link time

6. Split-DWARF — 缩短链接时间

Split DWARF puts debug info in
.dwo
sidecar files, dramatically reducing what the linker must process.
bash
undefined
Split-DWARF将调试信息存储在
.dwo
附属文件中,大幅减少链接器需要处理的数据量。
bash
undefined

GCC / 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.c
Link time comparison (large project, typical):
-g
full DWARF ~4×–6× longer link vs
-gsplit-dwarf
.
dwp -o prog.dwp prog # GNU dwp tool

搭配`--gdb-index`使用可加快GDB启动速度:

```bash
gcc -g -gsplit-dwarf -Wl,--gdb-index -o prog main.c
链接时间对比(大型项目典型情况):使用
-g
生成完整DWARF调试信息的链接时间比使用
-gsplit-dwarf
长约4-6倍。

7. distcc — distributed compilation

7. distcc — 分布式编译

bash
undefined
bash
undefined

Install 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
undefined
bash
undefined

Install

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
    skills/build-systems/cmake
    for CMake project structure
  • Use
    skills/build-systems/include-what-you-use
    for IWYU header pruning
  • Use
    skills/rust/rust-build-times
    for Rust-specific build acceleration
  • Use
    skills/debuggers/dwarf-debug-format
    for split-DWARF internals
  • 如需了解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
    技能