How to Use CCache with CMake?

前端 未结 8 729
陌清茗
陌清茗 2020-12-02 09:32

I would like to do the following: If CCache is present in PATH, use \"ccache g++\" for compilation, else use g++. I tried writing a small my-cmake script containing

相关标签:
8条回答
  • 2020-12-02 10:02

    As of CMAKE 3.4 you can do:

    -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
    
    0 讨论(0)
  • 2020-12-02 10:04

    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/

    The general gist of the article is as follows. The start of your CMakeLists.txt file should be set up something like this:

    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()
    

    The two script template files launch-c.in and launch-cxx.in look like this (they should be in the same directory as the CMakeLists.txt file):

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

    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.

    0 讨论(0)
  • 2020-12-02 10:08

    It is now possible to specify ccache as a launcher for compile commands and link commands (since cmake 2.8.0). That works for Makefile and Ninja generator. To do this, just set the following properties :

    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)
    

    It is also possible to set these properties only for specific directories or targets.

    For Ninja, this is possible since version 3.4. For XCode, Craig Scott gives a workaround in his answer.

    Edit : Thanks to uprego and Lekensteyn's comment, I edited the answer to check if ccache is available before using it as launcher and for which generators is it possible to use a compile launcher.

    Edit2: @Emilio Cobos recommended to avoid doing that for the linking part as ccache doesn't improve linking speed and can mess with other types of cache like sccache

    0 讨论(0)
  • 2020-12-02 10:14

    In my opinion the best way is to symlink gcc,g++ to ccache, but if you would like to use within cmake, try this:

    export CC="ccache gcc" CXX="ccache g++" cmake ...
    
    0 讨论(0)
  • 2020-12-02 10:15

    I verified the following works (source: 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" $*
    

    Update: I later realized that even this does not work. Strangely it works every alternate time (the other times cmake complains).

    0 讨论(0)
  • 2020-12-02 10:16

    Let me add one important item that was not mentioned here before.

    While bootstrapping a minimalistic build system from the ubunutu:18.04 docker image, I've found that order of installation makes a difference.

    In my case ccache worked fine when calling gcc, but failed to catch invocations of the same compiler by the other names: cc and c++. To fully install ccache, you need to make sure all compilers are installed first, or add a call to update-ccache symlinks to be safe.

    sudo apt-get install ccache build-essential # and everyhting ... 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!

    0 讨论(0)
提交回复
热议问题