如何在CMake中使用CCache?


90

我想执行以下操作:如果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失败(这是可以预期的)。


4
为什么不将gcc符号链接到ccache?并且,如果您要分发此文件,我认为如果用户自己安装了ccache并希望使用它,则他本人会完成符号链接
。– int3

1
@ int3是的,可能会起作用(我不知道ccache将编译器作为可选参数)。但是,更明确一点会更清洁。
艾米特

Answers:


67

我个人有/usr/lib/ccache我的$PATH。此目录包含符号链接的负载,这些符号链接包含可从中调用编译器的每个可能名称(如gccgcc-4.3),所有这些均指向ccache。

而且我什至没有创建符号链接。当我在Debian上安装ccache时,该目录已预先填充。


11
请注意,此ccache路径必须放置实际编译器所在的路径之前$PATH才能起作用。像export PATH = /usr/lib/ccache:$PATH
Gui13 2011年

6
@ Gui13:比更新PATH更好的方法是明确告诉cmake它应使用的gcc在哪里,例如cmake -DCMAKE_CXX_COMPILER = / usr / lib / ccache / bin / g ++
cib

3
之后brew install ccache,我有/usr/local/Cellar/ccache/3.2.1/libexec/
cdunn2001

96

现在可以将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)

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

从版本3.4开始,对于忍者来说,这是可能的。对于XCode,Craig Scott给出了解决方法。

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

Edit2:@Emilio Cobos建议避免对链接部分执行此操作,因为ccache不会提高链接速度,并且可能会与其他类型的缓存(如sccache)混淆


许多网站都隐式地建议使用双引号,例如in find_program(CCACHE_FOUND "ccache"),我不知道哪一个更便于移植,我的里程完全不需要双引号。
1737973

5
值得注意的是,这目前仅适用于Makefile生成器(从cmake 3.3.2开始)。请参阅的手册页cmake-properties
Lekensteyn

1
值得注意的是,这与CTEST_USE_LAUNCHERS设置冲突。这些属性也在这里设置:github.com/Kitware/CMake/blob/master/Modules/…–
PurpleKarrot

我认为您可能希望将代码更改为此 代码(除非从中删除文本endif()。改进之处包括:1.有一个配置选项可以将其禁用,以及2.原来,当使用这种方式时,颜色将从Make后端的GCC / Clang中消失。在ninja后台工作围绕它通过添加-fdiagnostics-color选项,因此建议为这样做make后端太。
Hi-Angel

94

从CMAKE 3.4开始,您可以执行以下操作:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

1
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache。这些工作精美!我不知道为什么cmake坚持clang要从中查找/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc(因此symlink技巧不起作用),而不是从中查找$PATH,但是您的答案仍然有效。
cdunn2001 '17

2
这应该是最好的答案。不再混乱路径变量和编译器符号链接!
ilya b。

1
我试过了,但是它只是给我一个错误“ ccache:错误:递归调用(ccache二进制文件的名称必须是“ ccache”))。看着详细的跟踪,它正在尝试运行“ / usr / local / bin / ccache ccache / usr / bin / c ++” ...
克里斯·多德

3
它如何与RULE_LAUNCH_COMPILE交互?
Trass3r

10

从CMake 3.1开始,可以将ccache与Xcode生成器一起使用,并且从CMake 3.4开始支持Ninja。Ninja会RULE_LAUNCH_COMPILE像Unix Makefiles生成器一样兑现荣誉(因此@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.inlaunch-cxx.in看起来像这样(他们应该在同一个目录中的CMakeLists.txt文件):

launch-c.in:

#!/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}" "$@"

上面的代码RULE_LAUNCH_COMPILE单独用于Unix Makefile和Ninja,但是对于Xcode生成器,它依赖于CMakeCMAKE_XCODE_ATTRIBUTE_...变量支持。的设置CCCXX用户自定义的Xcode的属性来控制编译器指令,LD并且LDPLUSPLUS对连接器的命令是没有的,据我所知,Xcode的项目的记录功能,但它似乎工作。如果任何人都可以确认它得到Apple的正式支持,我将更新链接的文章,并相应地更新此答案。


我还需要set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")上述文章中的。
约恩

感谢您的提醒,我已经更新了答案,其中包括设置LD和LDPLUSPLUS。
Craig Scott

ccache不支持VS编译器,因此您不能为此使用它。有一个名为clcache的项目,旨在为VS提供相同的功能,但是我无法评论它的运行情况。
克雷格·斯科特

9

我不想设置从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星期内忘记的符号链接,我感到更舒服,然后也许想知道是否有些事情不起作用...


5

我认为最好的方法是将gcc,g ++符号链接到ccache,但是如果您想在cmake中使用,请尝试以下操作:

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

5

我验证了以下作品(来源:此链接):

        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抱怨)。


4

让我添加一个以前没有在这里提到的重要项目。

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

在我的情况下,ccache在调用时工作正常gcc,但未能捕获其他名称对同一编译器的调用:ccc++。要完全安装ccache,您需要确保首先安装所有编译器,或者添加对update-ccache符号链接的调用以确保安全。

sudo apt-get install ccache build-essential # and everyhting ... sudo /usr/sbin/update-ccache-symlinks export PATH="/usr/lib/ccache/:$PATH"

...然后(由于更新了符号链接)还捕获了对cc和c ++的调用!


谢谢,我不知道update-ccache-symlinks,我正在c++为一个项目的脚本创建链接,并且该链接正在运行,但对于另一个项目却不起作用(仍然不知道为什么,链接很好),已update-ccache-symlinks解决。
亚历克斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.