Pitfalls with the cfamily cache

We are currently trying to improve the performance of the sonar cfamily cache (sonarqube 9.9LTS) in our distributed build system.
In our initial setup we would usually see a summary in the sonar scanner output like the following:

INFO: 962/1056 files marked as unchanged
INFO: 158/158 test files marked as unchanged
INFO: Cache: 3/505 hits, 6327479 bytes

Which is of course frustating.

So far we identified two issues that were causing a lot of cache misses.
Setting the property sonar.verbose=true is the key to find causes of the cache misses.

Issue 1: short path feature of the conan package manager (windows only). This lead to differing include paths for thirdparties on different build agents and caused a lot of cache misses. The verbose log contains a lot of messages of this kind:
dependencies changed; the first detected difference is file not found: C:\.conan\bae49c\1\include\boost\...
This can be resolved by switching conans short path feature off CONAN_USER_HOME_SHORT=None. See Environment variables — conan 1.62.0 documentation
It can also be resolved by upgrading from conan 1.x to conan 2.x where the feature was removed.

Issue 2: The build system configuration changed with each build because we added the build number as a macro definition. Same issue as described in this topic: CFamily Analysis cache - zero hits
The message logged here is quite cryptic and offers room for improvement ( response file not found, request changed ).

I hope this description can help other users too that are investigating into cache misses.
Will keep you posted in case we find out more reasons for cache misses.

But maybe the documentation at C/C++/Objective-C can be improved as well?

Suggestion for an additional paragraph:

Note that the cache will only be used efficiently if the build settings are kept unchanged. Especially in CI envionrments avoid adding macro definitions to the compiler arguments that contain build numbers or build dates.

2 Likes

hi @jsinge,

Your analysis is correct and I’m glad you were able to identify it and improve the cache rate on your own.

You can think about the analysis cache the same way as the build cache. If you change a macro, it will trigger a rebuild even if the macro isn’t used.
The same for header file directories relative to the analyzed project base directory. relative is to support checking out the project in different directories.

But maybe the documentation at C/C++/Objective-C can be improved as well?

I created this ticket to provide more insight: [CPP-4759] - Jira

Thanks,

Hi Abbas,
thanks for your reply. Actually I’m still at Cache Hit rates around 10/505 hits.
As several causes for the cache misses overlap each other, it’s not so easy to analyze.

One question though: Does a difference in the path inside “command” field of compile_commands.json also lead to a cache miss? In other words, does the compiler need to be installed in the same directory on all build agents that wan’t to share the cache?

I suspect that again it’s the windows short paths that CMake creates in our setup lead to “request changed” cache misses.
On one agent the commands generated by CMake contain this command path:
“C:\PROGRA~2\MICROS~1\2019\PROFES~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe”
on the next it’s:
“C:\PROGRA~2\MICROS~4\2019\PROFES~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe”

Hi @jsinge,

One question though: Does a difference in the path inside “command” field of compile_commands.json also lead to a cache miss? In other words, does the compiler need to be installed in the same directory on all build agents that wan’t to share the cache?

Yes. Changing the path of the compiler will lead to different System header directories (like the STL). If any of the included directories of a translation uni change, the entire header resolution can be impacted and the cache cannot be reused.