CMake 編譯支持 ccache 配置比較容易,但 Makefiles 等其他構(gòu)建工具支持 ccache 就不一定了,往往有些麻煩,想支持還不是那么容易。本文總結(jié)了主流 C/C++ 構(gòu)建工具啟用 ccache 的方法和注意事項。
1. CMake 支持 ccache
CMake 支持 ccache 是最簡單的,可以在 toolchain_file.cmake 中全局指定,也可以通過命令行參數(shù) -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache 動態(tài)設(shè)置,前提是 ccache 在環(huán)境變量 PATH 中存在。
方法一:在 toolchain_file.cmake 中設(shè)置
set(CMAKE_C_COMPILER_LAUNCHER "ccache")
set(CMAKE_CXX_COMPILER_LAUNCHER "ccache")
方法二:通過命令行參數(shù)
cmake .. -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
注意:在 Windows 下使用 CMake 時,如果默認 generator 是
Visual Studio xxxx,ccache 不會生效。必須指定 generator 為Ninja才能啟用 ccache:
cmake .. -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
2. Makefiles 支持 ccache
雖然很多第三方庫使用 Makefiles 來編譯,但它們往往存在很大的差異,沒有辦法用一種配置支持所有的 Makefiles 項目啟用 ccache。
2.1 常規(guī) Makefiles 項目(Linux/Unix)
對于使用標(biāo)準(zhǔn) autotools 的項目(如 x264、sqlite3 等),只需設(shè)置環(huán)境變量:
export CC="ccache gcc"
export CXX="ccache g++"
./configure
make
2.2 支持 --cc= 參數(shù)的項目(如 ffmpeg)
有些項目(如 ffmpeg)即使在環(huán)境變量中定義了 CC 并包含 ccache,configure 腳本也會自動剝離 ccache。需要通過 --cc= 參數(shù)顯式指定:
./configure --cc='ccache gcc' --cxx='ccache g++'
make
2.3 支持 -ccache 選項的項目(如 Qt)
Qt 等項目提供了專門的 ccache 選項:
./configure -ccache
make
2.4 Windows + MSVC + Makefiles 的特殊情況
在 Windows 下使用 MSVC + MSYS2/Cygwin + Makefiles 時,ccache 支持更加復(fù)雜:因為 msys2 不支持配置以CC="ccache cl.exe"配置編譯工具,可行的辦法是修改build目錄下產(chǎn)生的config.mak:
SRCPATH=../src
prefix=/d/Workspace/golang/celer/packages/x264@stable@x86_64-windows-msvc-community-14.44@unnamed@release
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
libdir=${exec_prefix}/lib
includedir=${prefix}/include
SYS_ARCH=X86_64
SYS=WINDOWS
CC=ccache cl.exe # add ccache as prefix of CC here.
CFLAGS=-DNDEBUG -O2 -fp:fast -I. -I$(SRCPATH) -nologo -GS- -DHAVE_STRING_H -I$(SRCPATH)/extras
...
此過程也屬于過度hardcode的方案,有侵入性,所以也不推薦。
3. Meson 支持 ccache
Meson 支持 ccache 只需要在配置編譯環(huán)境的 cross_file.toml 或 native_file.toml 里,將 c 和 cpp 編譯器定義為數(shù)組,在數(shù)組開頭加上 ccache 即可:
Linux 交叉編譯配置示例:
[binaries]
c = ['ccache', 'aarch64-linux-gnu-gcc']
cpp = ['ccache', 'aarch64-linux-gnu-g++']
ar = 'aarch64-linux-gnu-ar'
strip = 'aarch64-linux-gnu-strip'
本地編譯配置示例:
[binaries]
c = ['ccache', 'gcc']
cpp = ['ccache', 'g++']
3.1 Windows + MSVC 的限制
重要:Meson 在 Windows 下使用 MSVC 時,ccache 默認無法生效。
原因:Meson 在檢測到 MSVC 編譯器時,會特殊處理 compiler wrapper 數(shù)組:
- 生成的
build.ninja文件中,MSVC 的command會自動剝離ccache前綴 - 這是 Meson 的設(shè)計決策,認為 MSVC 不支持 compiler wrapper 方式
Windows + MSVC 生成的 build.ninja:
rule c_COMPILER
command = cl.exe $ARGS /Fo$out /c $in
deps = msvc
description = Compiling C object $out
Linux + GCC 生成的 build.ninja:
rule c_COMPILER
command = ccache aarch64-linux-gnu-gcc $ARGS -MD -MQ $out -MF $DEPFILE -o $out -c $in
deps = gcc
depfile = $DEPFILE_UNQUOTED
description = Compiling C object $out
解決方案(不推薦):
理論上可以手動修改生成的 build.ninja 文件,在 command 前添加 ccache,但這種方式過于侵入性,每次重新配置都會被覆蓋,因此不推薦使用。
建議:
- 在 Windows 上使用 Meson 時,改用 clang 或 gcc 編譯器
- 或使用 CMake + Ninja 替代 Meson
4. Boost (B2) 支持 ccache
Boost 有自己的構(gòu)建工具 B2(也稱為 bjam)。在 configure/bootstrap 階段會在源碼根目錄下生成 project-config.jam 配置文件。
啟用 ccache 的步驟:
- 運行 bootstrap 腳本:
./bootstrap.sh --prefix=/path/to/install
- 編輯生成的
project-config.jam,在 toolchain 路徑前添加ccache:
# B2 Configuration
# Automatically generated by bootstrap.sh
import option ;
import feature ;
# Compiler configuration
if ! gcc in [ feature.values <toolset> ]
{
using gcc : : "ccache" "/home/xxx/downloads/gcc-ubuntu-11.5.0-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-g++" ;
}
project : default-build <toolset>gcc ;
- 使用 B2 編譯:
./b2 install
4.1 Windows + MSVC 的特殊處理
在 Windows 上使用 MSVC 編譯 Boost 時:
-
不要在 bootstrap.bat 執(zhí)行時設(shè)置 CC/CXX 環(huán)境變量,因為 bootstrap.bat 會將
ccache cl.exe當(dāng)作單個命令名而失敗 - 只在后續(xù)的 B2 編譯階段設(shè)置環(huán)境變量或修改
project-config.jam
示例(不推薦在 bootstrap 時設(shè)置):
REM 錯誤示例 - bootstrap 會失敗
set CC=ccache cl.exe
bootstrap.bat
REM 正確示例 - bootstrap 后再設(shè)置
bootstrap.bat
REM 然后編輯 project-config.jam 或在 b2 時設(shè)置環(huán)境變量
總結(jié)與建議
| 構(gòu)建工具 | Linux/Unix | Windows + GCC/Clang | Windows + MSVC | 難度 |
|---|---|---|---|---|
| CMake | ? 簡單 | ? 簡單(使用 Ninja) | ? 簡單(使用 Ninja) | ? |
| Makefiles (標(biāo)準(zhǔn)) | ? 簡單 | ? 中等 | ?? 復(fù)雜 | ?? |
| Makefiles (--cc=) | ? 簡單 | ? 中等 | ?? 復(fù)雜 | ?? |
| Meson | ? 簡單 | ? 簡單 | ?? 復(fù)雜 | ??? |
| Boost (B2) | ? 中等 | ? 中等 | ?? 復(fù)雜 | ??? |
關(guān)鍵要點:
- ? Linux/Unix 環(huán)境:大部分構(gòu)建工具都能輕松啟用 ccache
- ?? Windows + MSVC:支持較為復(fù)雜,建議優(yōu)先使用 CMake + Ninja
- ?? 環(huán)境變量 vs 參數(shù):優(yōu)先使用環(huán)境變量,特殊項目才需要參數(shù)
- ?? 侵入性修改:盡量避免修改生成的構(gòu)建文件(如 build.ninja、config.mak)
6. 使用 Celer 簡化 ccache 配置
? 至此,你可能已經(jīng)感受到了手動配置各種構(gòu)建工具啟用 ccache 的麻煩和復(fù)雜性。如果你正在尋找更簡單的解決方案,不妨嘗試 Celer——一個現(xiàn)代化的 C/C++ 包管理器。
Celer 的優(yōu)勢:
- ?? 自動化:已經(jīng)為主流構(gòu)建工具(CMake、Meson、Makefiles、Boost B2 等)封裝了 ccache 支持
- ?? 統(tǒng)一配置:一個配置文件搞定所有項目的 ccache 設(shè)置
- ?? 跨平臺:Linux、Windows統(tǒng)一體驗
- ?? 依賴管理:自動處理依賴關(guān)系和構(gòu)建順序
Celer 配置示例(celer.toml):
[global]
conf_repo = ""
platform = "aarch64-linux-ubuntu-22.04-gcc-11.5.0"
project = "my_project"
build_type = "release"
jobs = 6
verbose = false
offline = false
[ccache]
dir = "/home/phil/Downloads/ccache"
maxsize = "10G"
nocompress = true
只需簡單配置,Celer 會自動為不同的構(gòu)建工具啟用 ccache:
- ? CMake 項目:自動設(shè)置
CMAKE_C_COMPILER_LAUNCHER和CMAKE_CXX_COMPILER_LAUNCHER - ? Meson 項目:自動在 cross_file.toml 中配置 compiler wrapper
- ? Makefiles 項目:智能檢測并設(shè)置環(huán)境變量或參數(shù)
- ? Boost B2:自動修改 project-config.jam
使用示例:
# 安裝依賴包
celer install opencv@4.10.0
# 所有編譯自動啟用 ccache,無需手動配置
查看 ccache 統(tǒng)計:
# Celer 會自動配置 CCACHE_DIR
ccache -s
了解更多:Celer GitHub 倉庫