我想做以下事情:如果 CCache 存在于 PATH 中,则使用“ccache g++”进行编译,否则使用 g++。我尝试编写一个小的 my-cmake 脚本,其中包含
CC="ccache gcc" CXX="ccache g++" cmake $*
但它似乎不起作用(运行 make 仍然不使用 ccache;我使用 CMAKE_VERBOSE_MAKEFILE 检查了这一点)。
更新:
根据 this link,我尝试将脚本更改为
cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
但是 cmake 会抱怨使用编译器 ccache 的测试失败(这是可以预料的)。
从 CMAKE 3.4 开始,您可以执行以下操作:
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
现在可以将 ccache 指定为编译命令和链接命令的启动器(从 cmake 2.8.0 开始)。这适用于 Makefile 和 Ninja 生成器。为此,只需设置以下属性:
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) # Less useful to do it for linking, see edit2
endif(CCACHE_FOUND)
也可以仅为特定目录或目标设置这些属性。
对于 Ninja,从 3.4 版本开始就可以做到这一点。对于 XCode,Craig Scott 在他的回答中给出了一个解决方法。
编辑:感谢 uprego 和 Lekensteyn 的评论,我编辑了答案以检查 ccache 在用作启动器之前是否可用,以及哪些生成器可以使用编译启动器。
Edit2:@Emilio Cobos 建议避免对链接部分这样做,因为 ccache 不会提高链接速度,并且可能会与其他类型的缓存(如 sccache)混淆
find_program(CCACHE_FOUND "ccache")
中的双引号,我不知道哪个更便携,我的里程做得非常好,不需要双引号。
cmake-properties
的手册页。
endif()
)。改进是: 1. 有一个禁用它的配置选项,以及 2. 事实证明,以这种方式使用时,颜色会从 Make backend 中的 GCC/Clang 中消失。 ninja
后端通过添加 -fdiagnostics-color
选项来解决它,因此建议对 make
后端也这样做。
我个人的 $PATH
中有 /usr/lib/ccache
。该目录包含大量符号链接,用于调用编译器的每个可能名称(如 gcc
和 gcc-4.3
),所有这些都指向 ccache。
而且我什至没有创建符号链接。当我在 Debian 上安装 ccache 时,该目录已预先填充。
$PATH
中的路径之前,它才能工作。 export PATH = /usr/lib/ccache:$PATH
之类的东西
brew install ccache
之后,我有 /usr/local/Cellar/ccache/3.2.1/libexec/
。
从 CMake 3.1 开始,可以将 ccache 与 Xcode 生成器一起使用,并且从 CMake 3.4 开始支持 Ninja。 Ninja 将像 Unix Makefiles 生成器一样尊重 RULE_LAUNCH_COMPILE
(所以@Babcool 的答案也可以让你到达 Ninja),但是让 ccache 为 Xcode 生成器工作需要更多的工作。以下文章详细解释了该方法,重点介绍适用于所有三个 CMake 生成器的通用实现,并且不假设设置 ccache 符号链接或使用的底层编译器(它仍然让 CMake 决定编译器):
https://crascit.com/2016/04/09/using-ccache-with-cmake/
文章的一般要点如下。您的 CMakeLists.txt
文件的开头应设置如下:
cmake_minimum_required(VERSION 2.8)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Support Unix Makefiles and Ninja
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()
project(SomeProject)
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
if(RULE_LAUNCH_COMPILE AND CMAKE_GENERATOR STREQUAL "Xcode")
# Set up wrapper scripts
configure_file(launch-c.in launch-c)
configure_file(launch-cxx.in launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_BINARY_DIR}/launch-c"
"${CMAKE_BINARY_DIR}/launch-cxx")
# Set Xcode project attributes to route compilation through our scripts
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
endif()
两个脚本模板文件 launch-c.in
和 launch-cxx.in
如下所示(它们应该与 CMakeLists.txt
文件位于同一目录中):
启动-c.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"
启动-cxx.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_CXX_COMPILER}" "$@"
以上对 Unix Makefile 和 Ninja 单独使用 RULE_LAUNCH_COMPILE
,但对于 Xcode 生成器,它依赖于 CMake 的 CMAKE_XCODE_ATTRIBUTE_...
变量支持的帮助。 CC
和 CXX
用户定义的 Xcode 属性的设置来控制编译器命令和链接器命令的 LD
和 LDPLUSPLUS
不是,据我所知,Xcode 项目的记录功能,但它似乎确实有效。如果有人可以确认它得到 Apple 的官方支持,我会相应地更新链接的文章和这个答案。
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")
。
我不喜欢设置从 g++
到 ccache
的符号链接。并且 CXX="ccache g++"
对我不起作用,因为某些 cmake 测试用例只想让编译器程序没有属性。
所以我改用了一个小的 bash 脚本:
#!/bin/bash
ccache g++ "$@"
并将其保存为 /usr/bin/ccache-g++
中的可执行文件。
然后 C 将 cmake 配置为使用 /usr/bin/ccache-g++
作为 C++ 编译器。这样它通过了 cmake 测试用例,我感觉比拥有我可能在 2 或 3 周内忘记的符号链接更舒服,然后可能想知道是否有什么不起作用......
我验证了以下作品(来源:this link):
CC="gcc" CXX="g++" cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
更新:我后来意识到,即使这样也行不通。奇怪的是,它每隔一段时间就会起作用(其他时间 cmake 抱怨)。
让我补充一个之前没有提到的重要项目。
在从 ubuntu:18.04 docker 映像引导一个简约的构建系统时,我发现安装顺序会有所不同。
在我的例子中,调用 gcc
时 ccache 运行良好,但未能捕获通过其他名称调用同一编译器:cc
和 c++
。要完全安装 ccache,您需要确保首先安装所有编译器,或添加对 update-ccache 符号链接的调用以确保安全。
sudo /usr/sbin/update-ccache-symlinks
export PATH="/usr/lib/ccache/:$PATH"```
... and then (due to updated symlinks) also calls to cc and c++ get caught!
update-ccache-symlinks
,我正在为一个项目创建带有脚本的 c++
链接,它正在工作,但不适用于另一个项目(仍然不知道为什么,链接很好),update-ccache-symlinks
解决了。
在我看来,最好的方法是将 gcc,g++ 符号链接到 ccache,但如果你想在 cmake 中使用,试试这个:
export CC="ccache gcc" CXX="ccache g++" cmake ...
它正在扩展@Nicolas answer。
将以下行添加到您的 cmake
文件中:
list(PREPEND CMAKE_PROGRAM_PATH /usr/lib/ccache)
或将其作为参数添加到 cmake
配置步骤:
cmake -DCMAKE_PROGRAM_PATH=/usr/lib/ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
。这些工作精美!我不知道为什么 cmake 坚持从/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
中找到clang
(因此符号链接技巧不起作用),而不是从$PATH
中,但您的答案仍然有效。