Repository: conan-io/conan
Pull request #16335 (2024-05-24 12:40:07)

Fix autodetect CMAKE_SYSTEM_VERSION to convert to Darwin version
Changelog: Fix: Change autodetect of CMAKE_SYSTEM_VERSION to use the Darwin version
Docs: https://github.com/conan-io/docs/pull/XXXX

`CMAKE_SYSTEM_NAME` and `CMAKE_SYSTEM_VERSION` are required to be set when cross-compiling.
https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_VERSION.html
We recommend that users set them in the toolchain or through confs, but if they are not set we autodetect them based on the profile settings.
In the case of macOS systems, the `CMAKE_SYSTEM_VERSION` variable was set to the macOS version, but it needs to be the Darwin version. We need to set the Darwin version for each Apple system:  https://en.wikipedia.org/wiki/Darwin_(operating_system)#Darwin_20_onwards

This PR fixes it by converting the macOS versions to Darwin versions when the user doesn't set the variable.
Other option could be to stop autodetecting this variables and force users to set it themselves.

CMake states that the `CMAKE_SYSTEM_VERSION` is not usually set for Darwin systems and is not particularly meaningful, and users should be careful when making use of it in their projects.
It has almost no utility on the CMake side for Darwin systems
https://github.com/Kitware/CMake/blob/f0074159d75601145b6ab0a98d636ec4c17a4370/Modules/Platform/Darwin.cmake#L18

Closes: https://github.com/conan-io/conan/issues/16282



Patch:
diff --git a/conan/api/subapi/cache.py b/conan/api/subapi/cache.py
index 77d8c6df8..e8504efc1 100644
--- a/conan/api/subapi/cache.py
+++ b/conan/api/subapi/cache.py
@@ -177,7 +177,10 @@ class CacheAPI:
         for ref, ref_bundle in package_list.refs().items():
             ref.timestamp = revision_timestamp_now()
             ref_bundle["timestamp"] = ref.timestamp
-            recipe_layout = cache.get_or_create_ref_layout(ref)  # DB folder entry
+            try:
+                recipe_layout = cache.recipe_layout(ref)
+            except ConanException:
+                recipe_layout = cache.create_ref_layout(ref)  # new DB folder entry
             recipe_folder = ref_bundle["recipe_folder"]
             rel_path = os.path.relpath(recipe_layout.base_folder, cache_folder)
             rel_path = rel_path.replace("\\", "/")
@@ -187,7 +190,11 @@ class CacheAPI:
             for pref, pref_bundle in package_list.prefs(ref, ref_bundle).items():
                 pref.timestamp = revision_timestamp_now()
                 pref_bundle["timestamp"] = pref.timestamp
-                pkg_layout = cache.get_or_create_pkg_layout(pref)  # DB Folder entry
+                try:
+                    pkg_layout = cache.pkg_layout(pref)
+                except ConanException:
+                    pkg_layout = cache.create_pkg_layout(pref)  # DB Folder entry
+                # FIXME: This is not taking into account the existence of previous package
                 unzipped_pkg_folder = pref_bundle["package_folder"]
                 out.info(f"Restore: {pref} in {unzipped_pkg_folder}")
                 # If the DB folder entry is different to the disk unzipped one, we need to move it
@@ -203,6 +210,7 @@ class CacheAPI:
                     pref_bundle["package_folder"] = db_pkg_folder
                 unzipped_metadata_folder = pref_bundle.get("metadata_folder")
                 if unzipped_metadata_folder:
+                    # FIXME: Restore metadata is not incremental, but destructive
                     out.info(f"Restore: {pref} metadata in {unzipped_metadata_folder}")
                     db_metadata_folder = os.path.relpath(pkg_layout.metadata(), cache_folder)
                     db_metadata_folder = db_metadata_folder.replace("\\", "/")
diff --git a/conan/api/subapi/install.py b/conan/api/subapi/install.py
index 6fd61d179..0fb5e1108 100644
--- a/conan/api/subapi/install.py
+++ b/conan/api/subapi/install.py
@@ -36,7 +36,8 @@ class InstallAPI:
         installer.install_system_requires(graph, only_info)
 
     def install_sources(self, graph, remotes):
-        """ Install sources for dependency graph
+        """ Install sources for dependency graph of packages to BUILD or packages that match
+        tools.build:download_source conf
         :param remotes:
         :param graph: Dependency graph to install packages for
         """
diff --git a/conan/cli/command.py b/conan/cli/command.py
index 9daeb03fd..7a074dc7c 100644
--- a/conan/cli/command.py
+++ b/conan/cli/command.py
@@ -52,7 +52,8 @@ class BaseConanCommand:
                                  "to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, "
                                  "-v or -vverbose, -vv or -vdebug, -vvv or -vtrace")
         parser.add_argument("-cc", "--core-conf", action="append",
-                            help="Global configuration for Conan")
+                            help="Define core configuration, overwriting global.conf "
+                                 "values. E.g.: -cc core:non_interactive=True")
 
     @property
     def _help_formatters(self):
diff --git a/conan/internal/cache/cache.py b/conan/internal/cache/cache.py
index edb2bb94a..92af0a603 100644
--- a/conan/internal/cache/cache.py
+++ b/conan/internal/cache/cache.py
@@ -8,8 +8,7 @@ from conan.internal.cache.conan_reference_layout import RecipeLayout, PackageLay
 # TODO: Random folders are no longer accessible, how to get rid of them asap?
 # TODO: We need the workflow to remove existing references.
 from conan.internal.cache.db.cache_database import CacheDatabase
-from conans.errors import ConanReferenceAlreadyExistsInDB, ConanReferenceDoesNotExistInDB, \
-    ConanException
+from conans.errors import ConanReferenceAlreadyExistsInDB, ConanException
 from conans.model.package_ref import PkgReference
 from conans.model.recipe_ref import RecipeReference
 from conans.util.dates import revision_timestamp_now
@@ -138,31 +137,29 @@ class PkgCache:
         # we use abspath to convert cache forward slash in Windows to backslash
         return PackageLayout(pref, os.path.abspath(os.path.join(self._base_folder, pref_path)))
 
-    def get_or_create_ref_layout(self, ref: RecipeReference):
-        """ called by RemoteManager.get_recipe()
+    def create_ref_layout(self, ref: RecipeReference):
+        """ called exclusively by:
+        - RemoteManager.get_recipe()
+        - cache restore
         """
-        try:
-            return self.recipe_layout(ref)
-        except ConanReferenceDoesNotExistInDB:
-            assert ref.revision, "Recipe revision must be known to create the package layout"
-            reference_path = self._get_path(ref)
-            self._db.create_recipe(reference_path, ref)
-            self._create_path(reference_path, remove_contents=False)
-            return RecipeLayout(ref, os.path.join(self._base_folder, reference_path))
-
-    def get_or_create_pkg_layout(self, pref: PkgReference):
-        """ called by RemoteManager.get_package() and  BinaryInstaller
+        assert ref.revision, "Recipe revision must be known to create the package layout"
+        reference_path = self._get_path(ref)
+        self._db.create_recipe(reference_path, ref)
+        self._create_path(reference_path, remove_contents=False)
+        return RecipeLayout(ref, os.path.join(self._base_folder, reference_path))
+
+    def create_pkg_layout(self, pref: PkgReference):
+        """ called by:
+         - RemoteManager.get_package()
+         - cacje restpre
         """
-        try:
-            return self.pkg_layout(pref)
-        except ConanReferenceDoesNotExistInDB:
-            assert pref.ref.revision, "Recipe revision must be known to create the package layout"
-            assert pref.package_id, "Package id must be known to create the package layout"
-            assert pref.revision, "Package revision should be known to create the package layout"
-            package_path = self._get_path_pref(pref)
-            self._db.create_package(package_path, pref, None)
-            self._create_path(package_path, remove_contents=False)
-            return PackageLayout(pref, os.path.join(self._base_folder, package_path))
+        assert pref.ref.revision, "Recipe revision must be known to create the package layout"
+        assert pref.package_id, "Package id must be known to create the package layout"
+        assert pref.revision, "Package revision should be known to create the package layout"
+        package_path = self._get_path_pref(pref)
+        self._db.create_package(package_path, pref, None)
+        self._create_path(package_path, remove_contents=False)
+        return PackageLayout(pref, os.path.join(self._base_folder, package_path))
 
     def update_recipe_timestamp(self, ref: RecipeReference):
         """ when the recipe already exists in cache, but we get a new timestamp from a server
diff --git a/conan/internal/cache/conan_reference_layout.py b/conan/internal/cache/conan_reference_layout.py
index 592c03c68..3a4aab9b0 100644
--- a/conan/internal/cache/conan_reference_layout.py
+++ b/conan/internal/cache/conan_reference_layout.py
@@ -81,14 +81,6 @@ class RecipeLayout(LayoutBase):
         src_folder = self.source()
         rmdir(src_folder)
 
-    def export_remove(self):
-        export_folder = self.export()
-        rmdir(export_folder)
-        export_src_folder = os.path.join(self._base_folder, EXPORT_SRC_FOLDER)
-        rmdir(export_src_folder)
-        download_export = self.download_export()
-        rmdir(download_export)
-
 
 class PackageLayout(LayoutBase):
 
diff --git a/conan/tools/build/cppstd.py b/conan/tools/build/cppstd.py
index 01ef4d71f..bf66fc624 100644
--- a/conan/tools/build/cppstd.py
+++ b/conan/tools/build/cppstd.py
@@ -11,12 +11,7 @@ def check_min_cppstd(conanfile, cppstd, gnu_extensions=False):
         In case the current cppstd doesn't fit the minimal version required
         by cppstd, a ConanInvalidConfiguration exception will be raised.
 
-        1. If settings.compiler.cppstd, the tool will use settings.compiler.cppstd to compare
-        2. It not settings.compiler.cppstd, the tool will use compiler to compare (reading the
-           default from cppstd_default)
-        3. If not settings.compiler is present (not declared in settings) will raise because it
-           cannot compare.
-        4. If can not detect the default cppstd for settings.compiler, a exception will be raised.
+        settings.compiler.cppstd must be defined, otherwise ConanInvalidConfiguration is raised
 
     :param conanfile: The current recipe object. Always use ``self``.
     :param cppstd: Minimal cppstd version required
@@ -31,12 +26,7 @@ def check_max_cppstd(conanfile, cppstd, gnu_extensions=False):
         In case the current cppstd doesn't fit the maximum version required
         by cppstd, a ConanInvalidConfiguration exception will be raised.
 
-        1. If settings.compiler.cppstd, the tool will use settings.compiler.cppstd to compare
-        2. It not settings.compiler.cppstd, the tool will use compiler to compare (reading the
-           default from cppstd_default)
-        3. If not settings.compiler is present (not declared in settings) will raise because it
-           cannot compare.
-        4. If can not detect the default cppstd for settings.compiler, a exception will be raised.
+        settings.compiler.cppstd must be defined, otherwise ConanInvalidConfiguration is raised
 
     :param conanfile: The current recipe object. Always use ``self``.
     :param cppstd: Maximum cppstd version required
@@ -126,12 +116,7 @@ def _check_cppstd(conanfile, cppstd, comparator, gnu_extensions):
         In case the current cppstd doesn't fit the maximum version required
         by cppstd, a ConanInvalidConfiguration exception will be raised.
 
-        1. If settings.compiler.cppstd, the tool will use settings.compiler.cppstd to compare
-        2. It not settings.compiler.cppstd, the tool will use compiler to compare (reading the
-           default from cppstd_default)
-        3. If not settings.compiler is present (not declared in settings) will raise because it
-           cannot compare.
-        4. If can not detect the default cppstd for settings.compiler, a exception will be raised.
+        settings.compiler.cppstd must be defined, otherwise ConanInvalidConfiguration is raised
 
     :param conanfile: The current recipe object. Always use ``self``.
     :param cppstd: Required cppstd version.
@@ -257,6 +242,7 @@ def _mcst_lcc_supported_cppstd(version):
 
     return ["98", "gnu98", "11", "gnu11", "14", "gnu14", "17", "gnu17", "20", "gnu20"]
 
+
 def _qcc_supported_cppstd(version):
     """
     [98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17]
diff --git a/conan/tools/cmake/cmakedeps/cmakedeps.py b/conan/tools/cmake/cmakedeps/cmakedeps.py
index f8a9cca02..e982c9ae5 100644
--- a/conan/tools/cmake/cmakedeps/cmakedeps.py
+++ b/conan/tools/cmake/cmakedeps/cmakedeps.py
@@ -1,4 +1,3 @@
-import os
 import textwrap
 
 import jinja2
@@ -15,7 +14,6 @@ from conan.tools.cmake.cmakedeps.templates.target_configuration import TargetCon
 from conan.tools.cmake.cmakedeps.templates.target_data import ConfigDataTemplate
 from conan.tools.cmake.cmakedeps.templates.targets import TargetsTemplate
 from conan.tools.files import save
-from conans.client.generators import relativize_generated_file
 from conan.errors import ConanException
 from conans.model.dependencies import get_transitive_requires
 
@@ -120,8 +118,7 @@ class CMakeDeps(object):
             ret[config_version.filename] = config_version.render()
 
         data_target = ConfigDataTemplate(self, require, dep, find_module_mode)
-        data_content = relativize_generated_file(data_target.render(), self._conanfile,
-                                                 "${CMAKE_CURRENT_LIST_DIR}")
+        data_content = data_target.render()
         ret[data_target.filename] = data_content
 
         target_configuration = TargetConfigurationTemplate(self, require, dep, find_module_mode)
@@ -131,11 +128,9 @@ class CMakeDeps(object):
         ret[targets.filename] = targets.render()
 
         config = ConfigTemplate(self, require, dep, find_module_mode)
-        # Check if the XXConfig.cmake exists to keep the first generated configuration
-        # to only include the build_modules from the first conan install. The rest of the
-        # file is common for the different configurations.
-        if not os.path.exists(config.filename):
-            ret[config.filename] = config.render()
+        # Only the latest configuration BUILD_MODULES and additional_variables will be used
+        # in multi-config they will be overwritten by the latest install
+        ret[config.filename] = config.render()
 
     def set_property(self, dep, prop, value, build_context=False):
         """
diff --git a/conan/tools/cmake/cmakedeps/templates/config.py b/conan/tools/cmake/cmakedeps/templates/config.py
index 6a161d293..68c456398 100644
--- a/conan/tools/cmake/cmakedeps/templates/config.py
+++ b/conan/tools/cmake/cmakedeps/templates/config.py
@@ -83,7 +83,7 @@ class ConfigTemplate(CMakeDepsFileTemplate):
 
         {% endfor %}
 
-        # Only the first installed configuration is included to avoid the collision
+        # Only the last installed configuration BUILD_MODULES are included to avoid the collision
         foreach(_BUILD_MODULE {{ pkg_var(pkg_name, 'BUILD_MODULES_PATHS', config_suffix) }} )
             message({% raw %}${{% endraw %}{{ file_name }}_MESSAGE_MODE} "Conan: Including build module from '${_BUILD_MODULE}'")
             include({{ '${_BUILD_MODULE}' }})
diff --git a/conan/tools/cmake/cmakedeps/templates/target_data.py b/conan/tools/cmake/cmakedeps/templates/target_data.py
index e86d89be4..315e2cf30 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_data.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_data.py
@@ -5,7 +5,7 @@ from conan.tools.cmake.cmakedeps import FIND_MODE_NONE, FIND_MODE_CONFIG, FIND_M
     FIND_MODE_BOTH
 from conan.tools.cmake.cmakedeps.templates import CMakeDepsFileTemplate
 from conan.errors import ConanException
-
+from conans.client.generators import relativize_path
 
 """
 
@@ -57,6 +57,9 @@ class ConfigDataTemplate(CMakeDepsFileTemplate):
         # Make the root_folder relative to the generated xxx-data.cmake file
         root_folder = self._root_folder
         root_folder = root_folder.replace('\\', '/').replace('$', '\\$').replace('"', '\\"')
+        # it is the relative path of the caller, not the dependency
+        root_folder = relativize_path(root_folder, self.cmakedeps._conanfile,
+                                      "${CMAKE_CURRENT_LIST_DIR}")
 
         return {"global_cpp": global_cpp,
                 "has_components": self.conanfile.cpp_info.has_components,
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 02d6c4723..575f520bf 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -16,8 +16,10 @@ from conan.tools.cmake.toolchain import CONAN_TOOLCHAIN_FILENAME
 from conan.tools.cmake.utils import is_multi_configuration
 from conan.tools.intel import IntelCC
 from conan.tools.microsoft.visual import msvc_version_to_toolset_version
+from conans.client.generators import relativize_path
 from conans.client.subsystems import deduce_subsystem, WINDOWS
 from conan.errors import ConanException
+from conans.model.version import Version
 from conans.util.files import load
 
 
@@ -146,8 +148,9 @@ class VSDebuggerEnvironment(Block):
         bin_dirs = [p for dep in host_deps for p in dep.cpp_info.aggregated_components().bindirs]
         test_bindirs = [p for dep in test_deps for p in dep.cpp_info.aggregated_components().bindirs]
         bin_dirs.extend(test_bindirs)
+        bin_dirs = [relativize_path(p, self._conanfile, "${CMAKE_CURRENT_LIST_DIR}")
+                    for p in bin_dirs]
         bin_dirs = [p.replace("\\", "/") for p in bin_dirs]
-
         bin_dirs = ";".join(bin_dirs) if bin_dirs else None
         if bin_dirs:
             config_dict[build_type] = bin_dirs
@@ -238,6 +241,8 @@ class LinkerScriptsBlock(Block):
         if not linker_scripts:
             return
         linker_scripts = [linker_script.replace('\\', '/') for linker_script in linker_scripts]
+        linker_scripts = [relativize_path(p, self._conanfile, "${CMAKE_CURRENT_LIST_DIR}")
+                          for p in linker_scripts]
         linker_script_flags = ['-T"' + linker_script + '"' for linker_script in linker_scripts]
         return {"linker_script_flags": " ".join(linker_script_flags)}
 
@@ -324,6 +329,8 @@ class AndroidSystemBlock(Block):
         if not android_ndk_path:
             raise ConanException('CMakeToolchain needs tools.android:ndk_path configuration defined')
         android_ndk_path = android_ndk_path.replace("\\", "/")
+        android_ndk_path = relativize_path(android_ndk_path, self._conanfile,
+                                           "${CMAKE_CURRENT_LIST_DIR}")
 
         use_cmake_legacy_toolchain = self._conanfile.conf.get("tools.android:cmake_legacy_toolchain",
                                                               check_type=bool)
@@ -430,6 +437,8 @@ class AppleSystemBlock(Block):
             "enable_visibility": enable_visibility
         }
         if host_sdk_name:
+            host_sdk_name = relativize_path(host_sdk_name, self._conanfile,
+                                            "${CMAKE_CURRENT_LIST_DIR}")
             ctxt_toolchain["cmake_osx_sysroot"] = host_sdk_name
         # this is used to initialize the OSX_ARCHITECTURES property on each target as it is created
         if host_architecture:
@@ -527,23 +536,22 @@ class FindFiles(Block):
                 host_runtime_dirs = {}
                 for k, v in matches:
                     host_runtime_dirs.setdefault(k, []).append(v)
-        
+
         # Calculate the dirs for the current build_type
         runtime_dirs = []
         for req in host_req:
             cppinfo = req.cpp_info.aggregated_components()
             runtime_dirs.extend(cppinfo.bindirs if is_win else cppinfo.libdirs)
-        
+
         build_type = settings.get_safe("build_type")
         host_runtime_dirs[build_type] = [s.replace("\\", "/") for s in runtime_dirs]
 
         return host_runtime_dirs
 
-    @staticmethod
-    def _join_paths(paths):
-        return " ".join(['"{}"'.format(p.replace('\\', '/')
-                                        .replace('$', '\\$')
-                                        .replace('"', '\\"')) for p in paths])
+    def _join_paths(self, paths):
+        paths = [relativize_path(p, self._conanfile, "${CMAKE_CURRENT_LIST_DIR}") for p in paths]
+        paths = [p.replace('\\', '/').replace('$', '\\$').replace('"', '\\"') for p in paths]
+        return " ".join([f'"{p}"' for p in paths])
 
     def context(self):
         # To find the generated cmake_find_package finders
@@ -630,7 +638,10 @@ class UserToolchain(Block):
         # This is global [conf] injection of extra toolchain files
         user_toolchain = self._conanfile.conf.get("tools.cmake.cmaketoolchain:user_toolchain",
                                                   default=[], check_type=list)
-        return {"paths": [ut.replace("\\", "/") for ut in user_toolchain]}
+        paths = [relativize_path(p, self._conanfile, "${CMAKE_CURRENT_LIST_DIR}")
+                 for p in user_toolchain]
+        paths = [p.replace("\\", "/") for p in paths]
+        return {"paths": paths}
 
 
 class ExtraFlagsBlock(Block):
@@ -849,9 +860,10 @@ class GenericSystemBlock(Block):
             toolset = settings.get_safe("compiler.toolset")
             if toolset is None:
                 compiler_version = str(settings.compiler.version)
-                compiler_update = str(settings.compiler.update)
+                msvc_update = conanfile.conf.get("tools.microsoft:msvc_update")
+                compiler_update = msvc_update or settings.get_safe("compiler.update")
                 toolset = msvc_version_to_toolset_version(compiler_version)
-                if compiler_update != "None":  # It is full one(19.28), not generic 19.2X
+                if compiler_update is not None:  # It is full one(19.28), not generic 19.2X
                     # The equivalent of compiler 19.26 is toolset 14.26
                     toolset += ",version=14.{}{}".format(compiler_version[-1], compiler_update)
         elif compiler == "clang":
@@ -867,6 +879,7 @@ class GenericSystemBlock(Block):
             toolset = toolset_arch if toolset is None else "{},{}".format(toolset, toolset_arch)
         toolset_cuda = conanfile.conf.get("tools.cmake.cmaketoolchain:toolset_cuda")
         if toolset_cuda is not None:
+            toolset_cuda = relativize_path(toolset_cuda, conanfile, "${CMAKE_CURRENT_LIST_DIR}")
             toolset_cuda = f"cuda={toolset_cuda}"
             toolset = toolset_cuda if toolset is None else f"{toolset},{toolset_cuda}"
         return toolset
@@ -919,6 +932,34 @@ class GenericSystemBlock(Block):
         return os_host in ('iOS', 'watchOS', 'tvOS', 'visionOS') or (
                 os_host == 'Macos' and (arch_host != arch_build or os_build != os_host))
 
+    def _get_darwin_version(self, os_name, os_version):
+        # version mapping from https://en.wikipedia.org/wiki/Darwin_(operating_system)
+        version_mapping = {
+            "Macos": {
+                "10.6": "10", "10.7": "11", "10.8": "12", "10.9": "13", "10.10": "14", "10.11": "15",
+                "10.12": "16", "10.13": "17", "10.14": "18", "10.15": "19", "11": "20", "12": "21",
+                "13": "22", "14": "23",
+            },
+            "iOS": {
+                "7": "14", "8": "14", "9": "15", "10": "16", "11": "17", "12": "18", "13": "19",
+                "14": "20", "15": "21", "16": "22", "17": "23"
+            },
+            "watchOS": {
+                "4": "17", "5": "18", "6": "19", "7": "20",
+                "8": "21", "9": "22", "10": "23"
+            },
+            "tvOS": {
+                "11": "17", "12": "18", "13": "19", "14": "20",
+                "15": "21", "16": "22", "17": "23"
+            },
+            "visionOS": {
+                "1": "23"
+            }
+        }
+        os_version = Version(os_version).major if os_name != "Macos" or (os_name == "Macos" and Version(
+            os_version) >= Version("11")) else os_version
+        return version_mapping.get(os_name, {}).get(str(os_version))
+
     def _get_cross_build(self):
         user_toolchain = self._conanfile.conf.get("tools.cmake.cmaketoolchain:user_toolchain")
 
@@ -930,6 +971,7 @@ class GenericSystemBlock(Block):
         if not user_toolchain and not is_universal_arch(self._conanfile.settings.get_safe("arch"),
                                                         self._conanfile.settings.possible_values().get("arch")):
             os_host = self._conanfile.settings.get_safe("os")
+            os_host_version = self._conanfile.settings.get_safe("os.version")
             arch_host = self._conanfile.settings.get_safe("arch")
             if arch_host == "armv8":
                 arch_host = {"Windows": "ARM64", "Macos": "arm64"}.get(os_host, "aarch64")
@@ -940,12 +982,12 @@ class GenericSystemBlock(Block):
                 if self._is_apple_cross_building():
                     # cross-build in Macos also for M1
                     system_name = {'Macos': 'Darwin'}.get(os_host, os_host)
-                    #  CMAKE_SYSTEM_VERSION for Apple sets the sdk version, not the os version
-                    _system_version = self._conanfile.settings.get_safe("os.sdk_version")
+                    #  CMAKE_SYSTEM_VERSION for Apple sets the Darwin version, not the os version
+                    _system_version = self._get_darwin_version(os_host, os_host_version)
                     _system_processor = to_apple_arch(self._conanfile)
                 elif os_host != 'Android':
                     system_name = self._get_generic_system_name()
-                    _system_version = self._conanfile.settings.get_safe("os.version")
+                    _system_version = os_host_version
                     _system_processor = arch_host
 
                 if system_name is not None and system_version is None:
@@ -990,6 +1032,9 @@ class GenericSystemBlock(Block):
         # 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
+        if cmake_sysroot is not None:
+            cmake_sysroot = relativize_path(cmake_sysroot, self._conanfile,
+                                            "${CMAKE_CURRENT_LIST_DIR}")
 
         result = self._get_winsdk_version(system_version, generator_platform)
         system_version, winsdk_version, gen_platform_sdk_version = result
diff --git a/conan/tools/cmake/toolchain/toolchain.py b/conan/tools/cmake/toolchain/toolchain.py
index 549e2c0b3..6924a1d9f 100644
--- a/conan/tools/cmake/toolchain/toolchain.py
+++ b/conan/tools/cmake/toolchain/toolchain.py
@@ -19,7 +19,6 @@ from conan.tools.env import VirtualBuildEnv, VirtualRunEnv
 from conan.tools.intel import IntelCC
 from conan.tools.microsoft import VCVars
 from conan.tools.microsoft.visual import vs_ide_version
-from conans.client.generators import relativize_generated_file
 from conan.errors import ConanException
 from conans.model.options import _PackageOption
 from conans.util.files import save
@@ -202,7 +201,6 @@ class CMakeToolchain(object):
         context = self._context()
         content = Template(self._template, trim_blocks=True, lstrip_blocks=True,
                            keep_trailing_newline=True).render(**context)
-        content = relativize_generated_file(content, self._conanfile, "${CMAKE_CURRENT_LIST_DIR}")
         return content
 
     @property
diff --git a/conan/tools/files/files.py b/conan/tools/files/files.py
index 73f0d6d82..661b88db3 100644
--- a/conan/tools/files/files.py
+++ b/conan/tools/files/files.py
@@ -66,7 +66,7 @@ def rmdir(conanfile, path):
     _internal_rmdir(path)
 
 
-def rm(conanfile, pattern, folder, recursive=False):
+def rm(conanfile, pattern, folder, recursive=False, excludes=None):
     """
     Utility functions to remove files matching a ``pattern`` in a ``folder``.
 
@@ -74,10 +74,17 @@ def rm(conanfile, pattern, folder, recursive=False):
     :param pattern: Pattern that the files to be removed have to match (fnmatch).
     :param folder: Folder to search/remove the files.
     :param recursive: If ``recursive`` is specified it will search in the subfolders.
+    :param excludes: (Optional, defaulted to None) A tuple/list of fnmatch patterns or even a
+                     single one to be excluded from the remove pattern.
     """
+    if excludes and not isinstance(excludes, (tuple, list)):
+        excludes = (excludes,)
+    elif not excludes:
+        excludes = []
+
     for root, _, filenames in os.walk(folder):
         for filename in filenames:
-            if fnmatch(filename, pattern):
+            if fnmatch(filename, pattern) and not any(fnmatch(filename, it) for it in excludes):
                 fullname = os.path.join(root, filename)
                 os.unlink(fullname)
         if not recursive:
diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py
index 67713d769..d00f29145 100644
--- a/conan/tools/meson/toolchain.py
+++ b/conan/tools/meson/toolchain.py
@@ -245,6 +245,11 @@ class MesonToolchain(object):
             default_comp = "cl"
             default_comp_cpp = "cl"
 
+        # Read configuration for sys_root property (honoring existing conf)
+        self._sys_root = self._conanfile_conf.get("tools.build:sysroot", check_type=str)
+        if self._sys_root:
+            self.properties["sys_root"] = self._sys_root
+
         # Read configuration for compilers
         compilers_by_conf = self._conanfile_conf.get("tools.build:compiler_executables", default={},
                                                      check_type=dict)
@@ -404,10 +409,11 @@ class MesonToolchain(object):
         linker_scripts = self._conanfile_conf.get("tools.build:linker_scripts", default=[], check_type=list)
         linker_script_flags = ['-T"' + linker_script + '"' for linker_script in linker_scripts]
         defines = [f"-D{d}" for d in self._conanfile.conf.get("tools.build:defines", default=[], check_type=list)]
+        sys_root = [f"--sysroot={self._sys_root}"] if self._sys_root else [""]
         return {
-            "cxxflags": cxxflags,
-            "cflags": cflags,
-            "ldflags": sharedlinkflags + exelinkflags + linker_script_flags,
+            "cxxflags": cxxflags + sys_root,
+            "cflags": cflags + sys_root,
+            "ldflags": sharedlinkflags + exelinkflags + linker_script_flags + sys_root,
             "defines": defines
         }
 
diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py
index 1632e3b95..844031489 100644
--- a/conan/tools/microsoft/visual.py
+++ b/conan/tools/microsoft/visual.py
@@ -33,7 +33,8 @@ def check_min_vs(conanfile, version, raise_invalid=True):
                             "11": "170"}.get(compiler_version)
     elif compiler == "msvc":
         compiler_version = conanfile.settings.get_safe("compiler.version")
-        compiler_update = conanfile.settings.get_safe("compiler.update")
+        msvc_update = conanfile.conf.get("tools.microsoft:msvc_update")
+        compiler_update = msvc_update or conanfile.settings.get_safe("compiler.update")
         if compiler_version and compiler_update is not None:
             compiler_version += ".{}".format(compiler_update)
 
@@ -169,7 +170,7 @@ class VCVars:
 
         is_ps1 = conanfile.conf.get("tools.env.virtualenv:powershell", check_type=bool, default=False)
         if is_ps1:
-            content_ps1 = textwrap.dedent(rf"""\
+            content_ps1 = textwrap.dedent(rf"""
             if (-not $env:VSCMD_ARG_VCVARS_VER){{
                 Push-Location "$PSScriptRoot"
                 cmd /c "conanvcvars.bat&set" |
@@ -180,7 +181,7 @@ class VCVars:
                 }}
                 Pop-Location
                 write-host conanvcvars.ps1: Activated environment}}
-            """)
+            """).strip()
             conan_vcvars_ps1 = f"{CONAN_VCVARS}.ps1"
             create_env_script(conanfile, content_ps1, conan_vcvars_ps1, scope)
             _create_deactivate_vcvars_file(conanfile, conan_vcvars_ps1)
diff --git a/conans/client/generators/__init__.py b/conans/client/generators/__init__.py
index eeed8ddbb..de0d06fd1 100644
--- a/conans/client/generators/__init__.py
+++ b/conans/client/generators/__init__.py
@@ -207,15 +207,6 @@ def _generate_aggregated_env(conanfile):
         conanfile.output.info(f"Generated aggregated env files: {generated}")
 
 
-def relativize_generated_file(content, conanfile, placeholder):
-    abs_base_path, new_path = relativize_paths(conanfile, placeholder)
-    if abs_base_path is None:
-        return content
-    content = content.replace(abs_base_path, new_path)
-    content = content.replace(abs_base_path.replace("\\", "/"), new_path.replace("\\", "/"))
-    return content
-
-
 def relativize_paths(conanfile, placeholder):
     abs_base_path = conanfile.folders._base_generators
     if not abs_base_path or not os.path.isabs(abs_base_path):
@@ -229,3 +220,17 @@ def relativize_paths(conanfile, placeholder):
     new_path = placeholder if rel_path == "." else os.path.join(placeholder, rel_path)
     new_path = os.path.join(new_path, "")  # For the trailing / to dissambiguate matches
     return abs_base_path, new_path
+
+
+def relativize_path(path, conanfile, placeholder):
+    abs_base_path, new_path = relativize_paths(conanfile, placeholder)
+    if abs_base_path is None:
+        return path
+    if path.startswith(abs_base_path):
+        path = path.replace(abs_base_path, new_path, 1)
+    else:
+        abs_base_path = abs_base_path.replace("\\", "/")
+        new_path = new_path.replace("\\", "/")
+        if path.startswith(abs_base_path):
+            path = path.replace(abs_base_path, new_path, 1)
+    return path
diff --git a/conans/client/graph/build_mode.py b/conans/client/graph/build_mode.py
index 5ed470988..f7a3cd61f 100644
--- a/conans/client/graph/build_mode.py
+++ b/conans/client/graph/build_mode.py
@@ -15,6 +15,7 @@ class BuildMode:
         self.editable = False
         self.patterns = []
         self.build_missing_patterns = []
+        self._build_missing_excluded = []
         self._excluded_patterns = []
         if params is None:
             return
@@ -34,7 +35,10 @@ class BuildMode:
             else:
                 if param.startswith("missing:"):
                     clean_pattern = param[len("missing:"):]
-                    self.build_missing_patterns.append(clean_pattern)
+                    if clean_pattern and clean_pattern[0] in ["!", "~"]:
+                        self._build_missing_excluded.append(clean_pattern[1:])
+                    else:
+                        self.build_missing_patterns.append(clean_pattern)
                 else:
                     clean_pattern = param
                     if clean_pattern and clean_pattern[0] in ["!", "~"]:
@@ -86,6 +90,12 @@ class BuildMode:
         return False
 
     def should_build_missing(self, conanfile):
+        if self._build_missing_excluded:
+            for pattern in self._build_missing_excluded:
+                if ref_matches(conanfile.ref, pattern, is_consumer=False):
+                    return False
+            return True  # If it has not been excluded by the negated patterns, it is included
+
         for pattern in self.build_missing_patterns:
-            if ref_matches(conanfile.ref, pattern, is_consumer=False):
+            if ref_matches(conanfile.ref, pattern, is_consumer=conanfile._conan_is_consumer):
                 return True
diff --git a/conans/client/graph/compatibility.py b/conans/client/graph/compatibility.py
index 967ddc90e..1d67e7cf5 100644
--- a/conans/client/graph/compatibility.py
+++ b/conans/client/graph/compatibility.py
@@ -41,8 +41,8 @@ def cppstd_compat(conanfile):
         cppstd_possible_values = supported_cppstd(conanfile)
         if cppstd_possible_values is None:
             conanfile.output.warning(f'No cppstd compatibility defined for compiler "{compiler}"')
-        else:
-            factors.append([{"compiler.cppstd": v} for v in cppstd_possible_values if v != cppstd])
+        else: # The current cppst must be included in case there is other factor
+            factors.append([{"compiler.cppstd": v} for v in cppstd_possible_values])
 
     if compiler == "msvc":
         msvc_fallback = {"194": "193"}.get(compiler_version)
diff --git a/conans/client/graph/graph_binaries.py b/conans/client/graph/graph_binaries.py
index 13030c5b8..c343ccd2b 100644
--- a/conans/client/graph/graph_binaries.py
+++ b/conans/client/graph/graph_binaries.py
@@ -181,11 +181,6 @@ class GraphBinariesAnalyzer(object):
             node.build_allowed = True
             node.binary = BINARY_BUILD if not node.cant_build else BINARY_INVALID
 
-        if (node.binary in (BINARY_BUILD, BINARY_MISSING) and node.conanfile.info.invalid and
-                node.conanfile.info.invalid[0] == BINARY_INVALID):
-            # BINARY_BUILD IS NOT A VIABLE fallback for invalid
-            node.binary = BINARY_INVALID
-
     def _process_node(self, node, build_mode, remotes, update):
         # Check that this same reference hasn't already been checked
         if self._evaluate_is_cached(node):
@@ -234,12 +229,6 @@ class GraphBinariesAnalyzer(object):
         else:  # This binary already exists in the cache, maybe can be updated
             self._evaluate_in_cache(cache_latest_prev, node, remotes, update)
 
-        # The INVALID should only prevail if a compatible package, due to removal of
-        # settings in package_id() was not found
-        if node.binary in (BINARY_MISSING, BINARY_BUILD):
-            if node.conanfile.info.invalid and node.conanfile.info.invalid[0] == BINARY_INVALID:
-                node.binary = BINARY_INVALID
-
     def _process_compatible_node(self, node, remotes, update):
         """ simplified checking of compatible_packages, that should be found existing, but
         will never be built, for example. They cannot be editable either at this point.
diff --git a/conans/client/graph/graph_builder.py b/conans/client/graph/graph_builder.py
index 64c9a4bad..d248d25bb 100644
--- a/conans/client/graph/graph_builder.py
+++ b/conans/client/graph/graph_builder.py
@@ -237,6 +237,7 @@ class DepsGraphBuilder(object):
             graph.aliased[alias] = pointed_ref  # Caching the alias
             new_req = Requirement(pointed_ref)  # FIXME: Ugly temp creation just for alias check
             alias = new_req.alias
+            node.conanfile.output.warning("Requirement 'alias' is provided in Conan 2 mainly for compatibility and upgrade from Conan 1, but it is an undocumented and legacy feature. Please update to use standard versioning mechanisms", warn_tag="legacy")
 
     def _resolve_recipe(self, ref, graph_lock):
         result = self._proxy.get_recipe(ref, self._remotes, self._update, self._check_update)
diff --git a/conans/client/installer.py b/conans/client/installer.py
index 7c05e2724..ce4755728 100644
--- a/conans/client/installer.py
+++ b/conans/client/installer.py
@@ -176,11 +176,11 @@ class BinaryInstaller:
         self._hook_manager = app.hook_manager
         self._global_conf = global_conf
 
-    def _install_source(self, node, remotes):
+    def _install_source(self, node, remotes, need_conf=False):
         conanfile = node.conanfile
         download_source = conanfile.conf.get("tools.build:download_source", check_type=bool)
 
-        if not download_source and node.binary != BINARY_BUILD:
+        if not download_source and (need_conf or node.binary != BINARY_BUILD):
             return
 
         conanfile = node.conanfile
@@ -235,7 +235,7 @@ class BinaryInstaller:
         for level in install_order:
             for install_reference in level:
                 for package in install_reference.packages.values():
-                    self._install_source(package.nodes[0], remotes)
+                    self._install_source(package.nodes[0], remotes, need_conf=True)
 
     def install(self, deps_graph, remotes, install_order=None):
         assert not deps_graph.error, "This graph cannot be installed: {}".format(deps_graph)
@@ -304,30 +304,29 @@ class BinaryInstaller:
 
         pref = PkgReference(install_reference.ref, package.package_id, package.prev)
 
-        if pref.revision is None:
-            assert package.binary == BINARY_BUILD
-            package_layout = self._cache.create_build_pkg_layout(pref)
-        else:
-            package_layout = self._cache.get_or_create_pkg_layout(pref)
-
         if package.binary == BINARY_BUILD:
+            assert pref.revision is None
             ConanOutput()\
                 .subtitle(f"Installing package {pref.ref} ({handled_count} of {total_count})")
             ConanOutput(scope=str(pref.ref))\
                 .highlight("Building from source")\
                 .info(f"Package {pref}")
+            package_layout = self._cache.create_build_pkg_layout(pref)
             self._handle_node_build(package, package_layout)
             # Just in case it was recomputed
             package.package_id = package.nodes[0].pref.package_id  # Just in case it was recomputed
             package.prev = package.nodes[0].pref.revision
             package.binary = package.nodes[0].binary
             pref = PkgReference(install_reference.ref, package.package_id, package.prev)
-        elif package.binary == BINARY_CACHE:
-            node = package.nodes[0]
-            pref = node.pref
-            self._cache.update_package_lru(pref)
-            assert node.prev, "PREV for %s is None" % str(pref)
-            node.conanfile.output.success(f'Already installed! ({handled_count} of {total_count})')
+        else:
+            assert pref.revision is not None
+            package_layout = self._cache.pkg_layout(pref)
+            if package.binary == BINARY_CACHE:
+                node = package.nodes[0]
+                pref = node.pref
+                self._cache.update_package_lru(pref)
+                assert node.prev, "PREV for %s is None" % str(pref)
+                node.conanfile.output.success(f'Already installed! ({handled_count} of {total_count})')
 
         # Make sure that all nodes with same pref compute package_info()
         pkg_folder = package_layout.package()
diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py
index 9827b83d7..51ce2e2d1 100644
--- a/conans/client/remote_manager.py
+++ b/conans/client/remote_manager.py
@@ -49,8 +49,7 @@ class RemoteManager:
         assert ref.revision, "get_recipe without revision specified"
         assert ref.timestamp, "get_recipe without ref.timestamp specified"
 
-        layout = self._cache.get_or_create_ref_layout(ref)
-        layout.export_remove()
+        layout = self._cache.create_ref_layout(ref)
 
         export_folder = layout.export()
         local_folder_remote = self._local_folder_remote(remote)
@@ -132,8 +131,7 @@ class RemoteManager:
 
         assert pref.revision is not None
 
-        pkg_layout = self._cache.get_or_create_pkg_layout(pref)
-        pkg_layout.package_remove()  # Remove first the destination folder
+        pkg_layout = self._cache.create_pkg_layout(pref)
         with pkg_layout.set_dirty_context_manager():
             self._get_package(pkg_layout, pref, remote, output, metadata)
 
diff --git a/conans/client/rest_client_local_recipe_index.py b/conans/client/rest_client_local_recipe_index.py
index 36d3b516e..9285d7942 100644
--- a/conans/client/rest_client_local_recipe_index.py
+++ b/conans/client/rest_client_local_recipe_index.py
@@ -10,6 +10,7 @@ from conan.api.model import LOCAL_RECIPES_INDEX
 from conan.api.output import ConanOutput
 from conan.internal.cache.home_paths import HomePaths
 from conans.client.cmd.export import cmd_export
+from conans.client.loader import ConanFileLoader
 from conans.errors import ConanException, PackageNotFoundException, RecipeNotFoundException
 from conans.model.conf import ConfDefinition
 from conans.model.recipe_ref import RecipeReference
@@ -190,7 +191,12 @@ class _LocalRecipesIndexLayout:
         recipes.sort()
         ret = []
         excluded = set()
+
+        loader = ConanFileLoader(None)
         for r in recipes:
+            if r.startswith("."):
+                # Skip hidden folders, no recipes should start with a dot
+                continue
             if not fnmatch(r, name_pattern):
                 continue
             folder = self._get_base_folder(r)
@@ -207,10 +213,18 @@ class _LocalRecipesIndexLayout:
                 # This check can be removed after compatibility with 2.0
                 conanfile = os.path.join(recipes_dir, r, subfolder, "conanfile.py")
                 conanfile_content = load(conanfile)
+
                 if "from conans" in conanfile_content or "import conans" in conanfile_content:
                     excluded.add(r)
                     continue
-                ret.append(RecipeReference.loads(ref))
+                ref = RecipeReference.loads(ref)
+                try:
+                    recipe = loader.load_basic(conanfile)
+                    ref.user = recipe.user
+                    ref.channel = recipe.channel
+                except Exception as e:
+                    ConanOutput().warning(f"Couldn't load recipe {conanfile}: {e}")
+                ret.append(ref)
         if excluded:
             ConanOutput().warning(f"Excluding recipes not Conan 2.0 ready: {', '.join(excluded)}")
         return ret
diff --git a/conans/model/conf.py b/conans/model/conf.py
index ef758d342..7809f4d9d 100644
--- a/conans/model/conf.py
+++ b/conans/model/conf.py
@@ -93,6 +93,7 @@ BUILT_IN_CONFS = {
     "tools.meson.mesontoolchain:backend": "Any Meson backend: ninja, vs, vs2010, vs2012, vs2013, 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.microsoft:winsdk_version": "Use this winsdk_version in vcvars",
+    "tools.microsoft:msvc_update": "Force the specific update irrespective of compiler.update (CMakeToolchain and VCVars)",
     "tools.microsoft.msbuild:vs_version": "Defines the IDE version (15, 16, 17) when using the msvc compiler. Necessary if compiler.version specifies a toolset that is not the IDE default",
     "tools.microsoft.msbuild:max_cpu_count": "Argument for the /m when running msvc to build parallel projects",
     "tools.microsoft.msbuild:installation_path": "VS install path, to avoid auto-detect via vswhere, like C:/Program Files (x86)/Microsoft Visual Studio/2019/Community. Use empty string to disable",
diff --git a/conans/model/recipe_ref.py b/conans/model/recipe_ref.py
index 01168f09f..0d86ff3fa 100644
--- a/conans/model/recipe_ref.py
+++ b/conans/model/recipe_ref.py
@@ -154,7 +154,7 @@ class RecipeReference:
         if self.channel and validation_pattern.match(self.channel) is None:
             raise ConanException(f"Invalid package channel '{self.channel}'")
 
-         # Warn if they use .+ in the name/user/channel, as it can be problematic for generators
+        # Warn if they use .+ in the name/user/channel, as it can be problematic for generators
         pattern = re.compile(r'[.+]')
         if pattern.search(self.name):
             ConanOutput().warning(f"Name containing special chars is discouraged '{self.name}'")
@@ -179,8 +179,8 @@ class RecipeReference:
             no_user_channel = True
 
         condition = ((pattern == "&" and is_consumer) or
-                      fnmatch.fnmatchcase(str(self), pattern) or
-                      fnmatch.fnmatchcase(self.repr_notime(), pattern))
+                     fnmatch.fnmatchcase(str(self), pattern) or
+                     fnmatch.fnmatchcase(self.repr_notime(), pattern))
         if no_user_channel:
             condition = condition and not self.user and not self.channel
         if negate:


Test patch:
diff --git a/test/functional/toolchains/env/test_virtualenv_powershell.py b/test/functional/toolchains/env/test_virtualenv_powershell.py
index 0f4e2e3f6..787eda008 100644
--- a/test/functional/toolchains/env/test_virtualenv_powershell.py
+++ b/test/functional/toolchains/env/test_virtualenv_powershell.py
@@ -148,6 +148,10 @@ def test_vcvars():
     assert "conanvcvars.ps1: Activated environment" in client.out
     #check that the new env variables are set
     assert "VSCMD_ARG_VCVARS_VER" in client.out
+
+    client.run_command(r'powershell.exe ".\build\Release\generators\conanvcvars.ps1"')
+    assert client.out.strip() == "conanvcvars.ps1: Activated environment"
+
     conanbuild = client.load(r".\build\Release\generators\conanbuild.ps1")
     vcvars_ps1 = client.load(r".\build\Release\generators\conanvcvars.ps1")
     #check that the conanvcvars.ps1 is being added to the conanbuild.ps1
diff --git a/test/functional/toolchains/gnu/autotools/test_win_bash.py b/test/functional/toolchains/gnu/autotools/test_win_bash.py
index 613544dac..ddfc375ab 100644
--- a/test/functional/toolchains/gnu/autotools/test_win_bash.py
+++ b/test/functional/toolchains/gnu/autotools/test_win_bash.py
@@ -4,6 +4,7 @@ import textwrap
 import pytest
 
 from conan.test.assets.autotools import gen_makefile_am, gen_configure_ac
+from conan.test.assets.genconanfile import GenConanfile
 from conan.test.assets.sources import gen_function_cpp
 from test.conftest import tools_locations
 from test.functional.utils import check_exe_run
@@ -100,3 +101,52 @@ def test_add_msys2_path_automatically():
     client.save({"conanfile.py": conanfile})
     client.run("create .")
     assert "ar.exe" in client.out
+
+
+@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows")
+def test_conf_inherited_in_test_package():
+    client = TestClient()
+    bash_path = None
+    try:
+        bash_path = tools_locations["msys2"]["system"]["path"]["Windows"] + "/bash.exe"
+    except KeyError:
+        pytest.skip("msys2 path not defined")
+
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+
+        class Recipe(ConanFile):
+            name="msys2"
+            version="1.0"
+
+            def package_info(self):
+                self.conf_info.define("tools.microsoft.bash:subsystem", "msys2")
+                self.conf_info.define("tools.microsoft.bash:path", "{}")
+    """.format(bash_path))
+    client.save({"conanfile.py": conanfile})
+    client.run("create .")
+
+    conanfile = GenConanfile("consumer", "1.0")
+    test_package = textwrap.dedent("""
+        from conan import ConanFile
+
+        class Recipe(ConanFile):
+            name="test"
+            version="1.0"
+            win_bash = True
+
+            def build_requirements(self):
+                self.tool_requires(self.tested_reference_str)
+                self.tool_requires("msys2/1.0")
+
+            def build(self):
+                self.output.warning(self.conf.get("tools.microsoft.bash:subsystem"))
+                self.run("aclocal --version")
+
+            def test(self):
+                pass
+        """)
+    client.save({"conanfile.py": conanfile, "test_package/conanfile.py": test_package})
+    client.run("create . -s:b os=Windows -s:h os=Windows")
+    assert "are needed to run commands in a Windows subsystem" not in client.out
+    assert "aclocal (GNU automake)" in client.out
diff --git a/test/functional/toolchains/meson/test_meson.py b/test/functional/toolchains/meson/test_meson.py
index a24f79600..8298c17b9 100644
--- a/test/functional/toolchains/meson/test_meson.py
+++ b/test/functional/toolchains/meson/test_meson.py
@@ -6,10 +6,10 @@ import textwrap
 
 import pytest
 
-from conans.model.recipe_ref import RecipeReference
 from conan.test.assets.sources import gen_function_cpp, gen_function_h
-from test.functional.toolchains.meson._base import TestMesonBase
 from conan.test.utils.tools import TestClient
+from conans.model.recipe_ref import RecipeReference
+from test.functional.toolchains.meson._base import TestMesonBase
 
 
 class MesonToolchainTest(TestMesonBase):
diff --git a/test/integration/command/alias_test.py b/test/integration/command/alias_test.py
index d8eb389b5..8b5c7243e 100644
--- a/test/integration/command/alias_test.py
+++ b/test/integration/command/alias_test.py
@@ -9,13 +9,13 @@ from conan.test.utils.tools import TestClient, GenConanfile
 class ConanAliasTest(unittest.TestCase):
 
     def test_repeated_alias(self):
-        client = TestClient()
+        client = TestClient(light=True)
         client.alias("hello/0.x@lasote/channel",  "hello/0.1@lasote/channel")
         client.alias("hello/0.x@lasote/channel",  "hello/0.2@lasote/channel")
         client.alias("hello/0.x@lasote/channel",  "hello/0.3@lasote/channel")
 
     def test_basic(self):
-        client = TestClient(default_server_user=True)
+        client = TestClient(light=True, default_server_user=True)
         for i in (1, 2):
             client.save({"conanfile.py": GenConanfile().with_name("hello").with_version("0.%s" % i)})
             client.run("export . --user=lasote --channel=channel")
@@ -33,6 +33,7 @@ class ConanAliasTest(unittest.TestCase):
         client.save({"conanfile.txt": "[requires]\nchat/1.0@lasote/channel"}, clean_first=True)
 
         client.run("install . --build=missing")
+        assert "chat/1.0@lasote/channel: WARN: legacy: Requirement 'alias' is provided in Conan 2" in client.out
 
         client.assert_listed_require({"hello/0.1@lasote/channel": "Cache"})
         assert "hello/0.x@lasote/channel: hello/0.1@lasote/channel" in client.out
@@ -64,7 +65,7 @@ class ConanAliasTest(unittest.TestCase):
             If we create an alias with the same name as an existing package, it will
             override the package without any warning.
         """
-        t = TestClient()
+        t = TestClient(light=True)
         conanfile = textwrap.dedent("""
             from conan import ConanFile
             class Pkg(ConanFile):
diff --git a/test/integration/command/create_test.py b/test/integration/command/create_test.py
index 7aa9e659b..bf0cd056e 100644
--- a/test/integration/command/create_test.py
+++ b/test/integration/command/create_test.py
@@ -318,6 +318,12 @@ def test_create_build_missing():
     c.assert_listed_binary({"dep/1.0": ("9a4eb3c8701508aa9458b1a73d0633783ecc2270", "Missing")})
     assert "ERROR: Missing prebuilt package for 'dep/1.0'" in c.out
 
+    # The & placeholder also works
+    c.run("create pkg -s os=Linux --build=missing:&", assert_error=True)
+    c.assert_listed_binary({"pkg/1.0": ("4c0c198b627f9af3e038af4da5e6b3ae205c2435", "Build")})
+    c.assert_listed_binary({"dep/1.0": ("9a4eb3c8701508aa9458b1a73d0633783ecc2270", "Missing")})
+    assert "ERROR: Missing prebuilt package for 'dep/1.0'" in c.out
+
 
 def test_create_no_user_channel():
     """ test the --build=pattern and --build=missing:pattern syntax to build missing packages
@@ -356,6 +362,28 @@ def test_create_no_user_channel():
                             "dep3/0.1": (NO_SETTINGS_PACKAGE_ID, "Build")})
 
 
+def test_create_build_missing_negation():
+    tc = TestClient(light=True)
+    tc.save({"dep/conanfile.py": GenConanfile("dep", "1.0"),
+             "lib/conanfile.py": GenConanfile("lib", "1.0").with_requires("dep/1.0"),
+             "pkg/conanfile.py": GenConanfile("pkg", "1.0").with_requires("lib/1.0")})
+
+    tc.run("export dep")
+    tc.run("export lib")
+    tc.run("create pkg --build=missing:~dep/*", assert_error=True)
+
+    tc.assert_listed_binary({"pkg/1.0": ("a72376edfbbdaf97c8608b5fda53cadebac46a20", "Build"),
+                             "lib/1.0": ("abfcc78fa8242cabcd1e3d92896aa24808c789a3", "Build"),
+                             "dep/1.0": ("da39a3ee5e6b4b0d3255bfef95601890afd80709", "Missing")})
+
+    tc.run("create pkg --build=missing:~dep/* --build=missing:~lib/*",
+           assert_error=True)
+
+    tc.assert_listed_binary({"pkg/1.0": ("a72376edfbbdaf97c8608b5fda53cadebac46a20", "Build"),
+                             "lib/1.0": ("abfcc78fa8242cabcd1e3d92896aa24808c789a3", "Missing"),
+                             "dep/1.0": ("da39a3ee5e6b4b0d3255bfef95601890afd80709", "Missing")})
+
+
 def test_create_format_json():
     """
     Tests the ``conan create . -f json`` result
@@ -711,22 +739,22 @@ def test_defaults_in_components():
 
     # The paths are absolute and the components have defaults
     # ".+" Check that there is a path, not only "lib"
-    assert re.search(r"BINDIRS: \['.+bin'\]", str(client.out))
-    assert re.search(r"LIBDIRS: \['.+lib'\]", str(client.out))
-    assert re.search(r"INCLUDEDIRS: \['.+include'\]", str(client.out))
+    assert re.search(r"BINDIRS: \['.+bin']", client.out)
+    assert re.search(r"LIBDIRS: \['.+lib']", client.out)
+    assert re.search(r"INCLUDEDIRS: \['.+include']", client.out)
     assert "WARN: RES DIRS: []"
-    assert re.search(r"WARN: FOO LIBDIRS: \['.+lib'\]", str(client.out))
-    assert re.search(r"WARN: FOO INCLUDEDIRS: \['.+include'\]", str(client.out))
+    assert re.search(r"WARN: FOO LIBDIRS: \['.+lib']", client.out)
+    assert re.search(r"WARN: FOO INCLUDEDIRS: \['.+include']", client.out)
     assert "WARN: FOO RESDIRS: []" in client.out
 
     # The paths are absolute and the components have defaults
     # ".+" Check that there is a path, not only "lib"
-    assert re.search("BINDIRS: \['.+bin'\]", str(client.out))
-    assert re.search("LIBDIRS: \['.+lib'\]", str(client.out))
-    assert re.search("INCLUDEDIRS: \['.+include'\]", str(client.out))
+    assert re.search(r"BINDIRS: \['.+bin']", client.out)
+    assert re.search(r"LIBDIRS: \['.+lib']", client.out)
+    assert re.search(r"INCLUDEDIRS: \['.+include']", client.out)
     assert "WARN: RES DIRS: []"
-    assert bool(re.search("WARN: FOO LIBDIRS: \['.+lib'\]", str(client.out)))
-    assert bool(re.search("WARN: FOO INCLUDEDIRS: \['.+include'\]", str(client.out)))
+    assert bool(re.search(r"WARN: FOO LIBDIRS: \['.+lib']", client.out))
+    assert bool(re.search(r"WARN: FOO INCLUDEDIRS: \['.+include']", client.out))
     assert "WARN: FOO RESDIRS: []" in client.out
 
 
diff --git a/test/integration/command/test_forced_download_source.py b/test/integration/command/test_forced_download_source.py
index dfe814815..cc06ceae6 100644
--- a/test/integration/command/test_forced_download_source.py
+++ b/test/integration/command/test_forced_download_source.py
@@ -44,6 +44,9 @@ def test_install(client):
 def test_info(client):
     client.run("graph info --requires=dep/0.1")
     assert "RUNNING SOURCE" not in client.out
+    # Even if the package is to be built, it shouldn't download sources unless the conf is defined
+    client.run("graph info --requires=dep/0.1 --build=dep*")
+    assert "RUNNING SOURCE" not in client.out
     client.run("graph info --requires=dep/0.1 -c tools.build:download_source=True")
     assert "RUNNING SOURCE" in client.out
     client.run("graph info --requires=dep/0.1 -c tools.build:download_source=True")
diff --git a/test/integration/configuration/conf/test_conf_profile.py b/test/integration/configuration/conf/test_conf_profile.py
index e6f81fc65..45b0589c3 100644
--- a/test/integration/configuration/conf/test_conf_profile.py
+++ b/test/integration/configuration/conf/test_conf_profile.py
@@ -1,4 +1,3 @@
-import platform
 import textwrap
 
 import pytest
@@ -156,9 +155,9 @@ def test_msbuild_config():
     assert "/verbosity:Quiet" in client.out
 
 
-@pytest.mark.tool("visual_studio")
-@pytest.mark.skipif(platform.system() != "Windows", reason="Only for windows")
 def test_msbuild_compile_options():
+    # This works in all platforms because MSBuildToolchain works even in Linux, it will
+    # just skip generating the conanvcvars.bat
     client = TestClient()
     conanfile = textwrap.dedent("""
         from conan import ConanFile
diff --git a/test/integration/graph/core/graph_manager_base.py b/test/integration/graph/core/graph_manager_base.py
index 6ff38f269..7f4ac1f73 100644
--- a/test/integration/graph/core/graph_manager_base.py
+++ b/test/integration/graph/core/graph_manager_base.py
@@ -50,7 +50,7 @@ class GraphManagerTest(unittest.TestCase):
     def _put_in_cache(self, ref, conanfile):
         ref = RecipeReference.loads("{}#123".format(ref))
         ref.timestamp = revision_timestamp_now()
-        layout = self.cache.get_or_create_ref_layout(ref)
+        layout = self.cache.create_ref_layout(ref)
         save(layout.conanfile(), str(conanfile))
         manifest = FileTreeManifest.create(layout.export())
         manifest.save(layout.export())
@@ -61,7 +61,7 @@ class GraphManagerTest(unittest.TestCase):
             ref = RecipeReference.loads(ref)
         ref = RecipeReference.loads(repr(ref) + "#{}".format(revision or 123))  # FIXME: Make access
         ref.timestamp = revision_timestamp_now()
-        recipe_layout = self.cache.get_or_create_ref_layout(ref)
+        recipe_layout = self.cache.create_ref_layout(ref)
         save(recipe_layout.conanfile(), str(test_conanfile))
         manifest = FileTreeManifest.create(recipe_layout.export())
         manifest.save(recipe_layout.export())
diff --git a/test/integration/graph/core/graph_manager_test.py b/test/integration/graph/core/graph_manager_test.py
index 290029814..bf620c4ca 100644
--- a/test/integration/graph/core/graph_manager_test.py
+++ b/test/integration/graph/core/graph_manager_test.py
@@ -349,24 +349,23 @@ class TestLinear(GraphManagerTest):
         _check_transitive(app, [(libb, True, True, False, False)])
         _check_transitive(libb, [(liba, False, False, True, True)])
 
-    def test_generic_build_require_adjust_run_with_package_type(self):
-        # FIXME: parametrize when superclass is not unittest
-        for package_type in ["application", "shared-library", "static-library",
-                             "header-library", "build-scripts", None]:
-            # app --br-> cmake (app)
-            self.recipe_conanfile("cmake/0.1", GenConanfile().with_package_type(package_type))
-            # build require with run=None by default
-            consumer = self.recipe_consumer("app/0.1", build_requires=["cmake/0.1"])
-
-            deps_graph = self.build_consumer(consumer)
-
-            self.assertEqual(2, len(deps_graph.nodes))
-            app = deps_graph.root
-            cmake = app.dependencies[0].dst
-
-            # node, headers, lib, build, run
-            run = package_type in ("application", "shared-library", "build-scripts")
-            _check_transitive(app, [(cmake, False, False, True, run)])
+    @parameterized.expand([("application",), ("shared-library",), ("static-library",),
+                           ("header-library",), ("build-scripts",), (None,)])
+    def test_generic_build_require_adjust_run_with_package_type(self, package_type):
+        # app --br-> cmake (app)
+        self.recipe_conanfile("cmake/0.1", GenConanfile().with_package_type(package_type))
+        # build require with run=None by default
+        consumer = self.recipe_consumer("app/0.1", build_requires=["cmake/0.1"])
+
+        deps_graph = self.build_consumer(consumer)
+
+        self.assertEqual(2, len(deps_graph.nodes))
+        app = deps_graph.root
+        cmake = app.dependencies[0].dst
+
+        # node, headers, lib, build, run
+        run = package_type in ("application", "shared-library", "build-scripts")
+        _check_transitive(app, [(cmake, False, False, True, run)])
 
     def test_direct_header_only(self):
         # app -> liba0.1 (header_only)
diff --git a/test/integration/package_id/test_cache_compatibles.py b/test/integration/package_id/test_cache_compatibles.py
index 1a9952f51..35fe89e92 100644
--- a/test/integration/package_id/test_cache_compatibles.py
+++ b/test/integration/package_id/test_cache_compatibles.py
@@ -398,6 +398,13 @@ class TestDefaultCompat:
         assert "mylib/1.0: Main binary package 'e340edd75790e7156c595edebd3d98b10a2e091e' missing."\
                f"Using compatible package '{package_id1}'"
 
+        c.run("install --requires=mylib/1.0@ -s os=Windows -s arch=x86_64 -s build_type=Release "
+              "-s compiler=msvc "
+              "-s compiler.version=194 -s compiler.cppstd=17 "
+              "-s compiler.runtime=dynamic -pr:b=profile_build")
+        assert "mylib/1.0: Main binary package 'e340edd75790e7156c595edebd3d98b10a2e091e' missing." \
+               f"Using compatible package '{package_id1}'"
+
 
 class TestErrorsCompatibility:
     """ when the plugin fails, we want a clear message and a helpful trace
diff --git a/test/integration/remote/test_local_recipes_index.py b/test/integration/remote/test_local_recipes_index.py
index e96dddce3..2b5114968 100644
--- a/test/integration/remote/test_local_recipes_index.py
+++ b/test/integration/remote/test_local_recipes_index.py
@@ -59,12 +59,15 @@ def c3i_folder():
             """))
     save(os.path.join(recipes_folder, "libcurl", "all", "conanfile.py"),
          str(GenConanfile().with_require("openssl/2.0")))
+
+    save(os.path.join(recipes_folder, ".DS_Store", "foo"), "")
+
     return folder
 
 
 class TestSearchList:
     def test_basic_search(self, c3i_folder):
-        client = TestClient()
+        client = TestClient(light=True)
         client.run(f"remote add local '{c3i_folder}' --type=local-recipes-index")  # Keep --type test
         assert "WARN" not in client.out  # Make sure it does not complain about url
         client.run("search *")
@@ -82,7 +85,7 @@ class TestSearchList:
             """) in client.out
 
     def test_list_refs(self, c3i_folder):
-        client = TestClient()
+        client = TestClient(light=True)
         client.run(f"remote add local '{c3i_folder}'")
         client.run("list *#* -r=local --format=json")
         listjson = json.loads(client.stdout)
@@ -100,7 +103,7 @@ class TestSearchList:
         assert len(revs) == 1 and "6f5c31bb1219e9393743d1fbf2ee1b52" in revs
 
     def test_list_rrevs(self, c3i_folder):
-        client = TestClient()
+        client = TestClient(light=True)
         client.run(f"remote add local '{c3i_folder}'")
         client.run("list libcurl/1.0#* -r=local --format=json")
         listjson = json.loads(client.stdout)
@@ -108,7 +111,7 @@ class TestSearchList:
         assert len(revs) == 1 and "e468388f0e4e098d5b62ad68979aebd5" in revs
 
     def test_list_binaries(self, c3i_folder):
-        client = TestClient()
+        client = TestClient(light=True)
         client.run(f"remote add local '{c3i_folder}'")
         client.run("list libcurl/1.0:* -r=local --format=json")
         listjson = json.loads(client.stdout)
@@ -118,7 +121,7 @@ class TestSearchList:
 
 class TestInstall:
     def test_install(self, c3i_folder):
-        c = TestClient()
+        c = TestClient(light=True)
         c.run(f"remote add local '{c3i_folder}'")
         c.run("install --requires=libcurl/1.0 --build missing")
         assert "zlib/1.2.11: CONANDATA: {}" in c.out
@@ -178,7 +181,7 @@ class TestInstall:
                    {"boost/config.yml": boost_config,
                     "boost/all/conanfile.py": boost,
                     "boost/all/dependencies/myfile.json": deps_json})
-        c = TestClient()
+        c = TestClient(light=True)
         c.run(f"remote add local '{folder}'")
         c.run("install --requires=boost/[*] --build missing")
         assert 'boost/1.0: {"potato": 42}' in c.out
@@ -204,7 +207,7 @@ class TestInstall:
                    {"pkg/config.yml": config,
                     "pkg/all/conanfile.py": str(GenConanfile("pkg")),
                     "pkg/all/conandata.yml": conandata})
-        c = TestClient()
+        c = TestClient(light=True)
         c.run(f"remote add local '{folder}'")
         c.run("install --requires=pkg/1.0 --build missing -vvv")
         assert "pkg/1.0#86b609916bbdfe63c579f034ad0edfe7" in c.out
@@ -264,19 +267,43 @@ class TestInstall:
                     "zlib/all/conandata.yml": conandata_yml,
                     "zlib/all/patches/patch1": patch,
                     "zlib/all/main.cpp": "\n"})
-        client = TestClient()
+        client = TestClient(light=True)
         client.run(f"remote add local '{folder}'")
         client.run("install --requires=zlib/0.1 --build=missing -vv")
         assert "zlib/0.1: Copied 1 file: patch1" in client.out
         assert "zlib/0.1: Apply patch (file): patches/patch1" in client.out
 
+    def test_export_user_channel(self):
+        folder = temp_folder()
+        recipes_folder = os.path.join(folder, "recipes")
+        zlib_config = textwrap.dedent("""
+            versions:
+              "0.1":
+                folder: all
+            """)
+        zlib = GenConanfile("zlib").with_class_attribute("user='myuser'")\
+                                   .with_class_attribute("channel='mychannel'")
+        conandata_yml = textwrap.dedent("""\
+            versions:
+              "0.1":
+            """)
+        save_files(recipes_folder, {"zlib/config.yml": zlib_config,
+                                    "zlib/all/conanfile.py": str(zlib),
+                                    "zlib/all/conandata.yml": conandata_yml})
+        client = TestClient()
+        client.run(f"remote add local '{folder}'")
+        client.run("install --requires=zlib/0.1@myuser/mychannel --build=missing")
+        assert "zlib/0.1@myuser/mychannel:" in client.out
+        client.run("list * -r=local")
+        assert "zlib/0.1@myuser/mychannel" in client.out
+
 
 class TestRestrictedOperations:
     def test_upload(self):
         folder = temp_folder()
         c3i_folder = os.path.join(folder, "recipes")
         mkdir(c3i_folder)
-        c = TestClient()
+        c = TestClient(light=True)
         c.run(f"remote add local '{c3i_folder}'")
         c.save({"conanfile.py": GenConanfile("pkg", "0.1")})
         c.run("create .")
@@ -300,7 +327,7 @@ class TestErrorsUx:
         save_files(recipes_folder,
                    {"zlib/config.yml": zlib_config,
                     "zlib/all/conanfile.py": zlib})
-        c = TestClient()
+        c = TestClient(light=True)
         c.run(f"remote add local '{folder}'")
         c.run("install --requires=zlib/[*] --build missing", assert_error=True)
         assert "NameError: name 'ConanFile' is not defined" in c.out
diff --git a/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py b/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
index 563f14069..50c2ec587 100644
--- a/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
+++ b/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
@@ -708,6 +708,7 @@ def test_cmakedeps_set_property_overrides():
     other = c.load("app/other-release-data.cmake")
     assert 'set(other_other_mycomp1_NO_SONAME_MODE_RELEASE TRUE)' in other
 
+
 def test_cmakedeps_set_legacy_variable_name():
     client = TestClient()
     base_conanfile = str(GenConanfile("dep", "1.0"))
@@ -742,3 +743,17 @@ def test_cmakedeps_set_legacy_variable_name():
         assert f"prefix_{variable}" in dep_config
     # Check that variables are not duplicated
     assert dep_config.count("PREFIX_VERSION") == 1
+
+
+def test_different_versions():
+    # https://github.com/conan-io/conan/issues/16274
+    c = TestClient()
+    c.save({"dep/conanfile.py": GenConanfile("dep")})
+    c.run("create dep --version 1.2")
+    c.run("create dep --version 2.3")
+    c.run("install --requires=dep/1.2 -g CMakeDeps")
+    config = c.load("dep-config.cmake")
+    assert 'set(dep_VERSION_STRING "1.2")' in config
+    c.run("install --requires=dep/2.3 -g CMakeDeps")
+    config = c.load("dep-config.cmake")
+    assert 'set(dep_VERSION_STRING "2.3")' in config
diff --git a/test/integration/toolchains/cmake/test_cmaketoolchain.py b/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 81ad493a1..df1fff5ef 100644
--- a/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -68,7 +68,7 @@ def test_cross_build_linux_to_macos():
     macos_profile = textwrap.dedent("""
         [settings]
         os=Macos
-        os.sdk_version=13.1
+        os.version=13.1
         arch=x86_64
         compiler=apple-clang
         compiler.version=13
@@ -85,7 +85,7 @@ def test_cross_build_linux_to_macos():
     toolchain = client.load("conan_toolchain.cmake")
 
     assert "set(CMAKE_SYSTEM_NAME Darwin)" in toolchain
-    assert "set(CMAKE_SYSTEM_VERSION 13.1)" in toolchain
+    assert "set(CMAKE_SYSTEM_VERSION 22)" in toolchain
     assert "set(CMAKE_SYSTEM_PROCESSOR x86_64)" in toolchain
 
 
@@ -437,7 +437,7 @@ def test_cmaketoolchain_cmake_system_processor_cross_apple():
     client.run("install hello.py -pr:h=./profile_ios -pr:b=default -g CMakeToolchain")
     toolchain = client.load("conan_toolchain.cmake")
     assert "set(CMAKE_SYSTEM_NAME iOS)" in toolchain
-    assert "set(CMAKE_SYSTEM_VERSION 15.0)" in toolchain
+    assert "set(CMAKE_SYSTEM_VERSION 21)" in toolchain
     assert "set(CMAKE_SYSTEM_PROCESSOR arm64)" in toolchain
 
 
diff --git a/test/integration/toolchains/env/test_virtualenv_winbash.py b/test/integration/toolchains/env/test_virtualenv_winbash.py
index 97acf9a9b..523ca7aef 100644
--- a/test/integration/toolchains/env/test_virtualenv_winbash.py
+++ b/test/integration/toolchains/env/test_virtualenv_winbash.py
@@ -107,54 +107,3 @@ def test_nowinbash(client):
     assert not os.path.exists(os.path.join(client.current_folder, "conanrunenv.bat"))
     run_contents = client.load("conanrunenv.sh")
     assert 'export RUNTIME_VAR="/c/path/to/exe"' in run_contents
-
-
-@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows")
-@pytest.mark.tool("msys2")
-def test_conf_inherited_in_test_package():
-    client = TestClient()
-    bash_path = tools_locations["msys2"]["system"]["path"]["Windows"] + "/bash.exe"
-    conanfile = textwrap.dedent("""
-            from conan import ConanFile
-
-            class Recipe(ConanFile):
-                name="msys2"
-                version="1.0"
-
-                def package_info(self):
-                    self.conf_info.define("tools.microsoft.bash:subsystem", "msys2")
-                    self.conf_info.define("tools.microsoft.bash:path", "{}")
-    """.format(bash_path))
-    client.save({"conanfile.py": conanfile})
-    client.run("create .")
-
-    conanfile = textwrap.dedent("""
-                from conan import ConanFile
-
-                class Recipe(ConanFile):
-                    name="consumer"
-                    version="1.0"
-        """)
-    test_package = textwrap.dedent("""
-                    from conan import ConanFile
-
-                    class Recipe(ConanFile):
-                        name="test"
-                        version="1.0"
-                        win_bash = True
-
-                        def build_requirements(self):
-                            self.tool_requires(self.tested_reference_str)
-                            self.tool_requires("msys2/1.0")
-
-                        def build(self):
-                            self.output.warning(self.conf.get("tools.microsoft.bash:subsystem"))
-                            self.run("aclocal --version")
-
-                        def test(self):
-                            pass
-            """)
-    client.save({"conanfile.py": conanfile, "test_package/conanfile.py": test_package})
-    client.run("create . -s:b os=Windows -s:h os=Windows")
-    assert "are needed to run commands in a Windows subsystem" not in client.out
-    assert "aclocal (GNU automake)" in client.out
diff --git a/test/integration/toolchains/meson/test_mesontoolchain.py b/test/integration/toolchains/meson/test_mesontoolchain.py
index b7a2742f7..602b4bb9a 100644
--- a/test/integration/toolchains/meson/test_mesontoolchain.py
+++ b/test/integration/toolchains/meson/test_mesontoolchain.py
@@ -1,13 +1,14 @@
 import os
 import platform
+import re
 import textwrap
 
 import pytest
 
 from conan.test.assets.genconanfile import GenConanfile
+from conan.test.utils.tools import TestClient
 from conan.tools.files import load
 from conan.tools.meson import MesonToolchain
-from conan.test.utils.tools import TestClient
 
 
 def test_apple_meson_keep_user_custom_flags():
@@ -534,3 +535,51 @@ def test_compiler_path_with_spaces():
     conan_meson_native = client.load("conan_meson_native.ini")
     assert "c = 'c compiler path with spaces'" in conan_meson_native
     assert "cpp = 'cpp compiler path with spaces'" in conan_meson_native
+
+
+def test_meson_sysroot_app():
+    """Testing when users pass tools.build:sysroot on the profile with Meson
+
+    The generated conan_meson_cross.ini needs to contain both sys_root property to fill the
+    PKG_CONFIG_PATH and the compiler flags with --sysroot.
+
+    When cross-building, Meson needs both compiler_executables in the config, otherwise it will fail
+    when running setup.
+    """
+    sysroot = "/my/new/sysroot/path"
+    client = TestClient()
+    profile = textwrap.dedent(f"""
+    [settings]
+    os = Macos
+    arch = armv8
+    compiler = apple-clang
+    compiler.version = 13.0
+    compiler.libcxx = libc++
+
+    [conf]
+    tools.build:sysroot={sysroot}
+    tools.build:verbosity=verbose
+    tools.compilation:verbosity=verbose
+    tools.apple:sdk_path=/my/sdk/path
+    """)
+    profile_build = textwrap.dedent(f"""
+    [settings]
+    os = Macos
+    arch = x86_64
+    compiler = apple-clang
+    compiler.version = 13.0
+    compiler.libcxx = libc++
+    """)
+    client.save({"conanfile.py": GenConanfile(name="hello", version="0.1")
+                .with_settings("os", "arch", "compiler", "build_type")
+                .with_generator("MesonToolchain"),
+                 "build": profile_build,
+                 "host": profile})
+    client.run("install . -pr:h host -pr:b build")
+    # Check the meson configuration file
+    conan_meson = client.load(os.path.join(client.current_folder, "conan_meson_cross.ini"))
+    assert f"sys_root = '{sysroot}'\n" in conan_meson
+    assert re.search(r"c_args =.+--sysroot={}.+".format(sysroot), conan_meson)
+    assert re.search(r"c_link_args =.+--sysroot={}.+".format(sysroot), conan_meson)
+    assert re.search(r"cpp_args =.+--sysroot={}.+".format(sysroot), conan_meson)
+    assert re.search(r"cpp_link_args =.+--sysroot={}.+".format(sysroot), conan_meson)
diff --git a/test/unittests/tools/cmake/test_cmaketoolchain.py b/test/unittests/tools/cmake/test_cmaketoolchain.py
index 8bba79509..3d66adada 100644
--- a/test/unittests/tools/cmake/test_cmaketoolchain.py
+++ b/test/unittests/tools/cmake/test_cmaketoolchain.py
@@ -201,7 +201,7 @@ def conanfile_msvc():
     c.settings.build_type = "Release"
     c.settings.arch = "x86"
     c.settings.compiler = "msvc"
-    c.settings.compiler.version = "193"
+    c.settings.compiler.version = "194"
     c.settings.compiler.cppstd = "20"
     c.settings.os = "Windows"
     c.settings_build = c.settings
@@ -221,11 +221,27 @@ def test_toolset(conanfile_msvc):
 
 
 def test_toolset_update_version(conanfile_msvc):
+    conanfile_msvc.settings.compiler.version = "193"
     conanfile_msvc.settings.compiler.update = "8"
     toolchain = CMakeToolchain(conanfile_msvc)
     assert 'set(CMAKE_GENERATOR_TOOLSET "v143,version=14.38" CACHE STRING "" FORCE)' in toolchain.content
 
 
+def test_toolset_update_version_conf(conanfile_msvc):
+    conanfile_msvc.settings.compiler.version = "193"
+    conanfile_msvc.conf.define("tools.microsoft:msvc_update", "7")
+    toolchain = CMakeToolchain(conanfile_msvc)
+    assert 'set(CMAKE_GENERATOR_TOOLSET "v143,version=14.37" CACHE STRING "" FORCE)' in toolchain.content
+
+
+def test_toolset_update_version_forced_conf(conanfile_msvc):
+    conanfile_msvc.settings.compiler.version = "193"
+    conanfile_msvc.settings.compiler.update = "8"
+    conanfile_msvc.conf.define("tools.microsoft:msvc_update", "7")
+    toolchain = CMakeToolchain(conanfile_msvc)
+    assert 'set(CMAKE_GENERATOR_TOOLSET "v143,version=14.37" CACHE STRING "" FORCE)' in toolchain.content
+
+
 def test_toolset_update_version_overflow(conanfile_msvc):
     # https://github.com/conan-io/conan/issues/15583
     conanfile_msvc.settings.compiler.version = "194"
diff --git a/test/unittests/tools/files/test_rm.py b/test/unittests/tools/files/test_rm.py
index 75f32fa84..b569ac331 100644
--- a/test/unittests/tools/files/test_rm.py
+++ b/test/unittests/tools/files/test_rm.py
@@ -1,4 +1,5 @@
 import os
+import pytest
 
 # Check it is importable from tools
 from conan.tools.files import rm, chdir
@@ -63,3 +64,46 @@ def test_remove_files_by_mask_non_recursively():
 
     assert os.path.exists(os.path.join(tmpdir, "1.txt"))
     assert os.path.exists(os.path.join(tmpdir, "subdir", "2.txt"))
+
+
+@pytest.mark.parametrize("recursive", [False, True])
+@pytest.mark.parametrize("results", [
+    ["*.dll", ("foo.dll",)],
+    [("*.dll",), ("foo.dll",)],
+    [["*.dll"], ("foo.dll",)],
+    [("*.dll", "*.lib"), ("foo.dll", "foo.dll.lib")],
+])
+def test_exclude_pattern_from_remove_list(recursive, results):
+    """ conan.tools.files.rm should not remove files that match the pattern but are excluded
+        by the excludes parameter.
+        It should obey the recursive parameter, only excluding the files in the root folder in case
+        it is False.
+    """
+    excludes, expected_files = results
+    temporary_folder = temp_folder()
+    with chdir(None, temporary_folder):
+        os.makedirs("subdir")
+
+    save_files(temporary_folder, {
+        "1.txt": "",
+        "1.pdb": "",
+        "1.pdb1": "",
+        "foo.dll": "",
+        "foo.dll.lib": "",
+        os.path.join("subdir", "2.txt"): "",
+        os.path.join("subdir", "2.pdb"): "",
+        os.path.join("subdir", "foo.dll"): "",
+        os.path.join("subdir", "foo.dll.lib"): "",
+        os.path.join("subdir", "2.pdb1"): ""})
+
+    rm(None, "*", temporary_folder, excludes=excludes, recursive=recursive)
+
+    for it in expected_files:
+        assert os.path.exists(os.path.join(temporary_folder, it))
+    assert not os.path.exists(os.path.join(temporary_folder, "1.pdb"))
+
+    # Check the recursive parameter and subfolder
+    condition = (lambda x: not x) if recursive else (lambda x: x)
+    assert condition(os.path.exists(os.path.join(temporary_folder, "subdir", "2.pdb")))
+    for it in expected_files:
+        assert os.path.exists(os.path.join(temporary_folder, "subdir", it))