Search code examples
cmakeccache

CCache - same project in different directories


I'm trying to configure CCache with my CMake projects. I intend to use this within my CI/CD system, and am preparing it locally first as a test. I cannot for the life of me get CCache to correctly reuse its cache for the same project when the project itself is in different directories. This is a dealbreaker for me, because in my CI/CD system I have several types of jobs that checkout projects in different directories, including directories with randomly generated names.

What I can get to work partially is different build directories within the project root, for example with a project named foo:

  • foo
    • build_debug_1
    • build_debug_2

but not:

  • projects
    • foo
      • build_debug
  • other_projects
    • foo
      • build_debug

That being said, even in the former case I don't get a 100% cache hit like when rebuilding after nuking the build directory's contents.


It seems to me that CCache also aims to enable multiple users to share a cache, or even multiple servers; unless I'm misunderstanding these use cases (or how to handle it correctly), how could CCache actually hope to achieve this unless all projects are stored in identical filesystems across multiple users/systems?

I hope I'm just doing something wrong.

In CMake, I'm enabling CCache as follows:

find_program(CCACHE_PROGRAM ccache)
if (CCACHE_PROGRAM)
    message(NOTICE "Selected CCache: ${CCACHE_PROGRAM}")
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_PROGRAM}")
    get_filename_component(PARENT_DIR ${PROJECT_SOURCE_DIR} DIRECTORY)
    set(ENV{CCACHE_BASEDIR} "${PARENT_DIR}")
    set(ENV{CCACHE_SLOPPINESS} "pch_defines,file_macro,include_file_ctime")
    set(ENV{CCACHE_NOHASHDIR} "1")
else ()
    message(WARNING "Could not find ccache, skipping!")
endif ()

Solution

  • Perhaps @jpr42's answer hits upon the cause of the issue, although a colleague of mine happened upon a solution.

    find_program(CCACHE_PROGRAM ccache)
    if (CCACHE_PROGRAM)
        message(NOTICE "Selected CCache: ${CCACHE_PROGRAM}")
        set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM} base_dir=${PROJECT_SOURCE_DIR} hash_dir=false)
        set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM} base_dir=${PROJECT_SOURCE_DIR} hash_dir=false)
    else ()
        message(WARNING "Could not find ccache, skipping!")
    endif ()
    

    I've tested with multiple compilers in different build modes across different directory structures and it worked