如何在 CMake 中使用 CCache?

我想执行以下操作: 如果 PATH 中存在 CCache,则使用“ CCache g + +”进行编译,否则使用 g + + 。我尝试编写一个小的 my-cmake 脚本,其中包含

    CC="ccache gcc" CXX="ccache g++" cmake $*

但它似乎不起作用(运行 make 仍然不使用 ccache; 我使用 CMAKE _ VERBOSE _ MAKEFILE 检查了这一点)。

更新:

根据 这个链接,我尝试将脚本更改为

     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 时测试失败(这是可以预料的)。

61278 次浏览

我核实了以下作品(来源: 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 抱怨)。

在我看来,最好的方法是将 gcc,g + + 符号链接到 ccache,但是如果您想在 cmake 中使用,请尝试这样做:

export CC="ccache gcc" CXX="ccache g++" cmake ...

我个人在我的 $PATH中有 /usr/lib/ccache。这个目录包含编译器可以调用的每个可能名称(如 gccgcc-4.3)的大量符号链接,它们都指向 ccache。

我甚至没有创建符号链接。当我在 Debian 上安装 ccache 时,那个目录是预填充的。

我不喜欢设置从 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周内忘记,然后可能会想,如果某些东西不工作..。

现在可以将 ccache 指定为编译命令和链接命令的启动程序(从 cmake 2.8.0开始)。这是 Makefile 和忍者发电机的工作原理。为此,只需设置以下属性:

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)

也可以只为特定的目录或目标设置这些属性。

对于忍者来说,这是可能的,因为版本3.4。 对于 XCode,Craig Scott 在他的答案中给出了一个变通方法。

编辑: 感谢 uprego 和 Lekensteyn 的评论,我在使用 ccache 作为启动程序之前编辑了答案,以检查 ccache 是否可用,以及哪些生成器可以使用编译启动程序。

编辑2:@Emilio Cobos 建议在链接部分避免这样做,因为 ccache 不会提高链接速度,并且会干扰其他类型的缓存,比如 sccache

From CMake 3.1, it is possible to use ccache with the Xcode generator and Ninja is supported from CMake 3.4 onwards. Ninja will honour RULE_LAUNCH_COMPILE just like the Unix Makefiles generator (so @Babcool's answer gets you there for Ninja too), but getting ccache working for the Xcode generator takes a little more work. The following article explains the method in detail, focussing on a general implementation which works for all three CMake generators and making no assumptions about setting up ccache symlinks or the underlying compiler used (it still lets CMake decide the compiler):

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.inlaunch-cxx.in如下所示(它们应该与 CMakeLists.txt文件在同一目录中) :

发射:

#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"

launch-cxx.in:

#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_CXX_COMPILER}" "$@"

The above uses RULE_LAUNCH_COMPILE alone for Unix Makefiles and Ninja, but for the Xcode generator it relies on help from CMake's CMAKE_XCODE_ATTRIBUTE_... variables support. The setting of the CC and CXX user-defined Xcode attributes to control the compiler command and LD and LDPLUSPLUS for the linker command is not, as far as I can tell, a documented feature of Xcode projects, but it does seem to work. If anyone can confirm it is officially supported by Apple, I'll update the linked article and this answer accordingly.

在 CMAKE 3.4中,你可以:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

让我补充一个以前没有提到的重要项目。

在从 ubuntu: 18.04 docker 镜像引导一个简约的构建系统时,我发现安装顺序有所不同。

在我的例子中,ccache 在调用 gcc时工作得很好,但是未能通过其他名称(ccc++)捕获同一个编译器的调用。 为了完全安装 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!

It is extending @Nicolas 回答.

cmake文件中添加以下代码行:

list(PREPEND CMAKE_PROGRAM_PATH /usr/lib/ccache)

或者将其作为参数添加到 cmake配置步骤:

cmake -DCMAKE_PROGRAM_PATH=/usr/lib/ccache

Here are 2 methods I think are clean/robust, and also 不要 pollute your CMake code.

1. 设置环境变量

这个方法很好,因为您不必为每个 CMake 项目单独设置它。缺点是您可能不希望每个 CMake 项目都有 ccache。

# Requires CMake 3.17 (https://cmake.org/cmake/help/latest/envvar/CMAKE_LANG_COMPILER_LAUNCHER.html)
export CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache
export CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache

2.) Pass in cache variables during project configuration

对于每个项目来说都有点烦人。但是这可以被 IDE 否定。

# Requires CMake 3.4
$ cmake ... -D CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache \
-D CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache

注意: 实际上没有必要指定完整路径。

如果 ccache在路径中,只需指定 ccache即可。

export CMAKE_CXX_COMPILER_LAUNCHER=ccache
export CMAKE_C_COMPILER_LAUNCHER=ccache