envconfig: Autodetect and support BuildCache

Add BuildCache as a supported compiler cache. Also autodetect
the presence of BuildCache as part of detect_compiler_cache().

The order of preference is:

  1. sccache
  2. ccache
  3. buildcache

Thus, when either sccache or ccache is present in the PATH the
compiler cache selection is unaffected by this change.
This commit is contained in:
m authored and Paolo Bonzini committed 2026-09-21 10:17:20 +02:00
1 parent 626d1e2632
commit 84cc9f5d42
6 files changed
+32 -3

No files matched your search

+3
View File
@@ -23,6 +23,9 @@ changed). Meson will then use the specified compiler without Ccache.
[sccache](https://github.com/mozilla/sccache) is auto-detected the
same way, and is preferred over Ccache when both are installed.
[BuildCache](https://gitlab.com/bits-n-bites/buildcache) is
auto-detected as well, after Ccache and sccache.
[kache](https://github.com/kunobi-ninja/kache) is also supported, but
is never added automatically: it must be invoked with a compiler
subcommand (`kache cc`, `kache c++`, ...), so Meson cannot safely
+1 -1
View File
@@ -181,7 +181,7 @@ pkg-config = '/usr/bin/i586-mingw32msvc-pkg-config'
```
The compiler may be prefixed with a supported compiler cache wrapper,
namely ccache, sccache or kache, e.g. `c = ['kache', 'cc']`.
namely ccache, sccache, kache or buildcache, e.g. `c = ['kache', 'cc']`.
An incomplete list of internally used programs that can be overridden
here is:
+7
View File
@@ -0,0 +1,7 @@
## Added support for buildcache
Meson now recognizes [BuildCache](https://gitlab.com/bits-n-bites/buildcache)
as a compiler wrapper, so setting e.g. `CC="buildcache cc"` works like it
already does for Ccache and sccache. BuildCache is also auto-detected
alongside Ccache and sccache, and is used as a fallback after both of those
when no compiler is specified explicitly.
+11 -1
View File
@@ -496,13 +496,20 @@ class BinaryTable:
def detect_kache() -> ExternalProgram:
return ExternalProgram('kache', silent=True)
@staticmethod
def detect_buildcache() -> ExternalProgram:
return ExternalProgram('buildcache', silent=True)
@staticmethod
def detect_compiler_cache() -> ExternalProgram:
# Sccache is "newer" so it is assumed that people would prefer it by default.
cache = BinaryTable.detect_sccache()
if cache.found():
return cache
return BinaryTable.detect_ccache()
cache = BinaryTable.detect_ccache()
if cache.found():
return cache
return BinaryTable.detect_buildcache()
@classmethod
def parse_entry(cls, entry: T.Union[str, T.List[str]]) -> T.Tuple[T.List[str], T.Union[None, ExternalProgram]]:
@@ -517,6 +524,9 @@ class BinaryTable:
elif parts[0] == 'kache':
compiler = parts[1:]
ccache = cls.detect_kache()
elif parts[0] == 'buildcache':
compiler = parts[1:]
ccache = cls.detect_buildcache()
else:
compiler = parts
ccache = None
+1 -1
View File
@@ -1341,7 +1341,7 @@ class AllPlatformTests(BasePlatformTests):
for cmd in self.get_compdb():
# Get compiler
split = split_args(cmd['command'])
if os.path.basename(split[0]) in ('ccache', 'sccache'):
if os.path.basename(split[0]) in ('ccache', 'sccache', 'buildcache'):
compiler = split[1]
else:
compiler = split[0]
+9
View File
@@ -394,3 +394,12 @@ class FailureTests(BasePlatformTests):
self.assertMesonRaises('',
'Compiler cache specified without compiler: ccache',
override_envvars={'CC': 'ccache'})
self.assertMesonRaises('',
'Compiler cache specified without compiler: sccache',
override_envvars={'CC': 'sccache'})
self.assertMesonRaises('',
'Compiler cache specified without compiler: kache',
override_envvars={'CC': 'kache'})
self.assertMesonRaises('',
'Compiler cache specified without compiler: buildcache',
override_envvars={'CC': 'buildcache'})