diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index 9eac37149..067966fc9 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -82,6 +82,7 @@ Using the option as-is with no prefix affects all machines. For example:
 | stdsplit                             | true          | Split stdout and stderr in test logs                           | no             |
 | strip                                | false         | Strip targets on install                                       | no             |
 | unity {on, off, subprojects}         | off           | Unity build                                                    | no             |
+| unity_size {>=2}                     | 4             | Unity file block size                                          | no             |
 | warning_level {0, 1, 2, 3}           | 1             | Set the warning level. From 0 = none to 3 = highest            | no             |
 | werror                               | false         | Treat warnings as errors                                       | no             |
 | wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use                            | no             |
diff --git a/docs/markdown/CMake-module.md b/docs/markdown/CMake-module.md
index 4cd62a5f7..a02139644 100644
--- a/docs/markdown/CMake-module.md
+++ b/docs/markdown/CMake-module.md
@@ -12,6 +12,11 @@ following functions will then be available as methods on the object
 with the name `cmake`. You can, of course, replace the name `cmake`
 with anything else.
 
+It is generally recommended to use the latest Meson version and
+CMake >=3.17 for best compatibility. CMake subprojects will
+usually also work with older CMake versions. However, this can
+lead to unexpected issues in rare cases.
+
 ## CMake subprojects
 
 Using CMake subprojects is similar to using the "normal" meson
diff --git a/docs/markdown/Release-notes-for-0.53.0.md b/docs/markdown/Release-notes-for-0.53.0.md
index 22db714df..b29759f46 100644
--- a/docs/markdown/Release-notes-for-0.53.0.md
+++ b/docs/markdown/Release-notes-for-0.53.0.md
@@ -74,15 +74,33 @@ flags passed via language flags and hoped things worked out. In meson 0.52.0
 meson started detecting the linker and making intelligent decisions about
 using it. Unfortunately this broke choosing a non-default linker.
 
-Now there is a generic mechanism for doing this, you may use the LD
-environment variable (with normal meson environment variable rules), or add
-the following to a cross or native file:
+Now there is a generic mechanism for doing this. In 0.53.0, you can use the `LD`
+environment variable. **In 0.53.1** this was changed to `<compiler_variable>_LD`,
+such as `CC_LD`, `CXX_LD`, `D_LD`, etc due to regressions. The usual meson
+[environment variable rules](https://mesonbuild.com/Running-Meson.html#environment-variables)
+apply. Alternatively, you can add the following to a cross or native file:
+
+In 0.53.0:
 
 ```ini
 [binaries]
 ld = 'gold'
 ```
 
+**In 0.53.1 or newer**:
+
+```ini
+[binaries]
+c = 'gcc'
+c_ld = 'gold'
+```
+
+```ini
+[binaries]
+c = 'clang'
+c_ld = 'lld'
+```
+
 And meson will select the linker if possible.
 
 ## `fortran_std` option
diff --git a/docs/markdown/howtox.md b/docs/markdown/howtox.md
index 452da2c24..f70ff47c3 100644
--- a/docs/markdown/howtox.md
+++ b/docs/markdown/howtox.md
@@ -31,11 +31,11 @@ native-files and the latter via the cross file only.
 *New in 0.53.0*
 
 Like the compiler, the linker is selected via the `<compiler variable>_LD`
-environment variable, or through the `<compiler entry>ld` entry in a native
+environment variable, or through the `<compiler entry>_ld` entry in a native
 or cross file. You must be aware of whether you're using a compiler that
 invokes the linker itself (most compilers including GCC and Clang) or a
 linker that is invoked directly (when using MSVC or compilers that act like
-it, including Clang-Cl). With the former `cld` or `CC_LD` should be the value
+it, including Clang-Cl). With the former `c_ld` or `CC_LD` should be the value
 to pass to the compiler's special argument (such as `-fuse-ld` with clang and
 gcc), with the latter it should be an executable, such as `lld-link.exe`.
 
diff --git a/docs/markdown/snippets/unitysize.md b/docs/markdown/snippets/unitysize.md
new file mode 100644
index 000000000..4919ce044
--- /dev/null
+++ b/docs/markdown/snippets/unitysize.md
@@ -0,0 +1,12 @@
+## Unity file block size is configurable
+
+Traditionally the unity files that Meson autogenerates contain all
+source files that belong to a single target. This is the most
+efficient setting for full builds but makes incremental builds slow.
+This release adds a new option `unity_size` which specifies how many
+source files should be put in each unity file.
+
+The default value for block size is 4. This means that if you have a
+target that has eight source files, Meson will generate two unity
+files each of which includes four source files. The old behaviour can
+be replicated by setting `unity_size` to a large value, such as 10000.
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 520332392..a8f4789e8 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -243,19 +243,20 @@ class Backend:
         # target that the GeneratedList is used in
         return os.path.join(self.get_target_private_dir(target), src)
 
-    def get_unity_source_file(self, target, suffix):
+    def get_unity_source_file(self, target, suffix, number):
         # There is a potential conflict here, but it is unlikely that
         # anyone both enables unity builds and has a file called foo-unity.cpp.
-        osrc = target.name + '-unity.' + suffix
+        osrc = '{}-unity{}.{}'.format(target.name, number, suffix)
         return mesonlib.File.from_built_file(self.get_target_private_dir(target), osrc)
 
     def generate_unity_files(self, target, unity_src):
         abs_files = []
         result = []
         compsrcs = classify_unity_sources(target.compilers.values(), unity_src)
+        unity_size = self.get_option_for_target('unity_size', target)
 
-        def init_language_file(suffix):
-            unity_src = self.get_unity_source_file(target, suffix)
+        def init_language_file(suffix, unity_file_number):
+            unity_src = self.get_unity_source_file(target, suffix, unity_file_number)
             outfileabs = unity_src.absolute_path(self.environment.get_source_dir(),
                                                  self.environment.get_build_dir())
             outfileabs_tmp = outfileabs + '.tmp'
@@ -266,11 +267,23 @@ class Backend:
             result.append(unity_src)
             return open(outfileabs_tmp, 'w')
 
-        # For each language, generate a unity source file and return the list
+        # For each language, generate unity source files and return the list
         for comp, srcs in compsrcs.items():
-            with init_language_file(comp.get_default_suffix()) as ofile:
-                for src in srcs:
-                    ofile.write('#include<%s>\n' % src)
+            files_in_current = unity_size + 1
+            unity_file_number = 0
+            ofile = None
+            for src in srcs:
+                if files_in_current >= unity_size:
+                    if ofile:
+                        ofile.close()
+                    ofile = init_language_file(comp.get_default_suffix(), unity_file_number)
+                    unity_file_number += 1
+                    files_in_current = 0
+                ofile.write('#include<%s>\n' % src)
+                files_in_current += 1
+            if ofile:
+                ofile.close()
+
         [mesonlib.replace_if_different(x, x + '.tmp') for x in abs_files]
         return result
 
@@ -489,16 +502,18 @@ class Backend:
 
         targetdir = self.get_target_private_dir(extobj.target)
 
-        # With unity builds, there's just one object that contains all the
-        # sources, and we only support extracting all the objects in this mode,
-        # so just return that.
+        # With unity builds, sources don't map directly to objects,
+        # we only support extracting all the objects in this mode,
+        # so just return all object files.
         if self.is_unity(extobj.target):
             compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources)
             sources = []
-            for comp in compsrcs.keys():
-                osrc = self.get_unity_source_file(extobj.target,
-                                                  comp.get_default_suffix())
-                sources.append(osrc)
+            unity_size = self.get_option_for_target('unity_size', extobj.target)
+            for comp, srcs in compsrcs.items():
+                for i in range(len(srcs) // unity_size + 1):
+                    osrc = self.get_unity_source_file(extobj.target,
+                                                      comp.get_default_suffix(), i)
+                    sources.append(osrc)
 
         for osrc in sources:
             objname = self.object_filename_from_source(extobj.target, osrc)
diff --git a/mesonbuild/cmake/executor.py b/mesonbuild/cmake/executor.py
index c3303ebd6..7b9edf7b0 100644
--- a/mesonbuild/cmake/executor.py
+++ b/mesonbuild/cmake/executor.py
@@ -23,6 +23,7 @@ import re
 import os
 import shutil
 import ctypes
+import textwrap
 
 from .. import mlog, mesonlib
 from ..mesonlib import PerMachine, Popen_safe, version_compare, MachineChoice
@@ -264,9 +265,12 @@ class CMakeExecutor:
             if lang in compilers:
                 exe_list = compilers[lang].get_exelist()
             else:
-                comp_obj = self.environment.compiler_from_language(lang, MachineChoice.BUILD)
-                if comp_obj is not None:
-                    exe_list = comp_obj.get_exelist()
+                try:
+                    comp_obj = self.environment.compiler_from_language(lang, MachineChoice.BUILD)
+                    if comp_obj is not None:
+                        exe_list = comp_obj.get_exelist()
+                except Exception:
+                    pass
 
             if len(exe_list) == 1:
                 return make_abs(exe_list[0], lang), ''
@@ -278,10 +282,7 @@ class CMakeExecutor:
 
         c_comp, c_launcher = choose_compiler('c')
         cxx_comp, cxx_launcher = choose_compiler('cpp')
-        try:
-            fortran_comp, fortran_launcher = choose_compiler('fortran')
-        except Exception:
-            fortran_comp = fortran_launcher = ''
+        fortran_comp, fortran_launcher = choose_compiler('fortran')
 
         # on Windows, choose_compiler returns path with \ as separator - replace by / before writing to CMAKE file
         c_comp = c_comp.replace('\\', '/')
@@ -302,47 +303,50 @@ class CMakeExecutor:
         cxx_comp_file = comp_dir / 'CMakeCXXCompiler.cmake'
         fortran_comp_file = comp_dir / 'CMakeFortranCompiler.cmake'
 
-        if not c_comp_file.is_file():
-            c_comp_file.write_text('''# Fake CMake file to skip the boring and slow stuff
-set(CMAKE_C_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
-set(CMAKE_C_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
-set(CMAKE_C_COMPILER_ID "GNU") # Pretend we have found GCC
-set(CMAKE_COMPILER_IS_GNUCC 1)
-set(CMAKE_C_COMPILER_LOADED 1)
-set(CMAKE_C_COMPILER_WORKS TRUE)
-set(CMAKE_C_ABI_COMPILED TRUE)
-set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
-set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
-set(CMAKE_SIZEOF_VOID_P "{}")
-'''.format(c_comp, c_launcher, ctypes.sizeof(ctypes.c_voidp)))
-
-        if not cxx_comp_file.is_file():
-            cxx_comp_file.write_text('''# Fake CMake file to skip the boring and slow stuff
-set(CMAKE_CXX_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
-set(CMAKE_CXX_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
-set(CMAKE_CXX_COMPILER_ID "GNU") # Pretend we have found GCC
-set(CMAKE_COMPILER_IS_GNUCXX 1)
-set(CMAKE_CXX_COMPILER_LOADED 1)
-set(CMAKE_CXX_COMPILER_WORKS TRUE)
-set(CMAKE_CXX_ABI_COMPILED TRUE)
-set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
-set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;mm;CPP)
-set(CMAKE_SIZEOF_VOID_P "{}")
-'''.format(cxx_comp, cxx_launcher, ctypes.sizeof(ctypes.c_voidp)))
+        if c_comp and not c_comp_file.is_file():
+            c_comp_file.write_text(textwrap.dedent('''\
+                # Fake CMake file to skip the boring and slow stuff
+                set(CMAKE_C_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
+                set(CMAKE_C_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
+                set(CMAKE_C_COMPILER_ID "GNU") # Pretend we have found GCC
+                set(CMAKE_COMPILER_IS_GNUCC 1)
+                set(CMAKE_C_COMPILER_LOADED 1)
+                set(CMAKE_C_COMPILER_WORKS TRUE)
+                set(CMAKE_C_ABI_COMPILED TRUE)
+                set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
+                set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+                set(CMAKE_SIZEOF_VOID_P "{}")
+            '''.format(c_comp, c_launcher, ctypes.sizeof(ctypes.c_voidp))))
+
+        if cxx_comp and not cxx_comp_file.is_file():
+            cxx_comp_file.write_text(textwrap.dedent('''\
+                # Fake CMake file to skip the boring and slow stuff
+                set(CMAKE_CXX_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
+                set(CMAKE_CXX_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
+                set(CMAKE_CXX_COMPILER_ID "GNU") # Pretend we have found GCC
+                set(CMAKE_COMPILER_IS_GNUCXX 1)
+                set(CMAKE_CXX_COMPILER_LOADED 1)
+                set(CMAKE_CXX_COMPILER_WORKS TRUE)
+                set(CMAKE_CXX_ABI_COMPILED TRUE)
+                set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
+                set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;mm;CPP)
+                set(CMAKE_SIZEOF_VOID_P "{}")
+            '''.format(cxx_comp, cxx_launcher, ctypes.sizeof(ctypes.c_voidp))))
 
         if fortran_comp and not fortran_comp_file.is_file():
-            fortran_comp_file.write_text('''# Fake CMake file to skip the boring and slow stuff
-set(CMAKE_Fortran_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
-set(CMAKE_Fortran_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
-set(CMAKE_Fortran_COMPILER_ID "GNU") # Pretend we have found GCC
-set(CMAKE_COMPILER_IS_GNUG77 1)
-set(CMAKE_Fortran_COMPILER_LOADED 1)
-set(CMAKE_Fortran_COMPILER_WORKS TRUE)
-set(CMAKE_Fortran_ABI_COMPILED TRUE)
-set(CMAKE_Fortran_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
-set(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;fpp;FPP;f77;F77;f90;F90;for;For;FOR;f95;F95)
-set(CMAKE_SIZEOF_VOID_P "{}")
-'''.format(fortran_comp, fortran_launcher, ctypes.sizeof(ctypes.c_voidp)))
+            fortran_comp_file.write_text(textwrap.dedent('''\
+                # Fake CMake file to skip the boring and slow stuff
+                set(CMAKE_Fortran_COMPILER "{}") # Should be a valid compiler for try_compile, etc.
+                set(CMAKE_Fortran_COMPILER_LAUNCHER "{}") # The compiler launcher (if presentt)
+                set(CMAKE_Fortran_COMPILER_ID "GNU") # Pretend we have found GCC
+                set(CMAKE_COMPILER_IS_GNUG77 1)
+                set(CMAKE_Fortran_COMPILER_LOADED 1)
+                set(CMAKE_Fortran_COMPILER_WORKS TRUE)
+                set(CMAKE_Fortran_ABI_COMPILED TRUE)
+                set(CMAKE_Fortran_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+                set(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;fpp;FPP;f77;F77;f90;F90;for;For;FOR;f95;F95)
+                set(CMAKE_SIZEOF_VOID_P "{}")
+            '''.format(fortran_comp, fortran_launcher, ctypes.sizeof(ctypes.c_voidp))))
 
         return self.call(args, build_dir, env)
 
diff --git a/mesonbuild/cmake/traceparser.py b/mesonbuild/cmake/traceparser.py
index 4aa34f1cc..7b29c86df 100644
--- a/mesonbuild/cmake/traceparser.py
+++ b/mesonbuild/cmake/traceparser.py
@@ -24,6 +24,7 @@ import typing as T
 from pathlib import Path
 import re
 import os
+import json
 
 class CMakeTraceLine:
     def __init__(self, file, line, func, args):
@@ -80,11 +81,12 @@ class CMakeTraceParser:
         self.cmake_version = cmake_version  # type: str
         self.trace_file = 'cmake_trace.txt'
         self.trace_file_path = Path(build_dir) / self.trace_file
-        self.trace_format = 'human'
+        self.trace_format = 'json-v1' if version_compare(cmake_version, '>=3.17') else 'human'
 
     def trace_args(self) -> T.List[str]:
         arg_map = {
             'human': ['--trace', '--trace-expand'],
+            'json-v1': ['--trace-expand', '--trace-format=json-v1'],
         }
 
         base_args = ['--no-warn-unused-cli']
@@ -109,8 +111,10 @@ class CMakeTraceParser:
         lexer1 = None
         if self.trace_format == 'human':
             lexer1 = self._lex_trace_human(trace)
+        elif self.trace_format == 'json-v1':
+            lexer1 = self._lex_trace_json(trace)
         else:
-            raise CMakeException('CMake: Internal error: Invalid trace format {}. Expected [human]'.format(self.trace_format))
+            raise CMakeException('CMake: Internal error: Invalid trace format {}. Expected [human, json-v1]'.format(self.trace_format))
 
         # All supported functions
         functions = {
@@ -421,21 +425,27 @@ class CMakeTraceParser:
         # Neither of these is awesome for obvious reasons. I'm going to try
         # option 1 first and fall back to 2, as 1 requires less code and less
         # synchroniztion for cmake changes.
+        #
+        # With the JSON output format, introduced in CMake 3.17, spaces are
+        # handled properly and we don't have to do either options
 
         arglist = []  # type: T.List[T.Tuple[str, T.List[str]]]
-        name = args.pop(0)
-        values = []
-        prop_regex = re.compile(r'^[A-Z_]+$')
-        for a in args:
-            if prop_regex.match(a):
-                if values:
-                    arglist.append((name, ' '.join(values).split(';')))
-                name = a
-                values = []
-            else:
-                values.append(a)
-        if values:
-            arglist.append((name, ' '.join(values).split(';')))
+        if self.trace_format == 'human':
+            name = args.pop(0)
+            values = []
+            prop_regex = re.compile(r'^[A-Z_]+$')
+            for a in args:
+                if prop_regex.match(a):
+                    if values:
+                        arglist.append((name, ' '.join(values).split(';')))
+                    name = a
+                    values = []
+                else:
+                    values.append(a)
+            if values:
+                arglist.append((name, ' '.join(values).split(';')))
+        else:
+            arglist = [(x[0], x[1].split(';')) for x in zip(args[::2], args[1::2])]
 
         for name, value in arglist:
             for i in targets:
@@ -549,7 +559,20 @@ class CMakeTraceParser:
 
             yield CMakeTraceLine(file, line, func, args)
 
+    def _lex_trace_json(self, trace: str):
+        lines = trace.splitlines(keepends=False)
+        lines.pop(0)  # The first line is the version
+        for i in lines:
+            data = json.loads(i)
+            args = data['args']
+            args = [parse_generator_expressions(x) for x in args]
+            yield CMakeTraceLine(data['file'], data['line'], data['cmd'], args)
+
     def _guess_files(self, broken_list: T.List[str]) -> T.List[str]:
+        # Nothing has to be done for newer formats
+        if self.trace_format != 'human':
+            return broken_list
+
         # Try joining file paths that contain spaces
 
         reg_start = re.compile(r'^([A-Za-z]:)?/.*/[^./]+$')
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index aea2d908e..720d0648a 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -96,11 +96,12 @@ class UserBooleanOption(UserOption[bool]):
         raise MesonException('Value %s is not boolean (true or false).' % value)
 
 class UserIntegerOption(UserOption[int]):
-    def __init__(self, description, min_value, max_value, value, yielding=None):
+    def __init__(self, description, value, yielding=None):
+        min_value, max_value, default_value = value
         super().__init__(description, [True, False], yielding)
         self.min_value = min_value
         self.max_value = max_value
-        self.set_value(value)
+        self.set_value(default_value)
         c = []
         if min_value is not None:
             c.append('>=' + str(min_value))
@@ -127,7 +128,7 @@ class UserIntegerOption(UserOption[int]):
 
 class UserUmaskOption(UserIntegerOption, UserOption[T.Union[str, int]]):
     def __init__(self, description, value, yielding=None):
-        super().__init__(description, 0, 0o777, value, yielding)
+        super().__init__(description, (0, 0o777, value), yielding)
         self.choices = ['preserve', '0000-0777']
 
     def printable_value(self):
@@ -525,7 +526,7 @@ class CoreData:
                 UserIntegerOption(
                     'Maximum number of linker processes to run or 0 for no '
                     'limit',
-                    0, None, 0)
+                    (0, None, 0))
         elif backend_name.startswith('vs'):
             self.backend_options['backend_startup_project'] = \
                 UserStringOption(
@@ -967,7 +968,7 @@ class BuiltinOption(T.Generic[_T, _U]):
 
     """Class for a builtin option type.
 
-    Currently doesn't support UserIntegerOption, or a few other cases.
+    There are some cases that are not fully supported yet.
     """
 
     def __init__(self, opt_type: T.Type[_U], description: str, default: T.Any, yielding: bool = True, *,
@@ -1066,6 +1067,7 @@ builtin_options = OrderedDict([
     ('stdsplit',        BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
     ('strip',           BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
     ('unity',           BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
+    ('unity_size',      BuiltinOption(UserIntegerOption, 'Unity block size', (2, None, 4))),
     ('warning_level',   BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'])),
     ('werror',          BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False)),
     ('wrap_mode',       BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index 4d790b6bc..1a8a04a4a 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -90,10 +90,9 @@ def ComboParser(description, kwargs):
 def IntegerParser(description, kwargs):
     if 'value' not in kwargs:
         raise OptionException('Integer option must contain value argument.')
+    inttuple = (kwargs.get('min', None), kwargs.get('max', None), kwargs['value'])
     return coredata.UserIntegerOption(description,
-                                      kwargs.get('min', None),
-                                      kwargs.get('max', None),
-                                      kwargs['value'],
+                                      inttuple,
                                       kwargs.get('yield', coredata.default_yielding))
 
 # FIXME: Cannot use FeatureNew while parsing options because we parse it before

meson claims Unknown compiler(s): ['c++', 'g++', 'clang++', 'pgc++', 'icpc']
This is kinda weird: I have a very small dummy meson.build which errors out with:

> meson.build:7:0: ERROR: Unknown compiler(s): ['c++', 'g++', 'clang++', 'pgc++', 'icpc']

Whereas it's correct I don't have any of those compilers on my system, there is also no indication in my meson.build that this would be needed.

The sample meson.build is:

```
project('sample',
	'c',
	version: '1.0.0',
	meson_version: '>= 0.47',
)

dep = dependency('doesnotexist', required: false)
```


diff --git a/run_unittests.py b/run_unittests.py
index c5ad49934..7c2ae0555 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -5305,9 +5305,9 @@ class LinuxlikeTests(BasePlatformTests):
         testdir = os.path.join(self.common_test_dir, '45 subproject')
         self.init(testdir, extra_args='--unity=subprojects')
         simpletest_id = Target.construct_id_from_path('subprojects/sublib', 'simpletest', '@exe')
-        self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', simpletest_id, 'simpletest-unity.c'))
+        self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', simpletest_id, 'simpletest-unity0.c'))
         sublib_id = Target.construct_id_from_path('subprojects/sublib', 'sublib', '@sha')
-        self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', sublib_id, 'sublib-unity.c'))
+        self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', sublib_id, 'sublib-unity0.c'))
         self.assertPathDoesNotExist(os.path.join(self.builddir, 'user@exe/user-unity.c'))
         self.build()
 

pip install -e .
parse_log_pytest
requirements.txt
ninja pytest
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup==1.2.2
iniconfig==2.1.0
-e git+https://github.com/mesonbuild/meson.git@a41a902f5e32d60ba3eb46979737274ca771fb6e#egg=meson
ninja==1.11.1.4
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
tomli==2.2.1

name: meson
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - meson==0.53.999
      - ninja==1.11.1.4
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - tomli==2.2.1
prefix: /opt/conda/envs/meson

run_unittests.py::LinuxlikeTests::test_unity_subproj
run_unittests.py::InternalTests::test_pkgconfig_parse_libs run_unittests.py::DataTests::test_compiler_options_documented run_unittests.py::DataTests::test_json_grammar_syntax_highlighting run_unittests.py::AllPlatformTests::test_absolute_prefix_libdir run_unittests.py::AllPlatformTests::test_always_prefer_c_compiler_for_asm run_unittests.py::AllPlatformTests::test_check_module_linking run_unittests.py::AllPlatformTests::test_compiler_detection run_unittests.py::AllPlatformTests::test_configure run_unittests.py::AllPlatformTests::test_default_options_prefix run_unittests.py::AllPlatformTests::test_introspect_buildoptions_without_configured_build run_unittests.py::AllPlatformTests::test_introspect_config_update run_unittests.py::AllPlatformTests::test_introspect_dependencies_from_source run_unittests.py::AllPlatformTests::test_introspect_file_dump_equals_all run_unittests.py::AllPlatformTests::test_introspect_json_dump run_unittests.py::AllPlatformTests::test_introspect_meson_info run_unittests.py::AllPlatformTests::test_introspect_targets_from_source run_unittests.py::AllPlatformTests::test_preprocessor_checks_CPPFLAGS run_unittests.py::AllPlatformTests::test_templates run_unittests.py::AllPlatformTests::test_warning_level_0 run_unittests.py::FailureTests::test_assert_default_message run_unittests.py::FailureTests::test_boost_BOOST_ROOT_dependency run_unittests.py::FailureTests::test_boost_notfound_dependency run_unittests.py::FailureTests::test_dependency_invalid_method run_unittests.py::FailureTests::test_dict_forbids_duplicate_keys run_unittests.py::FailureTests::test_dict_forbids_integer_key run_unittests.py::FailureTests::test_extraframework_dependency_method run_unittests.py::FailureTests::test_get_variable_on_not_found_project run_unittests.py::FailureTests::test_gnustep_notfound_dependency run_unittests.py::FailureTests::test_llvm_dependency run_unittests.py::FailureTests::test_message run_unittests.py::FailureTests::test_missing_subproject_not_required_and_required run_unittests.py::FailureTests::test_sdl2_notfound_dependency run_unittests.py::FailureTests::test_using_recent_feature run_unittests.py::FailureTests::test_using_too_recent_feature run_unittests.py::FailureTests::test_using_too_recent_feature_dependency run_unittests.py::FailureTests::test_vcs_tag_featurenew_build_always_stale run_unittests.py::FailureTests::test_warning run_unittests.py::FailureTests::test_wrap_nofallback run_unittests.py::FailureTests::test_wx_notfound_dependency run_unittests.py::LinuxlikeTests::test_build_rpath run_unittests.py::LinuxlikeTests::test_compiler_check_flags_order run_unittests.py::LinuxlikeTests::test_compiler_cpp_stds run_unittests.py::LinuxlikeTests::test_cpp_std_override run_unittests.py::LinuxlikeTests::test_ld_environment_variable_cpp run_unittests.py::LinuxlikeTests::test_ld_environment_variable_objcpp run_unittests.py::LinuxlikeTests::test_pch_with_address_sanitizer run_unittests.py::RewriterTests::test_default_options_delete run_unittests.py::RewriterTests::test_default_options_set run_unittests.py::RewriterTests::test_kwargs_add run_unittests.py::RewriterTests::test_kwargs_delete run_unittests.py::RewriterTests::test_kwargs_info run_unittests.py::RewriterTests::test_kwargs_remove run_unittests.py::RewriterTests::test_kwargs_remove_regex run_unittests.py::RewriterTests::test_kwargs_set run_unittests.py::RewriterTests::test_target_add_sources run_unittests.py::RewriterTests::test_target_add_sources_abs run_unittests.py::RewriterTests::test_target_remove run_unittests.py::RewriterTests::test_target_remove_sources run_unittests.py::RewriterTests::test_target_same_name_skip run_unittests.py::RewriterTests::test_target_source_list run_unittests.py::RewriterTests::test_target_source_sorting run_unittests.py::RewriterTests::test_tatrget_add run_unittests.py::NativeFileTests::test_cpp_compiler run_unittests.py::NativeFileTests::test_python_module
run_unittests.py::InternalTests::test_compiler_args_class run_unittests.py::InternalTests::test_compiler_args_class_gnuld run_unittests.py::InternalTests::test_compiler_args_remove_system run_unittests.py::InternalTests::test_dependency_factory_order run_unittests.py::InternalTests::test_depfile run_unittests.py::InternalTests::test_extract_as_list run_unittests.py::InternalTests::test_find_library_patterns run_unittests.py::InternalTests::test_listify run_unittests.py::InternalTests::test_log_once run_unittests.py::InternalTests::test_log_once_ansi run_unittests.py::InternalTests::test_mode_symbolic_to_bits run_unittests.py::InternalTests::test_needs_exe_wrapper_override run_unittests.py::InternalTests::test_pkgconfig_module run_unittests.py::InternalTests::test_quote_arg run_unittests.py::InternalTests::test_sort_libpaths run_unittests.py::InternalTests::test_split_args run_unittests.py::InternalTests::test_string_templates_substitution run_unittests.py::InternalTests::test_version_compare run_unittests.py::InternalTests::test_version_number run_unittests.py::DataTests::test_all_functions_defined_in_ast_interpreter run_unittests.py::DataTests::test_builtin_options_documented run_unittests.py::DataTests::test_cpu_families_documented run_unittests.py::DataTests::test_markdown_files_in_sitemap run_unittests.py::DataTests::test_snippets run_unittests.py::DataTests::test_vim_syntax_highlighting run_unittests.py::AllPlatformTests::test_alias_target run_unittests.py::AllPlatformTests::test_all_forbidden_targets_tested run_unittests.py::AllPlatformTests::test_array_option_bad_change run_unittests.py::AllPlatformTests::test_array_option_change run_unittests.py::AllPlatformTests::test_array_option_empty_equivalents run_unittests.py::AllPlatformTests::test_build_by_default run_unittests.py::AllPlatformTests::test_buildtype_setting run_unittests.py::AllPlatformTests::test_clike_get_library_dirs run_unittests.py::AllPlatformTests::test_command_line run_unittests.py::AllPlatformTests::test_compiler_run_command run_unittests.py::AllPlatformTests::test_configure_file_warnings run_unittests.py::AllPlatformTests::test_conflicting_d_dash_option run_unittests.py::AllPlatformTests::test_cross_file_system_paths run_unittests.py::AllPlatformTests::test_custom_target_changes_cause_rebuild run_unittests.py::AllPlatformTests::test_custom_target_exe_data_deterministic run_unittests.py::AllPlatformTests::test_dash_d_dedup run_unittests.py::AllPlatformTests::test_default_options_prefix_dependent_defaults run_unittests.py::AllPlatformTests::test_dirs run_unittests.py::AllPlatformTests::test_dist_git run_unittests.py::AllPlatformTests::test_dist_git_script run_unittests.py::AllPlatformTests::test_dist_hg run_unittests.py::AllPlatformTests::test_do_conf_file_preserve_newlines run_unittests.py::AllPlatformTests::test_env_ops_dont_stack run_unittests.py::AllPlatformTests::test_feature_check_usage_subprojects run_unittests.py::AllPlatformTests::test_flock run_unittests.py::AllPlatformTests::test_forcefallback run_unittests.py::AllPlatformTests::test_free_stringarray_setting run_unittests.py::AllPlatformTests::test_guessed_linker_dependencies run_unittests.py::AllPlatformTests::test_identical_target_name_in_subdir_flat_layout run_unittests.py::AllPlatformTests::test_identical_target_name_in_subproject_flat_layout run_unittests.py::AllPlatformTests::test_identity_cross run_unittests.py::AllPlatformTests::test_install_introspection run_unittests.py::AllPlatformTests::test_install_introspection_multiple_outputs run_unittests.py::AllPlatformTests::test_install_log_content run_unittests.py::AllPlatformTests::test_install_subdir_introspection run_unittests.py::AllPlatformTests::test_internal_include_order run_unittests.py::AllPlatformTests::test_introspect_projectinfo_subproject_dir run_unittests.py::AllPlatformTests::test_introspect_projectinfo_subproject_dir_from_source run_unittests.py::AllPlatformTests::test_introspect_projectinfo_subprojects run_unittests.py::AllPlatformTests::test_introspect_projectinfo_without_configured_build run_unittests.py::AllPlatformTests::test_introspection_target_subproject run_unittests.py::AllPlatformTests::test_libdir_must_be_inside_prefix run_unittests.py::AllPlatformTests::test_meson_configure_from_source_does_not_crash run_unittests.py::AllPlatformTests::test_minor_version_does_not_reconfigure_wipe run_unittests.py::AllPlatformTests::test_ndebug_if_release_disabled run_unittests.py::AllPlatformTests::test_ndebug_if_release_enabled run_unittests.py::AllPlatformTests::test_permitted_method_kwargs run_unittests.py::AllPlatformTests::test_prebuilt_object run_unittests.py::AllPlatformTests::test_prebuilt_shared_lib run_unittests.py::AllPlatformTests::test_prebuilt_static_lib run_unittests.py::AllPlatformTests::test_prefix_dependent_defaults run_unittests.py::AllPlatformTests::test_reconfigure run_unittests.py::AllPlatformTests::test_rpath_uses_ORIGIN run_unittests.py::AllPlatformTests::test_run_target_files_path run_unittests.py::AllPlatformTests::test_same_d_option_twice run_unittests.py::AllPlatformTests::test_same_d_option_twice_configure run_unittests.py::AllPlatformTests::test_same_dash_option_twice run_unittests.py::AllPlatformTests::test_same_dash_option_twice_configure run_unittests.py::AllPlatformTests::test_same_project_d_option_twice run_unittests.py::AllPlatformTests::test_same_project_d_option_twice_configure run_unittests.py::AllPlatformTests::test_source_changes_cause_rebuild run_unittests.py::AllPlatformTests::test_source_generator_program_cause_rebuild run_unittests.py::AllPlatformTests::test_static_compile_order run_unittests.py::AllPlatformTests::test_static_library_lto run_unittests.py::AllPlatformTests::test_static_library_overwrite run_unittests.py::AllPlatformTests::test_subproject_promotion run_unittests.py::AllPlatformTests::test_subproject_promotion_wrap run_unittests.py::AllPlatformTests::test_suite_selection run_unittests.py::AllPlatformTests::test_summary run_unittests.py::AllPlatformTests::test_target_construct_id_from_path run_unittests.py::AllPlatformTests::test_testsetup_default run_unittests.py::AllPlatformTests::test_testsetup_selection run_unittests.py::AllPlatformTests::test_uninstall run_unittests.py::AllPlatformTests::test_unstable_coredata run_unittests.py::AllPlatformTests::test_warning_location run_unittests.py::AllPlatformTests::test_wipe_from_builddir run_unittests.py::FailureTests::test_dict_requires_key_value_pairs run_unittests.py::FailureTests::test_exception_exit_status run_unittests.py::FailureTests::test_objc_cpp_detection run_unittests.py::FailureTests::test_subproject_variables run_unittests.py::FailureTests::test_version_checked_before_parsing_options run_unittests.py::LinuxlikeTests::test_basic_soname run_unittests.py::LinuxlikeTests::test_compiler_c_stds run_unittests.py::LinuxlikeTests::test_compiler_libs_static_dedup run_unittests.py::LinuxlikeTests::test_cross_find_program run_unittests.py::LinuxlikeTests::test_custom_soname run_unittests.py::LinuxlikeTests::test_deterministic_dep_order run_unittests.py::LinuxlikeTests::test_deterministic_rpath_order run_unittests.py::LinuxlikeTests::test_identity_cross run_unittests.py::LinuxlikeTests::test_install_subdir_symlinks run_unittests.py::LinuxlikeTests::test_install_subdir_symlinks_with_default_umask run_unittests.py::LinuxlikeTests::test_install_subdir_symlinks_with_default_umask_and_mode run_unittests.py::LinuxlikeTests::test_install_umask run_unittests.py::LinuxlikeTests::test_installed_modes run_unittests.py::LinuxlikeTests::test_installed_modes_extended run_unittests.py::LinuxlikeTests::test_installed_soname run_unittests.py::LinuxlikeTests::test_ld_environment_variable_bfd run_unittests.py::LinuxlikeTests::test_ld_environment_variable_gold run_unittests.py::LinuxlikeTests::test_ld_environment_variable_objc run_unittests.py::LinuxlikeTests::test_override_with_exe_dep run_unittests.py::LinuxlikeTests::test_pic run_unittests.py::LinuxlikeTests::test_pkg_unfound run_unittests.py::LinuxlikeTests::test_reconfigure run_unittests.py::LinuxlikeTests::test_run_installed run_unittests.py::LinuxlikeTests::test_soname run_unittests.py::LinuxlikeTests::test_wrap_with_file_url run_unittests.py::RewriterTests::test_target_add_subdir run_unittests.py::RewriterTests::test_target_remove_subdir run_unittests.py::RewriterTests::test_target_subdir run_unittests.py::NativeFileTests::test_compile_sys_path run_unittests.py::NativeFileTests::test_find_program run_unittests.py::NativeFileTests::test_multiple_native_files run_unittests.py::NativeFileTests::test_multiple_native_files_override run_unittests.py::NativeFileTests::test_native_file_dirs run_unittests.py::NativeFileTests::test_native_file_dirs_overriden run_unittests.py::NativeFileTests::test_native_file_is_pipe run_unittests.py::NativeFileTests::test_python3_module run_unittests.py::CrossFileTests::test_cross_file_dirs run_unittests.py::CrossFileTests::test_cross_file_dirs_chain run_unittests.py::CrossFileTests::test_cross_file_dirs_overriden run_unittests.py::TAPParserTests::test_diagnostics run_unittests.py::TAPParserTests::test_directive_case run_unittests.py::TAPParserTests::test_directive_explanation run_unittests.py::TAPParserTests::test_empty run_unittests.py::TAPParserTests::test_empty_line run_unittests.py::TAPParserTests::test_empty_plan run_unittests.py::TAPParserTests::test_many_early_plan run_unittests.py::TAPParserTests::test_many_late_plan run_unittests.py::TAPParserTests::test_middle_plan run_unittests.py::TAPParserTests::test_one_test_early_plan run_unittests.py::TAPParserTests::test_one_test_late_plan run_unittests.py::TAPParserTests::test_one_test_not_ok run_unittests.py::TAPParserTests::test_one_test_ok run_unittests.py::TAPParserTests::test_one_test_skip run_unittests.py::TAPParserTests::test_one_test_skip_failure run_unittests.py::TAPParserTests::test_one_test_todo run_unittests.py::TAPParserTests::test_one_test_with_name run_unittests.py::TAPParserTests::test_one_test_with_number run_unittests.py::TAPParserTests::test_out_of_order run_unittests.py::TAPParserTests::test_plan_directive run_unittests.py::TAPParserTests::test_too_few run_unittests.py::TAPParserTests::test_too_few_bailout run_unittests.py::TAPParserTests::test_too_many run_unittests.py::TAPParserTests::test_too_many_plans run_unittests.py::TAPParserTests::test_unexpected run_unittests.py::TAPParserTests::test_version run_unittests.py::TAPParserTests::test_yaml
mesonbuild/cmake/executor.py mesonbuild/coredata.py mesonbuild/optinterpreter.py docs/markdown/howtox.md mesonbuild/backend/backends.py docs/markdown/snippets/unitysize.md docs/markdown/Release-notes-for-0.53.0.md docs/markdown/Builtin-options.md docs/markdown/CMake-module.md mesonbuild/cmake/traceparser.py
mesonbuild/cmake/executor.py mesonbuild/coredata.py mesonbuild/optinterpreter.py docs/markdown/howtox.md mesonbuild/backend/backends.py docs/markdown/snippets/unitysize.md docs/markdown/Release-notes-for-0.53.0.md docs/markdown/Builtin-options.md docs/markdown/CMake-module.md mesonbuild/cmake/traceparser.py