1

I'm compiling my app with ccache enabled. Everything works fine until I change my repo's branch to the one with bigger diff.

Flow:

  • Compiling branch X for the first time (ccache cached everything) - compilation time about 3min
  • Compiling branch X again (using cache created in previous step) compilation time about 9 sek
  • Just changing to branch Y for 1 sek
  • Changing back to branch X
  • Compiling branch X again (ccache doesn't hit anymore, it caches files again) - compilation time about 3min

If I change to other branch with much smaller diff, ccache works ok.

I have no clue why it doesn't work in scenario above.

Here are options I'm using:

(default) absolute_paths_in_stderr = false
(default) base_dir =
(environment) cache_dir = /ccache
(default) compiler =
(default) compiler_check = mtime
(environment) compiler_type = clang
(default) compression = true
(default) compression_level = 0
(default) cpp_extension =
(environment) debug = true
(environment) debug_dir = /ccache/debug
(environment) depend_mode = true
(environment) direct_mode = true
(default) disable = false
(default) extra_files_to_hash =
(environment) file_clone = true
(default) hard_link = false
(default) hash_dir = true
(default) ignore_headers_in_manifest =
(default) ignore_options =
(environment) inode_cache = true
(default) keep_comments_cpp = false
(default) limit_multiple = 0.8
(environment) log_file = /ccache/ccache-log
(default) max_files = 0
(/ccache/config) max_size = 20.0G
(default) namespace =
(default) path =
(default) pch_external_checksum = false
(default) prefix_command =
(default) prefix_command_cpp =
(default) read_only = false
(default) read_only_direct = false
(default) recache = false
(default) reshare = false
(environment) run_second_cpp = true
(default) secondary_storage =
(environment) sloppiness = clang_index_store, include_file_ctime, include_file_mtime, ivfsoverlay, locale, modules, pch_defines, system_headers, time_macros
(default) stats = true
(default) stats_log =
(default) temporary_dir = /ccache/tmp
(default) umask =

Anyone has any idea what am I doing wrong ?

PS. It's probably because of that my .hpp files timestamps changes during that branch switching, but isn't ccache resistant for such a timestamp change ? It's is obvious that during compilation without ccache after such a change program will have compile from scratch, but I think that ccache should help for that. Am I wrong ?

AnDevi
  • 67
  • 7
  • Nothing, probably. ccache *caches* previous compiles, up to some size limit. Make big changes and you get big outputs, and this means your previously cached files are discarded to make room. Make big change back, cache results are useless and must be discarded, compile time returns to "slow". – torek Aug 03 '22 at 15:42
  • Not, 100% it's not it. That's why: 1) I can see that my cache used ~1/20 gb of space. 2) As I wrote above, I'm switching to second branch just for second, I don't even compile it and I going back to compile branch which is already cached. – AnDevi Aug 04 '22 at 07:23
  • ccache can be told on what basis to use the cached data. The cache size settings don't seem to work right sometimes (search for ccache cache size). Also: I don't know ccache in the level of detail needed here, but `(environment) inode_cache = true` looks potentially suspicious to me. When Git swaps out your files, it will remove the "wrong" ones, then create new "right" ones, which switches the inode numbers. Switching back to the original branch, you'll have different inode numbers yet again. – torek Aug 04 '22 at 07:54
  • I've already tried recompilation with and without `inode_cache` with unsatisfying result. :( – AnDevi Aug 04 '22 at 08:17
  • I remember that long ago the ccache documentation was poor; it probably still is. One thing you might try here is: don't check out any other branch. If you need to look at some other branch for some reason, use `git worktree` instead. – torek Aug 04 '22 at 08:20
  • For local use maybe I would use `git worktree`, but I want to setup ccache in gitlab's CI/CD. And there this problem with changing between specific branches will still occur. – AnDevi Aug 04 '22 at 08:25
  • CI/CD systems generally remove everything and do a "clean" checkout into a newly created directory. ccache isn't designed for this setup; you probably want something like a Bazel build system. (The only ccache mode that *can* work for this kind of setup is "preprocessor mode". Whether it *will* be useful, I don't know.) – torek Aug 04 '22 at 08:27
  • No, It can work perfectly I think, I'm building inside docker which has mounted docker's volume (with ccache stored inside) which is shared between compilations. Ccache works very good with this setup expect scenario I described above, but it's not just CI/CD problem. – AnDevi Aug 04 '22 at 08:35
  • Do you observe the same behavior when using the default value for all options? – Maarten Bamelis Aug 22 '22 at 12:28
  • I found out what is the problem. I'm using precompile headers, and I'm compiling them to .gch. When timestamp of some header which is included in that pch changes there is a problem, cuz newly generated .gch differs from previous one and then all .cpp files which use this pch have to be recompiled, cuz ccache doesn't find hits for them. Workaround solution for me in that case is to use pch files as prefix headers and just include them instead of using them as precompile headers. – AnDevi Aug 23 '22 at 08:13

1 Answers1

2

I found out what is the problem. I'm using precompile headers, and I'm compiling them to .gch. When timestamp of some header which is included in that pch changes there is a problem, cuz newly generated .gch differs from previous one and then all .cpp files which use this pch have to be recompiled, cuz ccache doesn't find hits for them.

Workaround solution for me in that case is to use pch files as prefix headers and just include them instead of using them as precompile headers.

AnDevi
  • 67
  • 7