Repository: conan-io/conan
Pull request #12117 (2022-09-14 14:54:11)

[Meson] Meson appending extra machine files
Changelog: Feature: `Meson` build helper is listening to new configuration field `tools.meson.mesontoolchain:extra_machine_files=["FILENAMES"]` to append all the passed files to the list of the ones created by Conan.
Docs: https://github.com/conan-io/docs/pull/XXXX
Closes: https://github.com/conan-io/conan/issues/11961



eli-schwartz: From a documentation perspective, what is a meson "user filename"? Shouldn't this use a name more evocative of the fact that Meson calls them native machine files?
lasote: > From a documentation perspective, what is a meson "user filename"? Shouldn't this use a name more evocative of the fact that Meson calls them native machine files?

But there are `native` and `cross` files, right? Maybe something like  `tools.meson.mesontoolchain:additional_machine_files` ?
franramirez688: > I am not convinced that the user story is injecting some meson files to all meson projects, or the users are missing a "local" way to inject those files inside package recipes, but like a different file for each project. I don't know enough about Meson usage and patterns, but we need to think about it.

I've changed the configuration name to `tools.meson.mesontoolchain:extra_machine_files` so I think it's more evident than before. In my opinion, the user story is if you want to add your own variables from any section to the existing Conan ones, so we don't need to add more public attributes to the `MesonToolchain` class interface to manage all the machine file sections. 
franramirez688: > From a documentation perspective, what is a meson "user filename"? Shouldn't this use a name more evocative of the fact that Meson calls them native machine files?

Changed to `tools.meson.mesontoolchain:extra_machine_files`. I think it's clear enough, doesn't it?

Patch:
diff --git a/conan/tools/cmake/cmake.py b/conan/tools/cmake/cmake.py
index cdd07fb27..63cb6a1a1 100644
--- a/conan/tools/cmake/cmake.py
+++ b/conan/tools/cmake/cmake.py
@@ -99,7 +99,7 @@ class CMake(object):
         with chdir(self, build_folder):
             self._conanfile.run(command)
 
-    def _build(self, build_type=None, target=None, cli_args=None, build_tool_args=None):
+    def _build(self, build_type=None, target=None, cli_args=None, build_tool_args=None, env=""):
         bf = self._conanfile.build_folder
         is_multi = is_multi_configuration(self._generator)
         if build_type and not is_multi:
@@ -127,7 +127,7 @@ class CMake(object):
         arg_list = " ".join(filter(None, arg_list))
         command = "%s --build %s" % (self._cmake_program, arg_list)
         self._conanfile.output.info("CMake command: %s" % command)
-        self._conanfile.run(command)
+        self._conanfile.run(command, env=env)
 
     def build(self, build_type=None, target=None, cli_args=None, build_tool_args=None):
         self._build(build_type, target, cli_args, build_tool_args)
@@ -149,7 +149,7 @@ class CMake(object):
         self._conanfile.output.info("CMake command: %s" % command)
         self._conanfile.run(command)
 
-    def test(self, build_type=None, target=None, cli_args=None, build_tool_args=None):
+    def test(self, build_type=None, target=None, cli_args=None, build_tool_args=None, env=""):
         if self._conanfile.conf.get("tools.build:skip_test", check_type=bool):
             return
         if not target:
@@ -157,5 +157,7 @@ class CMake(object):
             is_ninja = "Ninja" in self._generator
             target = "RUN_TESTS" if is_multi and not is_ninja else "test"
 
+        # The default for ``test()`` is both the buildenv and the runenv
+        env = ["conanbuild", "conanrun"] if env == "" else env
         self._build(build_type=build_type, target=target, cli_args=cli_args,
-                    build_tool_args=build_tool_args)
+                    build_tool_args=build_tool_args, env=env)
diff --git a/conan/tools/cmake/cmakedeps/templates/macros.py b/conan/tools/cmake/cmakedeps/templates/macros.py
index 17d96f88d..6ae09ea75 100644
--- a/conan/tools/cmake/cmakedeps/templates/macros.py
+++ b/conan/tools/cmake/cmakedeps/templates/macros.py
@@ -59,7 +59,7 @@ class MacrosTemplate(CMakeDepsFileTemplate):
                        add_library(${_LIB_NAME} UNKNOWN IMPORTED)
                    endif()
                    # Link library file
-                   set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${CONAN_FOUND_LIBRARY})
+                   set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION${config_suffix} ${CONAN_FOUND_LIBRARY})
                    list(APPEND _out_libraries_target ${_LIB_NAME})
                    message(VERBOSE "Conan: Found: ${CONAN_FOUND_LIBRARY}")
                else()
diff --git a/conan/tools/cmake/cmakedeps/templates/target_configuration.py b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
index a56422356..190cde0a4 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_configuration.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
@@ -49,16 +49,6 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
 
         ########### VARIABLES #######################################################################
         #############################################################################################
-
-        set({{ pkg_name }}_COMPILE_OPTIONS{{ config_suffix }}
-            "$<$<COMPILE_LANGUAGE:CXX>{{ ':${' }}{{ pkg_name }}_COMPILE_OPTIONS_CXX{{ config_suffix }}}>"
-            "$<$<COMPILE_LANGUAGE:C>{{ ':${' }}{{ pkg_name }}_COMPILE_OPTIONS_C{{ config_suffix }}}>")
-
-        set({{ pkg_name }}_LINKER_FLAGS{{ config_suffix }}
-            "$<$<STREQUAL{{ ':$' }}<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>{{ ':${' }}{{ pkg_name }}_SHARED_LINK_FLAGS{{ config_suffix }}}>"
-            "$<$<STREQUAL{{ ':$' }}<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>{{ ':${' }}{{ pkg_name }}_SHARED_LINK_FLAGS{{ config_suffix }}}>"
-            "$<$<STREQUAL{{ ':$' }}<TARGET_PROPERTY:TYPE>,EXECUTABLE>{{ ':${' }}{{ pkg_name }}_EXE_LINK_FLAGS{{ config_suffix }}}>")
-
         set({{ pkg_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "") # Will be filled later
         conan_find_apple_frameworks({{ pkg_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "{{ '${' }}{{ pkg_name }}_FRAMEWORKS{{ config_suffix }}}" "{{ '${' }}{{ pkg_name }}_FRAMEWORK_DIRS{{ config_suffix }}}")
 
@@ -67,7 +57,7 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
 
         ######## Create an interface target to contain all the dependencies (frameworks, system and conan deps)
         if(NOT TARGET {{ pkg_name+'_DEPS_TARGET'}})
-            add_library({{ pkg_name+'_DEPS_TARGET'}} INTERFACE)
+            add_library({{ pkg_name+'_DEPS_TARGET'}} INTERFACE IMPORTED)
         endif()
 
         set_property(TARGET {{ pkg_name + '_DEPS_TARGET'}}
@@ -146,7 +136,7 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
 
                 ######## Create an interface target to contain all the dependencies (frameworks, system and conan deps)
                 if(NOT TARGET {{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}})
-                    add_library({{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}} INTERFACE)
+                    add_library({{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}} INTERFACE IMPORTED)
                 endif()
 
                 set_property(TARGET {{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}}
@@ -188,10 +178,7 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
                 set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_COMPILE_DEFINITIONS
                              $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'COMPILE_DEFINITIONS', config_suffix)}}> APPEND)
                 set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_COMPILE_OPTIONS
-                             $<$<CONFIG:{{ configuration }}>:
-                             {{tvalue(pkg_name, comp_variable_name, 'COMPILE_OPTIONS_C', config_suffix)}}
-                             {{tvalue(pkg_name, comp_variable_name, 'COMPILE_OPTIONS_CXX', config_suffix)}}> APPEND)
-                set({{ pkg_name }}_{{ comp_variable_name }}_TARGET_PROPERTIES TRUE)
+                             $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'COMPILE_OPTIONS', config_suffix)}}> APPEND)
 
                 {%- if set_interface_link_directories %}
                 # This is only used for '#pragma comment(lib, "foo")' (automatic link)
diff --git a/conan/tools/cmake/cmakedeps/templates/target_data.py b/conan/tools/cmake/cmakedeps/templates/target_data.py
index cb4b733b0..f22858592 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_data.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_data.py
@@ -102,6 +102,15 @@ class ConfigDataTemplate(CMakeDepsFileTemplate):
               set({{ pkg_name }}_FRAMEWORKS{{ config_suffix }} {{ global_cpp.frameworks }})
               set({{ pkg_name }}_BUILD_DIRS{{ config_suffix }} {{ global_cpp.build_paths }})
 
+              # COMPOUND VARIABLES
+              set({{ pkg_name }}_COMPILE_OPTIONS{{ config_suffix }}
+                  "$<$<COMPILE_LANGUAGE:CXX>{{ ':${' }}{{ pkg_name }}_COMPILE_OPTIONS_CXX{{ config_suffix }}}>"
+                  "$<$<COMPILE_LANGUAGE:C>{{ ':${' }}{{ pkg_name }}_COMPILE_OPTIONS_C{{ config_suffix }}}>")
+              set({{ pkg_name }}_LINKER_FLAGS{{ config_suffix }}
+                  "$<$<STREQUAL{{ ':$' }}<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>{{ ':${' }}{{ pkg_name }}_SHARED_LINK_FLAGS{{ config_suffix }}}>"
+                  "$<$<STREQUAL{{ ':$' }}<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>{{ ':${' }}{{ pkg_name }}_SHARED_LINK_FLAGS{{ config_suffix }}}>"
+                  "$<$<STREQUAL{{ ':$' }}<TARGET_PROPERTY:TYPE>,EXECUTABLE>{{ ':${' }}{{ pkg_name }}_EXE_LINK_FLAGS{{ config_suffix }}}>")
+
 
               set({{ pkg_name }}_COMPONENTS{{ config_suffix }} {{ components_names }})
               {%- for comp_variable_name, comp_target_name, cpp in components_cpp %}
@@ -123,12 +132,15 @@ class ConfigDataTemplate(CMakeDepsFileTemplate):
               set({{ pkg_name }}_{{ comp_variable_name }}_DEPENDENCIES{{ config_suffix }} {{ cpp.public_deps }})
               set({{ pkg_name }}_{{ comp_variable_name }}_SHARED_LINK_FLAGS{{ config_suffix }} {{ cpp.sharedlinkflags_list }})
               set({{ pkg_name }}_{{ comp_variable_name }}_EXE_LINK_FLAGS{{ config_suffix }} {{ cpp.exelinkflags_list }})
+              # COMPOUND VARIABLES
               set({{ pkg_name }}_{{ comp_variable_name }}_LINKER_FLAGS{{ config_suffix }}
                       $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>{{ ':${' }}{{ pkg_name }}_{{ comp_variable_name }}_SHARED_LINK_FLAGS{{ config_suffix }}}>
                       $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>{{ ':${' }}{{ pkg_name }}_{{ comp_variable_name }}_SHARED_LINK_FLAGS{{ config_suffix }}}>
                       $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>{{ ':${' }}{{ pkg_name }}_{{ comp_variable_name }}_EXE_LINK_FLAGS{{ config_suffix }}}>
               )
-
+              set({{ pkg_name }}_{{ comp_variable_name }}_COMPILE_OPTIONS{{ config_suffix }}
+                  "$<$<COMPILE_LANGUAGE:CXX>{{ ':${' }}{{ pkg_name }}_{{ comp_variable_name }}_COMPILE_OPTIONS_CXX{{ config_suffix }}}>"
+                  "$<$<COMPILE_LANGUAGE:C>{{ ':${' }}{{ pkg_name }}_{{ comp_variable_name }}_COMPILE_OPTIONS_C{{ config_suffix }}}>")
 
               {%- endfor %}
           """)
diff --git a/conan/tools/cmake/presets.py b/conan/tools/cmake/presets.py
index c58a2337e..6d4a9a735 100644
--- a/conan/tools/cmake/presets.py
+++ b/conan/tools/cmake/presets.py
@@ -142,7 +142,8 @@ def _contents(conanfile, toolchain_file, cache_variables, generator):
     return ret
 
 
-def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables):
+def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables,
+                        user_presets_path=None):
     cache_variables = cache_variables or {}
     if platform.system() == "Windows" and generator == "MinGW Makefiles":
         if "CMAKE_SH" not in cache_variables:
@@ -186,18 +187,27 @@ def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables):
 
     data = json.dumps(data, indent=4)
     save(preset_path, data)
-    save_cmake_user_presets(conanfile, preset_path)
+    save_cmake_user_presets(conanfile, preset_path, user_presets_path)
 
 
-def save_cmake_user_presets(conanfile, preset_path):
+def save_cmake_user_presets(conanfile, preset_path, user_presets_path=None):
+    if user_presets_path is False:
+        return
+
     # Try to save the CMakeUserPresets.json if layout declared and CMakeLists.txt found
     if conanfile.source_folder and conanfile.source_folder != conanfile.generators_folder:
-        if os.path.exists(os.path.join(conanfile.source_folder, "CMakeLists.txt")):
+        if user_presets_path:
+            output_dir = os.path.join(conanfile.source_folder, user_presets_path) \
+                if not os.path.isabs(user_presets_path) else user_presets_path
+        else:
+            output_dir = conanfile.source_folder
+
+        if user_presets_path or os.path.exists(os.path.join(output_dir, "CMakeLists.txt")):
             """
                 Contents for the CMakeUserPresets.json
                 It uses schema version 4 unless it is forced to 2
             """
-            user_presets_path = os.path.join(conanfile.source_folder, "CMakeUserPresets.json")
+            user_presets_path = os.path.join(output_dir, "CMakeUserPresets.json")
             if not os.path.exists(user_presets_path):
                 data = {"version": _schema_version(conanfile, default=4),
                         "vendor": {"conan": dict()}}
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 698e050d2..f22d6f760 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -11,7 +11,7 @@ from conan.tools.build import build_jobs
 from conan.tools.build.cross_building import cross_building
 from conan.tools.cmake.toolchain import CONAN_TOOLCHAIN_FILENAME
 from conan.tools.intel import IntelCC
-from conan.tools.microsoft.visual import is_msvc, msvc_version_to_toolset_version
+from conan.tools.microsoft.visual import msvc_version_to_toolset_version
 from conans.client.subsystems import deduce_subsystem, WINDOWS
 from conans.errors import ConanException
 from conans.util.files import load
@@ -667,6 +667,30 @@ class TryCompileBlock(Block):
         """)
 
 
+class CompilersBlock(Block):
+    template = textwrap.dedent(r"""
+        {% for lang, compiler_path in compilers.items() %}
+        set(CMAKE_{{ lang }}_COMPILER "{{ compiler_path|replace('\\', '/') }}")
+        {% endfor %}
+    """)
+
+    def context(self):
+        # Reading configuration from "tools.build:compiler_executables" -> {"C": "/usr/bin/gcc"}
+        compilers_by_conf = self._conanfile.conf.get("tools.build:compiler_executables", default={},
+                                                     check_type=dict)
+        # Map the possible languages
+        compilers = {}
+        # Allowed <LANG> variables (and <LANG>_LAUNCHER)
+        compilers_mapping = {"c": "C", "cuda": "CUDA", "cpp": "CXX", "objc": "OBJC",
+                             "objcxx": "OBJCXX", "rc": "RC", 'fortran': "Fortran", 'asm': "ASM",
+                             "hip": "HIP", "ispc": "ISPC"}
+        for comp, lang in compilers_mapping.items():
+            # To set CMAKE_<LANG>_COMPILER
+            if comp in compilers_by_conf:
+                compilers[lang] = compilers_by_conf[comp]
+        return {"compilers": compilers}
+
+
 class GenericSystemBlock(Block):
     template = textwrap.dedent("""
         {% if cmake_sysroot %}
@@ -690,21 +714,6 @@ class GenericSystemBlock(Block):
         {% if toolset %}
         set(CMAKE_GENERATOR_TOOLSET "{{ toolset }}" CACHE STRING "" FORCE)
         {% endif %}
-        {% if compiler %}
-        if(NOT DEFINED ENV{CC})
-        set(CMAKE_C_COMPILER {{ compiler }})
-        endif()
-        {% endif %}
-        {% if compiler_cpp %}
-        if(NOT DEFINED ENV{CXX})
-        set(CMAKE_CXX_COMPILER {{ compiler_cpp }})
-        endif()
-        {% endif %}
-        {% if compiler_rc %}
-        if(NOT DEFINED ENV{RC})
-        set(CMAKE_RC_COMPILER {{ compiler_rc }})
-        endif()
-        {% endif %}
         """)
 
     def _get_toolset(self, generator):
@@ -766,23 +775,6 @@ class GenericSystemBlock(Block):
                     "armv8": "ARM64"}.get(arch)
         return None
 
-    def _get_compiler(self, generator):
-        compiler = self._conanfile.settings.get_safe("compiler")
-        os_ = self._conanfile.settings.get_safe("os")
-
-        compiler_c = compiler_cpp = compiler_rc = None
-
-        # TODO: Check if really necessary now that conanvcvars is used
-        if "Ninja" in str(generator) and is_msvc(self._conanfile):
-            compiler_c = compiler_cpp = "cl"
-        elif os_ == "Windows" and compiler == "clang" and "Visual" not in generator:
-            # definition of compiler only if not using the VS Clang toolset
-            compiler_rc = "clang"
-            compiler_c = "clang"
-            compiler_cpp = "clang++"
-
-        return compiler_c, compiler_cpp, compiler_rc
-
     def _get_generic_system_name(self):
         os_host = self._conanfile.settings.get_safe("os")
         os_build = self._conanfile.settings_build.get_safe("os")
@@ -843,19 +835,13 @@ class GenericSystemBlock(Block):
         generator = self._toolchain.generator
         generator_platform = self._get_generator_platform(generator)
         toolset = self._get_toolset(generator)
-
-        compiler, compiler_cpp, compiler_rc = self._get_compiler(generator)
-
         system_name, system_version, system_processor = self._get_cross_build()
 
         # This is handled by the tools.apple:sdk_path and CMAKE_OSX_SYSROOT in Apple
         cmake_sysroot = self._conanfile.conf.get("tools.build:sysroot")
         cmake_sysroot = cmake_sysroot.replace("\\", "/") if cmake_sysroot is not None else None
 
-        return {"compiler": compiler,
-                "compiler_rc": compiler_rc,
-                "compiler_cpp": compiler_cpp,
-                "toolset": toolset,
+        return {"toolset": toolset,
                 "generator_platform": generator_platform,
                 "cmake_system_name": system_name,
                 "cmake_system_version": system_version,
diff --git a/conan/tools/cmake/toolchain/toolchain.py b/conan/tools/cmake/toolchain/toolchain.py
index 599a9338c..cd54a9a87 100644
--- a/conan/tools/cmake/toolchain/toolchain.py
+++ b/conan/tools/cmake/toolchain/toolchain.py
@@ -12,7 +12,7 @@ from conan.tools.cmake.toolchain import CONAN_TOOLCHAIN_FILENAME
 from conan.tools.cmake.toolchain.blocks import ToolchainBlocks, UserToolchain, GenericSystemBlock, \
     AndroidSystemBlock, AppleSystemBlock, FPicBlock, ArchitectureBlock, GLibCXXBlock, VSRuntimeBlock, \
     CppStdBlock, ParallelBlock, CMakeFlagsInitBlock, TryCompileBlock, FindFiles, PkgConfigBlock, \
-    SkipRPath, SharedLibBock, OutputDirsBlock, ExtraFlagsBlock
+    SkipRPath, SharedLibBock, OutputDirsBlock, ExtraFlagsBlock, CompilersBlock
 from conan.tools.intel import IntelCC
 from conan.tools.microsoft import VCVars
 from conan.tools.microsoft.visual import vs_ide_version
@@ -127,6 +127,7 @@ class CMakeToolchain(object):
         self.blocks = ToolchainBlocks(self._conanfile, self,
                                       [("user_toolchain", UserToolchain),
                                        ("generic_system", GenericSystemBlock),
+                                       ("compilers", CompilersBlock),
                                        ("android_system", AndroidSystemBlock),
                                        ("apple_system", AppleSystemBlock),
                                        ("fpic", FPicBlock),
@@ -145,6 +146,7 @@ class CMakeToolchain(object):
                                        ("output_dirs", OutputDirsBlock)])
 
         check_using_build_profile(self._conanfile)
+        self.user_presets_path = None
 
     def _context(self):
         """ Returns dict, the context for the template
@@ -194,7 +196,8 @@ class CMakeToolchain(object):
             else:
                 cache_variables[name] = value
 
-        write_cmake_presets(self._conanfile, toolchain, self.generator, cache_variables)
+        write_cmake_presets(self._conanfile, toolchain, self.generator, cache_variables,
+                            self.user_presets_path)
 
     def _get_generator(self, recipe_generator):
         # Returns the name of the generator to be used by CMake
diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py
index 7b0f735df..df84c6c2d 100644
--- a/conan/tools/gnu/autotoolstoolchain.py
+++ b/conan/tools/gnu/autotoolstoolchain.py
@@ -123,9 +123,12 @@ class AutotoolsToolchain:
 
     def environment(self):
         env = Environment()
-        if is_msvc(self._conanfile):
-            env.define("CXX", "cl")
-            env.define("CC", "cl")
+        compilers_by_conf = self._conanfile.conf.get("tools.build:compiler_executables", default={}, check_type=dict)
+        if compilers_by_conf:
+            compilers_mapping = {"c": "CC", "cpp": "CXX", "cuda": "NVCC", "fortran": "FC"}
+            for comp, env_var in compilers_mapping.items():
+                if comp in compilers_by_conf:
+                    env.define(env_var, compilers_by_conf[comp])
         env.append("CPPFLAGS", ["-D{}".format(d) for d in self.defines])
         env.append("CXXFLAGS", self.cxxflags)
         env.append("CFLAGS", self.cflags)
diff --git a/conan/tools/meson/meson.py b/conan/tools/meson/meson.py
index 82ed7e745..e16326afa 100644
--- a/conan/tools/meson/meson.py
+++ b/conan/tools/meson/meson.py
@@ -17,17 +17,23 @@ class Meson(object):
         cross = os.path.join(generators_folder, MesonToolchain.cross_filename)
         native = os.path.join(generators_folder, MesonToolchain.native_filename)
         deps_flags = os.path.join(generators_folder, MesonDeps.filename)  # extra machine files layer
-        has_deps_flags = os.path.exists(deps_flags)
-
+        meson_filenames = []
         if os.path.exists(cross):
-            cmd += ' --cross-file "{}"'.format(cross)
-            if has_deps_flags:
-                cmd += ' --cross-file "{}"'.format(deps_flags)
+            cmd_param = " --cross-file"
+            meson_filenames.append(cross)
         else:
-            cmd += ' --native-file "{}"'.format(native)
-            if has_deps_flags:
-                cmd += ' --native-file "{}"'.format(deps_flags)
+            cmd_param = " --native-file"
+            meson_filenames.append(native)
+
+        if os.path.exists(deps_flags):
+            meson_filenames.append(deps_flags)
+
+        machine_files = self._conanfile.conf.get("tools.meson.mesontoolchain:extra_machine_files",
+                                                 default=[], check_type=list)
+        if machine_files:
+            meson_filenames.extend(machine_files)
 
+        cmd += "".join([f'{cmd_param} "{meson_option}"' for meson_option in meson_filenames])
         cmd += ' "{}" "{}"'.format(build_folder, source_folder)
         if self._conanfile.package_folder:
             cmd += ' -Dprefix="{}"'.format(self._conanfile.package_folder)
diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py
index b75fec4bd..e5ca38954 100644
--- a/conan/tools/meson/toolchain.py
+++ b/conan/tools/meson/toolchain.py
@@ -163,10 +163,14 @@ class MesonToolchain(object):
                 default_comp = "gcc"
                 default_comp_cpp = "g++"
 
+        # Read configuration for compilers
+        compilers_by_conf = self._conanfile.conf.get("tools.build:compiler_executables", default={},
+                                                     check_type=dict)
         # Read the VirtualBuildEnv to update the variables
         build_env = VirtualBuildEnv(self._conanfile).vars()
-        self.c = build_env.get("CC") or default_comp
-        self.cpp = build_env.get("CXX") or default_comp_cpp
+        self.c = compilers_by_conf.get("c") or build_env.get("CC") or default_comp
+        self.cpp = compilers_by_conf.get("cpp") or build_env.get("CXX") or default_comp_cpp
+        # FIXME: Should we use the new tools.build:compiler_executables and avoid buildenv?
         self.c_ld = build_env.get("CC_LD") or build_env.get("LD")
         self.cpp_ld = build_env.get("CXX_LD") or build_env.get("LD")
         self.ar = build_env.get("AR")
@@ -190,7 +194,7 @@ class MesonToolchain(object):
         self.objcpp_args = []
         self.objcpp_link_args = []
 
-        self._resolve_apple_flags_and_variables(build_env)
+        self._resolve_apple_flags_and_variables(build_env, compilers_by_conf)
         self._resolve_android_cross_compilation()
 
     def _get_default_dirs(self):
@@ -232,7 +236,7 @@ class MesonToolchain(object):
             ret["libdir"] = libdir
         return ret
 
-    def _resolve_apple_flags_and_variables(self, build_env):
+    def _resolve_apple_flags_and_variables(self, build_env, compilers_by_conf):
         if not self._is_apple_system:
             return
         # SDK path is mandatory for cross-building
@@ -251,8 +255,8 @@ class MesonToolchain(object):
         self.apple_isysroot_flag = ["-isysroot", sdk_path] if sdk_path else []
         self.apple_min_version_flag = [apple_min_version_flag(self._conanfile)]
         # Objective C/C++ ones
-        self.objc = "clang"
-        self.objcpp = "clang++"
+        self.objc = compilers_by_conf.get("objc", "clang")
+        self.objcpp = compilers_by_conf.get("objcxx", "clang++")
         self.objc_args = self._get_env_list(build_env.get('OBJCFLAGS', []))
         self.objc_link_args = self._get_env_list(build_env.get('LDFLAGS', []))
         self.objcpp_args = self._get_env_list(build_env.get('OBJCXXFLAGS', []))
diff --git a/conan/tools/microsoft/__init__.py b/conan/tools/microsoft/__init__.py
index c956ae068..79598b28e 100644
--- a/conan/tools/microsoft/__init__.py
+++ b/conan/tools/microsoft/__init__.py
@@ -3,5 +3,7 @@ from conan.tools.microsoft.msbuild import MSBuild
 from conan.tools.microsoft.msbuilddeps import MSBuildDeps
 from conan.tools.microsoft.subsystems import unix_path
 from conan.tools.microsoft.toolchain import MSBuildToolchain
+from conan.tools.microsoft.nmaketoolchain import NMakeToolchain
+from conan.tools.microsoft.nmakedeps import NMakeDeps
 from conan.tools.microsoft.visual import msvc_runtime_flag, VCVars, is_msvc, \
     is_msvc_static_runtime, check_min_vs
diff --git a/conan/tools/microsoft/nmakedeps.py b/conan/tools/microsoft/nmakedeps.py
new file mode 100644
index 000000000..f8af5696e
--- /dev/null
+++ b/conan/tools/microsoft/nmakedeps.py
@@ -0,0 +1,61 @@
+import os
+
+from conan.tools.env import Environment
+from conans.model.new_build_info import NewCppInfo
+
+
+class NMakeDeps(object):
+
+    def __init__(self, conanfile):
+        """
+        :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``.
+        """
+        self._conanfile = conanfile
+        self._environment = None
+
+    # TODO: This is similar from AutotoolsDeps: Refactor and make common
+    def _get_cpp_info(self):
+        ret = NewCppInfo()
+        deps = self._conanfile.dependencies.host.topological_sort
+        deps = [dep for dep in reversed(deps.values())]
+        for dep in deps:
+            dep_cppinfo = dep.cpp_info.aggregated_components()
+            # In case we have components, aggregate them, we do not support isolated
+            # "targets" with autotools
+            ret.merge(dep_cppinfo)
+        return ret
+
+    @property
+    def environment(self):
+        # TODO: Seems we want to make this uniform, equal to other generators
+        if self._environment is None:
+            cpp_info = self._get_cpp_info()
+
+            lib_paths = ";".join(cpp_info.libdirs or [])
+
+            def format_lib(lib):
+                ext = os.path.splitext(lib)[1]
+                return lib if ext in (".so", ".lib", ".a", ".dylib", ".bc") else '%s.lib' % lib
+
+            ret = []
+            ret.extend(cpp_info.exelinkflags or [])
+            ret.extend(cpp_info.sharedlinkflags or [])
+            ret.extend([format_lib(lib) for lib in cpp_info.libs or []])
+            link_args = " ".join(ret)
+
+            cl_flags = [f'-I"{p}"' for p in cpp_info.includedirs or []]
+            cl_flags.extend(cpp_info.cflags or [])
+            cl_flags.extend(cpp_info.cxxflags or [])
+
+            env = Environment()
+            env.append("CL", " ".join(cl_flags))
+            env.append_path("LIB", lib_paths)
+            env.append("_LINK_", link_args)
+            self._environment = env
+        return self._environment
+
+    def vars(self, scope="build"):
+        return self.environment.vars(self._conanfile, scope=scope)
+
+    def generate(self, scope="build"):
+        self.vars(scope).save_script("conannmakedeps")
diff --git a/conan/tools/microsoft/nmaketoolchain.py b/conan/tools/microsoft/nmaketoolchain.py
new file mode 100644
index 000000000..ef4795385
--- /dev/null
+++ b/conan/tools/microsoft/nmaketoolchain.py
@@ -0,0 +1,56 @@
+from conan.tools._compilers import cppstd_flag, build_type_flags
+from conan.tools.env import Environment
+
+
+class NMakeToolchain(object):
+    """
+    https://learn.microsoft.com/en-us/cpp/build/reference/running-nmake?view=msvc-170#toolsini-and-nmake
+    We have also explored the usage of Tools.ini:
+    https://learn.microsoft.com/en-us/cpp/build/reference/running-nmake?view=msvc-170
+    but not possible, because it cannot include other files, it will also potentially collide with
+    a user Tool.ini, without easy resolution. At least the environment is additive.
+    """
+    def __init__(self, conanfile):
+        """
+        :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``.
+        """
+        self._conanfile = conanfile
+        self._environment = None
+
+    @property
+    def cl_flags(self):
+        cppflags = []
+        build_type = self._conanfile.settings.get_safe("build_type")
+        if build_type in ['Release', 'RelWithDebInfo', 'MinSizeRel']:
+            cppflags.append("/DNDEBUG")
+
+        bt = build_type_flags(self._conanfile.settings)
+        if bt:
+            cppflags.extend(bt)
+
+        cppstd = cppstd_flag(self._conanfile.settings)
+        if cppstd:
+            cppflags.append(cppstd)
+        from conan.tools.microsoft import msvc_runtime_flag
+        flag = msvc_runtime_flag(self._conanfile)
+        if flag:
+            cppflags.append("-{}".format(flag))
+        return " ".join(cppflags).replace("-", "/")
+
+    @property
+    def environment(self):
+        # TODO: Seems we want to make this uniform, equal to other generators
+        if self._environment is None:
+            env = Environment()
+            # The whole injection of toolchain happens in CL env-var, the others LIBS, _LINK_
+            env.append("CL", self.cl_flags)
+            self._environment = env
+        return self._environment
+
+    def vars(self, scope="build"):
+        return self.environment.vars(self._conanfile, scope=scope)
+
+    def generate(self, scope="build"):
+        self.vars(scope).save_script("conannmaketoolchain")
+        from conan.tools.microsoft import VCVars
+        VCVars(self._conanfile).generate()
diff --git a/conans/client/conan_api.py b/conans/client/conan_api.py
index 7e4a23ac6..1c46eabb6 100644
--- a/conans/client/conan_api.py
+++ b/conans/client/conan_api.py
@@ -1343,6 +1343,9 @@ class ConanAPIV1(object):
         old_lock = GraphLockFile.load(old_lockfile, revisions_enabled)
         new_lockfile = _make_abs_path(new_lockfile, cwd)
         new_lock = GraphLockFile.load(new_lockfile, revisions_enabled)
+        if old_lock.profile_host is None or new_lock.profile_host is None:
+            raise ConanException("Lockfiles with --base do not contain profile information, "
+                                 "cannot be used. Create a full lockfile")
         if old_lock.profile_host.dumps() != new_lock.profile_host.dumps():
             raise ConanException("Profiles of lockfiles are different\n%s:\n%s\n%s:\n%s"
                                  % (old_lockfile, old_lock.profile_host.dumps(),
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
index c7f6c8bd6..ad204d43b 100644
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -94,7 +94,7 @@ _t_default_settings_yml = Template(textwrap.dedent("""
                       "9", "9.1", "9.2", "9.3", "9.4",
                       "10", "10.1", "10.2", "10.3",
                       "11", "11.1", "11.2", "11.3",
-                      "12"]
+                      "12", "12.1", "12.2"]
             libcxx: [libstdc++, libstdc++11]
             threads: [None, posix, win32]  # Windows MinGW
             exception: [None, dwarf2, sjlj, seh]  # Windows MinGW
diff --git a/conans/client/generators/__init__.py b/conans/client/generators/__init__.py
index 86d19ae10..dad8cdc36 100644
--- a/conans/client/generators/__init__.py
+++ b/conans/client/generators/__init__.py
@@ -73,7 +73,7 @@ class GeneratorManager(object):
                                 "VirtualRunEnv", "VirtualBuildEnv", "AutotoolsDeps",
                                 "AutotoolsToolchain", "BazelDeps", "BazelToolchain", "PkgConfigDeps",
                                 "VCVars", "IntelCC", "XcodeDeps", "PremakeDeps", "XcodeToolchain",
-                                "MesonDeps"]
+                                "MesonDeps", "NMakeToolchain", "NMakeDeps"]
 
     def add(self, name, generator_class, custom=False):
         if name not in self._generators or custom:
@@ -150,6 +150,12 @@ class GeneratorManager(object):
         elif generator_name == "XcodeToolchain":
             from conan.tools.apple import XcodeToolchain
             return XcodeToolchain
+        elif generator_name == "NMakeToolchain":
+            from conan.tools.microsoft import NMakeToolchain
+            return NMakeToolchain
+        elif generator_name == "NMakeDeps":
+            from conan.tools.microsoft import NMakeDeps
+            return NMakeDeps
         else:
             raise ConanException("Internal Conan error: Generator '{}' "
                                  "not commplete".format(generator_name))
diff --git a/conans/client/migrations_settings.py b/conans/client/migrations_settings.py
index 31bd00bf6..599a389fd 100644
--- a/conans/client/migrations_settings.py
+++ b/conans/client/migrations_settings.py
@@ -4030,4 +4030,156 @@ cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
 
 settings_1_54_0 = settings_1_53_0
 
-settings_1_55_0 = settings_1_54_0
+settings_1_55_0 = """
+# Only for cross building, 'os_build/arch_build' is the system that runs Conan
+os_build: [Windows, WindowsStore, Linux, Macos, FreeBSD, SunOS, AIX, VxWorks]
+arch_build: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7]
+
+# Only for building cross compilation tools, 'os_target/arch_target' is the system for
+# which the tools generate code
+os_target: [Windows, Linux, Macos, Android, iOS, watchOS, tvOS, FreeBSD, SunOS, AIX, Arduino, Neutrino]
+arch_target: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7, xtensalx6, xtensalx106, xtensalx7]
+
+# Rest of the settings are "host" settings:
+# - For native building/cross building: Where the library/program will run.
+# - For building cross compilation tools: Where the cross compiler will run.
+os:
+    Windows:
+        subsystem: [None, cygwin, msys, msys2, wsl]
+    WindowsStore:
+        version: ["8.1", "10.0"]
+    WindowsCE:
+        platform: ANY
+        version: ["5.0", "6.0", "7.0", "8.0"]
+    Linux:
+    iOS:
+        version: &ios_version
+                 ["7.0", "7.1", "8.0", "8.1", "8.2", "8.3", "9.0", "9.1", "9.2", "9.3", "10.0", "10.1", "10.2", "10.3",
+                  "11.0", "11.1", "11.2", "11.3", "11.4", "12.0", "12.1", "12.2", "12.3", "12.4",
+                  "13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7",
+                  "14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7", "14.8",
+                  "15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6", "16.0", "16.1"]
+        sdk: [None, "iphoneos", "iphonesimulator"]
+        sdk_version: [None, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4",
+                      "13.0", "13.1", "13.2", "13.4", "13.5", "13.6", "13.7",
+                      "14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "15.0", "15.2", "15.4", "15.5", "16.0", "16.1"]
+    watchOS:
+        version: ["4.0", "4.1", "4.2", "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2",
+                  "7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6", "8.0", "8.1", "8.3", "8.4", "8.5", "8.6", "8.7", "9.0", "9.1"]
+        sdk: [None, "watchos", "watchsimulator"]
+        sdk_version: [None, "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2",
+                      "7.0", "7.1", "7.2", "7.4", "8.0", "8.0.1", "8.3", "8.5", "9.0", "9.1"]
+    tvOS:
+        version: ["11.0", "11.1", "11.2", "11.3", "11.4", "12.0", "12.1", "12.2", "12.3", "12.4",
+                  "13.0", "13.2", "13.3", "13.4", "14.0", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7",
+                  "15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6", "16.0", "16.1"]
+        sdk: [None, "appletvos", "appletvsimulator"]
+        sdk_version: [None, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4",
+                      "13.0", "13.1", "13.2", "13.4", "14.0", "14.2", "14.3", "14.5", "15.0", "15.2", "15.4", "16.0", "16.1"]
+    Macos:
+        version: [None, "10.6", "10.7", "10.8", "10.9", "10.10", "10.11", "10.12", "10.13", "10.14", "10.15", "11.0", "12.0", "13.0"]
+        sdk: [None, "macosx"]
+        sdk_version: [None, "10.13", "10.14", "10.15", "11.0", "11.1", "11.3", "12.0", "12.1", "12.3", "13.0"]
+        subsystem:
+            None:
+            catalyst:
+                ios_version: *ios_version
+    Android:
+        api_level: ANY
+    FreeBSD:
+    SunOS:
+    AIX:
+    Arduino:
+        board: ANY
+    Emscripten:
+    Neutrino:
+        version: ["6.4", "6.5", "6.6", "7.0", "7.1"]
+    baremetal:
+    VxWorks:
+        version: ["7"]
+arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7, xtensalx6, xtensalx106, xtensalx7]
+compiler:
+    sun-cc:
+        version: ["5.10", "5.11", "5.12", "5.13", "5.14", "5.15"]
+        threads: [None, posix]
+        libcxx: [libCstd, libstdcxx, libstlport, libstdc++]
+    gcc: &gcc
+        version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9",
+                  "5", "5.1", "5.2", "5.3", "5.4", "5.5",
+                  "6", "6.1", "6.2", "6.3", "6.4", "6.5",
+                  "7", "7.1", "7.2", "7.3", "7.4", "7.5",
+                  "8", "8.1", "8.2", "8.3", "8.4",
+                  "9", "9.1", "9.2", "9.3", "9.4",
+                  "10", "10.1", "10.2", "10.3",
+                  "11", "11.1", "11.2", "11.3",
+                  "12", "12.1", "12.2"]
+        libcxx: [libstdc++, libstdc++11]
+        threads: [None, posix, win32]  # Windows MinGW
+        exception: [None, dwarf2, sjlj, seh]  # Windows MinGW
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+    Visual Studio: &visual_studio
+        runtime: [MD, MT, MTd, MDd]
+        version: ["8", "9", "10", "11", "12", "14", "15", "16", "17"]
+        toolset: [None, v90, v100, v110, v110_xp, v120, v120_xp,
+                  v140, v140_xp, v140_clang_c2, LLVM-vs2012, LLVM-vs2012_xp,
+                  LLVM-vs2013, LLVM-vs2013_xp, LLVM-vs2014, LLVM-vs2014_xp,
+                  LLVM-vs2017, LLVM-vs2017_xp, v141, v141_xp, v141_clang_c2, v142,
+                  llvm, ClangCL, v143]
+        cppstd: [None, 14, 17, 20, 23]
+    msvc:
+        version: [170, 180, 190, 191, 192, 193]
+        update: [None, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        runtime: [static, dynamic]
+        runtime_type: [Debug, Release]
+        cppstd: [98, 14, 17, 20, 23]
+        toolset: [None, v110_xp, v120_xp, v140_xp, v141_xp]
+    clang:
+        version: ["3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0",
+                  "5.0", "6.0", "7.0", "7.1",
+                  "8", "9", "10", "11", "12", "13", "14", "15", "16"]
+        libcxx: [None, libstdc++, libstdc++11, libc++, c++_shared, c++_static]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        runtime: [None, MD, MT, MTd, MDd, static, dynamic]
+        runtime_type: [None, Debug, Release]
+        runtime_version: [None, v140, v141, v142, v143]
+    apple-clang: &apple_clang
+        version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", "9.1", "10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", "14.0"]
+        libcxx: [libstdc++, libc++]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+    intel:
+        version: ["11", "12", "13", "14", "15", "16", "17", "18", "19", "19.1"]
+        update: [None, ANY]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exception: [None]
+            Visual Studio:
+                <<: *visual_studio
+            apple-clang:
+                <<: *apple_clang
+    intel-cc:
+        version: ["2021.1", "2021.2", "2021.3"]
+        update: [None, ANY]
+        mode: ["icx", "classic", "dpcpp"]
+        libcxx: [None, libstdc++, libstdc++11, libc++]
+        cppstd: [None, 98, gnu98, 03, gnu03, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        runtime: [None, static, dynamic]
+        runtime_type: [None, Debug, Release]
+    qcc:
+        version: ["4.4", "5.4", "8.3"]
+        libcxx: [cxx, gpp, cpp, cpp-ne, accp, acpp-ne, ecpp, ecpp-ne]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17]
+    mcst-lcc:
+        version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exceptions: [None]
+
+build_type: [None, Debug, Release, RelWithDebInfo, MinSizeRel]
+
+
+cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]  # Deprecated, use compiler.cppstd
+"""
diff --git a/conans/model/conan_file.py b/conans/model/conan_file.py
index b3737b516..bacba824f 100644
--- a/conans/model/conan_file.py
+++ b/conans/model/conan_file.py
@@ -438,7 +438,8 @@ class ConanFile(object):
                     return tools.run_in_windows_bash(self, bashcmd=cmd, cwd=cwd, subsystem=subsystem,
                                                      msys_mingw=msys_mingw, with_login=with_login)
             envfiles_folder = self.generators_folder or os.getcwd()
-            _env = [_env] if _env and isinstance(_env, str) else []
+            _env = [_env] if _env and isinstance(_env, str) else (_env or [])
+            assert isinstance(_env, list)
             wrapped_cmd = command_env_wrapper(self, cmd, _env, envfiles_folder=envfiles_folder,
                                               scope=scope)
             return self._conan_runner(wrapped_cmd, output, os.path.abspath(RUN_LOG_NAME), cwd)
diff --git a/conans/model/conf.py b/conans/model/conf.py
index b7044625b..49b0e0b33 100644
--- a/conans/model/conf.py
+++ b/conans/model/conf.py
@@ -52,6 +52,7 @@ BUILT_IN_CONFS = {
     "tools.build:defines": "List of extra definition flags used by different toolchains like CMakeToolchain and AutotoolsToolchain",
     "tools.build:sharedlinkflags": "List of extra flags used by CMakeToolchain for CMAKE_SHARED_LINKER_FLAGS_INIT variable",
     "tools.build:exelinkflags": "List of extra flags used by CMakeToolchain for CMAKE_EXE_LINKER_FLAGS_INIT variable",
+    "tools.build:compiler_executables": "Defines a Python dict-like with the compilers path to be used. Allowed keys {'c', 'cpp', 'cuda', 'objc', 'objcxx', 'rc', 'fortran', 'asm', 'hip', 'ispc'}",
     "tools.microsoft.bash:subsystem": "Set subsystem to use for Windows. Possible values: 'msys2', 'msys', 'cygwin', 'wsl' and 'sfu'",
     "tools.microsoft.bash:path": "Path to the shell executable. Default: 'bash'",
     "tools.apple:sdk_path": "Path for the sdk location. This value will be passed as SDKROOT or -isysroot depending on the generator used",
@@ -59,6 +60,7 @@ BUILT_IN_CONFS = {
     "tools.gnu:pkg_config": "Define the 'pkg_config' executable name or full path",
     "tools.env.virtualenv:powershell": "Opt-in to generate Powershell '.ps1' scripts instead of '.bat'",
     "tools.meson.mesontoolchain:backend": "Set the Meson backend. Possible values: 'ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'vs2019', 'xcode'",
+    "tools.meson.mesontoolchain:extra_machine_files": "List of paths for any additional native/cross file references to be appended to the existing Conan ones",
     "tools.files.download:download_cache": "Location for the download cache",
     "tools.build.cross_building:can_run": "Set the return value for the 'conan.tools.build.can_run()' tool",
 }


Test patch:
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
index f44aea035..45b5d1d97 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
@@ -574,3 +574,86 @@ def test_error_missing_build_type():
     run_app = r".\Release\app.exe" if platform.system() == "Windows" else "./Release/app"
     client.run_command(run_app)
     assert "Hello World Release!" in client.out
+
+
+@pytest.mark.tool_cmake
+def test_map_imported_config():
+    # https://github.com/conan-io/conan/issues/12041
+
+    client = TestClient()
+    client.run("new hello/1.0 -m=cmake_lib")
+    client.run("create . -tf=None -s build_type=Release")
+
+    # It is necessary a 2-level test to make the fixes evident
+    talk_cpp = gen_function_cpp(name="talk", includes=["hello"], calls=["hello"])
+    talk_h = gen_function_h(name="talk")
+    conanfile = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        from conan.tools.cmake import CMake
+        from conan.tools.files import copy
+        class HelloConan(ConanFile):
+            name = 'talk'
+            version = '1.0'
+            exports_sources = "*"
+            generators = "CMakeDeps", "CMakeToolchain"
+            requires = ("hello/1.0", )
+            settings = "os", "compiler", "arch", "build_type"
+
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+                cmake.build()
+
+            def package(self):
+                cmake = CMake(self)
+                cmake.install()
+
+            def package_info(self):
+                self.cpp_info.libs.append("talk")
+        """)
+
+    client.save({"conanfile.py": conanfile,
+                 "CMakeLists.txt": gen_cmakelists(libname="talk",
+                                                  libsources=["talk.cpp"], find_package=["hello"],
+                                                  install=True, public_header="talk.h"),
+                 "talk.cpp": talk_cpp,
+                 "talk.h": talk_h}, clean_first=True)
+    client.run("create . -tf=None -s build_type=Release")
+
+    conanfile = textwrap.dedent("""
+        [requires]
+        talk/1.0
+        [generators]
+        CMakeDeps
+        CMakeToolchain
+        """)
+
+    cmakelists = textwrap.dedent("""
+        cmake_minimum_required(VERSION 3.15)
+        project(app)
+        set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release)
+        find_package(talk REQUIRED)
+        add_executable(app main.cpp)
+        target_link_libraries(app talk::talk)
+        """)
+
+    client.save({
+        "conanfile.txt": conanfile,
+        "main.cpp": gen_function_cpp(name="main", includes=["talk"], calls=["talk"]),
+        "CMakeLists.txt": cmakelists
+    }, clean_first=True)
+
+    client.run("install . -s build_type=Release")
+    if platform.system() != "Windows":
+        client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake "
+                           "-DCMAKE_BUILD_TYPE=DEBUG")
+        client.run_command("cmake --build .")
+        client.run_command("./app")
+    else:
+        client.run_command("cmake . -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake")
+        client.run_command("cmake --build . --config Debug")
+        client.run_command("Debug\\app.exe")
+    assert "hello/1.0: Hello World Release!" in client.out
+    assert "talk: Release!" in client.out
+    assert "main: Debug!" in client.out
diff --git a/conans/test/functional/toolchains/cmake/test_cmake.py b/conans/test/functional/toolchains/cmake/test_cmake.py
index 5451a7fbb..1d29c3c6d 100644
--- a/conans/test/functional/toolchains/cmake/test_cmake.py
+++ b/conans/test/functional/toolchains/cmake/test_cmake.py
@@ -552,9 +552,7 @@ class CMakeInstallTest(unittest.TestCase):
         cmakelist = textwrap.dedent("""
             cmake_minimum_required(VERSION 2.8)
             project(App C)
-            if(CONAN_TOOLCHAIN_INCLUDED AND CMAKE_VERSION VERSION_LESS "3.15")
-                include("${CMAKE_BINARY_DIR}/conan_project_include.cmake")
-            endif()
+
             if(NOT CMAKE_TOOLCHAIN_FILE)
                 message(FATAL ">> Not using toolchain")
             endif()
@@ -585,6 +583,56 @@ class CMakeInstallTest(unittest.TestCase):
         self.assertTrue(os.path.exists(os.path.join(package_folder, "include", "header.h")))
 
 
+@pytest.mark.tool_cmake
+class CMakeTestTest(unittest.TestCase):
+    """
+    test the cmake.test() helper
+    """
+    def test_test(self):
+
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.cmake import CMake
+            class App(ConanFile):
+                settings = "os", "arch", "compiler", "build_type"
+                generators = "CMakeDeps", "CMakeToolchain", "VirtualBuildEnv", "VirtualRunEnv"
+                exports_sources = "CMakeLists.txt", "example.cpp"
+
+                def build_requirements(self):
+                    self.test_requires("test/0.1")
+
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+                    cmake.test()
+            """)
+
+        cmakelist = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(App CXX)
+            find_package(test CONFIG REQUIRED)
+            add_executable(example example.cpp)
+            target_link_libraries(example test::test)
+
+            enable_testing()
+            add_test(NAME example
+                      COMMAND example)
+            """)
+        c = TestClient()
+        c.run("new test/0.1 -m=cmake_lib")
+        c.run("create .  -tf=None -o test*:shared=True")
+
+        c.save({"conanfile.py": conanfile,
+                "CMakeLists.txt": cmakelist,
+                "example.cpp": gen_function_cpp(name="main", includes=["test"], calls=["test"])},
+               clean_first=True)
+
+        # The create flow must work
+        c.run("create . pkg/0.1@ -pr:b=default -o test*:shared=True")
+        assert "1/1 Test #1: example ..........................   Passed" in c.out
+
+
 @pytest.mark.tool_cmake
 class CMakeOverrideCacheTest(unittest.TestCase):
 
diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain_win_clang.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain_win_clang.py
index 368645491..a6c30e1b7 100644
--- a/conans/test/functional/toolchains/cmake/test_cmake_toolchain_win_clang.py
+++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain_win_clang.py
@@ -27,6 +27,8 @@ def client():
         build_type=Release
         compiler=clang
         compiler.version=12
+        [conf]
+        tools.build:compiler_executables={"cpp": "clang++", "c": "clang", "rc": "clang"}
         """)
     conanfile = textwrap.dedent("""
         import os
diff --git a/conans/test/functional/toolchains/gnu/autotools/test_win_bash.py b/conans/test/functional/toolchains/gnu/autotools/test_win_bash.py
index 1fbb389a8..28d0972a2 100644
--- a/conans/test/functional/toolchains/gnu/autotools/test_win_bash.py
+++ b/conans/test/functional/toolchains/gnu/autotools/test_win_bash.py
@@ -20,6 +20,7 @@ def test_autotools_bash_complete():
     save(client.cache.new_config_path, textwrap.dedent("""
             tools.microsoft.bash:subsystem=msys2
             tools.microsoft.bash:path={}
+            tools.build:compiler_executables={{"c": "cl", "cpp": "cl"}}
             """.format(bash_path)))
 
     main = gen_function_cpp(name="main")
@@ -31,7 +32,6 @@ def test_autotools_bash_complete():
     conanfile = textwrap.dedent("""
         from conans import ConanFile
         from conan.tools.gnu import Autotools
-        from conan.tools.env import Environment
 
         class TestConan(ConanFile):
             settings = "os", "compiler", "arch", "build_type"
diff --git a/conans/test/functional/toolchains/meson/_base.py b/conans/test/functional/toolchains/meson/_base.py
index 41c2d6858..818ac542b 100644
--- a/conans/test/functional/toolchains/meson/_base.py
+++ b/conans/test/functional/toolchains/meson/_base.py
@@ -1,5 +1,4 @@
 import platform
-import sys
 import unittest
 
 import pytest
@@ -8,7 +7,6 @@ from conans.test.utils.tools import TestClient
 
 
 @pytest.mark.tool_meson
-@pytest.mark.skipif(sys.version_info.major == 2, reason="Meson not supported in Py2")
 @pytest.mark.skipif(platform.system() not in ("Darwin", "Windows", "Linux"),
                     reason="Not tested for not mainstream boring operating systems")
 class TestMesonBase(unittest.TestCase):
diff --git a/conans/test/functional/toolchains/meson/test_meson.py b/conans/test/functional/toolchains/meson/test_meson.py
index 6ee637ad7..e754c052f 100644
--- a/conans/test/functional/toolchains/meson/test_meson.py
+++ b/conans/test/functional/toolchains/meson/test_meson.py
@@ -1,10 +1,14 @@
 import os
 import platform
+import sys
 import textwrap
 
+import pytest
+
 from conans.model.ref import ConanFileReference
 from conans.test.assets.sources import gen_function_cpp, gen_function_h
 from conans.test.functional.toolchains.meson._base import TestMesonBase
+from conans.test.utils.tools import TestClient
 
 
 class MesonToolchainTest(TestMesonBase):
@@ -167,3 +171,57 @@ class MesonToolchainTest(TestMesonBase):
         # res/tutorial -> tutorial is being added automatically by Meson
         assert os.path.exists(os.path.join(package_folder, "res", "tutorial", "file1.txt"))
         assert os.path.exists(os.path.join(package_folder, "res", "tutorial", "file2.txt"))
+
+
+@pytest.mark.tool_meson
+@pytest.mark.skipif(sys.version_info.minor < 8, reason="Latest Meson versions needs Python >= 3.8")
+def test_meson_and_additional_machine_files_composition():
+    """
+    Testing when users wants to append their own meson machine files and override/complement some
+    sections from Conan file ones.
+
+    See more information in Meson web page: https://mesonbuild.com/Machine-files.html
+
+    In this test, we're overriding only the Meson section ``[binaries]`` for instance.
+    """
+    profile = textwrap.dedent("""
+        [settings]
+        os=Windows
+        arch=x86_64
+        compiler=gcc
+        compiler.version=9
+        compiler.cppstd=17
+        compiler.libcxx=libstdc++11
+        build_type=Release
+
+        [conf]
+        tools.meson.mesontoolchain:extra_machine_files=["myfilename.ini"]
+   """)
+    myfilename = textwrap.dedent("""
+    [project options]
+    my_option = 'fake-option'
+    """)
+    conanfile = textwrap.dedent("""
+    from conan import ConanFile
+    from conan.tools.meson import Meson
+    class Pkg(ConanFile):
+        settings = "os", "compiler", "build_type", "arch"
+        generators = "MesonToolchain"
+        def build(self):
+            meson = Meson(self)
+            meson.configure()
+            meson.build()
+    """)
+    client = TestClient()
+    client.save({"conanfile.py": conanfile,
+                 "build/myfilename.ini": myfilename,
+                 "meson.build": "project('tutorial', 'cpp')",  # dummy one
+                 "profile": profile})
+
+    client.run("install . -pr=profile -if build")
+    client.run("build . -bf build", assert_error=True)
+    # Checking the order of the appended user file (the order matters)
+    conan_meson_native = os.path.join(client.current_folder, "build", "conan_meson_native.ini")
+    assert f'meson setup --native-file "{conan_meson_native}" --native-file "myfilename.ini"' in client.out
+    # Meson fails because of an unknown option
+    assert 'ERROR: Unknown options: "my_option"' in client.out
diff --git a/conans/test/functional/toolchains/test_nmake_toolchain.py b/conans/test/functional/toolchains/test_nmake_toolchain.py
new file mode 100644
index 000000000..e1a2409bf
--- /dev/null
+++ b/conans/test/functional/toolchains/test_nmake_toolchain.py
@@ -0,0 +1,57 @@
+import platform
+import textwrap
+
+import pytest
+
+from conans.test.assets.sources import gen_function_cpp
+from conans.test.functional.utils import check_exe_run
+from conans.test.utils.tools import TestClient
+
+
+@pytest.mark.parametrize("compiler, version, runtime, cppstd, build_type",
+                         [("msvc", "190", "dynamic", "14", "Release"),
+                          ("msvc", "191", "static", "17", "Debug")])
+@pytest.mark.skipif(platform.system() != "Windows", reason="Only for windows")
+def test_toolchain_nmake(compiler, version, runtime, cppstd, build_type):
+    client = TestClient(path_with_spaces=False)
+    settings = {"compiler": compiler,
+                "compiler.version": version,
+                "compiler.cppstd": cppstd,
+                "compiler.runtime": runtime,
+                "build_type": build_type,
+                "arch": "x86_64"}
+
+    # Build the profile according to the settings provided
+    settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v)
+    client.run("new dep/1.0 -m=cmake_lib")
+    client.run(f'create . -tf=None {settings} '
+               f'-c tools.cmake.cmaketoolchain:generator="Visual Studio 15"')
+
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            requires = "dep/1.0"
+            generators = "NMakeToolchain", "NMakeDeps"
+
+            def build(self):
+                self.run(f"nmake /f makefile")
+            """)
+    makefile = textwrap.dedent("""\
+        all: simple.exe
+
+        .cpp.obj:
+          cl $(cppflags) $*.cpp
+
+        simple.exe: simple.obj
+          cl $(cppflags) simple.obj
+        """)
+    client.save({"conanfile.py": conanfile,
+                 "makefile": makefile,
+                 "simple.cpp": gen_function_cpp(name="main", includes=["dep"], calls=["dep"])},
+                clean_first=True)
+    client.run("install . {}".format(settings))
+    client.run("build .")
+    client.run_command("simple.exe")
+    assert "dep/1.0" in client.out
+    check_exe_run(client.out, "main", "msvc", version, build_type, "x86_64", cppstd)
diff --git a/conans/test/functional/utils.py b/conans/test/functional/utils.py
index e318c6c6d..611fb8bab 100644
--- a/conans/test/functional/utils.py
+++ b/conans/test/functional/utils.py
@@ -83,7 +83,7 @@ def check_exe_run(output, names, compiler, version, build_type, arch, cppstd, de
         if extra_msg:  # For ``conan new`` templates
             assert "{} {} {}".format(name, extra_msg, build_type) in output
         else:
-            assert "{}: {}".format(name, extra_msg, build_type) in output
+            assert "{}: {}".format(name, build_type) in output
         if compiler == "msvc":
             if arch == "x86":
                 assert "{} _M_IX86 defined".format(name) in output
diff --git a/conans/test/integration/configuration/conf/test_conf_profile.py b/conans/test/integration/configuration/conf/test_conf_profile.py
index fd23859c0..c2c208665 100644
--- a/conans/test/integration/configuration/conf/test_conf_profile.py
+++ b/conans/test/integration/configuration/conf/test_conf_profile.py
@@ -17,7 +17,7 @@ def client():
             settings = "os", "arch", "compiler", "build_type"
             generators = "CMakeToolchain"
 
-            def run(self, cmd):  # INTERCEPTOR of running
+            def run(self, cmd, env=None):  # INTERCEPTOR of running
                 self.output.info("RECIPE-RUN: {}".format(cmd))
 
             def build(self):
diff --git a/conans/test/integration/graph_lock/lock_recipe_test.py b/conans/test/integration/graph_lock/lock_recipe_test.py
index 989e5fefa..f3b6e96be 100644
--- a/conans/test/integration/graph_lock/lock_recipe_test.py
+++ b/conans/test/integration/graph_lock/lock_recipe_test.py
@@ -20,6 +20,17 @@ class LockRecipeTest(unittest.TestCase):
         self.assertIn("Lockfiles with --base do not contain profile information, "
                       "cannot be used. Create a full lockfile", client.out)
 
+    def test_error_pass_base_update(self):
+        client = TestClient()
+        client.save({"conanfile.py": GenConanfile()})
+        client.run("create . pkg/0.1@")
+        client.save({"conanfile.py": GenConanfile().with_require("pkg/0.1")})
+        client.run("lock create conanfile.py --base --lockfile-out=conan.lock")
+        client.run("lock create conanfile.py --base --lockfile-out=conan2.lock")
+        client.run("lock update conan.lock conan2.lock", assert_error=True)
+        self.assertIn("Lockfiles with --base do not contain profile information, "
+                      "cannot be used. Create a full lockfile", client.out)
+
     def test_lock_recipe(self):
         client = TestClient()
         client.save({"conanfile.py": GenConanfile().with_setting("os")})
diff --git a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 1b1a9b76c..e219bcc5a 100644
--- a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -8,6 +8,7 @@ from mock import mock
 
 from conan.tools.cmake.presets import load_cmake_presets
 from conans.test.assets.genconanfile import GenConanfile
+from conans.test.utils.test_files import temp_folder
 from conans.test.utils.tools import TestClient
 from conans.util.files import rmdir
 
@@ -784,3 +785,63 @@ def test_pkg_config_block():
     pkg_config_path_set = 'set(ENV{PKG_CONFIG_PATH} "%s$ENV{PKG_CONFIG_PATH}")' % \
                           (client.current_folder.replace("\\", "/") + pathsep)
     assert pkg_config_path_set in toolchain
+
+
+@pytest.mark.parametrize("path", ["subproject", False])
+def test_user_presets_custom_location(path):
+    client = TestClient()
+    conanfile = textwrap.dedent("""
+                import os
+                from conan import ConanFile
+                from conan.tools.cmake import cmake_layout, CMakeToolchain
+
+                class Conan(ConanFile):
+                    settings = "os", "arch", "compiler", "build_type"
+
+                    def generate(self):
+                        t = CMakeToolchain(self)
+                        t.user_presets_path = {}
+                        t.generate()
+
+                    def layout(self):
+                        cmake_layout(self)
+                """.format('"{}"'.format(path) if isinstance(path, str) else path))
+    client.save({"CMakeLists.txt": "",
+                 "subproject/CMakeLists.txt": "",
+                 "subproject2/foo.txt": "",
+                 "conanfile.py": conanfile})
+
+    # We want to generate it to build the subproject
+    client.run("install . ")
+
+    if path is not False:
+        assert not os.path.exists(os.path.join(client.current_folder, "CMakeUserPresets.json"))
+        assert os.path.exists(os.path.join(client.current_folder, "subproject", "CMakeUserPresets.json"))
+    else:
+        assert not os.path.exists(os.path.join(client.current_folder, "CMakeUserPresets.json"))
+        assert not os.path.exists(os.path.join(client.current_folder, "False", "CMakeUserPresets.json"))
+
+
+def test_set_cmake_lang_compilers_and_launchers():
+    profile = textwrap.dedent(r"""
+    [settings]
+    os=Windows
+    arch=x86_64
+    compiler=clang
+    compiler.version=15
+    compiler.libcxx=libstdc++11
+    [conf]
+    tools.build:compiler_executables={"c": "/my/local/gcc", "cpp": "g++", "rc": "C:\\local\\rc.exe"}
+    """)
+    client = TestClient(path_with_spaces=False)
+    conanfile = GenConanfile().with_settings("os", "arch", "compiler")\
+        .with_generator("CMakeToolchain")
+    client.save({"conanfile.py": conanfile,
+                "profile": profile})
+    client.run("install . -pr:b profile -pr:h profile")
+    toolchain = client.load("conan_toolchain.cmake")
+    assert 'set(CMAKE_C_COMPILER clang)' not in toolchain
+    assert 'set(CMAKE_CXX_COMPILER clang++)' not in toolchain
+    assert 'set(CMAKE_C_COMPILER "/my/local/gcc")' in toolchain
+    assert 'set(CMAKE_CXX_COMPILER "g++")' in toolchain
+    assert 'set(CMAKE_RC_COMPILER "C:/local/rc.exe")' in toolchain
diff --git a/conans/test/integration/toolchains/meson/test_mesontoolchain.py b/conans/test/integration/toolchains/meson/test_mesontoolchain.py
index c5b273ada..7a1932fb9 100644
--- a/conans/test/integration/toolchains/meson/test_mesontoolchain.py
+++ b/conans/test/integration/toolchains/meson/test_mesontoolchain.py
@@ -1,13 +1,9 @@
-import sys
 import textwrap
 
-import pytest
-
 from conan.tools.meson import MesonToolchain
 from conans.test.utils.tools import TestClient
 
 
-@pytest.mark.skipif(sys.version_info.major == 2, reason="Meson not supported in Py2")
 def test_apple_meson_keep_user_custom_flags():
     default = textwrap.dedent("""
     [settings]
@@ -62,7 +58,6 @@ def test_apple_meson_keep_user_custom_flags():
     assert "cpp_link_args = ['-isysroot', '/other/sdk/path', '-arch', 'myarch', '-otherminversion=10.7', '-stdlib=libc++']" in content
 
 
-@pytest.mark.skipif(sys.version_info.major == 2, reason="Meson not supported in Py2")
 def test_extra_flags_via_conf():
     profile = textwrap.dedent("""
         [settings]
@@ -97,7 +92,6 @@ def test_extra_flags_via_conf():
     assert "cpp_link_args = ['-flag0', '-other=val', '-flag5', '-flag6']" in content
 
 
-@pytest.mark.skipif(sys.version_info.major == 2, reason="Meson not supported in Py2")
 def test_correct_quotes():
     profile = textwrap.dedent("""
        [settings]
diff --git a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
index 2d30b9eb1..2b9670452 100644
--- a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
+++ b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
@@ -29,6 +29,7 @@ def conanfile():
     c.settings.compiler.libcxx = "libstdc++"
     c.settings.os = "Windows"
     c.conf = Conf()
+    c.conf.define("tools.cmake.cmaketoolchain:system_name", "potato")
     c.folders.set_base_generators(".")
     c._conan_node = Mock()
     c._conan_node.dependencies = []
@@ -38,29 +39,29 @@ def conanfile():
 def test_cmake_toolchain(conanfile):
     toolchain = CMakeToolchain(conanfile)
     content = toolchain.content
-    assert 'set(CMAKE_C_COMPILER clang)' in content
+    assert 'set(CMAKE_SYSTEM_NAME potato)' in content
 
 
 def test_remove(conanfile):
     toolchain = CMakeToolchain(conanfile)
     toolchain.blocks.remove("generic_system")
     content = toolchain.content
-    assert 'CMAKE_C_COMPILER' not in content
+    assert 'CMAKE_SYSTEM_NAME' not in content
 
 
 def test_template_remove(conanfile):
     toolchain = CMakeToolchain(conanfile)
     toolchain.blocks["generic_system"].template = ""
     content = toolchain.content
-    assert 'CMAKE_C_COMPILER' not in content
+    assert 'CMAKE_SYSTEM_NAME' not in content
 
 
 def test_template_change(conanfile):
     toolchain = CMakeToolchain(conanfile)
     tmp = toolchain.blocks["generic_system"].template
-    toolchain.blocks["generic_system"].template = tmp.replace("CMAKE_C_COMPILER", "OTHER_THING")
+    toolchain.blocks["generic_system"].template = tmp.replace("CMAKE_SYSTEM_NAME", "OTHER_THING")
     content = toolchain.content
-    assert 'set(OTHER_THING clang)' in content
+    assert 'set(OTHER_THING potato)' in content
 
 
 def test_context_change(conanfile):
@@ -69,25 +70,26 @@ def test_context_change(conanfile):
 
     def context(self):
         assert self
-        return {"compiler": None}
+        return {"cmake_system_name": None}
+
     tmp.context = types.MethodType(context, tmp)
     content = toolchain.content
-    assert 'CMAKE_C_COMPILER' not in content
+    assert 'CMAKE_SYSTEM_NAME' not in content
 
 
 def test_context_update(conanfile):
     toolchain = CMakeToolchain(conanfile)
-    compiler = toolchain.blocks["generic_system"].values["compiler"]
-    toolchain.blocks["generic_system"].values["compiler"] = "Super" + compiler
+    cmake_system_name = toolchain.blocks["generic_system"].values["cmake_system_name"]
+    toolchain.blocks["generic_system"].values["cmake_system_name"] = "Super" + cmake_system_name
     content = toolchain.content
-    assert 'set(CMAKE_C_COMPILER Superclang)' in content
+    assert 'set(CMAKE_SYSTEM_NAME Superpotato)' in content
 
 
 def test_context_replace(conanfile):
     toolchain = CMakeToolchain(conanfile)
-    toolchain.blocks["generic_system"].values = {"compiler": "SuperClang"}
+    toolchain.blocks["generic_system"].values = {"cmake_system_name": "SuperPotato"}
     content = toolchain.content
-    assert 'set(CMAKE_C_COMPILER SuperClang)' in content
+    assert 'set(CMAKE_SYSTEM_NAME SuperPotato)' in content
 
 
 def test_replace_block(conanfile):
@@ -102,7 +104,7 @@ def test_replace_block(conanfile):
     toolchain.blocks["generic_system"] = MyBlock
     content = toolchain.content
     assert 'HelloWorld' in content
-    assert 'CMAKE_C_COMPILER' not in content
+    assert 'set(CMAKE_SYSTEM_NAME potato)' not in content
 
 
 def test_add_new_block(conanfile):
@@ -117,7 +119,7 @@ def test_add_new_block(conanfile):
     toolchain.blocks["mynewblock"] = MyBlock
     content = toolchain.content
     assert 'Hello World!!!' in content
-    assert 'CMAKE_C_COMPILER' in content
+    assert 'set(CMAKE_SYSTEM_NAME potato)' in content
 
 
 def test_user_toolchain(conanfile):