【问题标题】:How to Use CCache with CMake?如何在 CMake 中使用 CCache?
【发布时间】:2010-12-21 09:40:17
【问题描述】:

我想做以下事情:如果 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 测试失败(这是可以预料的)。

【问题讨论】:

  • 你为什么不把 gcc 符号链接到 ccache?如果您要分发它,我认为如果用户安装了 ccache 并希望使用它,他自己会完成符号链接..
  • @int3 是的,这可能会起作用(我不知道 ccache 将编译器作为可选参数)。但是,更明确会更清晰。

标签: c++ unix cmake ccache


【解决方案1】:

从 CMAKE 3.4 开始,您可以:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

【讨论】:

  • 还有-DCMAKE_CXX_COMPILER_LAUNCHER=ccache。这些工作精美!我不知道为什么 cmake 坚持要从 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc 找到 clang(所以符号链接技巧不起作用),而不是从 $PATH,但你的答案仍然有效。
  • 这应该是最好的答案。不再弄乱路径变量和编译器符号链接!
  • 我试过这个,但它只是给了我错误“ccache:错误:递归调用(ccache 二进制文件的名称必须是“ccache”)”。查看详细跟踪,它正在尝试运行“/usr/local/bin/ccache ccache /usr/bin/c++”...
  • 它如何与 RULE_LAUNCH_COMPILE 交互?
  • 这个是一直有效的;即使您使用的是工具链文件,它也可以工作,并且它指定了编译器的完整路径(其中修改系统 PATH 没有帮助)。谢谢!
【解决方案2】:

现在可以将 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"),我不知道哪个更便携,我的里程做得很好,不需要双引号。
  • 值得注意的是,这目前仅适用于 Makefile 生成器(从 cmake 3.3.2 开始)。请参阅cmake-properties 的手册页。
  • 值得注意的是,这与 CTEST_USE_LAUNCHERS 设置冲突。这些属性也在这里设置:github.com/Kitware/CMake/blob/master/Modules/…
  • 我想你可能想把代码改成this one(除了remove text from inside of endif()。改进是: 1. 有一个禁用它的配置选项,以及 2. 事实证明,当使用这种方式时,颜色会从 Make backend 中的 GCC/Clang 中消失。 ninja 后端通过添加 -fdiagnostics-color 选项来解决它,因此建议对 make 后端也这样做。
【解决方案3】:

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

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

【讨论】:

  • 请注意,此 ccache 路径必须放在 真正编译器在 $PATH 中的路径之前,它才能工作。类似export PATH = /usr/lib/ccache:$PATH
  • @Gui13:比更新 PATH 更好的是明确告诉 cmake 它应该使用的 gcc 在哪里,例如cmake -DCMAKE_CXX_COMPILER=/usr/lib/ccache/bin/g++
  • brew install ccache之后,我有/usr/local/Cellar/ccache/3.2.1/libexec/
【解决方案4】:

从 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.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 Makefiles 和Ninja,但对于Xcode 生成器它依赖于CMake 的CMAKE_XCODE_ATTRIBUTE_... 变量支持的帮助。 CCCXX 用户定义的 Xcode 属性的设置来控制编译器命令以及链接器命令的 LDLDPLUSPLUS 不是,据我所知,Xcode 项目的记录功能,但它似乎确实有效。如果有人可以确认它得到 Apple 的官方支持,我会相应地更新链接的文章和这个答案。

【讨论】:

  • 我还需要上述文章中的set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")
  • 感谢提醒,我已经更新了答案,包括设置 LD 和 LDPLUSPLUS。
  • ccache 不支持 VS 编译器,因此您不能使用它。有一个名为 clcache 的项目旨在为 VS 提供相同的功能,但我无法评论它的效果如何。
【解决方案5】:

我不喜欢设置从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 周内忘记的符号链接更舒服,然后可能想知道是否有什么不起作用......

【讨论】:

    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

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

        在从 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!
        

        【讨论】:

        • 谢谢,我不知道 update-ccache-symlinks,我正在为一个项目创建带有脚本的 c++ 链接,它正在工作,但对于另一个项目却没有(仍然不知道为什么,链接很好),update-ccache-symlinks 已解决。
        【解决方案9】:

        它正在扩展@Nicolas answer

        将以下行添加到您的 cmake 文件中:

        list(PREPEND CMAKE_PROGRAM_PATH /usr/lib/ccache)
        

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

        cmake -DCMAKE_PROGRAM_PATH=/usr/lib/ccache
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-11-14
          • 1970-01-01
          • 2012-12-24
          • 1970-01-01
          • 2017-07-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多