Repository: conan-io/conan
Pull request #12873 (2023-01-09 13:36:32)

add `conan.tools.android.android_abi()`
Changelog: (Feature): Add android_abi() function in conan.tools.android
Docs: https://github.com/conan-io/docs/pull/XXXX

closes https://github.com/conan-io/conan/issues/12814

- [x] Refer to the issue that supports this Pull Request.
- [x] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).
- [x] I've followed the PEP8 style guides for Python code.
- [ ] I've opened another PR in the Conan docs repo to the ``develop`` branch, documenting this one. 

<sup>**Note:** By default this PR will skip the slower tests and will use a limited set of python versions. Check [here](https://github.com/conan-io/conan/blob/develop/.github/PR_INCREASE_TESTING.md) how to increase the testing level by writing some tags in the current PR body text.</sup>



Patch:
diff --git a/conan/tools/android/__init__.py b/conan/tools/android/__init__.py
new file mode 100644
index 000000000..c969bbebd
--- /dev/null
+++ b/conan/tools/android/__init__.py
@@ -0,0 +1,1 @@
+from conan.tools.android.utils import android_abi
diff --git a/conan/tools/android/utils.py b/conan/tools/android/utils.py
new file mode 100644
index 000000000..12a5e7551
--- /dev/null
+++ b/conan/tools/android/utils.py
@@ -0,0 +1,31 @@
+from conan.errors import ConanException
+
+
+def android_abi(conanfile, context="host"):
+    """
+    Returns Android-NDK ABI
+    :param conanfile: ConanFile instance
+    :param context: either "host", "build" or "target"
+    :return: Android-NDK ABI
+    """
+    if context not in ("host", "build", "target"):
+        raise ConanException(f"context argument must be either 'host', 'build' or 'target', was '{context}'")
+
+    try:
+        settings = getattr(conanfile, f"settings_{context}")
+    except AttributeError:
+        if context == "host":
+            settings = conanfile.settings
+        else:
+            raise ConanException(f"settings_{context} not declared in recipe")
+    arch = settings.get_safe("arch")
+    # https://cmake.org/cmake/help/latest/variable/CMAKE_ANDROID_ARCH_ABI.html
+    return {
+        "armv5el": "armeabi",
+        "armv5hf": "armeabi",
+        "armv5": "armeabi",
+        "armv6": "armeabi-v6",
+        "armv7": "armeabi-v7a",
+        "armv7hf": "armeabi-v7a",
+        "armv8": "arm64-v8a",
+    }.get(arch, arch)
diff --git a/conan/tools/apple/apple.py b/conan/tools/apple/apple.py
index f08f325d5..00d82783e 100644
--- a/conan/tools/apple/apple.py
+++ b/conan/tools/apple/apple.py
@@ -159,14 +159,18 @@ class XCRun(object):
         """path to libtool"""
         return self.find('libtool')
 
+def _get_dylib_install_name(path_to_dylib):
+    command = "otool -D {}".format(path_to_dylib)
+    output =  iter(check_output_runner(command).splitlines())
+    # Note: if otool return multiple entries for different architectures
+    # assume they are the same and pick the first one.
+    for line in output:
+        if ":" in line:
+            return next(output)
+    raise ConanException(f"Unable to extract install_name for {path_to_dylib}")
 
 def fix_apple_shared_install_name(conanfile):
 
-    def _get_install_name(path_to_dylib):
-        command = "otool -D {}".format(path_to_dylib)
-        install_name = check_output_runner(command).strip().split(":")[1].strip()
-        return install_name
-
     def _darwin_is_binary(file, binary_type):
         if binary_type not in ("DYLIB", "EXECUTE") or os.path.islink(file) or os.path.isdir(file):
             return False
@@ -212,7 +216,7 @@ def fix_apple_shared_install_name(conanfile):
             shared_libs = _darwin_collect_binaries(full_folder, "DYLIB")
             # fix LC_ID_DYLIB in first pass
             for shared_lib in shared_libs:
-                install_name = _get_install_name(shared_lib)
+                install_name = _get_dylib_install_name(shared_lib)
                 #TODO: we probably only want to fix the install the name if
                 # it starts with `/`.
                 rpath_name = f"@rpath/{os.path.basename(install_name)}"
@@ -258,7 +262,7 @@ def fix_apple_shared_install_name(conanfile):
                     command = f"install_name_tool {executable} -add_rpath {entry}"
                     conanfile.run(command)
 
-    if is_apple_os(conanfile) and conanfile.options.get_safe("shared", False):
+    if is_apple_os(conanfile):
         substitutions = _fix_dylib_files(conanfile)
 
         # Only "fix" executables if dylib files were patched, otherwise
diff --git a/conan/tools/cmake/cmake.py b/conan/tools/cmake/cmake.py
index 9b8e1a0f0..d52a8ecb4 100644
--- a/conan/tools/cmake/cmake.py
+++ b/conan/tools/cmake/cmake.py
@@ -1,7 +1,7 @@
 import os
 
 from conan.tools.build import build_jobs
-from conan.tools.cmake.presets import load_cmake_presets, get_configure_preset
+from conan.tools.cmake.presets import load_cmake_presets
 from conan.tools.cmake.utils import is_multi_configuration
 from conan.tools.files import chdir, mkdir
 from conan.tools.microsoft.msbuild import msbuild_verbosity_cmd_line_arg
@@ -53,7 +53,8 @@ class CMake(object):
         self._conanfile = conanfile
 
         cmake_presets = load_cmake_presets(conanfile.generators_folder)
-        configure_preset = get_configure_preset(cmake_presets, conanfile)
+        # Conan generated presets will have exactly 1 configurePresets, no more
+        configure_preset = cmake_presets["configurePresets"][0]
 
         self._generator = configure_preset["generator"]
         self._toolchain_file = configure_preset.get("toolchainFile")
diff --git a/conan/tools/cmake/cmakedeps/templates/config.py b/conan/tools/cmake/cmakedeps/templates/config.py
index 5892a4160..07b44a4a8 100644
--- a/conan/tools/cmake/cmakedeps/templates/config.py
+++ b/conan/tools/cmake/cmakedeps/templates/config.py
@@ -45,6 +45,12 @@ class ConfigTemplate(CMakeDepsFileTemplate):
             message(FATAL_ERROR "The 'CMakeDeps' generator only works with CMake >= 3.15")
         endif()
 
+        if({{ file_name }}_FIND_QUIETLY)
+            set({{ file_name }}_MESSAGE_MODE VERBOSE)
+        else()
+            set({{ file_name }}_MESSAGE_MODE STATUS)
+        endif()
+
         include(${CMAKE_CURRENT_LIST_DIR}/cmakedeps_macros.cmake)
         include(${CMAKE_CURRENT_LIST_DIR}/{{ targets_include_file }})
         include(CMakeFindDependencyMacro)
@@ -66,7 +72,7 @@ class ConfigTemplate(CMakeDepsFileTemplate):
 
         # Only the first installed configuration is included to avoid the collision
         foreach(_BUILD_MODULE {{ '${' + pkg_name + '_BUILD_MODULES_PATHS' + config_suffix + '}' }} )
-            message(STATUS "Conan: Including build module from '${_BUILD_MODULE}'")
+            message({% raw %}${{% endraw %}{{ file_name }}_MESSAGE_MODE} "Conan: Including build module from '${_BUILD_MODULE}'")
             include({{ '${_BUILD_MODULE}' }})
         endforeach()
 
@@ -76,7 +82,7 @@ class ConfigTemplate(CMakeDepsFileTemplate):
         if({{ file_name }}_FIND_COMPONENTS)
             foreach(_FIND_COMPONENT {{ '${'+file_name+'_FIND_COMPONENTS}' }})
                 if (TARGET ${_FIND_COMPONENT})
-                    message(STATUS "Conan: Component '${_FIND_COMPONENT}' found in package '{{ pkg_name }}'")
+                    message({% raw %}${{% endraw %}{{ file_name }}_MESSAGE_MODE} "Conan: Component '${_FIND_COMPONENT}' found in package '{{ pkg_name }}'")
                 else()
                     message(FATAL_ERROR "Conan: Component '${_FIND_COMPONENT}' NOT found in package '{{ pkg_name }}'")
                 endif()
diff --git a/conan/tools/cmake/cmakedeps/templates/target_configuration.py b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
index 0429375b3..aec498c52 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_configuration.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
@@ -78,7 +78,6 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
 
         # FIXME: What is the result of this for multi-config? All configs adding themselves to path?
         set(CMAKE_MODULE_PATH {{ '${' }}{{ pkg_name }}_BUILD_DIRS{{ config_suffix }}} {{ '${' }}CMAKE_MODULE_PATH})
-
         {% if not components_names %}
 
         ########## GLOBAL TARGET PROPERTIES {{ configuration }} ########################################
diff --git a/conan/tools/cmake/cmakedeps/templates/targets.py b/conan/tools/cmake/cmakedeps/templates/targets.py
index c3cea116d..42d8d7f9c 100644
--- a/conan/tools/cmake/cmakedeps/templates/targets.py
+++ b/conan/tools/cmake/cmakedeps/templates/targets.py
@@ -66,13 +66,13 @@ class TargetsTemplate(CMakeDepsFileTemplate):
         foreach(_COMPONENT {{ '${' + pkg_name + '_COMPONENT_NAMES' + '}' }} )
             if(NOT TARGET ${_COMPONENT})
                 add_library(${_COMPONENT} INTERFACE IMPORTED)
-                message(STATUS "Conan: Component target declared '${_COMPONENT}'")
+                message({% raw %}${{% endraw %}{{ file_name }}_MESSAGE_MODE} "Conan: Component target declared '${_COMPONENT}'")
             endif()
         endforeach()
 
         if(NOT TARGET {{ root_target_name }})
             add_library({{ root_target_name }} INTERFACE IMPORTED)
-            message(STATUS "Conan: Target declared '{{ root_target_name }}'")
+            message({% raw %}${{% endraw %}{{ file_name }}_MESSAGE_MODE} "Conan: Target declared '{{ root_target_name }}'")
         endif()
 
         {%- for alias, target in cmake_target_aliases.items() %}
diff --git a/conan/tools/cmake/layout.py b/conan/tools/cmake/layout.py
index abddc047f..959ae93e5 100644
--- a/conan/tools/cmake/layout.py
+++ b/conan/tools/cmake/layout.py
@@ -23,14 +23,11 @@ def cmake_layout(conanfile, generator=None, src_folder=".", build_folder="build"
 
     build_folder = build_folder if not subproject else os.path.join(subproject, build_folder)
     config_build_folder, user_defined_build = get_build_folder_custom_vars(conanfile)
-
     if config_build_folder:
-        conanfile.folders.build = os.path.join(build_folder, config_build_folder)
-    else:
-        if not multi and not user_defined_build:
-            conanfile.folders.build = os.path.join(build_folder, build_type)
-        else:
-            conanfile.folders.build = build_folder
+        build_folder = os.path.join(build_folder, config_build_folder)
+    if not multi and not user_defined_build:
+        build_folder = os.path.join(build_folder, build_type)
+    conanfile.folders.build = build_folder
 
     conanfile.folders.generators = os.path.join(conanfile.folders.build, "generators")
 
diff --git a/conan/tools/cmake/presets.py b/conan/tools/cmake/presets.py
index dacf021ef..246a85431 100644
--- a/conan/tools/cmake/presets.py
+++ b/conan/tools/cmake/presets.py
@@ -9,17 +9,18 @@ from conans.errors import ConanException
 from conans.util.files import save, load
 
 
-def _build_preset(conanfile, multiconfig):
+def _build_and_test_preset_fields(conanfile, multiconfig):
     build_type = conanfile.settings.get_safe("build_type")
     configure_preset_name = _configure_preset_name(conanfile, multiconfig)
-    ret = {"name": _build_preset_name(conanfile),
+    build_preset_name = _build_and_test_preset_name(conanfile)
+    ret = {"name": build_preset_name,
            "configurePreset": configure_preset_name}
     if multiconfig:
         ret["configuration"] = build_type
     return ret
 
 
-def _build_preset_name(conanfile):
+def _build_and_test_preset_name(conanfile):
     build_type = conanfile.settings.get_safe("build_type")
     custom_conf, user_defined_build = get_build_folder_custom_vars(conanfile)
     if user_defined_build:
@@ -108,6 +109,14 @@ def _configure_preset(conanfile, generator, cache_variables, toolchain_file, mul
     return ret
 
 
+def _insert_preset(data, preset_name, preset):
+    position = _get_already_existing_preset_index(preset["name"], data.setdefault(preset_name, []))
+    if position is not None:
+        data[preset_name][position] = preset
+    else:
+        data[preset_name].append(preset)
+
+
 def _forced_schema_2(conanfile):
     version = conanfile.conf.get("tools.cmake.cmaketoolchain.presets:max_schema_version",
                                  check_type=int)
@@ -135,16 +144,16 @@ def _contents(conanfile, toolchain_file, cache_variables, generator):
     Contents for the CMakePresets.json
     It uses schema version 3 unless it is forced to 2
     """
+    multiconfig = is_multi_configuration(generator)
+    conf = _configure_preset(conanfile, generator, cache_variables, toolchain_file, multiconfig)
+    build = _build_and_test_preset_fields(conanfile, multiconfig)
     ret = {"version": _schema_version(conanfile, default=3),
+           "vendor": {"conan": {}},
            "cmakeMinimumRequired": {"major": 3, "minor": 15, "patch": 0},
-           "configurePresets": [],
-           "buildPresets": [],
-           "testPresets": []
-          }
-    multiconfig = is_multi_configuration(generator)
-    ret["buildPresets"].append(_build_preset(conanfile, multiconfig))
-    _conf = _configure_preset(conanfile, generator, cache_variables, toolchain_file, multiconfig)
-    ret["configurePresets"].append(_conf)
+           "configurePresets": [conf],
+           "buildPresets": [build],
+           "testPresets": [build]
+           }
     return ret
 
 
@@ -170,61 +179,55 @@ def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables,
 
     preset_path = os.path.join(conanfile.generators_folder, "CMakePresets.json")
     multiconfig = is_multi_configuration(generator)
-
-    if os.path.exists(preset_path):
+    if os.path.exists(preset_path) and multiconfig:
         data = json.loads(load(preset_path))
-        build_preset = _build_preset(conanfile, multiconfig)
-        position = _get_already_existing_preset_index(build_preset["name"], data["buildPresets"])
-        if position is not None:
-            data["buildPresets"][position] = build_preset
-        else:
-            data["buildPresets"].append(build_preset)
-
+        build_preset = _build_and_test_preset_fields(conanfile, multiconfig)
+        _insert_preset(data, "buildPresets", build_preset)
+        _insert_preset(data, "testPresets", build_preset)
         configure_preset = _configure_preset(conanfile, generator, cache_variables, toolchain_file,
                                              multiconfig)
-        position = _get_already_existing_preset_index(configure_preset["name"],
-                                                      data["configurePresets"])
-        if position is not None:
-            data["configurePresets"][position] = configure_preset
-        else:
-            data["configurePresets"].append(configure_preset)
+        # Conan generated presets should have only 1 configurePreset, no more, overwrite it
+        data["configurePresets"] = [configure_preset]
     else:
         data = _contents(conanfile, toolchain_file, cache_variables, generator)
 
-    data = json.dumps(data, indent=4)
-    save(preset_path, data)
-    save_cmake_user_presets(conanfile, preset_path, user_presets_path)
+    preset_content = json.dumps(data, indent=4)
+    save(preset_path, preset_content)
+    _save_cmake_user_presets(conanfile, preset_path, user_presets_path)
 
 
-def save_cmake_user_presets(conanfile, preset_path, user_presets_path=None):
-    if user_presets_path is False:
+def _save_cmake_user_presets(conanfile, preset_path, user_presets_path):
+    if not user_presets_path:
         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 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(output_dir, "CMakeUserPresets.json")
-            if not os.path.exists(user_presets_path):
-                data = {"version": _schema_version(conanfile, default=4),
-                        "vendor": {"conan": dict()}}
-            else:
-                data = json.loads(load(user_presets_path))
-                if "conan" not in data.get("vendor", {}):
-                    # The file is not ours, we cannot overwrite it
-                    return
-            data = _append_user_preset_path(conanfile, data, preset_path)
-            data = json.dumps(data, indent=4)
-            save(user_presets_path, data)
+    # If generators folder is the same as source folder, do not create the user presets
+    # we already have the CMakePresets.json right there
+    if not (conanfile.source_folder and conanfile.source_folder != conanfile.generators_folder):
+        return
+
+    user_presets_path = os.path.join(conanfile.source_folder, user_presets_path)
+    if os.path.isdir(user_presets_path):  # Allows user to specify only the folder
+        output_dir = user_presets_path
+        user_presets_path = os.path.join(user_presets_path, "CMakeUserPresets.json")
+    else:
+        output_dir = os.path.dirname(user_presets_path)
+
+    if not os.path.exists(os.path.join(output_dir, "CMakeLists.txt")):
+        return
+
+    # It uses schema version 4 unless it is forced to 2
+    if not os.path.exists(user_presets_path):
+        data = {"version": _schema_version(conanfile, default=4),
+                "vendor": {"conan": dict()}}
+    else:
+        data = json.loads(load(user_presets_path))
+        if "conan" not in data.get("vendor", {}):
+            # The file is not ours, we cannot overwrite it
+            return
+    data = _append_user_preset_path(conanfile, data, preset_path)
+
+    data = json.dumps(data, indent=4)
+    save(user_presets_path, data)
 
 
 def _get_already_existing_preset_index(name, presets):
@@ -268,25 +271,11 @@ def _append_user_preset_path(conanfile, data, preset_path):
 
 
 def load_cmake_presets(folder):
-    tmp = load(os.path.join(folder, "CMakePresets.json"))
+    try:
+        tmp = load(os.path.join(folder, "CMakePresets.json"))
+    except FileNotFoundError:
+        # Issue: https://github.com/conan-io/conan/issues/12896
+        raise ConanException(f"CMakePresets.json was not found in {folder} folder. Check that you "
+                             f"are using CMakeToolchain as generator to ensure its correct "
+                             f"initialization.")
     return json.loads(tmp)
-
-
-def get_configure_preset(cmake_presets, conanfile):
-    expected_name = _configure_preset_name(conanfile, multiconfig=False)
-    # Do we find a preset for the current configuration?
-    for preset in cmake_presets["configurePresets"]:
-        if preset["name"] == expected_name:
-            return preset
-
-    expected_name = _configure_preset_name(conanfile, multiconfig=True)
-    # In case of multi-config generator or None build_type
-    for preset in cmake_presets["configurePresets"]:
-        if preset["name"] == expected_name:
-            return preset
-
-    # FIXME: Might be an issue if someone perform several conan install that involves different
-    #        CMake generators (multi and single config). Would be impossible to determine which
-    #        is the correct configurePreset because the generator IS in the configure preset.
-
-    raise ConanException("Not available configurePreset, expected name is {}".format(expected_name))
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 5846f0097..baacbca8b 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -6,6 +6,7 @@ from collections import OrderedDict
 from jinja2 import Template
 
 from conan.tools._compilers import architecture_flag, libcxx_flags
+from conan.tools.android.utils import android_abi
 from conan.tools.apple.apple import is_apple_os, to_apple_arch
 from conan.tools.build import build_jobs
 from conan.tools.build.cross_building import cross_building
@@ -215,6 +216,21 @@ class ArchitectureBlock(Block):
         return {"arch_flag": arch_flag}
 
 
+class LinkerScriptsBlock(Block):
+    template = textwrap.dedent("""
+        string(APPEND CONAN_EXE_LINKER_FLAGS {{ linker_script_flags }})
+        """)
+
+    def context(self):
+        linker_scripts = self._conanfile.conf.get(
+            "tools.build:linker_scripts", check_type=list, default=[])
+        if not linker_scripts:
+            return
+        linker_scripts = [linker_script.replace('\\', '/') for linker_script in linker_scripts]
+        linker_script_flags = ['-T"' + linker_script + '"' for linker_script in linker_scripts]
+        return {"linker_script_flags": " ".join(linker_script_flags)}
+
+
 class CppStdBlock(Block):
     template = textwrap.dedent("""
         message(STATUS "Conan toolchain: C++ Standard {{ cppstd }} with extensions {{ cppstd_extensions }}")
@@ -286,11 +302,6 @@ class AndroidSystemBlock(Block):
         if os_ != "Android":
             return
 
-        android_abi = {"x86": "x86",
-                       "x86_64": "x86_64",
-                       "armv7": "armeabi-v7a",
-                       "armv8": "arm64-v8a"}.get(str(self._conanfile.settings.arch))
-
         # TODO: only 'c++_shared' y 'c++_static' supported?
         #  https://developer.android.com/ndk/guides/cpp-support
         libcxx_str = self._conanfile.settings.get_safe("compiler.libcxx")
@@ -302,7 +313,7 @@ class AndroidSystemBlock(Block):
 
         ctxt_toolchain = {
             'android_platform': 'android-' + str(self._conanfile.settings.os.api_level),
-            'android_abi': android_abi,
+            'android_abi': android_abi(self._conanfile),
             'android_stl': libcxx_str,
             'android_ndk_path': android_ndk_path,
         }
@@ -517,6 +528,7 @@ class FindFiles(Block):
         host_build_paths_root = []
         host_build_paths_noroot = []
         host_lib_paths = []
+        host_bin_paths = [] # Only to be used when only one profile is present
         host_framework_paths = []
         host_include_paths = []
         for req in host_req:
@@ -532,6 +544,7 @@ class FindFiles(Block):
                 host_build_paths_root = []
                 host_build_paths_noroot.extend(p for p in cppinfo.builddirs)
             host_lib_paths.extend(cppinfo.libdirs)
+            host_bin_paths.extend(cppinfo.bindirs)
             if is_apple_:
                 host_framework_paths.extend(cppinfo.frameworkdirs)
             host_include_paths.extend(cppinfo.includedirs)
@@ -544,6 +557,8 @@ class FindFiles(Block):
             cppinfo = req.cpp_info.aggregated_components()
             build_build_paths.extend(cppinfo.builddirs)
             build_bin_paths.extend(cppinfo.bindirs)
+        has_build_context = hasattr(self._conanfile, "settings_build") # always true in Conan 2.0
+        bin_paths = build_bin_paths if has_build_context else host_bin_paths
 
         return {
             "find_package_prefer_config": find_package_prefer_config,
@@ -551,7 +566,7 @@ class FindFiles(Block):
             "host_build_paths_root": self._join_paths(host_build_paths_root),
             "host_build_paths_noroot": self._join_paths(host_build_paths_noroot),
             "build_build_paths": self._join_paths(build_build_paths),
-            "cmake_program_path": self._join_paths(build_bin_paths),
+            "cmake_program_path": self._join_paths(bin_paths),
             "cmake_library_path": self._join_paths(host_lib_paths),
             "cmake_framework_path": self._join_paths(host_framework_paths),
             "cmake_include_path": self._join_paths(host_include_paths),
diff --git a/conan/tools/cmake/toolchain/toolchain.py b/conan/tools/cmake/toolchain/toolchain.py
index 2a0e181f8..a18d515fb 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, CompilersBlock
+    SkipRPath, SharedLibBock, OutputDirsBlock, ExtraFlagsBlock, CompilersBlock, LinkerScriptsBlock
 from conan.tools.intel import IntelCC
 from conan.tools.microsoft import VCVars
 from conan.tools.microsoft.visual import vs_ide_version
@@ -133,6 +133,7 @@ class CMakeToolchain(object):
                                        ("apple_system", AppleSystemBlock),
                                        ("fpic", FPicBlock),
                                        ("arch_flags", ArchitectureBlock),
+                                       ("linker_scripts", LinkerScriptsBlock),
                                        ("libcxx", GLibCXXBlock),
                                        ("vs_runtime", VSRuntimeBlock),
                                        ("cppstd", CppStdBlock),
@@ -147,7 +148,7 @@ class CMakeToolchain(object):
                                        ("output_dirs", OutputDirsBlock)])
 
         check_using_build_profile(self._conanfile)
-        self.user_presets_path = None
+        self.user_presets_path = "CMakeUserPresets.json"
 
     def _context(self):
         """ Returns dict, the context for the template
diff --git a/conan/tools/env/environment.py b/conan/tools/env/environment.py
index edc229083..999f384b8 100644
--- a/conan/tools/env/environment.py
+++ b/conan/tools/env/environment.py
@@ -302,28 +302,29 @@ class EnvVars:
             os.environ.update(old_env)
 
     def save_bat(self, file_location, generate_deactivate=True):
-        filepath, filename = os.path.split(file_location)
-        deactivate_file = os.path.join(filepath, "deactivate_{}".format(filename))
+        _, filename = os.path.split(file_location)
+        deactivate_file = "deactivate_{}".format(filename)
         deactivate = textwrap.dedent("""\
             setlocal
-            echo @echo off > "{deactivate_file}"
-            echo echo Restoring environment >> "{deactivate_file}"
+            echo @echo off > "%~dp0/{deactivate_file}"
+            echo echo Restoring environment >> "%~dp0/{deactivate_file}"
             for %%v in ({vars}) do (
                 set foundenvvar=
                 for /f "delims== tokens=1,2" %%a in ('set') do (
                     if /I "%%a" == "%%v" (
-                        echo set "%%a=%%b">> "{deactivate_file}"
+                        echo set "%%a=%%b">> "%~dp0/{deactivate_file}"
                         set foundenvvar=1
                     )
                 )
                 if not defined foundenvvar (
-                    echo set %%v=>> "{deactivate_file}"
+                    echo set %%v=>> "%~dp0/{deactivate_file}"
                 )
             )
             endlocal
             """).format(deactivate_file=deactivate_file, vars=" ".join(self._values.keys()))
         capture = textwrap.dedent("""\
             @echo off
+            chcp 65001 > nul
             {deactivate}
             """).format(deactivate=deactivate if generate_deactivate else "")
         result = [capture]
@@ -332,12 +333,15 @@ class EnvVars:
             result.append('set "{}={}"'.format(varname, value))
 
         content = "\n".join(result)
-        save(file_location, content)
+        # It is very important to save it correctly with utf-8, the Conan util save() is broken
+        os.makedirs(os.path.dirname(os.path.abspath(file_location)), exist_ok=True)
+        open(file_location, "w", encoding="utf-8").write(content)
 
     def save_ps1(self, file_location, generate_deactivate=True,):
-        filepath, filename = os.path.split(file_location)
-        deactivate_file = os.path.join(filepath, "deactivate_{}".format(filename))
+        _, filename = os.path.split(file_location)
+        deactivate_file = "deactivate_{}".format(filename)
         deactivate = textwrap.dedent("""\
+            Push-Location $PSScriptRoot
             "echo `"Restoring environment`"" | Out-File -FilePath "{deactivate_file}"
             $vars = (Get-ChildItem env:*).name
             $updated_vars = @({vars})
@@ -354,6 +358,7 @@ class EnvVars:
                     Add-Content "{deactivate_file}" "`nif (Test-Path env:$var) {{ Remove-Item env:$var }}"
                 }}
             }}
+            Pop-Location
         """).format(
             deactivate_file=deactivate_file,
             vars=",".join(['"{}"'.format(var) for var in self._values.keys()])
@@ -372,7 +377,10 @@ class EnvVars:
                 result.append('if (Test-Path env:{0}) {{ Remove-Item env:{0} }}'.format(varname))
 
         content = "\n".join(result)
-        save(file_location, content)
+        # It is very important to save it correctly with utf-16, the Conan util save() is broken
+        # and powershell uses utf-16 files!!!
+        os.makedirs(os.path.dirname(os.path.abspath(file_location)), exist_ok=True)
+        open(file_location, "w", encoding="utf-16").write(content)
 
     def save_sh(self, file_location, generate_deactivate=True):
         filepath, filename = os.path.split(file_location)
diff --git a/conan/tools/files/symlinks/symlinks.py b/conan/tools/files/symlinks/symlinks.py
index 98c4b2040..7700e8713 100644
--- a/conan/tools/files/symlinks/symlinks.py
+++ b/conan/tools/files/symlinks/symlinks.py
@@ -37,7 +37,7 @@ def remove_external_symlinks(conanfile, base_folder=None):
     for fullpath in get_symlinks(base_folder):
         link_target = os.readlink(fullpath)
         if not os.path.isabs(link_target):
-            link_target = os.path.join(base_folder, link_target)
+            link_target = os.path.join(os.path.dirname(fullpath), link_target)
         if not _path_inside(base_folder, link_target):
             os.unlink(fullpath)
 
@@ -47,6 +47,6 @@ def remove_broken_symlinks(conanfile, base_folder=None):
     for fullpath in get_symlinks(base_folder):
         link_target = os.readlink(fullpath)
         if not os.path.isabs(link_target):
-            link_target = os.path.join(base_folder, link_target)
+            link_target = os.path.join(os.path.dirname(fullpath), link_target)
         if not os.path.exists(link_target):
             os.unlink(fullpath)
diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py
index 58115a607..b870bd5b0 100644
--- a/conan/tools/gnu/autotoolstoolchain.py
+++ b/conan/tools/gnu/autotoolstoolchain.py
@@ -7,7 +7,7 @@ from conan.tools.build.cross_building import cross_building, get_cross_building_
 from conan.tools.env import Environment
 from conan.tools.files.files import save_toolchain_args
 from conan.tools.gnu.get_gnu_triplet import _get_gnu_triplet
-from conan.tools.microsoft import VCVars, is_msvc, msvc_runtime_flag
+from conan.tools.microsoft import VCVars, msvc_runtime_flag
 from conans.errors import ConanException
 from conans.tools import args_to_string
 
@@ -18,10 +18,6 @@ class AutotoolsToolchain:
         self._namespace = namespace
         self._prefix = prefix
 
-        self.configure_args = self._default_configure_shared_flags() + self._default_configure_install_flags()
-        self.autoreconf_args = self._default_autoreconf_flags()
-        self.make_args = []
-
         # Flags
         self.extra_cxxflags = []
         self.extra_cflags = []
@@ -55,12 +51,13 @@ class AutotoolsToolchain:
         self.sysroot_flag = None
 
         if cross_building(self._conanfile):
+            # Host triplet
             os_build, arch_build, os_host, arch_host = get_cross_building_settings(self._conanfile)
             compiler = self._conanfile.settings.get_safe("compiler")
             if not self._host:
                 self._host = _get_gnu_triplet(os_host, arch_host, compiler=compiler)
+            # Build triplet
             self._build = _get_gnu_triplet(os_build, arch_build, compiler=compiler)
-
             # Apple Stuff
             if os_build == "Macos":
                 sdk_path = apple_sdk_path(conanfile)
@@ -74,6 +71,12 @@ class AutotoolsToolchain:
         sysroot = sysroot.replace("\\", "/") if sysroot is not None else None
         self.sysroot_flag = "--sysroot {}".format(sysroot) if sysroot else None
 
+        self.configure_args = self._default_configure_shared_flags() + \
+                              self._default_configure_install_flags() + \
+                              self._get_triplets()
+        self.autoreconf_args = self._default_autoreconf_flags()
+        self.make_args = []
+
         check_using_build_profile(self._conanfile)
 
     def _get_msvc_runtime_flag(self):
@@ -113,6 +116,8 @@ class AutotoolsToolchain:
                                               check_type=list)
         conf_flags.extend(self._conanfile.conf.get("tools.build:exelinkflags", default=[],
                                                    check_type=list))
+        linker_scripts = self._conanfile.conf.get("tools.build:linker_scripts", default=[], check_type=list)
+        conf_flags.extend(["-T'" + linker_script + "'" for linker_script in linker_scripts])
         ret = ret + apple_flags + conf_flags + self.build_type_link_flags + self.extra_ldflags
         return self._filter_list_empty_fields(ret)
 
@@ -178,19 +183,72 @@ class AutotoolsToolchain:
                                        _get_argument("datarootdir", "resdirs")])
         return [el for el in configure_install_flags if el]
 
-    def _default_autoreconf_flags(self):
+    @staticmethod
+    def _default_autoreconf_flags():
         return ["--force", "--install"]
 
+    def _get_triplets(self):
+        triplets = []
+        for flag, value in (("--host=", self._host), ("--build=", self._build),
+                            ("--target=", self._target)):
+            if value:
+                triplets.append(f'{flag}{value}')
+        return triplets
+
+    def update_configure_args(self, updated_flags):
+        """
+        Helper to update/prune flags from ``self.configure_args``.
+
+        :param updated_flags: ``dict`` with arguments as keys and their argument values.
+                              Notice that if argument value is ``None``, this one will be pruned.
+        """
+        self._update_flags("configure_args", updated_flags)
+
+    def update_make_args(self, updated_flags):
+        """
+        Helper to update/prune arguments from ``self.make_args``.
+
+        :param updated_flags: ``dict`` with arguments as keys and their argument values.
+                              Notice that if argument value is ``None``, this one will be pruned.
+        """
+        self._update_flags("make_args", updated_flags)
+
+    def update_autoreconf_args(self, updated_flags):
+        """
+        Helper to update/prune arguments from ``self.autoreconf_args``.
+
+        :param updated_flags: ``dict`` with arguments as keys and their argument values.
+                              Notice that if argument value is ``None``, this one will be pruned.
+        """
+        self._update_flags("autoreconf_args", updated_flags)
+
+    # FIXME: Remove all these update_xxxx whenever xxxx_args are dicts or new ones replace them
+    def _update_flags(self, attr_name, updated_flags):
+
+        def _list_to_dict(flags):
+            ret = {}
+            for flag in flags:
+                # Only splitting if "=" is there
+                option = flag.split("=", 1)
+                if len(option) == 2:
+                    ret[option[0]] = option[1]
+                else:
+                    ret[option[0]] = ""
+            return ret
+
+        def _dict_to_list(flags):
+            return [f"{k}={v}" if v else k for k, v in flags.items() if v is not None]
+
+        self_args = getattr(self, attr_name)
+        # FIXME: if xxxxx_args -> dict-type at some point, all these lines could be removed
+        options = _list_to_dict(self_args)
+        # Add/update/remove the current xxxxx_args with the new flags given
+        options.update(updated_flags)
+        # Update the current ones
+        setattr(self, attr_name, _dict_to_list(options))
+
     def generate_args(self):
-        configure_args = []
-        configure_args.extend(self.configure_args)
-        user_args_str = args_to_string(self.configure_args)
-        for flag, var in (("host", self._host), ("build", self._build), ("target", self._target)):
-            if var and flag not in user_args_str:
-                configure_args.append('--{}={}'.format(flag, var))
-
-        args = {"configure_args": args_to_string(configure_args),
+        args = {"configure_args": args_to_string(self.configure_args),
                 "make_args":  args_to_string(self.make_args),
                 "autoreconf_args": args_to_string(self.autoreconf_args)}
-
         save_toolchain_args(args, namespace=self._namespace)
diff --git a/conan/tools/gnu/get_gnu_triplet.py b/conan/tools/gnu/get_gnu_triplet.py
index c082f3007..d25e8c506 100644
--- a/conan/tools/gnu/get_gnu_triplet.py
+++ b/conan/tools/gnu/get_gnu_triplet.py
@@ -68,7 +68,7 @@ def _get_gnu_triplet(os_, arch, compiler=None):
     if compiler == "gcc":
         windows_op = "w64-mingw32"
     elif compiler == "Visual Studio":
-        windows_op = "windows-msvc"
+        windows_op = "unknown-windows"
     else:
         windows_op = "windows"
 
diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py
index 17f553242..d4e808f16 100644
--- a/conan/tools/meson/toolchain.py
+++ b/conan/tools/meson/toolchain.py
@@ -5,7 +5,7 @@ from jinja2 import Template
 
 from conan.tools._check_build_profile import check_using_build_profile
 from conan.tools._compilers import libcxx_flags
-from conan.tools.apple.apple import to_apple_arch, is_apple_os, apple_min_version_flag
+from conan.tools.apple.apple import to_apple_arch, is_apple_os, apple_min_version_flag, apple_sdk_path
 from conan.tools.build.cross_building import cross_building, get_cross_building_settings
 from conan.tools.env import VirtualBuildEnv
 from conan.tools.meson.helpers import *
@@ -242,9 +242,12 @@ class MesonToolchain(object):
         if not self._is_apple_system:
             return
         # SDK path is mandatory for cross-building
-        sdk_path = self._conanfile.conf.get("tools.apple:sdk_path")
+        sdk_path = apple_sdk_path(self._conanfile)
         if not sdk_path and self.cross_build:
-            raise ConanException("You must provide a valid SDK path for cross-compilation.")
+            raise ConanException(
+                "Apple SDK path not found. For cross-compilation, you must "
+                "provide a valid SDK path in 'tools.apple:sdk_path' config."
+            )
 
         # TODO: Delete this os_sdk check whenever the _guess_apple_sdk_name() function disappears
         os_sdk = self._conanfile.settings.get_safe('os.sdk')
@@ -291,10 +294,12 @@ class MesonToolchain(object):
         cflags = self._conanfile.conf.get("tools.build:cflags", default=[], check_type=list)
         sharedlinkflags = self._conanfile.conf.get("tools.build:sharedlinkflags", default=[], check_type=list)
         exelinkflags = self._conanfile.conf.get("tools.build:exelinkflags", default=[], check_type=list)
+        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]
         return {
             "cxxflags": cxxflags,
             "cflags": cflags,
-            "ldflags": sharedlinkflags + exelinkflags
+            "ldflags": sharedlinkflags + exelinkflags + linker_script_flags
         }
 
     @staticmethod
diff --git a/conan/tools/microsoft/__init__.py b/conan/tools/microsoft/__init__.py
index 79598b28e..c060c64b8 100644
--- a/conan/tools/microsoft/__init__.py
+++ b/conan/tools/microsoft/__init__.py
@@ -1,9 +1,9 @@
 from conan.tools.microsoft.layout import vs_layout
 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.subsystems import unix_path, unix_path_package_info_legacy
 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
+    is_msvc_static_runtime, check_min_vs, msvs_toolset
diff --git a/conan/tools/microsoft/nmakedeps.py b/conan/tools/microsoft/nmakedeps.py
index f8af5696e..fe77e9480 100644
--- a/conan/tools/microsoft/nmakedeps.py
+++ b/conan/tools/microsoft/nmakedeps.py
@@ -41,11 +41,23 @@ class NMakeDeps(object):
             ret.extend(cpp_info.exelinkflags or [])
             ret.extend(cpp_info.sharedlinkflags or [])
             ret.extend([format_lib(lib) for lib in cpp_info.libs or []])
+            ret.extend([format_lib(lib) for lib in cpp_info.system_libs or []])
             link_args = " ".join(ret)
 
+            def format_define(define):
+                if "=" in define:
+                    # CL env-var can't accept '=' sign in /D option, it can be replaced by '#' sign:
+                    # https://learn.microsoft.com/en-us/cpp/build/reference/cl-environment-variables
+                    macro, value = define.split("=", 1)
+                    if value and not value.isnumeric():
+                        value = f'\\"{value}\\"'
+                    define = f"{macro}#{value}"
+                return f"/D{define}"
+
             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 [])
+            cl_flags.extend([format_define(define) for define in cpp_info.defines or []])
 
             env = Environment()
             env.append("CL", " ".join(cl_flags))
diff --git a/conan/tools/microsoft/nmaketoolchain.py b/conan/tools/microsoft/nmaketoolchain.py
index ef4795385..c9c1c666f 100644
--- a/conan/tools/microsoft/nmaketoolchain.py
+++ b/conan/tools/microsoft/nmaketoolchain.py
@@ -1,5 +1,6 @@
-from conan.tools._compilers import cppstd_flag, build_type_flags
+from conan.tools._compilers import cppstd_flag, build_type_flags, build_type_link_flags
 from conan.tools.env import Environment
+from conan.tools.microsoft.visual import msvc_runtime_flag, VCVars
 
 
 class NMakeToolchain(object):
@@ -15,42 +16,100 @@ class NMakeToolchain(object):
         :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``.
         """
         self._conanfile = conanfile
-        self._environment = None
+
+        # Flags
+        self.extra_cflags = []
+        self.extra_cxxflags = []
+        self.extra_ldflags = []
+        self.extra_defines = []
+
+    def _format_options(self, options):
+        return [f"{opt[0].replace('-', '/')}{opt[1:]}" for opt in options if len(opt) > 1]
+
+    def _format_defines(self, defines):
+        formated_defines = []
+        for define in defines:
+            if "=" in define:
+                # CL env-var can't accept '=' sign in /D option, it can be replaced by '#' sign:
+                # https://learn.microsoft.com/en-us/cpp/build/reference/cl-environment-variables
+                macro, value = define.split("=", 1)
+                if value and not value.isnumeric():
+                    value = f'\\"{value}\\"'
+                define = f"{macro}#{value}"
+            formated_defines.append(f"/D{define}")
+        return formated_defines
 
     @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")
+    def _cl(self):
+        bt_flags = build_type_flags(self._conanfile.settings)
+        bt_flags = bt_flags if bt_flags else []
 
-        bt = build_type_flags(self._conanfile.settings)
-        if bt:
-            cppflags.extend(bt)
+        rt_flags = msvc_runtime_flag(self._conanfile)
+        rt_flags = [f"/{rt_flags}"] if rt_flags else []
 
+        cflags = []
+        cflags.extend(self._conanfile.conf.get("tools.build:cflags", default=[], check_type=list))
+        cflags.extend(self.extra_cflags)
+
+        cxxflags = []
         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("-", "/")
+            cxxflags.append(cppstd)
+        cxxflags.extend(self._conanfile.conf.get("tools.build:cxxflags", default=[], check_type=list))
+        cxxflags.extend(self.extra_cxxflags)
+
+        defines = []
+        build_type = self._conanfile.settings.get_safe("build_type")
+        if build_type in ["Release", "RelWithDebInfo", "MinSizeRel"]:
+            defines.append("NDEBUG")
+        defines.extend(self._conanfile.conf.get("tools.build:defines", default=[], check_type=list))
+        defines.extend(self.extra_defines)
+
+        return ["/nologo"] + \
+               self._format_options(bt_flags + rt_flags + cflags + cxxflags) + \
+               self._format_defines(defines)
 
     @property
+    def _link(self):
+        bt_ldflags = build_type_link_flags(self._conanfile.settings)
+        bt_ldflags = bt_ldflags if bt_ldflags else []
+
+        ldflags = []
+        ldflags.extend(bt_ldflags)
+        ldflags.extend(self._conanfile.conf.get("tools.build:sharedlinkflags", default=[], check_type=list))
+        ldflags.extend(self._conanfile.conf.get("tools.build:exelinkflags", default=[], check_type=list))
+        ldflags.extend(self.extra_ldflags)
+
+        return ["/nologo"] + self._format_options(ldflags)
+
     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()
+        env = Environment()
+        # Injection of compile flags in CL env-var:
+        # https://learn.microsoft.com/en-us/cpp/build/reference/cl-environment-variables
+        env.append("CL", self._cl)
+        # Injection of link flags in _LINK_ env-var:
+        # https://learn.microsoft.com/en-us/cpp/build/reference/linking
+        env.append("_LINK_", self._link)
+        # Also define some special env-vars which can override special NMake macros:
+        # https://learn.microsoft.com/en-us/cpp/build/reference/special-nmake-macros
+        conf_compilers = self._conanfile.conf.get("tools.build:compiler_executables", default={}, check_type=dict)
+        if conf_compilers:
+            compilers_mapping = {
+                "AS": "asm",
+                "CC": "c",
+                "CPP": "cpp",
+                "CXX": "cpp",
+                "RC": "rc",
+            }
+            for env_var, comp in compilers_mapping.items():
+                if comp in conf_compilers:
+                    env.define(env_var, conf_compilers[comp])
+        return env
+
+    def vars(self):
+        return self.environment().vars(self._conanfile, scope="build")
+
+    def generate(self, env=None, scope="build"):
+        env = env or self.environment()
+        env.vars(self._conanfile, scope=scope).save_script("conannmaketoolchain")
+        VCVars(self._conanfile).generate(scope=scope)
diff --git a/conan/tools/microsoft/subsystems.py b/conan/tools/microsoft/subsystems.py
index 55789e8ea..5d1a59e35 100644
--- a/conan/tools/microsoft/subsystems.py
+++ b/conan/tools/microsoft/subsystems.py
@@ -1,6 +1,12 @@
 from conans.client.subsystems import deduce_subsystem, subsystem_path
+from conans.client.tools.win import unix_path as unix_path_legacy_tools
 
 
 def unix_path(conanfile, path, scope="build"):
     subsystem = deduce_subsystem(conanfile, scope=scope)
     return subsystem_path(subsystem, path)
+
+def unix_path_package_info_legacy(conanfile, path, path_flavor=None):
+    # Call legacy implementation, which has different logic
+    # to autodeduce the subsystem type for the conversion.
+    return unix_path_legacy_tools(path, path_flavor)
diff --git a/conan/tools/microsoft/toolchain.py b/conan/tools/microsoft/toolchain.py
index b98f6be45..2be8a67da 100644
--- a/conan/tools/microsoft/toolchain.py
+++ b/conan/tools/microsoft/toolchain.py
@@ -7,7 +7,7 @@ from jinja2 import Template
 from conan.tools._check_build_profile import check_using_build_profile
 from conan.tools.build import build_jobs
 from conan.tools.intel.intel_cc import IntelCC
-from conan.tools.microsoft.visual import VCVars, msvc_version_to_toolset_version
+from conan.tools.microsoft.visual import VCVars, msvs_toolset
 from conans.errors import ConanException
 from conans.util.files import save, load
 
@@ -54,7 +54,7 @@ class MSBuildToolchain(object):
         self.configuration = conanfile.settings.build_type
         self.runtime_library = self._runtime_library(conanfile.settings)
         self.cppstd = conanfile.settings.get_safe("compiler.cppstd")
-        self.toolset = self._msvs_toolset(conanfile)
+        self.toolset = msvs_toolset(conanfile)
         self.properties = {}
         check_using_build_profile(self._conanfile)
 
@@ -82,37 +82,6 @@ class MSBuildToolchain(object):
         else:
             VCVars(self._conanfile).generate()
 
-    @staticmethod
-    def _msvs_toolset(conanfile):
-        settings = conanfile.settings
-        compiler = settings.get_safe("compiler")
-        compiler_version = settings.get_safe("compiler.version")
-        if compiler == "msvc":
-            subs_toolset = settings.get_safe("compiler.toolset")
-            if subs_toolset:
-                return subs_toolset
-            return msvc_version_to_toolset_version(compiler_version)
-        if compiler == "intel":
-            compiler_version = compiler_version if "." in compiler_version else \
-                "%s.0" % compiler_version
-            return "Intel C++ Compiler " + compiler_version
-        if compiler == "intel-cc":
-            return IntelCC(conanfile).ms_toolset
-        if compiler == "Visual Studio":
-            toolset = settings.get_safe("compiler.toolset")
-            if not toolset:
-                toolsets = {"17": "v143",
-                            "16": "v142",
-                            "15": "v141",
-                            "14": "v140",
-                            "12": "v120",
-                            "11": "v110",
-                            "10": "v100",
-                            "9": "v90",
-                            "8": "v80"}
-                toolset = toolsets.get(compiler_version)
-            return toolset or ""
-
     @staticmethod
     def _runtime_library(settings):
         compiler = settings.compiler
@@ -148,7 +117,7 @@ class MSBuildToolchain(object):
 
         cppstd = "stdcpp%s" % self.cppstd if self.cppstd else ""
         runtime_library = self.runtime_library
-        toolset = self.toolset
+        toolset = self.toolset or ""
         compile_options = self._conanfile.conf.get("tools.microsoft.msbuildtoolchain:compile_options",
                                                    default={}, check_type=dict)
         self.compile_options.update(compile_options)
diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py
index 882b867e5..1c6925949 100644
--- a/conan/tools/microsoft/visual.py
+++ b/conan/tools/microsoft/visual.py
@@ -4,11 +4,12 @@ import textwrap
 from conans.client.tools import vs_installation_path
 from conans.client.tools.version import Version
 from conans.errors import ConanException, ConanInvalidConfiguration
+from conan.tools.intel.intel_cc import IntelCC
 
 CONAN_VCVARS_FILE = "conanvcvars.bat"
 
 
-def check_min_vs(conanfile, version):
+def check_min_vs(conanfile, version, raise_invalid=True):
     """ this is a helper method to allow the migration of 1.X->2.0 and VisualStudio->msvc settings
     withoug breaking recipes
     The legacy "Visual Studio" with different toolset is not managed, not worth the complexity
@@ -30,9 +31,13 @@ def check_min_vs(conanfile, version):
             compiler_version += ".{}".format(compiler_update)
 
     if compiler_version and Version(compiler_version) < version:
-        msg = "This package doesn't work with VS compiler version '{}'" \
-              ", it requires at least '{}'".format(compiler_version, version)
-        raise ConanInvalidConfiguration(msg)
+        if raise_invalid:
+            msg = f"This package doesn't work with VS compiler version '{compiler_version}'" \
+                  f", it requires at least '{version}'"
+            raise ConanInvalidConfiguration(msg)
+        else:
+            return False
+    return True
 
 
 def msvc_version_to_vs_ide_version(version):
@@ -52,7 +57,7 @@ def msvc_version_to_toolset_version(version):
                 '191': 'v141',
                 '192': 'v142',
                 "193": 'v143'}
-    return toolsets[str(version)]
+    return toolsets.get(str(version))
 
 
 class VCVars:
@@ -72,6 +77,10 @@ class VCVars:
         if compiler not in ("Visual Studio", "msvc", "clang"):
             return
 
+        vs_install_path = conanfile.conf.get("tools.microsoft.msbuild:installation_path")
+        if vs_install_path == "":  # Empty string means "disable"
+            return
+
         if compiler == "clang":
             # The vcvars only needed for LLVM/Clang and VS ClangCL, who define runtime
             if not conanfile.settings.get_safe("compiler.runtime"):
@@ -93,7 +102,6 @@ class VCVars:
             vcvars_ver = _vcvars_vers(conanfile, compiler, vs_version)
         vcvarsarch = vcvars_arch(conanfile)
 
-        vs_install_path = conanfile.conf.get("tools.microsoft.msbuild:installation_path")
         # The vs_install_path is like
         # C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
         # C:\Program Files (x86)\Microsoft Visual Studio\2017\Community
@@ -268,3 +276,42 @@ def is_msvc_static_runtime(conanfile):
     :return: True, if msvc + runtime MT. Otherwise, False
     """
     return is_msvc(conanfile) and "MT" in msvc_runtime_flag(conanfile)
+
+
+def msvs_toolset(conanfile):
+    """ Returns the corresponding platform toolset based on the compiler of the given conanfile.
+        In case no toolset is configured in the profile, it will return a toolset based on the
+        compiler version, otherwise, it will return the toolset from the profile.
+        When there is no compiler version neither toolset configured, it will return None
+        It supports Visual Studio, msvc and Intel.
+    :param conanfile: Conanfile instance to access settings.compiler
+    :return: A toolset when compiler.version is valid or compiler.toolset is configured. Otherwise, None.
+    """
+    settings = conanfile.settings
+    compiler = settings.get_safe("compiler")
+    compiler_version = settings.get_safe("compiler.version")
+    if compiler == "msvc":
+        subs_toolset = settings.get_safe("compiler.toolset")
+        if subs_toolset:
+            return subs_toolset
+        return msvc_version_to_toolset_version(compiler_version)
+    if compiler == "intel" and compiler_version:
+        compiler_version = compiler_version if "." in compiler_version else \
+            f"{compiler_version}.0"
+        return "Intel C++ Compiler " + compiler_version
+    if compiler == "intel-cc":
+        return IntelCC(conanfile).ms_toolset
+    if compiler == "Visual Studio":
+        toolset = settings.get_safe("compiler.toolset")
+        if not toolset:
+            toolsets = {"17": "v143",
+                        "16": "v142",
+                        "15": "v141",
+                        "14": "v140",
+                        "12": "v120",
+                        "11": "v110",
+                        "10": "v100",
+                        "9": "v90",
+                        "8": "v80"}
+            toolset = toolsets.get(str(compiler_version))
+        return toolset
diff --git a/conan/tools/scm/__init__.py b/conan/tools/scm/__init__.py
index 59846cc18..7947ecae2 100644
--- a/conan/tools/scm/__init__.py
+++ b/conan/tools/scm/__init__.py
@@ -165,7 +165,7 @@ class Version:
     def __eq__(self, other):
         if other is None:
             return False
-        if isinstance(other, str):
+        if not isinstance(other, Version):
             other = Version(other)
 
         return (self._nonzero_items, self._pre, self._build) ==\
diff --git a/conans/__init__.py b/conans/__init__.py
index fda098f9d..7458ba70e 100644
--- a/conans/__init__.py
+++ b/conans/__init__.py
@@ -20,4 +20,4 @@ OAUTH_TOKEN = "oauth_token"
 SERVER_CAPABILITIES = [COMPLEX_SEARCH_CAPABILITY, REVISIONS]  # Server is always with revisions
 DEFAULT_REVISION_V1 = "0"
 
-__version__ = '1.57.0-dev'
+__version__ = '1.59.0-dev'
diff --git a/conans/client/build/cmake.py b/conans/client/build/cmake.py
index 0006d8622..d9a668b37 100644
--- a/conans/client/build/cmake.py
+++ b/conans/client/build/cmake.py
@@ -47,8 +47,14 @@ class CMake(object):
         :param generator_platform: Generator platform name or none to autodetect (-A cmake option)
         """
         if getattr(conanfile, "must_use_new_helpers", None):
-            raise ConanException("Using the wrong 'CMake' helper. To use CMakeDeps, CMakeToolchain "
-                                 "you should use 'from conan.tools.cmake import CMake'")
+            wrong_helper_msg = "Using the wrong 'CMake' helper. To use CMakeDeps, CMakeToolchain "\
+                               "you should use 'from conan.tools.cmake import CMake'. "\
+                               "Set environment variable CONAN_DISABLE_STRICT_MODE=1 to override "\
+                               "this check (should only be used to build old packages)."
+            if get_env("CONAN_DISABLE_STRICT_MODE", False):
+                conanfile.output.warning(wrong_helper_msg)
+            else:
+                raise ConanException(wrong_helper_msg)
         self._append_vcvars = append_vcvars
         self._conanfile = conanfile
         self._settings = conanfile.settings
diff --git a/conans/client/build/msbuild.py b/conans/client/build/msbuild.py
index 778b81a76..df8b7bee4 100644
--- a/conans/client/build/msbuild.py
+++ b/conans/client/build/msbuild.py
@@ -23,9 +23,14 @@ class MSBuild(object):
     def __init__(self, conanfile):
         if isinstance(conanfile, ConanFile):
             if getattr(conanfile, "must_use_new_helpers", None):
-                raise ConanException(
-                    "Using the wrong 'MSBuild' helper. To use MSBuildDeps, MSBuildToolchain "
-                    "you should use 'from conan.tools.microsoft import MSBuild'")
+                wrong_helper_msg = "Using the wrong 'MSBuild' helper. To use MSBuildDeps, MSBuildToolchain "\
+                                   "you should use 'from conan.tools.microsoft import MSBuild'. "\
+                                   "Set environment variable CONAN_DISABLE_STRICT_MODE=1 to override "\
+                                   "this check (should only be used to build old packages)."
+                if get_env("CONAN_DISABLE_STRICT_MODE", False):
+                    conanfile.output.warning(wrong_helper_msg)
+                else:
+                    raise ConanException(wrong_helper_msg)
             self._conanfile = conanfile
             self._settings = self._conanfile.settings
             self._output = self._conanfile.output
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
index ad204d43b..7971b1feb 100644
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -90,9 +90,9 @@ _t_default_settings_yml = Template(textwrap.dedent("""
                       "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",
+                      "8", "8.1", "8.2", "8.3", "8.4", "8.5",
+                      "9", "9.1", "9.2", "9.3", "9.4", "9.5",
+                      "10", "10.1", "10.2", "10.3", "10.4",
                       "11", "11.1", "11.2", "11.3",
                       "12", "12.1", "12.2"]
             libcxx: [libstdc++, libstdc++11]
diff --git a/conans/client/generators/__init__.py b/conans/client/generators/__init__.py
index dad8cdc36..3413e98d0 100644
--- a/conans/client/generators/__init__.py
+++ b/conans/client/generators/__init__.py
@@ -291,12 +291,16 @@ def _generate_aggregated_env(conanfile):
         ps1s = []
         for env_script in env_scripts:
             path = os.path.join(conanfile.generators_folder, env_script)
+            # Only the .bat and .ps1 are made relative to current script
             if env_script.endswith(".bat"):
-                bats.append(path)
+                path = os.path.relpath(path, conanfile.generators_folder)
+                bats.append("%~dp0/"+path)
             elif env_script.endswith(".sh"):
                 shs.append(subsystem_path(subsystem, path))
             elif env_script.endswith(".ps1"):
-                ps1s.append(path)
+                path = os.path.relpath(path, conanfile.generators_folder)
+                # This $PSScriptRoot uses the current script directory
+                ps1s.append("$PSScriptRoot/"+path)
         if shs:
             def sh_content(files):
                 return ". " + " && . ".join('"{}"'.format(s) for s in files)
diff --git a/conans/client/graph/graph_builder.py b/conans/client/graph/graph_builder.py
index 05b7ef1df..a9015d928 100644
--- a/conans/client/graph/graph_builder.py
+++ b/conans/client/graph/graph_builder.py
@@ -78,6 +78,10 @@ class DepsGraphBuilder(object):
         # an option conflict while expanding the build_requires is impossible
         node.conanfile.build_requires_options.clear_unscoped_options()
         new_options = node.conanfile.build_requires_options._reqs_options
+        # FIXME: Convert to pattern-based for build_requires, do not fail hard if some option
+        #  was removed
+        if profile_build:  # Apply the fix only for the 2 profile scenario
+            new_options = {k+"*": v for k, v in new_options.items()}
         new_reqs = Requirements()
 
         conanfile = node.conanfile
diff --git a/conans/client/migrations_settings.py b/conans/client/migrations_settings.py
index bdb5c3311..9da8dc597 100644
--- a/conans/client/migrations_settings.py
+++ b/conans/client/migrations_settings.py
@@ -4187,3 +4187,159 @@ cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
 settings_1_56_0 = settings_1_55_0
 
 settings_1_57_0 = settings_1_56_0
+
+settings_1_58_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", "8.5",
+                  "9", "9.1", "9.2", "9.3", "9.4", "9.5",
+                  "10", "10.1", "10.2", "10.3", "10.4",
+                  "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
+"""
+
+settings_1_59_0 = settings_1_58_0
diff --git a/conans/model/build_info.py b/conans/model/build_info.py
index e27d432d5..94c0a6f61 100644
--- a/conans/model/build_info.py
+++ b/conans/model/build_info.py
@@ -400,14 +400,6 @@ class CppInfo(_CppInfo):
 
         def _check_components_requires_instersection(comp_requires):
             reqs = [it.split(COMPONENT_SCOPE)[0] for it in comp_requires if COMPONENT_SCOPE in it]
-            # Raise on components requires without package requires
-            for pkg_require in pkg_requires:
-                if package_requires[pkg_require].private or package_requires[pkg_require].override:
-                    # Not standard requires, skip
-                    continue
-                if pkg_require not in reqs:
-                    raise ConanException("Package require '%s' not used in components requires"
-                                         % pkg_require)
             # Raise on components requires requiring inexistent package requires
             for comp_require in reqs:
                 reason = None
diff --git a/conans/model/conf.py b/conans/model/conf.py
index 62f91da8d..fcad44d96 100644
--- a/conans/model/conf.py
+++ b/conans/model/conf.py
@@ -35,7 +35,7 @@ BUILT_IN_CONFS = {
     "tools.microsoft.msbuild:verbosity": "Verbosity level for MSBuild: 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic'",
     "tools.microsoft.msbuild:vs_version": "Defines the IDE version when using the new msvc compiler",
     "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",
+    "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",
     "tools.microsoft.msbuilddeps:exclude_code_analysis": "Suppress MSBuild code analysis for patterns",
     "tools.microsoft.msbuildtoolchain:compile_options": "Dictionary with MSBuild compiler options",
     "tools.intel:installation_path": "Defines the Intel oneAPI installation root path",
@@ -54,6 +54,7 @@ BUILT_IN_CONFS = {
     "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', 'objcpp', 'rc', 'fortran', 'asm', 'hip', 'ispc'}",
+    "tools.build:linker_scripts": "List of linker script files to pass to the linker used by different toolchains like CMakeToolchain, AutotoolsToolchain, and MesonToolchain",
     "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",
diff --git a/conans/server/service/common/search.py b/conans/server/service/common/search.py
index af0c58ac3..e9c576206 100644
--- a/conans/server/service/common/search.py
+++ b/conans/server/service/common/search.py
@@ -61,7 +61,10 @@ def search_packages(server_store, ref, query, look_in_all_rrevs):
     param ref: ConanFileReference object
     """
     if not look_in_all_rrevs and ref.revision is None:
-        latest_rev = server_store.get_last_revision(ref).revision
+        found_ref = server_store.get_last_revision(ref)
+        if found_ref is None:
+            raise RecipeNotFoundException(ref)
+        latest_rev = found_ref.revision
         ref = ref.copy_with_rev(latest_rev)
 
     if not os.path.exists(server_store.conan_revisions_root(ref.copy_clear_rev())):


Test patch:
diff --git a/conans/test/conftest.py b/conans/test/conftest.py
index e70221448..f41b99dba 100644
--- a/conans/test/conftest.py
+++ b/conans/test/conftest.py
@@ -87,8 +87,7 @@ tools_locations = {
         },
         "3.23": {
             "path": {'Windows': 'C:/cmake/cmake-3.23.1-win64-x64/bin',
-                     'Darwin': '/Users/jenkins/cmake/cmake-3.23.1/bin'
-                               if not MacOS_arm else "skip-tests",
+                     'Darwin': '/Users/jenkins/cmake/cmake-3.23.1/bin',
                      # Not available in Linux
                      'Linux': "skip-tests"}
         }
diff --git a/conans/test/functional/command/test_command_test.py b/conans/test/functional/command/test_command_test.py
index 970e50aaf..c34fddfff 100644
--- a/conans/test/functional/command/test_command_test.py
+++ b/conans/test/functional/command/test_command_test.py
@@ -1,4 +1,5 @@
 import os
+import platform
 import time
 import unittest
 
@@ -26,5 +27,6 @@ class ConanTestTest(unittest.TestCase):
         client.run("test test_package hello/0.1@lasote/stable -s hello:build_type=Debug "
                    "--build missing")
         self.assertIn('hello/0.1: Hello World Debug!', client.out)
+        subfolder = "Release" if platform.system() != "Windows" else ""
         assert os.path.exists(os.path.join(client.current_folder, "test_package",
-                                           "build", "generators", "conaninfo.txt"))
+                                           "build", subfolder, "generators", "conaninfo.txt"))
diff --git a/conans/test/functional/generators/components/propagate_specific_components_test.py b/conans/test/functional/generators/components/propagate_specific_components_test.py
index a1ac6e7a5..b4270ee04 100644
--- a/conans/test/functional/generators/components/propagate_specific_components_test.py
+++ b/conans/test/functional/generators/components/propagate_specific_components_test.py
@@ -1,8 +1,6 @@
 import textwrap
 import unittest
 
-import pytest
-
 from conans.test.utils.tools import TestClient
 
 
@@ -133,25 +131,6 @@ class WrongComponentsTestCase(unittest.TestCase):
             self.assertIn("ERROR: Component 'top::not-existing' not found in 'top'"
                           " package requirement", t.out)
 
-    def test_unused_requirement(self):
-        """ Requires should include all listed requirements
-            This error is known when creating the package if the requirement is consumed.
-        """
-        consumer = textwrap.dedent("""
-            from conans import ConanFile
-
-            class Recipe(ConanFile):
-                requires = "top/version"
-                def package_info(self):
-                    self.cpp_info.requires = ["other::other"]
-        """)
-        t = TestClient()
-        t.save({'top.py': self.top, 'consumer.py': consumer})
-        t.run('create top.py top/version@')
-        t.run('create consumer.py wrong/version@', assert_error=True)
-        self.assertIn("wrong/version package_info(): Package require 'top' not used"
-                      " in components requires", t.out)
-
     def test_wrong_requirement(self):
         """ If we require a wrong requirement, we get a meaninful error.
             This error is known when creating the package if the requirement is not there.
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
index c1ceb5d3a..370b371a5 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
@@ -657,3 +657,42 @@ def test_map_imported_config():
     assert "hello/1.0: Hello World Release!" in client.out
     assert "talk: Release!" in client.out
     assert "main: Debug!" in client.out
+
+
+@pytest.mark.tool_cmake
+def test_quiet():
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+
+        class Test(ConanFile):
+            name = "test"
+            version = "0.1"
+
+            def package_info(self):
+                self.cpp_info.system_libs = ["lib1"]
+        """)
+    client = TestClient()
+    client.save({"conanfile.py": conanfile})
+    client.run("create .")
+
+    conanfile = textwrap.dedent("""
+        [requires]
+        test/0.1
+
+        [generators]
+        CMakeDeps
+        """)
+    cmakelists = textwrap.dedent("""
+        cmake_minimum_required(VERSION 3.15)
+        project(consumer NONE)
+        set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
+        set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
+        find_package(test QUIET)
+        """)
+
+    client.save({"conanfile.txt": conanfile,
+                 "CMakeLists.txt": cmakelists}, clean_first=True)
+    client.run("install .")
+    client.run_command('cmake . -DCMAKE_BUILD_TYPE=Release')
+    # Because we used QUIET, not in output
+    assert "Target declared 'test::test'" not in client.out
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py
index 44b0565f5..a94d0977c 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py
@@ -116,26 +116,6 @@ def test_wrong_component(top_conanfile, from_component):
     assert "Component 'top::not-existing' not found in 'top' package requirement" in t.out
 
 
-def test_unused_requirement(top_conanfile):
-    """ Requires should include all listed requirements
-        This error is known when creating the package if the requirement is consumed.
-    """
-    consumer = textwrap.dedent("""
-        from conans import ConanFile
-
-        class Recipe(ConanFile):
-            requires = "top/version"
-            def package_info(self):
-                self.cpp_info.requires = ["other::other"]
-    """)
-    t = TestClient()
-    t.save({'top.py': top_conanfile, 'consumer.py': consumer})
-    t.run('create top.py top/version@')
-    t.run('create consumer.py wrong/version@', assert_error=True)
-    assert "wrong/version package_info(): Package require 'top' not used in components " \
-           "requires" in t.out
-
-
 def test_wrong_requirement(top_conanfile):
     """ If we require a wrong requirement, we get a meaninful error.
         This error is known when creating the package if the requirement is not there.
diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
index dbd70681e..bfa6239c0 100644
--- a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
+++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
@@ -556,20 +556,20 @@ def test_cmake_toolchain_runtime_types_cmake_older_than_3_15():
 def test_cmake_presets_missing_option():
     client = TestClient(path_with_spaces=False)
     client.run("new hello/0.1 --template=cmake_exe")
-    settings_layout = '-c tools.cmake.cmake_layout:build_folder_vars=' \
-                      '\'["options.missing"]\''
+    settings_layout = '-c tools.cmake.cmake_layout:build_folder_vars=\'["options.missing"]\' ' \
+                      '-c tools.cmake.cmaketoolchain:generator=Ninja'
     client.run("install . {}".format(settings_layout))
-    assert os.path.exists(os.path.join(client.current_folder, "build", "generators"))
+    assert os.path.exists(os.path.join(client.current_folder, "build", "Release", "generators"))
 
 
 @pytest.mark.tool_cmake(version="3.23")
 def test_cmake_presets_missing_setting():
     client = TestClient(path_with_spaces=False)
     client.run("new hello/0.1 --template=cmake_exe")
-    settings_layout = '-c tools.cmake.cmake_layout:build_folder_vars=' \
-                      '\'["settings.missing"]\''
+    settings_layout = '-c tools.cmake.cmake_layout:build_folder_vars=\'["settings.missing"]\' ' \
+                      '-c tools.cmake.cmaketoolchain:generator=Ninja'
     client.run("install . {}".format(settings_layout))
-    assert os.path.exists(os.path.join(client.current_folder, "build", "generators"))
+    assert os.path.exists(os.path.join(client.current_folder, "build", "Release", "generators"))
 
 
 @pytest.mark.tool_cmake(version="3.23")
@@ -587,33 +587,47 @@ def test_cmake_presets_multiple_settings_single_config():
                "-s compiler.version=12.0 -s compiler.cppstd=gnu17"
     client.run("install . {} {}".format(settings, settings_layout))
     assert os.path.exists(os.path.join(client.current_folder, "build", "apple-clang-12.0-gnu17",
-                                       "generators"))
+                                       "Release", "generators"))
     assert os.path.exists(user_presets_path)
     user_presets = json.loads(load(user_presets_path))
     assert len(user_presets["include"]) == 1
     presets = json.loads(load(user_presets["include"][0]))
     assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 1
+    assert len(presets["testPresets"]) == 1
     assert presets["configurePresets"][0]["name"] == "apple-clang-12.0-gnu17-release"
     assert presets["buildPresets"][0]["name"] == "apple-clang-12.0-gnu17-release"
     assert presets["buildPresets"][0]["configurePreset"] == "apple-clang-12.0-gnu17-release"
+    assert presets["testPresets"][0]["name"] == "apple-clang-12.0-gnu17-release"
+    assert presets["testPresets"][0]["configurePreset"] == "apple-clang-12.0-gnu17-release"
 
-    # If we create the "Debug" one, it has the same toolchain and preset file, that is
-    # always multiconfig
+    # If we create the "Debug" one, it will be appended
     client.run("install . {} -s build_type=Debug {}".format(settings, settings_layout))
-    assert os.path.exists(os.path.join(client.current_folder, "build", "apple-clang-12.0-gnu17", "generators"))
+    assert os.path.exists(os.path.join(client.current_folder, "build", "apple-clang-12.0-gnu17",
+                                       "Release", "generators"))
     assert os.path.exists(user_presets_path)
+    print(load(user_presets_path))
     user_presets = json.loads(load(user_presets_path))
-    assert len(user_presets["include"]) == 1
+    assert len(user_presets["include"]) == 2
     presets = json.loads(load(user_presets["include"][0]))
-    assert len(presets["configurePresets"]) == 2
-    assert len(presets["buildPresets"]) == 2
+    assert len(presets["configurePresets"]) == 1
+    assert len(presets["buildPresets"]) == 1
+    assert len(presets["testPresets"]) == 1
     assert presets["configurePresets"][0]["name"] == "apple-clang-12.0-gnu17-release"
-    assert presets["configurePresets"][1]["name"] == "apple-clang-12.0-gnu17-debug"
     assert presets["buildPresets"][0]["name"] == "apple-clang-12.0-gnu17-release"
-    assert presets["buildPresets"][1]["name"] == "apple-clang-12.0-gnu17-debug"
     assert presets["buildPresets"][0]["configurePreset"] == "apple-clang-12.0-gnu17-release"
-    assert presets["buildPresets"][1]["configurePreset"] == "apple-clang-12.0-gnu17-debug"
+    assert presets["testPresets"][0]["name"] == "apple-clang-12.0-gnu17-release"
+    assert presets["testPresets"][0]["configurePreset"] == "apple-clang-12.0-gnu17-release"
+
+    presets = json.loads(load(user_presets["include"][1]))
+    assert len(presets["configurePresets"]) == 1
+    assert len(presets["buildPresets"]) == 1
+    assert len(presets["testPresets"]) == 1
+    assert presets["configurePresets"][0]["name"] == "apple-clang-12.0-gnu17-debug"
+    assert presets["buildPresets"][0]["name"] == "apple-clang-12.0-gnu17-debug"
+    assert presets["buildPresets"][0]["configurePreset"] == "apple-clang-12.0-gnu17-debug"
+    assert presets["testPresets"][0]["name"] == "apple-clang-12.0-gnu17-debug"
+    assert presets["testPresets"][0]["configurePreset"] == "apple-clang-12.0-gnu17-debug"
 
     # But If we change, for example, the cppstd and the compiler version, the toolchain
     # and presets will be different, but it will be appended to the UserPresets.json
@@ -621,34 +635,40 @@ def test_cmake_presets_multiple_settings_single_config():
                "-s compiler.version=13 -s compiler.cppstd=gnu20"
     client.run("install . {} {}".format(settings, settings_layout))
     assert os.path.exists(os.path.join(client.current_folder, "build", "apple-clang-13-gnu20",
-                                       "generators"))
+                                       "Release", "generators"))
     assert os.path.exists(user_presets_path)
     user_presets = json.loads(load(user_presets_path))
     # The [0] is the apple-clang 12 the [1] is the apple-clang 13
-    assert len(user_presets["include"]) == 2
-    presets = json.loads(load(user_presets["include"][1]))
+    assert len(user_presets["include"]) == 3
+    presets = json.loads(load(user_presets["include"][2]))
     assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 1
+    assert len(presets["testPresets"]) == 1
     assert presets["configurePresets"][0]["name"] == "apple-clang-13-gnu20-release"
     assert presets["buildPresets"][0]["name"] == "apple-clang-13-gnu20-release"
     assert presets["buildPresets"][0]["configurePreset"] == "apple-clang-13-gnu20-release"
+    assert presets["testPresets"][0]["name"] == "apple-clang-13-gnu20-release"
+    assert presets["testPresets"][0]["configurePreset"] == "apple-clang-13-gnu20-release"
 
     # We can build with cmake manually
     if platform.system() == "Darwin":
         client.run_command("cmake . --preset apple-clang-12.0-gnu17-release")
         client.run_command("cmake --build --preset apple-clang-12.0-gnu17-release")
+        client.run_command("ctest --preset apple-clang-12.0-gnu17-release")
         client.run_command("./build/apple-clang-12.0-gnu17/Release/hello")
         assert "Hello World Release!" in client.out
         assert "__cplusplus2017" in client.out
 
         client.run_command("cmake . --preset apple-clang-12.0-gnu17-debug")
         client.run_command("cmake --build --preset apple-clang-12.0-gnu17-debug")
+        client.run_command("ctest --preset apple-clang-12.0-gnu17-debug")
         client.run_command("./build/apple-clang-12.0-gnu17/Debug/hello")
         assert "Hello World Debug!" in client.out
         assert "__cplusplus2017" in client.out
 
         client.run_command("cmake . --preset apple-clang-13-gnu20-release")
         client.run_command("cmake --build --preset apple-clang-13-gnu20-release")
+        client.run_command("ctest --preset apple-clang-13-gnu20-release")
         client.run_command("./build/apple-clang-13-gnu20/Release/hello")
         assert "Hello World Release!" in client.out
         assert "__cplusplus2020" in client.out
@@ -667,11 +687,16 @@ def test_cmake_presets_duplicated_install(multiconfig):
         settings += '-c tools.cmake.cmaketoolchain:generator="Multi-Config"'
     client.run("install . {}".format(settings))
     client.run("install . {}".format(settings))
-    presets_path = os.path.join(client.current_folder, "build", "gcc-5", "generators",
-                                "CMakePresets.json")
+    if multiconfig:
+        presets_path = os.path.join(client.current_folder, "build", "gcc-5", "generators",
+                                    "CMakePresets.json")
+    else:
+        presets_path = os.path.join(client.current_folder, "build", "gcc-5", "Release", "generators",
+                                    "CMakePresets.json")
     assert os.path.exists(presets_path)
     contents = json.loads(load(presets_path))
     assert len(contents["buildPresets"]) == 1
+    assert len(contents["testPresets"]) == 1
 
 
 def test_remove_missing_presets():
@@ -708,8 +733,8 @@ def test_remove_missing_presets():
 def test_cmake_presets_options_single_config():
     client = TestClient(path_with_spaces=False)
     client.run("new hello/0.1 --template=cmake_lib")
-    conf_layout = '-c tools.cmake.cmake_layout:build_folder_vars=\'["settings.compiler", ' \
-                  '"options.shared"]\''
+    conf_layout = '-c tools.cmake.cmake_layout:build_folder_vars=\'["settings.compiler",' \
+                  '"settings.build_type", "options.shared"]\''
 
     default_compiler = {"Darwin": "apple-clang",
                         "Windows": "visual studio",  # FIXME:  replace it with 'msvc' in develop2
@@ -719,12 +744,12 @@ def test_cmake_presets_options_single_config():
         client.run("install . {} -o shared={}".format(conf_layout, shared))
         shared_str = "shared_true" if shared else "shared_false"
         assert os.path.exists(os.path.join(client.current_folder,
-                                           "build", "{}-{}".format(default_compiler, shared_str),
+                                           "build", "{}-release-{}".format(default_compiler, shared_str),
                                            "generators"))
 
     client.run("install . {}".format(conf_layout))
     assert os.path.exists(os.path.join(client.current_folder,
-                                       "build", "{}-shared_false".format(default_compiler),
+                                       "build", "{}-release-shared_false".format(default_compiler),
                                        "generators"))
 
     user_presets_path = os.path.join(client.current_folder, "CMakeUserPresets.json")
@@ -734,11 +759,12 @@ def test_cmake_presets_options_single_config():
     if platform.system() == "Darwin":
         for shared in (True, False):
             shared_str = "shared_true" if shared else "shared_false"
-            client.run_command("cmake . --preset apple-clang-{}-release".format(shared_str))
-            client.run_command("cmake --build --preset apple-clang-{}-release".format(shared_str))
+            client.run_command("cmake . --preset apple-clang-release-{}".format(shared_str))
+            client.run_command("cmake --build --preset apple-clang-release-{}".format(shared_str))
+            client.run_command("ctest --preset apple-clang-release-{}".format(shared_str))
             the_lib = "libhello.a" if not shared else "libhello.dylib"
             path = os.path.join(client.current_folder,
-                                "build", "apple-clang-{}".format(shared_str), "release", the_lib)
+                                "build", "apple-clang-release-{}".format(shared_str), the_lib)
             assert os.path.exists(path)
 
 
@@ -763,9 +789,12 @@ def test_cmake_presets_multiple_settings_multi_config():
     presets = json.loads(load(user_presets["include"][0]))
     assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 1
+    assert len(presets["testPresets"]) == 1
     assert presets["configurePresets"][0]["name"] == "dynamic-14"
     assert presets["buildPresets"][0]["name"] == "dynamic-14-release"
     assert presets["buildPresets"][0]["configurePreset"] == "dynamic-14"
+    assert presets["testPresets"][0]["name"] == "dynamic-14-release"
+    assert presets["testPresets"][0]["configurePreset"] == "dynamic-14"
 
     # If we create the "Debug" one, it has the same toolchain and preset file, that is
     # always multiconfig
@@ -777,11 +806,16 @@ def test_cmake_presets_multiple_settings_multi_config():
     presets = json.loads(load(user_presets["include"][0]))
     assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 2
+    assert len(presets["testPresets"]) == 2
     assert presets["configurePresets"][0]["name"] == "dynamic-14"
     assert presets["buildPresets"][0]["name"] == "dynamic-14-release"
     assert presets["buildPresets"][1]["name"] == "dynamic-14-debug"
     assert presets["buildPresets"][0]["configurePreset"] == "dynamic-14"
     assert presets["buildPresets"][1]["configurePreset"] == "dynamic-14"
+    assert presets["testPresets"][0]["name"] == "dynamic-14-release"
+    assert presets["testPresets"][1]["name"] == "dynamic-14-debug"
+    assert presets["testPresets"][0]["configurePreset"] == "dynamic-14"
+    assert presets["testPresets"][1]["configurePreset"] == "dynamic-14"
 
     # But If we change, for example, the cppstd and the compiler version, the toolchain
     # and presets will be different, but it will be appended to the UserPresets.json
@@ -796,19 +830,24 @@ def test_cmake_presets_multiple_settings_multi_config():
     presets = json.loads(load(user_presets["include"][1]))
     assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 1
+    assert len(presets["testPresets"]) == 1
     assert presets["configurePresets"][0]["name"] == "static-17"
     assert presets["buildPresets"][0]["name"] == "static-17-release"
     assert presets["buildPresets"][0]["configurePreset"] == "static-17"
+    assert presets["testPresets"][0]["name"] == "static-17-release"
+    assert presets["testPresets"][0]["configurePreset"] == "static-17"
 
     # We can build with cmake manually
     client.run_command("cmake . --preset dynamic-14")
 
     client.run_command("cmake --build --preset dynamic-14-release")
+    client.run_command("ctest --preset dynamic-14-release")
     client.run_command("build\\dynamic-14\\Release\\hello")
     assert "Hello World Release!" in client.out
     assert "MSVC_LANG2014" in client.out
 
     client.run_command("cmake --build --preset dynamic-14-debug")
+    client.run_command("ctest --preset dynamic-14-debug")
     client.run_command("build\\dynamic-14\\Debug\\hello")
     assert "Hello World Debug!" in client.out
     assert "MSVC_LANG2014" in client.out
@@ -816,6 +855,7 @@ def test_cmake_presets_multiple_settings_multi_config():
     client.run_command("cmake . --preset static-17")
 
     client.run_command("cmake --build --preset static-17-release")
+    client.run_command("ctest --preset static-17-release")
     client.run_command("build\\static-17\\Release\\hello")
     assert "Hello World Release!" in client.out
     assert "MSVC_LANG2017" in client.out
@@ -843,10 +883,12 @@ def test_user_presets_version2():
     if platform.system() == "Windows":
         client.run_command("cmake . --preset 14")
         client.run_command("cmake --build --preset 14-release")
+        client.run_command("ctest --preset 14-release")
         client.run_command(r"build\14\Release\hello.exe")
     else:
         client.run_command("cmake . --preset 14-release")
         client.run_command("cmake --build --preset 14-release")
+        client.run_command("ctest --preset 14-release")
         client.run_command("./build/14/Release/hello")
 
     assert "Hello World Release!" in client.out
@@ -859,10 +901,12 @@ def test_user_presets_version2():
     if platform.system() == "Windows":
         client.run_command("cmake . --preset 17")
         client.run_command("cmake --build --preset 17-release")
+        client.run_command("ctest --preset 17-release")
         client.run_command(r"build\17\Release\hello.exe")
     else:
         client.run_command("cmake . --preset 17-release")
         client.run_command("cmake --build --preset 17-release")
+        client.run_command("ctest --preset 17-release")
         client.run_command("./build/17/Release/hello")
 
     assert "Hello World Release!" in client.out
@@ -942,17 +986,16 @@ def test_cmake_presets_with_conanfile_txt():
 
     c.run("install .")
     c.run("install . -s build_type=Debug")
-    assert os.path.exists(os.path.join(c.current_folder, "CMakeUserPresets.json"))
-    presets_path = os.path.join(c.current_folder, "build", "generators", "CMakePresets.json")
-    assert os.path.exists(presets_path)
 
     if platform.system() != "Windows":
         c.run_command("cmake --preset debug")
         c.run_command("cmake --build --preset debug")
+        c.run_command("ctest --preset debug")
         c.run_command("./build/Debug/foo")
     else:
         c.run_command("cmake --preset default")
         c.run_command("cmake --build --preset debug")
+        c.run_command("ctest --preset debug")
         c.run_command("build\\Debug\\foo")
 
     assert "Hello World Debug!" in c.out
@@ -960,9 +1003,11 @@ def test_cmake_presets_with_conanfile_txt():
     if platform.system() != "Windows":
         c.run_command("cmake --preset release")
         c.run_command("cmake --build --preset release")
+        c.run_command("ctest --preset release")
         c.run_command("./build/Release/foo")
     else:
         c.run_command("cmake --build --preset release")
+        c.run_command("ctest --preset release")
         c.run_command("build\\Release\\foo")
 
     assert "Hello World Release!" in c.out
@@ -1140,7 +1185,8 @@ def test_cmake_toolchain_vars_when_option_declared():
 
 
 @pytest.mark.tool_cmake
-def test_find_program_for_tool_requires():
+@pytest.mark.parametrize("single_profile", [True, False])
+def test_find_program_for_tool_requires(single_profile):
     """Test that the same reference can be both a tool_requires and a regular requires,
     and that find_program (executables) and find_package (libraries) find the correct ones
     when cross building.
@@ -1192,8 +1238,11 @@ def test_find_program_for_tool_requires():
                 "build_profile": build_profile
                 })
 
-    client.run("create . -pr:b build_profile -pr:h build_profile")
-    client.run("create . -pr:b build_profile -pr:h host_profile")
+    if single_profile:
+        client.run("create . --profile host_profile")
+    else:
+        client.run("create . -pr:b build_profile -pr:h build_profile")
+        client.run("create . -pr:b build_profile -pr:h host_profile")
 
     conanfile_consumer = textwrap.dedent("""
         from conan import ConanFile
@@ -1208,7 +1257,7 @@ def test_find_program_for_tool_requires():
                 self.requires("foobar/1.0")
 
             def build_requirements(self):
-                self.tool_requires("foobar/1.0")
+               self.tool_requires("foobar/1.0")
     """)
 
     cmakelists_consumer = textwrap.dedent("""
@@ -1218,6 +1267,9 @@ def test_find_program_for_tool_requires():
         find_program(FOOBIN_EXECUTABLE foobin)
         message("foobin executable: ${FOOBIN_EXECUTABLE}")
         message("foobar include dir: ${foobar_INCLUDE_DIR}")
+        if(NOT FOOBIN_EXECUTABLE)
+          message(FATAL_ERROR "FOOBIN executable not found")
+        endif()
     """)
 
     client.save({
@@ -1225,17 +1277,24 @@ def test_find_program_for_tool_requires():
         "CMakeLists.txt": cmakelists_consumer,
         "host_profile": host_profile,
         "build_profile": build_profile}, clean_first=True)
-    client.run("install conanfile_consumer.py pkg/0.1@ -g CMakeToolchain -g CMakeDeps -pr:b build_profile -pr:h host_profile")
-
-    build_context_package_id = "581814504b2e960b35df487e5bdb32b1ecf02253"
-    host_context_package_id = "bf544cd3bc20b82121fd76b82eacbb36d75fa167"
+    
+    if single_profile:
+        profiles = "-pr host_profile"
+    else:
+        profiles = "-pr:b build_profile -pr:h host_profile"
+    
+    client.run(f"install conanfile_consumer.py pkg/0.1@ -g CMakeToolchain -g CMakeDeps {profiles}")
 
     with client.chdir("build"):
         client.run_command("cmake .. -DCMAKE_TOOLCHAIN_FILE=Release/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release")
         # Verify binary executable is found from build context package,
         # and library comes from host context package
-        assert f"package/{build_context_package_id}/bin/foobin" in client.out
-        assert f"package/{host_context_package_id}/include" in client.out
+
+        if not single_profile:
+            build_context_package_id = "581814504b2e960b35df487e5bdb32b1ecf02253"
+            host_context_package_id = "bf544cd3bc20b82121fd76b82eacbb36d75fa167"
+            assert f"package/{build_context_package_id}/bin/foobin" in client.out
+            assert f"package/{host_context_package_id}/include" in client.out
 
 
 @pytest.mark.tool_pkg_config
diff --git a/conans/test/functional/toolchains/meson/test_cross_compilation.py b/conans/test/functional/toolchains/meson/test_cross_compilation.py
index a03d9b971..89e4ad334 100644
--- a/conans/test/functional/toolchains/meson/test_cross_compilation.py
+++ b/conans/test/functional/toolchains/meson/test_cross_compilation.py
@@ -71,14 +71,8 @@ def test_apple_meson_toolchain_cross_compiling(arch, os_, os_version, sdk):
     compiler = apple-clang
     compiler.version = 12.0
     compiler.libcxx = libc++
-
-    [conf]
-    tools.apple:sdk_path={sdk_path}
     """)
 
-    xcrun = XCRun(None, sdk)
-    sdk_path = xcrun.sdk_path
-
     hello_h = gen_function_h(name="hello")
     hello_cpp = gen_function_cpp(name="hello", preprocessor=["STRING_DEFINITION"])
     app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
@@ -86,8 +80,7 @@ def test_apple_meson_toolchain_cross_compiling(arch, os_, os_version, sdk):
         os=os_,
         os_version=os_version,
         os_sdk=sdk,
-        arch=arch,
-        sdk_path=sdk_path)
+        arch=arch)
 
     t = TestClient()
     t.save({"conanfile.py": _conanfile_py,
@@ -106,6 +99,7 @@ def test_apple_meson_toolchain_cross_compiling(arch, os_, os_version, sdk):
     demo = os.path.join(t.current_folder, "build", "demo")
     assert os.path.isfile(demo) is True
 
+    xcrun = XCRun(None, sdk)
     lipo = xcrun.find('lipo')
 
     t.run_command('"%s" -info "%s"' % (lipo, libhello))
diff --git a/conans/test/functional/toolchains/meson/test_meson_and_objc.py b/conans/test/functional/toolchains/meson/test_meson_and_objc.py
index 6f657a87b..c15080b82 100644
--- a/conans/test/functional/toolchains/meson/test_meson_and_objc.py
+++ b/conans/test/functional/toolchains/meson/test_meson_and_objc.py
@@ -98,13 +98,8 @@ def test_apple_meson_toolchain_cross_compiling_and_objective_c(arch, os_, os_ver
     compiler = apple-clang
     compiler.version = 12.0
     compiler.libcxx = libc++
-
-    [conf]
-    tools.apple:sdk_path={sdk_path}
     """)
 
-    xcrun = XCRun(None, sdk)
-    sdk_path = xcrun.sdk_path
     app = textwrap.dedent("""
     #import <Foundation/Foundation.h>
 
@@ -120,8 +115,7 @@ def test_apple_meson_toolchain_cross_compiling_and_objective_c(arch, os_, os_ver
         os=os_,
         os_version=os_version,
         os_sdk=sdk,
-        arch=arch,
-        sdk_path=sdk_path)
+        arch=arch)
 
     t = TestClient()
     t.save({"conanfile.py": _conanfile_py,
@@ -136,6 +130,7 @@ def test_apple_meson_toolchain_cross_compiling_and_objective_c(arch, os_, os_ver
     demo = os.path.join(t.current_folder, "build", "demo")
     assert os.path.isfile(demo) is True
 
+    xcrun = XCRun(None, sdk)
     lipo = xcrun.find('lipo')
     t.run_command('"%s" -info "%s"' % (lipo, demo))
     assert "architecture: %s" % to_apple_arch(arch) in t.out
diff --git a/conans/test/functional/toolchains/microsoft/test_v2_msbuild_template.py b/conans/test/functional/toolchains/microsoft/test_v2_msbuild_template.py
index 779cb64ea..a356a0308 100644
--- a/conans/test/functional/toolchains/microsoft/test_v2_msbuild_template.py
+++ b/conans/test/functional/toolchains/microsoft/test_v2_msbuild_template.py
@@ -10,7 +10,7 @@ from conans.test.utils.tools import TestClient
 
 @pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows")
 def test_msbuild_lib_template():
-    client = TestClient(path_with_spaces=False)
+    client = TestClient()
     client.run("new hello/0.1 --template=msbuild_lib")
     # Local flow works
     client.run("install . -if=install")
diff --git a/conans/test/functional/toolchains/test_nmake_toolchain.py b/conans/test/functional/toolchains/test_nmake_toolchain.py
index e1a2409bf..f45b97592 100644
--- a/conans/test/functional/toolchains/test_nmake_toolchain.py
+++ b/conans/test/functional/toolchains/test_nmake_toolchain.py
@@ -8,11 +8,19 @@ 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.parametrize(
+    "compiler, version, runtime, cppstd, build_type, defines, cflags, cxxflags, sharedlinkflags, exelinkflags",
+    [
+        ("msvc", "190", "dynamic", "14", "Release", [], [], [], [], []),
+        ("msvc", "190", "dynamic", "14", "Release",
+         ["TEST_DEFINITION1", "TEST_DEFINITION2=0", "TEST_DEFINITION3=", "TEST_DEFINITION4=TestPpdValue4"],
+         ["/GL"], ["/GL"], ["/LTCG"], ["/LTCG"]),
+        ("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):
+def test_toolchain_nmake(compiler, version, runtime, cppstd, build_type,
+                         defines, cflags, cxxflags, sharedlinkflags, exelinkflags):
     client = TestClient(path_with_spaces=False)
     settings = {"compiler": compiler,
                 "compiler.version": version,
@@ -21,11 +29,31 @@ def test_toolchain_nmake(compiler, version, runtime, cppstd, build_type):
                 "build_type": build_type,
                 "arch": "x86_64"}
 
+    serialize_array = lambda arr: "[{}]".format(",".join([f"'{v}'" for v in arr]))
+    conf = {
+        "tools.build:defines": serialize_array(defines) if defines else "",
+        "tools.build:cflags": serialize_array(cflags) if cflags else "",
+        "tools.build:cxxflags": serialize_array(cxxflags) if cxxflags else "",
+        "tools.build:sharedlinkflags": serialize_array(sharedlinkflags) if sharedlinkflags else "",
+        "tools.build:exelinkflags": serialize_array(exelinkflags) if exelinkflags else "",
+    }
+
     # Build the profile according to the settings provided
     settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v)
+    conf = " ".join(f'-c {k}="{v}"' for k, v in conf.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"')
+    client.run(f'create . -tf=None {settings} {conf}')
+
+    # Rearrange defines to macro / value dict
+    conf_preprocessors = {}
+    for define in defines:
+        if "=" in define:
+            key, value = define.split("=", 1)
+            # gen_function_cpp doesn't properly handle empty macros
+            if value:
+                conf_preprocessors[key] = value
+        else:
+            conf_preprocessors[define] = "1"
 
     conanfile = textwrap.dedent("""
         from conan import ConanFile
@@ -41,17 +69,17 @@ def test_toolchain_nmake(compiler, version, runtime, cppstd, build_type):
         all: simple.exe
 
         .cpp.obj:
-          cl $(cppflags) $*.cpp
+          $(CPP) $*.cpp
 
         simple.exe: simple.obj
-          cl $(cppflags) simple.obj
+          $(CPP) simple.obj
         """)
     client.save({"conanfile.py": conanfile,
                  "makefile": makefile,
-                 "simple.cpp": gen_function_cpp(name="main", includes=["dep"], calls=["dep"])},
+                 "simple.cpp": gen_function_cpp(name="main", includes=["dep"], calls=["dep"], preprocessor=conf_preprocessors.keys())},
                 clean_first=True)
-    client.run("install . {}".format(settings))
+    client.run(f"install . {settings} {conf}")
     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)
+    check_exe_run(client.out, "main", "msvc", version, build_type, "x86_64", cppstd, conf_preprocessors)
diff --git a/conans/test/integration/cache/test_home_special_char.py b/conans/test/integration/cache/test_home_special_char.py
new file mode 100644
index 000000000..9c8ad39a7
--- /dev/null
+++ b/conans/test/integration/cache/test_home_special_char.py
@@ -0,0 +1,72 @@
+import os
+import platform
+
+import pytest
+
+from conans.test.utils.test_files import temp_folder
+from conans.test.utils.tools import TestClient
+
+import textwrap
+
+_path_chars = "päthñç$"
+
+
+@pytest.fixture(scope="module")
+def client_with_special_chars():
+    """ the path with special characters is creating a conanbuild.bat that fails
+    """
+    cache_folder = os.path.join(temp_folder(), _path_chars)
+    current_folder = os.path.join(temp_folder(), _path_chars)
+    c = TestClient(cache_folder, current_folder)
+
+    tool = textwrap.dedent(r"""
+        import os
+        from conan import ConanFile
+        from conan.tools.files import save, chdir
+        class Pkg(ConanFile):
+            name = "mytool"
+            version = "1.0"
+            def package(self):
+                with chdir(self, self.package_folder):
+                    echo = "@echo off\necho MYTOOL WORKS!!"
+                    save(self, "bin/mytool.bat", echo)
+                    save(self, "bin/mytool.sh", echo)
+                    os.chmod("bin/mytool.sh", 0o777)
+            """)
+    c.save({"conanfile.py": tool})
+    c.run("create .")
+
+    conan_file = textwrap.dedent("""
+        import platform
+        from conan import ConanFile
+
+        class App(ConanFile):
+            name="failure"
+            version="0.1"
+            settings = 'os', 'arch', 'compiler', 'build_type'
+            generators = "VirtualBuildEnv"
+            tool_requires = "mytool/1.0"
+            apply_env = False  # SUPER IMPORTANT, DO NOT REMOVE
+
+            def build(self):
+                mycmd = "mytool.bat" if platform.system() == "Windows" else "mytool.sh"
+                self.run(mycmd)
+        """)
+    c.save({"conanfile.py": conan_file})
+    return c
+
+
+def test_reuse_buildenv(client_with_special_chars):
+    c = client_with_special_chars
+    # Need the 2 profile to work correctly buildenv
+    c.run("create . -s:b build_type=Release")
+    assert _path_chars in c.out
+    assert "MYTOOL WORKS!!" in c.out
+
+
+@pytest.mark.skipif(platform.system() != "Windows", reason="powershell only win")
+def test_reuse_buildenv_powershell(client_with_special_chars):
+    c = client_with_special_chars
+    c.run("create . -s:b build_type=Release -c tools.env.virtualenv:powershell=True")
+    assert _path_chars in c.out
+    assert "MYTOOL WORKS!!" in c.out
diff --git a/conans/test/integration/command/search_test.py b/conans/test/integration/command/search_test.py
index dd3ce69ab..71e276fe8 100644
--- a/conans/test/integration/command/search_test.py
+++ b/conans/test/integration/command/search_test.py
@@ -1639,3 +1639,10 @@ class TestMixConan1and2:
         c.run("search pkg/0.1@ -r=default")
         assert "Package_ID: package_id_1X" in c.out
         assert "package_id_20" not in c.out
+
+
+def test_error_revision_search():
+    c = TestClient(default_server_user=True)
+    c.run("config set general.revisions_enabled=1")
+    c.run("search mozilla/1.0.0@ -r=default", assert_error=True)
+    assert "ERROR: Recipe not found: 'mozilla/1.0.0'. [Remote: default]" in c.out
diff --git a/conans/test/integration/configuration/conf/test_conf_profile.py b/conans/test/integration/configuration/conf/test_conf_profile.py
index c2c208665..0f55ad7eb 100644
--- a/conans/test/integration/configuration/conf/test_conf_profile.py
+++ b/conans/test/integration/configuration/conf/test_conf_profile.py
@@ -164,3 +164,36 @@ def test_msbuild_compile_options():
     client.run("install . -pr=myprofile")
     msbuild_tool = client.load("conantoolchain_release_x64.props")
     assert "<ExceptionHandling>Async</ExceptionHandling>" in msbuild_tool
+
+
+def test_config_package_append(client):
+    profile1 = textwrap.dedent("""\
+        [conf]
+        user.myteam:myconf=["a", "b", "c"]
+        """)
+    profile2 = textwrap.dedent("""\
+        include(profile1)
+        [conf]
+        mypkg*:user.myteam:myconf+=["d"]
+        mydep*:user.myteam:myconf=+["e"]
+        """)
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            def generate(self):
+                self.output.info(f"MYCONF: {self.conf.get('user.myteam:myconf')}")
+            def build(self):
+                self.output.info(f"MYCONFBUILD: {self.conf.get('user.myteam:myconf')}")
+            """)
+    client.save({"profile1": profile1,
+                 "profile2": profile2,
+                 "conanfile.py": conanfile})
+    client.run("install . mypkg/0.1@ -pr=profile2")
+    assert "conanfile.py (mypkg/0.1): MYCONF: ['a', 'b', 'c', 'd']" in client.out
+    client.run("install . mydep/0.1@ -pr=profile2")
+    assert "conanfile.py (mydep/0.1): MYCONF: ['e', 'a', 'b', 'c']" in client.out
+
+    client.run("create . mypkg/0.1@ -pr=profile2")
+    assert "mypkg/0.1: MYCONFBUILD: ['a', 'b', 'c', 'd']" in client.out
+    client.run("create . mydep/0.1@ -pr=profile2")
+    assert "mydep/0.1: MYCONFBUILD: ['e', 'a', 'b', 'c']" in client.out
diff --git a/conans/test/integration/cross_building/test_cross_build_options.py b/conans/test/integration/cross_building/test_cross_build_options.py
new file mode 100644
index 000000000..3d85188e8
--- /dev/null
+++ b/conans/test/integration/cross_building/test_cross_build_options.py
@@ -0,0 +1,33 @@
+import textwrap
+
+from conans.test.utils.tools import TestClient
+
+
+def test_cross_build_options():
+    # https://github.com/conan-io/conan/issues/8443
+    c = TestClient()
+    dep = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            name = "dep"
+            version = "0.1"
+            options = {"fPIC": [True, False]}
+            default_options = {"fPIC": True}
+            settings = "os"
+            def config_options(self):
+                if self.settings.os == "Windows":
+                    del self.options.fPIC
+            """)
+    consumer = textwrap.dedent("""
+        from conan import ConanFile
+        class Consumer(ConanFile):
+            requires = "dep/0.1"
+            tool_requires = "dep/0.1"
+        """)
+    c.save({"dep/conanfile.py": dep,
+            "consumer/conanfile.py": consumer})
+    c.run("create dep -s os=Android -s os.api_level=22")
+    c.run("create dep -s os=Windows")
+    c.run("install consumer -s:b os=Windows -s:h os=Android -s:h os.api_level=22")
+    assert "dep/0.1:0e4b89e69f340b0e6f4b08523b5215bacf5eae3e - Cache" in c.out
+    assert "dep/0.1:3475bd55b91ae904ac96fde0f106a136ab951a5e - Cache" in c.out
diff --git a/conans/test/integration/environment/test_env.py b/conans/test/integration/environment/test_env.py
index 334936ae8..0b3ef5ecf 100644
--- a/conans/test/integration/environment/test_env.py
+++ b/conans/test/integration/environment/test_env.py
@@ -720,3 +720,48 @@ def test_error_with_dots_virtualenv():
     client.run("create dep -s arch=armv8.3")
     client.run("create consumer -s arch=armv8.3")
     assert "DUMMY=123456" in client.out
+
+
+def test_runenv_info_propagated():
+    """
+    A runenv_info in a recipe, which is required by an executable that is used
+    in another place as a tool_require (also its own test_package), should be
+    propagated
+    test_package --(tool_requires)->tools-(requires)->lib(defines runenv_info)
+    https://github.com/conan-io/conan/issues/12939
+    """
+    c = TestClient()
+    lib = textwrap.dedent("""
+        from conan import ConanFile
+        class Lib(ConanFile):
+            name = "lib"
+            version = "0.1"
+            settings = "build_type"
+            def package_info(self):
+                self.runenv_info.define("MYLIBVAR", f"MYLIBVALUE:{self.settings.build_type}")
+        """)
+    tool_test_package = textwrap.dedent("""
+        import platform
+        from conan import ConanFile
+        class TestTool(ConanFile):
+            settings = "build_type"
+            test_type = "explicit"
+            generators = "VirtualBuildEnv"
+            def build_requirements(self):
+                self.tool_requires(self.tested_reference_str)
+            def build(self):
+                self.output.info(f"Building TEST_PACKAGE IN {self.settings.build_type}!!")
+                if platform.system()!= "Windows":
+                    self.run("echo MYLIBVAR=$MYLIBVAR")
+                else:
+                    self.run("set MYLIBVAR")
+            def test(self):
+                pass
+        """)
+    c.save({"lib/conanfile.py": lib,
+            "tool/conanfile.py": GenConanfile("tool", "0.1").with_requires("lib/0.1"),
+            "tool/test_package/conanfile.py": tool_test_package})
+    c.run("create lib -s build_type=Release")
+    c.run("create tool --build-require -s:b build_type=Release -s:h build_type=Debug")
+    assert "tool/0.1 (test package): Building TEST_PACKAGE IN Debug!!" in c.out
+    assert "MYLIBVAR=MYLIBVALUE:Release" in c.out
diff --git a/conans/test/integration/generators/package_info/package_info_test.py b/conans/test/integration/generators/package_info/package_info_test.py
index 3b4df5c2d..20e2bdcde 100644
--- a/conans/test/integration/generators/package_info/package_info_test.py
+++ b/conans/test/integration/generators/package_info/package_info_test.py
@@ -391,59 +391,6 @@ class HelloConan(ConanFile):
         client.run("create conanfile1.py")
         client.run("create conanfile2.py")
 
-        conanfile = GenConanfile("consumer", "0.1") \
-            .with_requirement("dep1/0.1") \
-            .with_requirement("dep2/0.1") \
-            .with_package_info(cpp_info={"components": {"kk": {"requires": []}}},
-                               env_info={})
-        client.save({"conanfile.py": conanfile})
-        client.run("create conanfile.py", assert_error=True)
-        self.assertIn("consumer/0.1 package_info(): Package require 'dep1' not used in "
-                      "components requires", client.out)
-
-        conanfile = GenConanfile("consumer", "0.1") \
-            .with_requirement("dep1/0.1") \
-            .with_requirement("dep2/0.1") \
-            .with_package_info(cpp_info={"components": {"kk": {"requires": ["dep1::dep1"]}}},
-                               env_info={})
-        client.save({"conanfile.py": conanfile})
-        client.run("create conanfile.py", assert_error=True)
-        self.assertIn("consumer/0.1 package_info(): Package require 'dep2' not used in components "
-                      "requires", client.out)
-
-        conanfile = GenConanfile("consumer", "0.1") \
-            .with_requirement("dep1/0.1") \
-            .with_requirement("dep2/0.1") \
-            .with_package_info(cpp_info={"components": {"kk": {"requires": ["dep1::dep1"]},
-                                                        "kkk": {"requires": ["kk"]}}},
-                               env_info={})
-        client.save({"conanfile.py": conanfile})
-        client.run("create conanfile.py", assert_error=True)
-        self.assertIn("consumer/0.1 package_info(): Package require 'dep2' not used in components "
-                      "requires", client.out)
-
-        conanfile = GenConanfile("consumer", "0.1") \
-            .with_requirement("dep1/0.1") \
-            .with_requirement("dep2/0.1") \
-            .with_package_info(cpp_info={"components": {"kk": {"requires": []},
-                                                        "kkk": {"requires": ["kk"]}}},
-                               env_info={})
-        client.save({"conanfile.py": conanfile})
-        client.run("create conanfile.py", assert_error=True)
-        self.assertIn("consumer/0.1 package_info(): Package require 'dep1' not used in components "
-                      "requires", client.out)
-
-        conanfile = GenConanfile("consumer", "0.1") \
-            .with_requirement("dep1/0.1") \
-            .with_requirement("dep2/0.1") \
-            .with_package_info(cpp_info={"components": {"kk": {"requires": ["dep2::comp"]},
-                                                        "kkk": {"requires": ["dep3::dep3"]}}},
-                               env_info={})
-        client.save({"conanfile.py": conanfile})
-        client.run("create conanfile.py", assert_error=True)
-        self.assertIn("consumer/0.1 package_info(): Package require 'dep1' not used in components "
-                      "requires", client.out)
-
         conanfile = GenConanfile("consumer", "0.1") \
             .with_requirement("dep2/0.1") \
             .with_package_info(cpp_info={"components": {"kk": {"requires": ["dep2::comp"]},
diff --git a/conans/test/integration/py_requires/python_requires_test.py b/conans/test/integration/py_requires/python_requires_test.py
index c2d5bab40..174f92ad1 100644
--- a/conans/test/integration/py_requires/python_requires_test.py
+++ b/conans/test/integration/py_requires/python_requires_test.py
@@ -1020,3 +1020,103 @@ def test_multiple_reuse():
     c.run("install consumer")
     assert "VALUE COMMON: 42!!!" in c.out
     assert "VALUE TOOL: 42!!!" in c.out
+
+
+class TestTransitiveExtend:
+    # https://github.com/conan-io/conan/issues/10511
+    # https://github.com/conan-io/conan/issues/10565
+    def test_transitive_extend(self):
+        client = TestClient()
+        company = textwrap.dedent("""
+            from conan import ConanFile
+            class CompanyConanFile(ConanFile):
+                name = "company"
+                version = "1.0"
+
+                def msg1(self):
+                    return "company"
+                def msg2(self):
+                    return "company"
+            """)
+        project = textwrap.dedent("""
+            from conan import ConanFile
+            class ProjectBaseConanFile(ConanFile):
+                name = "project"
+                version = "1.0"
+
+                python_requires = "company/1.0"
+                python_requires_extend = "company.CompanyConanFile"
+
+                def msg1(self):
+                    return "project"
+            """)
+        consumer = textwrap.dedent("""
+            from conan import ConanFile
+            class Base(ConanFile):
+                name = "consumer"
+                version = "1.0"
+                python_requires = "project/1.0"
+                python_requires_extend = "project.ProjectBaseConanFile"
+                def generate(self):
+                    self.output.info("Msg1:{}!!!".format(self.msg1()))
+                    self.output.info("Msg2:{}!!!".format(self.msg2()))
+                """)
+        client.save({"company/conanfile.py": company,
+                     "project/conanfile.py": project,
+                     "consumer/conanfile.py": consumer})
+        client.run("export company")
+        client.run("export project")
+        client.run("install consumer")
+        assert "conanfile.py (consumer/1.0): Msg1:project!!!" in client.out
+        assert "conanfile.py (consumer/1.0): Msg2:company!!!" in client.out
+
+    def test_transitive_extend2(self):
+        client = TestClient()
+        company = textwrap.dedent("""
+            from conan import ConanFile
+            class CompanyConanFile(ConanFile):
+                name = "company"
+                version = "1.0"
+
+            class CompanyBase:
+                def msg1(self):
+                    return "company"
+                def msg2(self):
+                    return "company"
+            """)
+        project = textwrap.dedent("""
+            from conan import ConanFile
+            class ProjectBase:
+                def msg1(self):
+                    return "project"
+
+            class ProjectBaseConanFile(ConanFile):
+                name = "project"
+                version = "1.0"
+                python_requires = "company/1.0"
+
+                def init(self):
+                    pkg_name, base_class_name = "company", "CompanyBase"
+                    base_class = getattr(self.python_requires[pkg_name].module, base_class_name)
+                    global ProjectBase
+                    ProjectBase = type('ProjectBase', (ProjectBase, base_class, object), {})
+            """)
+        consumer = textwrap.dedent("""
+            from conan import ConanFile
+            class Base(ConanFile):
+                name = "consumer"
+                version = "1.0"
+                python_requires = "project/1.0"
+                python_requires_extend = "project.ProjectBase"
+                def generate(self):
+                    self.output.info("Msg1:{}!!!".format(self.msg1()))
+                    self.output.info("Msg2:{}!!!".format(self.msg2()))
+                """)
+        client.save({"company/conanfile.py": company,
+                     "project/conanfile.py": project,
+                     "consumer/conanfile.py": consumer})
+        client.run("export company")
+        client.run("export project")
+        client.run("install consumer")
+        assert "conanfile.py (consumer/1.0): Msg1:project!!!" in client.out
+        assert "conanfile.py (consumer/1.0): Msg2:company!!!" in client.out
diff --git a/conans/test/integration/test_components.py b/conans/test/integration/test_components.py
index 202dae8d3..822f936e5 100644
--- a/conans/test/integration/test_components.py
+++ b/conans/test/integration/test_components.py
@@ -1,5 +1,6 @@
 import textwrap
 
+from conans.test.assets.genconanfile import GenConanfile
 from conans.test.utils.tools import TestClient
 
 
@@ -23,3 +24,27 @@ def test_components_cycles():
     assert "a requires c"
     assert "b requires a"
     assert "c rquires b"
+
+
+def test_components_not_required():
+    """
+    Allow requiring and building against one component, but not propagating it
+    https://github.com/conan-io/conan/issues/12965
+    """
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+
+        class TestcycleConan(ConanFile):
+            name = "wayland"
+            version = "1.0"
+            requires = "expat/1.0"
+
+            def package_info(self):
+                self.cpp_info.components["wayland-scanner"].libdirs = []
+        """)
+    c.save({"expat/conanfile.py": GenConanfile("expat", "1.0"),
+            "wayland/conanfile.py": conanfile})
+    c.run("create expat")
+    c.run("create wayland")
+    assert "wayland/1.0: Created package" in c.out
diff --git a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 38a793f42..bc389df5c 100644
--- a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -399,40 +399,63 @@ def test_cmake_presets_multiconfig():
 
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=Release --profile:h=profile")
     presets = json.loads(client.load("CMakePresets.json"))
+    assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 1
     assert presets["buildPresets"][0]["configuration"] == "Release"
+    assert len(presets["testPresets"]) == 1
+    assert presets["testPresets"][0]["configuration"] == "Release"
 
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=Debug --profile:h=profile")
     presets = json.loads(client.load("CMakePresets.json"))
+    assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 2
     assert presets["buildPresets"][0]["configuration"] == "Release"
     assert presets["buildPresets"][1]["configuration"] == "Debug"
+    assert len(presets["testPresets"]) == 2
+    assert presets["testPresets"][0]["configuration"] == "Release"
+    assert presets["testPresets"][1]["configuration"] == "Debug"
 
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=RelWithDebInfo "
                "--profile:h=profile")
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=MinSizeRel --profile:h=profile")
     presets = json.loads(client.load("CMakePresets.json"))
+    assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 4
     assert presets["buildPresets"][0]["configuration"] == "Release"
     assert presets["buildPresets"][1]["configuration"] == "Debug"
     assert presets["buildPresets"][2]["configuration"] == "RelWithDebInfo"
     assert presets["buildPresets"][3]["configuration"] == "MinSizeRel"
+    assert len(presets["testPresets"]) == 4
+    assert presets["testPresets"][0]["configuration"] == "Release"
+    assert presets["testPresets"][1]["configuration"] == "Debug"
+    assert presets["testPresets"][2]["configuration"] == "RelWithDebInfo"
+    assert presets["testPresets"][3]["configuration"] == "MinSizeRel"
 
     # Repeat one
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=Debug --profile:h=profile")
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=Debug --profile:h=profile")
     presets = json.loads(client.load("CMakePresets.json"))
+    assert len(presets["configurePresets"]) == 1
     assert len(presets["buildPresets"]) == 4
     assert presets["buildPresets"][0]["configuration"] == "Release"
     assert presets["buildPresets"][1]["configuration"] == "Debug"
     assert presets["buildPresets"][2]["configuration"] == "RelWithDebInfo"
     assert presets["buildPresets"][3]["configuration"] == "MinSizeRel"
 
+    assert len(presets["testPresets"]) == 4
+    assert presets["testPresets"][0]["configuration"] == "Release"
+    assert presets["testPresets"][1]["configuration"] == "Debug"
+    assert presets["testPresets"][2]["configuration"] == "RelWithDebInfo"
+    assert presets["testPresets"][3]["configuration"] == "MinSizeRel"
+
     assert len(presets["configurePresets"]) == 1
     assert presets["configurePresets"][0]["name"] == "default"
 
 
 def test_cmake_presets_singleconfig():
+    """ without defining a layout, single config always overwrites
+    the existing CMakePresets.json
+    """
     client = TestClient()
     profile = textwrap.dedent("""
         [settings]
@@ -453,19 +476,25 @@ def test_cmake_presets_singleconfig():
     assert len(presets["buildPresets"]) == 1
     assert presets["buildPresets"][0]["configurePreset"] == "release"
 
-    # Now two configurePreset, but named correctly
+    assert len(presets["testPresets"]) == 1
+    assert presets["testPresets"][0]["configurePreset"] == "release"
+
+    # This overwrites the existing profile, as there is no layout
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=Debug --profile:h=profile")
     presets = json.loads(client.load("CMakePresets.json"))
-    assert len(presets["configurePresets"]) == 2
-    assert presets["configurePresets"][1]["name"] == "debug"
+    assert len(presets["configurePresets"]) == 1
+    assert presets["configurePresets"][0]["name"] == "debug"
 
-    assert len(presets["buildPresets"]) == 2
-    assert presets["buildPresets"][1]["configurePreset"] == "debug"
+    assert len(presets["buildPresets"]) == 1
+    assert presets["buildPresets"][0]["configurePreset"] == "debug"
+
+    assert len(presets["testPresets"]) == 1
+    assert presets["testPresets"][0]["configurePreset"] == "debug"
 
     # Repeat configuration, it shouldn't add a new one
     client.run("install mylib/1.0@ -g CMakeToolchain -s build_type=Debug --profile:h=profile")
     presets = json.loads(client.load("CMakePresets.json"))
-    assert len(presets["configurePresets"]) == 2
+    assert len(presets["configurePresets"]) == 1
 
 
 def test_toolchain_cache_variables():
@@ -561,7 +590,8 @@ def test_user_presets_version2():
 
             """)
     client.save({"conanfile.py": conanfile, "CMakeLists.txt": "foo"})
-    configs = ["-c tools.cmake.cmaketoolchain.presets:max_schema_version=2 ",
+    configs = ["-c tools.cmake.cmaketoolchain:generator=Ninja",
+               "-c tools.cmake.cmaketoolchain.presets:max_schema_version=2 ",
                "-c tools.cmake.cmake_layout:build_folder_vars='[\"settings.compiler.cppstd\"]'"]
     client.run("install . {} -s compiler.cppstd=14".format(" ".join(configs)))
     client.run("install . {} -s compiler.cppstd=17".format(" ".join(configs)))
@@ -569,10 +599,10 @@ def test_user_presets_version2():
     presets = json.loads(client.load("CMakeUserPresets.json"))
     assert len(presets["configurePresets"]) == 2
     assert presets["version"] == 2
-    assert "build/14/generators/conan_toolchain.cmake" \
+    assert "build/14/Release/generators/conan_toolchain.cmake" \
            in presets["configurePresets"][0]["cacheVariables"]["CMAKE_TOOLCHAIN_FILE"].replace("\\",
                                                                                                "/")
-    assert "build/17/generators/conan_toolchain.cmake" \
+    assert "build/17/Release/generators/conan_toolchain.cmake" \
            in presets["configurePresets"][1]["cacheVariables"]["CMAKE_TOOLCHAIN_FILE"].replace("\\",
                                                                                                "/")
 
@@ -729,7 +759,7 @@ def test_presets_ninja_msvc(arch, arch_toolset):
            "-s compiler.runtime_type=Release"
     client.run("install . {} -s compiler.cppstd=14 {} -s arch={}".format(" ".join(configs), msvc, arch))
 
-    presets = json.loads(client.load("build/14/generators/CMakePresets.json"))
+    presets = json.loads(client.load("build/14/Release/generators/CMakePresets.json"))
 
     toolset_value = {"x86_64": "host=x86_64", "x86": "x86"}.get(arch_toolset)
     arch_value = {"x86_64": "x64", "x86": "x86"}.get(arch)
@@ -757,7 +787,7 @@ def test_presets_ninja_msvc(arch, arch_toolset):
 
     client.run(
         "install . {} -s compiler.cppstd=14 {} -s arch={}".format(" ".join(configs), msvc, arch))
-    presets = json.loads(client.load("build/14/generators/CMakePresets.json"))
+    presets = json.loads(client.load("build/14/Release/generators/CMakePresets.json"))
     assert "architecture" in presets["configurePresets"][0]
     assert "toolset" not in presets["configurePresets"][0]
 
@@ -876,6 +906,92 @@ def test_cmake_layout_toolchain_folder():
     c.run("install . -s os=Linux -s compiler=gcc -s compiler.version=7 -s build_type=Debug "
           "-s compiler.libcxx=libstdc++11 -s arch=x86 "
           "-c tools.cmake.cmake_layout:build_folder_vars='[\"settings.arch\", \"settings.build_type\"]'")
-    print(c.out)
     assert os.path.exists(os.path.join(c.current_folder,
                                        "build/x86-debug/generators/conan_toolchain.cmake"))
+    c.run("install . -s os=Linux -s compiler=gcc -s compiler.version=7 -s build_type=Debug "
+          "-s compiler.libcxx=libstdc++11 -s arch=x86 "
+          "-c tools.cmake.cmake_layout:build_folder_vars='[\"settings.os\"]'")
+    assert os.path.exists(os.path.join(c.current_folder,
+                                       "build/linux/Debug/generators/conan_toolchain.cmake"))
+
+
+def test_set_linker_scripts():
+    profile = textwrap.dedent(r"""
+    [settings]
+    os=Windows
+    arch=x86_64
+    compiler=clang
+    compiler.version=15
+    compiler.libcxx=libstdc++11
+    [conf]
+    tools.build:linker_scripts=["/usr/local/src/flash.ld", "C:\\local\\extra_data.ld"]
+    """)
+    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 'string(APPEND CONAN_EXE_LINKER_FLAGS -T"/usr/local/src/flash.ld" -T"C:/local/extra_data.ld")' in toolchain
+
+
+def test_test_package_layout():
+    """
+    test that the ``test_package`` folder also follows the cmake_layout and the
+    build_folder_vars
+    """
+    client = TestClient()
+    test_conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import cmake_layout
+
+        class Conan(ConanFile):
+            settings = "os", "arch", "compiler", "build_type"
+            generators = "CMakeToolchain"
+            test_type = "explicit"
+
+            def requirements(self):
+                self.requires(self.tested_reference_str)
+
+            def layout(self):
+                cmake_layout(self)
+
+            def test(self):
+                pass
+    """)
+    client.save({"conanfile.py": GenConanfile("pkg", "0.1"),
+                 "test_package/conanfile.py": test_conanfile})
+    config = "-c tools.cmake.cmake_layout:build_folder_vars='[\"settings.compiler.cppstd\"]'"
+    client.run(f"create . {config} -s compiler.cppstd=14")
+    client.run(f"create . {config} -s compiler.cppstd=17")
+    assert os.path.exists(os.path.join(client.current_folder, "test_package/build/14"))
+    assert os.path.exists(os.path.join(client.current_folder, "test_package/build/17"))
+
+
+def test_presets_not_found_error_msg():
+    client = TestClient()
+    test_conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import cmake_layout, CMake
+
+        class Conan(ConanFile):
+            settings = "build_type"
+            generators = "CMakeDeps"
+            test_type = "explicit"
+
+            def requirements(self):
+                self.requires(self.tested_reference_str)
+
+            def build(self):
+                CMake(self).configure()
+
+            def test(self):
+                pass
+    """)
+    client.save({"conanfile.py": GenConanfile("pkg", "0.1"),
+                 "test_package/conanfile.py": test_conanfile})
+    client.run("create .", assert_error=True)
+    assert "CMakePresets.json was not found" in client.out
+    assert "Check that you are using CMakeToolchain as generator " \
+           "to ensure its correct initialization." in client.out
diff --git a/conans/test/integration/toolchains/env/test_virtualenv_powershell.py b/conans/test/integration/toolchains/env/test_virtualenv_powershell.py
index 4aa80ef0e..00f36f7fa 100644
--- a/conans/test/integration/toolchains/env/test_virtualenv_powershell.py
+++ b/conans/test/integration/toolchains/env/test_virtualenv_powershell.py
@@ -14,6 +14,7 @@ from conans.tools import save
 def client():
     # We use special characters and spaces, to check everything works
     # https://github.com/conan-io/conan/issues/12648
+    # FIXME: This path still fails the creation of the deactivation script
     cache_folder = os.path.join(temp_folder(), "[sub] folder")
     client = TestClient(cache_folder)
     conanfile = str(GenConanfile("pkg", "0.1"))
@@ -40,6 +41,7 @@ def test_virtualenv(client):
             name = "app"
             version = "0.1"
             requires = "pkg/0.1"
+            apply_env = False
 
             def build(self):
                 self.output.info("----------BUILD----------------")
diff --git a/conans/test/integration/toolchains/gnu/test_autotoolstoolchain.py b/conans/test/integration/toolchains/gnu/test_autotoolstoolchain.py
index 9c91d3c8e..4bc28f2fe 100644
--- a/conans/test/integration/toolchains/gnu/test_autotoolstoolchain.py
+++ b/conans/test/integration/toolchains/gnu/test_autotoolstoolchain.py
@@ -45,6 +45,36 @@ def test_extra_flags_via_conf():
         assert 'export LDFLAGS="$LDFLAGS --flag5 --flag6"' in toolchain
 
 
+def test_linker_scripts_via_conf():
+    os_ = platform.system()
+    os_ = "Macos" if os_ == "Darwin" else os_
+
+    profile = textwrap.dedent("""
+        [settings]
+        os=%s
+        compiler=gcc
+        compiler.version=6
+        compiler.libcxx=libstdc++11
+        arch=armv8
+        build_type=Release
+
+        [conf]
+        tools.build:sharedlinkflags+=["--flag5"]
+        tools.build:exelinkflags+=["--flag6"]
+        tools.build:linker_scripts+=["/linker/scripts/flash.ld", "/linker/scripts/extra_data.ld"]
+        """ % os_)
+    client = TestClient()
+    conanfile = GenConanfile().with_settings("os", "arch", "compiler", "build_type")\
+        .with_generator("AutotoolsToolchain")
+    client.save({"conanfile.py": conanfile,
+                "profile": profile})
+    client.run("install . --profile:build=profile --profile:host=profile")
+    toolchain = client.load("conanautotoolstoolchain{}".format('.bat' if os_ == "Windows" else '.sh'))
+    if os_ == "Windows":
+        assert 'set "LDFLAGS=%LDFLAGS% --flag5 --flag6 -T\'/linker/scripts/flash.ld\' -T\'/linker/scripts/extra_data.ld\'"' in toolchain
+    else:
+        assert 'export LDFLAGS="$LDFLAGS --flag5 --flag6 -T\'/linker/scripts/flash.ld\' -T\'/linker/scripts/extra_data.ld\'"' in toolchain
+
 def test_not_none_values():
 
     conanfile = textwrap.dedent("""
diff --git a/conans/test/integration/toolchains/meson/test_mesontoolchain.py b/conans/test/integration/toolchains/meson/test_mesontoolchain.py
index 7a1932fb9..d360c1706 100644
--- a/conans/test/integration/toolchains/meson/test_mesontoolchain.py
+++ b/conans/test/integration/toolchains/meson/test_mesontoolchain.py
@@ -92,6 +92,35 @@ def test_extra_flags_via_conf():
     assert "cpp_link_args = ['-flag0', '-other=val', '-flag5', '-flag6']" in content
 
 
+def test_linker_scripts_via_conf():
+    profile = textwrap.dedent("""
+        [settings]
+        os=Windows
+        arch=x86_64
+        compiler=gcc
+        compiler.version=9
+        compiler.cppstd=17
+        compiler.libcxx=libstdc++
+        build_type=Release
+
+        [buildenv]
+        LDFLAGS=-flag0 -other=val
+
+        [conf]
+        tools.build:sharedlinkflags+=["-flag5"]
+        tools.build:exelinkflags+=["-flag6"]
+        tools.build:linker_scripts+=["/linker/scripts/flash.ld", "/linker/scripts/extra_data.ld"]
+   """)
+    t = TestClient()
+    t.save({"conanfile.txt": "[generators]\nMesonToolchain",
+            "profile": profile})
+
+    t.run("install . -pr=profile")
+    content = t.load(MesonToolchain.native_filename)
+    assert "c_link_args = ['-flag0', '-other=val', '-flag5', '-flag6', '-T\"/linker/scripts/flash.ld\"', '-T\"/linker/scripts/extra_data.ld\"']" in content
+    assert "cpp_link_args = ['-flag0', '-other=val', '-flag5', '-flag6', '-T\"/linker/scripts/flash.ld\"', '-T\"/linker/scripts/extra_data.ld\"']" in content
+
+
 def test_correct_quotes():
     profile = textwrap.dedent("""
        [settings]
diff --git a/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py b/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py
index 32f40c7c2..4fad84f40 100644
--- a/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py
+++ b/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py
@@ -17,7 +17,7 @@ from conans.test.utils.tools import TestClient
     ],
 )
 def test_msbuilddeps_maps_architecture_to_platform(arch, exp_platform):
-    client = TestClient(path_with_spaces=False)
+    client = TestClient()
     client.run("new hello/0.1 --template=msbuild_lib")
     client.run(f"install . -g MSBuildDeps -s arch={arch} -pr:b=default -if=install")
     toolchain = client.load(os.path.join("conan", "conantoolchain.props"))
diff --git a/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py b/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py
index 9432f4b51..94fb45739 100644
--- a/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py
+++ b/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py
@@ -20,7 +20,7 @@ def test_msbuildtoolchain_props_with_extra_flags():
     tools.build:exelinkflags+=["--flag6"]
     tools.build:defines+=["DEF1", "DEF2"]
     """)
-    client = TestClient(path_with_spaces=False)
+    client = TestClient()
     client.run("new hello/0.1 --template=msbuild_lib")
     client.save({
         "myprofile": profile
diff --git a/conans/test/integration/toolchains/microsoft/test_nmakedeps.py b/conans/test/integration/toolchains/microsoft/test_nmakedeps.py
new file mode 100644
index 000000000..3cf032512
--- /dev/null
+++ b/conans/test/integration/toolchains/microsoft/test_nmakedeps.py
@@ -0,0 +1,46 @@
+import platform
+import re
+import textwrap
+
+import pytest
+
+from conans.test.utils.tools import TestClient
+
+
+@pytest.mark.skipif(platform.system() != "Windows", reason="Only for windows")
+def test_nmakedeps():
+    client = TestClient()
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            settings = "os", "arch", "compiler", "build_type"
+            name = "test-nmakedeps"
+            version = "1.0"
+
+            def package_info(self):
+                self.cpp_info.components["pkg-1"].libs = ["pkg-1"]
+                self.cpp_info.components["pkg-1"].defines = ["TEST_DEFINITION1"]
+                self.cpp_info.components["pkg-1"].system_libs = ["ws2_32"]
+                self.cpp_info.components["pkg-2"].libs = ["pkg-2"]
+                self.cpp_info.components["pkg-2"].defines = ["TEST_DEFINITION2=0"]
+                self.cpp_info.components["pkg-2"].requires = ["pkg-1"]
+                self.cpp_info.components["pkg-3"].libs = ["pkg-3"]
+                self.cpp_info.components["pkg-3"].defines = ["TEST_DEFINITION3="]
+                self.cpp_info.components["pkg-3"].requires = ["pkg-1", "pkg-2"]
+                self.cpp_info.components["pkg-4"].libs = ["pkg-4"]
+                self.cpp_info.components["pkg-4"].defines = ["TEST_DEFINITION4=foo"]
+    """)
+    client.save({"conanfile.py": conanfile})
+    client.run("create . -s arch=x86_64")
+    client.run("install test-nmakedeps/1.0@ -g NMakeDeps -s build_type=Release -s arch=x86_64")
+    # Checking that NMakeDeps builds correctly .bat file
+    bat_file = client.load("conannmakedeps.bat")
+    # Checking that defines are added to CL
+    for flag in (
+        r"/DTEST_DEFINITION1", r"/DTEST_DEFINITION2#0",
+        r"/DTEST_DEFINITION3#", r'/DTEST_DEFINITION4#\\"foo\\"',
+    ):
+        assert re.search(fr'set "CL=%CL%.*\s{flag}(?:\s|")', bat_file)
+    # Checking that libs and system libs are added to _LINK_
+    for flag in (r"pkg-1\.lib", r"pkg-2\.lib", r"pkg-3\.lib", r"pkg-4\.lib", r"ws2_32\.lib"):
+        assert re.search(fr'set "_LINK_=%_LINK_%.*\s{flag}(?:\s|")', bat_file)
diff --git a/conans/test/integration/toolchains/microsoft/vcvars_test.py b/conans/test/integration/toolchains/microsoft/vcvars_test.py
index 27db87bbd..fb6779ab8 100644
--- a/conans/test/integration/toolchains/microsoft/vcvars_test.py
+++ b/conans/test/integration/toolchains/microsoft/vcvars_test.py
@@ -4,6 +4,7 @@ import os
 
 import pytest
 
+from conans.test.assets.genconanfile import GenConanfile
 from conans.test.utils.tools import TestClient
 
 
@@ -36,6 +37,23 @@ def test_vcvars_generator(scope):
         assert not os.path.exists(os.path.join(client.current_folder, "conanbuild.bat"))
 
 
+@pytest.mark.skipif(platform.system() not in ["Windows"], reason="Requires Windows")
+def test_vcvars_generator_skip():
+    """
+    tools.microsoft.msbuild:installation_path=disabled avoids creation of conanvcvars.bat
+    """
+    client = TestClient()
+    client.save({"conanfile.py": GenConanfile().with_generator("VCVars")
+                                               .with_settings("os", "compiler",
+                                                              "arch", "build_type"),
+                 "profile": 'include(default)\n[conf]\ntools.microsoft.msbuild:installation_path='})
+
+    client.run('install . -c tools.microsoft.msbuild:installation_path=""')
+    assert not os.path.exists(os.path.join(client.current_folder, "conanvcvars.bat"))
+    client.run('install . -pr=profile')
+    assert not os.path.exists(os.path.join(client.current_folder, "conanvcvars.bat"))
+
+
 @pytest.mark.skipif(platform.system() not in ["Windows"], reason="Requires Windows")
 def test_vcvars_generator_string():
     client = TestClient(path_with_spaces=False)
diff --git a/conans/test/unittests/tools/android/__init__.py b/conans/test/unittests/tools/android/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/conans/test/unittests/tools/android/test_android_tools.py b/conans/test/unittests/tools/android/test_android_tools.py
new file mode 100644
index 000000000..038bd0b46
--- /dev/null
+++ b/conans/test/unittests/tools/android/test_android_tools.py
@@ -0,0 +1,79 @@
+from conans.test.utils.mocks import ConanFileMock, MockSettings
+from conans.errors import ConanException
+from conan.tools.android import android_abi
+
+from pytest import raises
+
+def test_tools_android_abi():
+    settings_linux = MockSettings({"os": "Linux", "arch": "foo"})
+
+    for (arch, expected) in [
+        ("armv5el", "armeabi"),
+        ("armv5hf", "armeabi"),
+        ("armv5", "armeabi"),
+        ("armv6", "armeabi-v6"),
+        ("armv7", "armeabi-v7a"),
+        ("armv7hf", "armeabi-v7a"),
+        ("armv8", "arm64-v8a"),
+        ("x86", "x86"),
+        ("x86_64", "x86_64"),
+        ("mips", "mips"),
+        ("mips_64", "mips_64"),
+    ]:
+        conanfile = ConanFileMock()
+        settings_android = MockSettings({"os": "Android", "arch": arch})
+
+        # 1 profile (legacy native build)
+        conanfile.settings = settings_android
+        assert android_abi(conanfile) == expected
+        assert android_abi(conanfile, context="host") == expected
+
+        with raises(ConanException):
+            assert android_abi(conanfile, context="build") == expected
+
+        with raises(ConanException):
+            assert android_abi(conanfile, context="target") == expected
+
+        # 2 profiles
+        ## native build
+        conanfile.settings = settings_android
+        conanfile.settings_host = settings_android
+        conanfile.settings_build = settings_android
+        assert android_abi(conanfile) == expected
+        assert android_abi(conanfile, context="host") == expected
+        assert android_abi(conanfile, context="build") == expected
+
+        with raises(ConanException):
+            assert android_abi(conanfile, context="target") == expected
+
+        ## cross-build from Android to Linux (quite hypothetical)
+        conanfile.settings = settings_linux
+        conanfile.settings_host = settings_linux
+        conanfile.settings_build = settings_android
+        assert android_abi(conanfile) != expected
+        assert android_abi(conanfile, context="host") != expected
+        assert android_abi(conanfile, context="build") == expected
+
+        with raises(ConanException):
+            assert android_abi(conanfile, context="target")
+
+        ## cross-build a recipe from Linux to Android:
+        ### test android_abi in recipe itself
+        conanfile.settings = settings_android
+        conanfile.settings_host = settings_android
+        conanfile.settings_build = settings_linux
+        assert android_abi(conanfile) == expected
+        assert android_abi(conanfile, context="host") == expected
+        assert android_abi(conanfile, context="build") != expected
+        with raises(ConanException):
+            android_abi(conanfile, context="target")
+
+        ### test android_abi in "compiler recipe" (ie a android-ndk recipe in tool_requires of recipe being cross-build)
+        conanfile.settings = settings_linux
+        conanfile.settings_host = settings_linux
+        conanfile.settings_build = settings_linux
+        conanfile.settings_target = settings_android
+        assert android_abi(conanfile) != expected
+        assert android_abi(conanfile, context="host") != expected
+        assert android_abi(conanfile, context="build") != expected
+        assert android_abi(conanfile, context="target") == expected
diff --git a/conans/test/unittests/tools/apple/test_apple_tools.py b/conans/test/unittests/tools/apple/test_apple_tools.py
index 78dd0e93d..18622458a 100644
--- a/conans/test/unittests/tools/apple/test_apple_tools.py
+++ b/conans/test/unittests/tools/apple/test_apple_tools.py
@@ -1,8 +1,11 @@
+import mock
 import pytest
+import textwrap
 
 from conans.test.utils.mocks import ConanFileMock, MockSettings
 from conans.test.utils.test_files import temp_folder
 from conan.tools.apple import is_apple_os, to_apple_arch, fix_apple_shared_install_name, XCRun
+from conan.tools.apple.apple import _get_dylib_install_name # testing private function
 
 def test_tools_apple_is_apple_os():
     conanfile = ConanFileMock()
@@ -48,3 +51,23 @@ def test_xcrun_public_settings():
     settings = xcrun.settings
 
     assert settings.os == "watchOS"
+
+def test_get_dylib_install_name():
+    # https://github.com/conan-io/conan/issues/13014
+    single_arch = textwrap.dedent("""
+    /path/to/libwebp.7.dylib:
+    /absolute/path/lib/libwebp.7.dylib
+    """)
+
+    universal_binary = textwrap.dedent("""
+    /.conan/data/package/lib/libwebp.7.dylib (architecture x86_64):
+    /absolute/path/lib/libwebp.7.dylib
+    /.conan/data/package/lib/libwebp.7.dylib (architecture arm64):
+    /absolute/path/lib/libwebp.7.dylib
+    """)
+
+    for mock_output in (single_arch, universal_binary):
+        with mock.patch("conan.tools.apple.apple.check_output_runner") as mock_output_runner:
+            mock_output_runner.return_value = mock_output
+            install_name = _get_dylib_install_name("/path/to/libwebp.7.dylib")
+            assert "/absolute/path/lib/libwebp.7.dylib" == install_name
diff --git a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
index d66be8732..25776873e 100644
--- a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
+++ b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
@@ -505,3 +505,10 @@ def test_compilers_block(conanfile):
     content = toolchain.content
     for compiler, lang in cmake_mapping.items():
         assert f'set(CMAKE_{lang}_COMPILER "path_to_{compiler}")' in content
+
+
+def test_linker_scripts_block(conanfile):
+    conanfile.conf.define("tools.build:linker_scripts", ["path_to_first_linker_script", "path_to_second_linker_script"])
+    toolchain = CMakeToolchain(conanfile)
+    content = toolchain.content
+    assert f'string(APPEND CONAN_EXE_LINKER_FLAGS -T"path_to_first_linker_script" -T"path_to_second_linker_script")' in content
diff --git a/conans/test/unittests/tools/files/test_symlinks.py b/conans/test/unittests/tools/files/test_symlinks.py
index 83433228a..3a2fd174f 100644
--- a/conans/test/unittests/tools/files/test_symlinks.py
+++ b/conans/test/unittests/tools/files/test_symlinks.py
@@ -17,7 +17,7 @@ def folders():
         (os.path.join(tmp, "foo/var/file.txt"), "foo/var/other/absolute.txt"),  # Absolute link
         (os.path.join(tmp, "foo/var"), "foo/var/other/other/myfolder"),  # Absolute link folder
         (os.path.join(tmp, "foo/var/file.txt"), "foo/absolute.txt"),  # Absolute link
-        ("foo/var/file.txt", "foo/var/other/relative.txt"),  # Relative link
+        ("../file.txt", "foo/var/other/relative.txt"),  # Relative link
         ("missing.txt", "foo/var/other/broken.txt"),  # Broken link
         (outside_folder, "foo/var/other/absolute_outside"),  # Absolute folder outside the folder
         ("../../../../../outside", "foo/absolute_outside"),  # Relative folder outside the folder
@@ -54,7 +54,7 @@ def test_absolute_to_relative_symlinks(folders):
     assert linked_to == "var/file.txt"
 
     linked_to = os.readlink(os.path.join(folder, "foo/var/other/relative.txt")).replace("\\", "/")
-    assert linked_to == "foo/var/file.txt"
+    assert linked_to == "../file.txt"
 
     linked_to = os.readlink(os.path.join(folder, "foo/var/other/broken.txt"))
     assert linked_to == "missing.txt"
@@ -81,7 +81,7 @@ def test_remove_external_symlinks(folders):
     assert linked_to == os.path.join(folder, "foo/var/file.txt")
 
     linked_to = os.readlink(os.path.join(folder, "foo/var/other/relative.txt"))
-    assert linked_to == "foo/var/file.txt"
+    assert linked_to == "../file.txt"
 
     linked_to = os.readlink(os.path.join(folder, "foo/var/other/broken.txt"))
     assert linked_to == "missing.txt"
@@ -112,7 +112,7 @@ def test_remove_broken_symlinks(folders):
     assert linked_to == os.path.join(folder, "foo/var/file.txt")
 
     linked_to = os.readlink(os.path.join(folder, "foo/var/other/relative.txt"))
-    assert linked_to == "foo/var/file.txt"
+    assert linked_to == "../file.txt"
 
     # This one is removed
     assert not os.path.islink(os.path.join(folder, "foo/var/other/broken.txt"))
diff --git a/conans/test/unittests/tools/gnu/autotoolschain_test.py b/conans/test/unittests/tools/gnu/autotoolschain_test.py
index 93b7d31ec..61a20034a 100644
--- a/conans/test/unittests/tools/gnu/autotoolschain_test.py
+++ b/conans/test/unittests/tools/gnu/autotoolschain_test.py
@@ -1,9 +1,29 @@
+from unittest.mock import patch
+
 import pytest
 
 from conan.tools.gnu import AutotoolsToolchain
 from conans.errors import ConanException
 from conans.model.conf import Conf
 from conans.test.utils.mocks import ConanFileMock, MockSettings
+from conans.tools import args_to_string
+
+
+@pytest.fixture()
+def cross_building_conanfile():
+    settings_build = MockSettings({"os": "Linux",
+                                   "arch": "x86_64",
+                                   "compiler": "gcc",
+                                   "compiler.version": "11",
+                                   "compiler.libcxx": "libstdc++",
+                                   "build_type": "Release"})
+    settings_target = MockSettings({"os": "Android", "arch": "armv8"})
+    settings = MockSettings({"os": "Emscripten", "arch": "wasm"})
+    conanfile = ConanFileMock()
+    conanfile.settings = settings
+    conanfile.settings_build = settings_build
+    conanfile.settings_target = settings_target
+    return conanfile
 
 
 def test_get_gnu_triplet_for_cross_building():
@@ -125,3 +145,66 @@ def test_compilers_mapping():
     env = autotoolschain.environment().vars(conanfile)
     for compiler, env_var in autotools_mapping.items():
         assert env[env_var] == f"path_to_{compiler}"
+
+
+def test_linker_scripts():
+    conanfile = ConanFileMock()
+    conanfile.conf = Conf()
+    conanfile.conf.define("tools.build:linker_scripts", ["path_to_first_linker_script", "path_to_second_linker_script"])
+    settings = MockSettings({"build_type": "Release",
+                             "os": "Windows",
+                             "arch": "x86_64"})
+    conanfile.settings = settings
+    autotoolschain = AutotoolsToolchain(conanfile)
+    env = autotoolschain.environment().vars(conanfile)
+    assert "-T'path_to_first_linker_script'" in env["LDFLAGS"]
+    assert "-T'path_to_second_linker_script'" in env["LDFLAGS"]
+
+
+@patch("conan.tools.gnu.autotoolstoolchain.save_toolchain_args")
+def test_check_configure_args_overwriting_and_deletion(save_args, cross_building_conanfile):
+    # Issue: https://github.com/conan-io/conan/issues/12642
+    at = AutotoolsToolchain(cross_building_conanfile)
+    at.configure_args.extend([
+        "--with-cross-build=my_path",
+        "--something-host=my_host"
+    ])
+    at.generate_args()
+    configure_args = save_args.call_args[0][0]['configure_args']
+    assert "--build=x86_64-linux-gnu" in configure_args
+    assert "--host=wasm32-local-emscripten" in configure_args
+    assert "--with-cross-build=my_path" in configure_args
+    assert "--something-host=my_host" in configure_args
+    # https://github.com/conan-io/conan/issues/12431
+    at.configure_args.remove("--build=x86_64-linux-gnu")
+    at.configure_args.remove("--host=wasm32-local-emscripten")
+    at.generate_args()
+    configure_args = save_args.call_args[0][0]['configure_args']
+    assert "--build=x86_64-linux-gnu" not in configure_args  # removed
+    assert "--host=wasm32-local-emscripten" not in configure_args  # removed
+    assert "--with-cross-build=my_path" in configure_args
+    assert "--something-host=my_host" in configure_args
+
+
+def test_update_or_prune_any_args(cross_building_conanfile):
+    at = AutotoolsToolchain(cross_building_conanfile)
+    at.configure_args.append("--enable-flag1=false")
+    # Update configure_args
+    at.update_configure_args({"--prefix": "/my/other/prefix",
+                              "--build": None,  # prune value
+                              "--enable-flag1": "",  # without value
+                              "-NEW-FLAG": "no"  # new flag
+                              })
+    new_configure_args = args_to_string(at.configure_args)
+    assert "--prefix=/my/other/prefix" in new_configure_args
+    assert "--build=" not in new_configure_args  # pruned
+    assert "--enable-flag1" in new_configure_args  # flag without value
+    assert "-NEW-FLAG=no" in new_configure_args  # new flag
+    # Update autoreconf_args
+    at.update_autoreconf_args({"--force": None})
+    new_autoreconf_args = args_to_string(at.autoreconf_args)
+    assert "'--force" not in new_autoreconf_args
+    # Add new value to make_args
+    at.update_make_args({"--new-complex-flag": "new-value"})
+    new_make_args = args_to_string(at.make_args)
+    assert "--new-complex-flag=new-value" in new_make_args
diff --git a/conans/test/unittests/tools/microsoft/test_check_min_vs.py b/conans/test/unittests/tools/microsoft/test_check_min_vs.py
index bca089093..4810a6a81 100644
--- a/conans/test/unittests/tools/microsoft/test_check_min_vs.py
+++ b/conans/test/unittests/tools/microsoft/test_check_min_vs.py
@@ -7,6 +7,23 @@ from conans.test.utils.mocks import MockConanfile, MockSettings
 
 class TestCheckMinVS:
 
+    parametrize_vars = "compiler,version,update,minimum"
+    valid_parametrize_values = [
+        ("Visual Studio", "15", None, "191"),
+        ("Visual Studio", "16", None, "192"),
+        ("msvc", "193", None, "193"),
+        ("msvc", "193", None, "192"),
+        ("msvc", "193", "2", "193.1"),
+    ]
+
+    invalid_parametrize_values = [
+        ("Visual Studio", "15", None, "192"),
+        ("Visual Studio", "16", None, "193.1"),
+        ("msvc", "192", None, "193"),
+        ("msvc", "193", None, "193.1"),
+        ("msvc", "193", "1", "193.2"),
+    ]
+
     @staticmethod
     def _create_conanfile(compiler, version, update=None):
         settings = MockSettings({"compiler": compiler,
@@ -15,25 +32,23 @@ class TestCheckMinVS:
         conanfile = MockConanfile(settings)
         return conanfile
 
-    @pytest.mark.parametrize("compiler,version,update,minimum", [
-        ("Visual Studio", "15", None, "191"),
-        ("Visual Studio", "16", None, "192"),
-        ("msvc", "193", None, "193"),
-        ("msvc", "193", None, "192"),
-        ("msvc", "193", "2", "193.1"),
-    ])
+    @pytest.mark.parametrize(parametrize_vars, valid_parametrize_values)
     def test_valid(self, compiler, version, update, minimum):
         conanfile = self._create_conanfile(compiler, version, update)
         check_min_vs(conanfile, minimum)
 
-    @pytest.mark.parametrize("compiler,version,update,minimum", [
-        ("Visual Studio", "15", None, "192"),
-        ("Visual Studio", "16", None, "193.1"),
-        ("msvc", "192", None, "193"),
-        ("msvc", "193", None, "193.1"),
-        ("msvc", "193", "1", "193.2"),
-    ])
+    @pytest.mark.parametrize(parametrize_vars, valid_parametrize_values)
+    def test_valid_nothrows(self, compiler, version, update, minimum):
+        conanfile = self._create_conanfile(compiler, version, update)
+        assert check_min_vs(conanfile, minimum, raise_invalid=False)
+
+    @pytest.mark.parametrize(parametrize_vars, invalid_parametrize_values)
     def test_invalid(self, compiler, version, update, minimum):
         conanfile = self._create_conanfile(compiler, version, update)
         with pytest.raises(ConanInvalidConfiguration):
             check_min_vs(conanfile, minimum)
+
+    @pytest.mark.parametrize(parametrize_vars, invalid_parametrize_values)
+    def test_invalid_nothrows(self, compiler, version, update, minimum):
+        conanfile = self._create_conanfile(compiler, version, update)
+        assert not check_min_vs(conanfile, minimum, raise_invalid=False)
diff --git a/conans/test/unittests/tools/microsoft/test_msvs_toolset.py b/conans/test/unittests/tools/microsoft/test_msvs_toolset.py
new file mode 100644
index 000000000..de1ec93b0
--- /dev/null
+++ b/conans/test/unittests/tools/microsoft/test_msvs_toolset.py
@@ -0,0 +1,141 @@
+import pytest
+from conan.tools.microsoft import msvs_toolset
+from conan.errors import ConanException
+from conans.test.utils.mocks import ConanFileMock, MockSettings
+
+
+@pytest.mark.parametrize("compiler_version,expected_toolset", [
+    ("17", "v143"),
+    ("16", "v142"),
+    ("15", "v141"),
+    ("14", "v140"),
+    ("12", "v120"),
+    ("11", "v110"),
+    ("10", "v100"),
+    ("9", "v90"),
+    ("8", "v80")])
+def test_visual_studio_default(compiler_version, expected_toolset):
+    """ When running Visual Studio as compiler, and there is no toolset configured,
+        msvs_toolset must return a specific version based on the compiler version
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "Visual Studio", "compiler.version": compiler_version})
+    assert msvs_toolset(conanfile) == expected_toolset
+
+
+@pytest.mark.parametrize("compiler_version,toolset,expected_toolset", [
+    ("16", "v142_xp", "v142_xp"),
+    ("15", "v141_xp", "v141_xp"),
+    ("14", "v140_xp", "v140_xp"),
+    ("12", "v120_xp", "v120_xp"),
+    ("11", "v110_xp", "v110_xp")])
+def test_visual_studio_custom(compiler_version, toolset, expected_toolset):
+    """ When running Visual Studio as compiler, and there is a toolset configured,
+        msvs_toolset must return the specified toolset from profile
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "Visual Studio",
+                             "compiler.version": compiler_version,
+                             "compiler.toolset": toolset})
+    assert msvs_toolset(conanfile) == expected_toolset
+
+
+def test_invalid_compiler():
+    """ When the compiler version is unknown and there is no toolset configured,
+        msvs_toolset must return None
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "Visual Studio",
+                                       "compiler.version": "20220203"})
+    assert msvs_toolset(conanfile) is None
+
+
+@pytest.mark.parametrize("compiler_version,expected_toolset", [
+    ("193", "v143"),
+    ("192", "v142"),
+    ("191", "v141"),
+    ("190", "v140"),
+    ("180", "v120"),
+    ("170", "v110")])
+def test_msvc_default(compiler_version, expected_toolset):
+    """ When running msvc as compiler, and there is no toolset configured,
+        msvs_toolset must return a specific version based on the compiler version
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "msvc", "compiler.version": compiler_version})
+    assert msvs_toolset(conanfile) == expected_toolset
+
+
+@pytest.mark.parametrize("compiler_version,toolset,expected_toolset", [
+    ("193", "v143_xp", "v143_xp"),
+    ("192", "v142_xp", "v142_xp"),
+    ("191", "v141_xp", "v141_xp"),
+    ("190", "v140_xp", "v140_xp"),
+    ("180", "v120_xp", "v120_xp"),
+    ("170", "v110_xp", "v110_xp")])
+def test_msvc_custom(compiler_version, toolset, expected_toolset):
+    """ When running msvc as compiler, and there is a toolset configured,
+        msvs_toolset must return the specified toolset from profile
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "msvc",
+                             "compiler.version": compiler_version,
+                             "compiler.toolset": toolset})
+    assert msvs_toolset(conanfile) == expected_toolset
+
+
+@pytest.mark.parametrize("compiler_version,expected_toolset", [
+    ("19.1", "Intel C++ Compiler 19.1"),
+    ("19", "Intel C++ Compiler 19.0"),
+    ("18", "Intel C++ Compiler 18.0"),
+    ("17", "Intel C++ Compiler 17.0")])
+def test_intel_default(compiler_version, expected_toolset):
+    """ When running intel as compiler, and there is a compiler version configured,
+        msvs_toolset must return the compiler version as its toolset
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "intel", "compiler.version": compiler_version})
+    assert msvs_toolset(conanfile) == expected_toolset
+
+
+def test_intel_invalid():
+    """ When running intel as compiler, and there is no compiler version configured,
+        msvs_toolset must return None
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "intel"})
+    assert msvs_toolset(conanfile) is None
+
+
+def test_intel_cc_old_compiler():
+    """ When running intel-cc as compiler, and the compiler version configured is older than 2021
+        msvs_toolset must raise an ConanExpection
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "intel-cc", "compiler.version": "19.1"})
+    with pytest.raises(ConanException) as error:
+        msvs_toolset(conanfile)
+    assert "You have to use 'intel' compiler" in str(error.value)
+
+
+@pytest.mark.parametrize("compiler_version,compiler_mode,expected_toolset", [
+    ("2021.3", "classic", "Intel C++ Compiler 19.2"),
+    ("2021.2", "classic", "Intel C++ Compiler 19.2"),
+    ("2021.1", "classic", "Intel C++ Compiler 19.2"),
+    ("2021.3", "icx", "Intel C++ Compiler 2021"),
+    ("2021.2", "icx", "Intel C++ Compiler 2021"),
+    ("2021.1", "icx", "Intel C++ Compiler 2021"),
+    ("2021.3", "dpcpp", "Intel(R) oneAPI DPC++ Compiler"),
+    ("2021.2", "dpcpp", "Intel(R) oneAPI DPC++ Compiler"),
+    ("2021.1", "dpcpp", "Intel(R) oneAPI DPC++ Compiler"),
+    ("2021.3", None, "Intel(R) oneAPI DPC++ Compiler")])
+def test_intel_cc_default(compiler_version, compiler_mode, expected_toolset):
+    """ When running intel-cc as compiler, and there is a proper compiler version configured,
+        and the compiler.mode is configured,
+        msvs_toolset must return a compiler toolset based on compiler.mode
+    """
+    conanfile = ConanFileMock()
+    conanfile.settings = MockSettings({"compiler": "intel-cc",
+                                       "compiler.version": compiler_version,
+                                       "compiler.mode": compiler_mode})
+    assert msvs_toolset(conanfile) == expected_toolset
diff --git a/conans/test/unittests/tools/microsoft/test_subsystem.py b/conans/test/unittests/tools/microsoft/test_subsystem.py
index 65e5423e8..0e010e23a 100644
--- a/conans/test/unittests/tools/microsoft/test_subsystem.py
+++ b/conans/test/unittests/tools/microsoft/test_subsystem.py
@@ -1,19 +1,20 @@
+import mock
 import textwrap
-
 import pytest
 
-from conan.tools.microsoft import unix_path
+from conan.tools.microsoft import unix_path, unix_path_package_info_legacy
 from conans.model.conf import ConfDefinition
 from conans.test.utils.mocks import MockSettings, ConanFileMock
 
-
-@pytest.mark.parametrize("subsystem, expected_path", [
+expected_results = [
     ("msys2", '/c/path/to/stuff'),
     ("msys", '/c/path/to/stuff'),
     ("cygwin", '/cygdrive/c/path/to/stuff'),
     ("wsl", '/mnt/c/path/to/stuff'),
     ("sfu", '/dev/fs/C/path/to/stuff')
-])
+]
+
+@pytest.mark.parametrize("subsystem, expected_path", expected_results)
 def test_unix_path(subsystem, expected_path):
     c = ConfDefinition()
     c.loads(textwrap.dedent("""\
@@ -29,3 +30,19 @@ def test_unix_path(subsystem, expected_path):
 
     path = unix_path(conanfile, "c:/path/to/stuff")
     assert expected_path == path
+
+@mock.patch("platform.system", mock.MagicMock(return_value='Windows'))
+@pytest.mark.parametrize("subsystem, expected_path", expected_results)
+def test_unix_path_package_info_legacy_windows(subsystem, expected_path):
+    test_path = "c:/path/to/stuff"
+    conanfile = ConanFileMock()
+    package_info_legacy_path = unix_path_package_info_legacy(conanfile, test_path, path_flavor=subsystem)
+    assert expected_path == package_info_legacy_path
+
+@mock.patch("platform.system", mock.MagicMock(return_value='Darwin'))
+@pytest.mark.parametrize("subsystem, expected_path", expected_results)
+def test_unix_path_package_info_legacy_not_windows(subsystem, expected_path):
+    test_path = "c:/path/to/stuff"
+    conanfile = ConanFileMock()
+    package_info_legacy_path = unix_path_package_info_legacy(conanfile, test_path, path_flavor=subsystem)
+    assert test_path == package_info_legacy_path
\ No newline at end of file
diff --git a/conans/test/unittests/tools/scm/test_git_get_commit.py b/conans/test/unittests/tools/scm/test_git_get_commit.py
index 4ee7f984f..c5f54a570 100644
--- a/conans/test/unittests/tools/scm/test_git_get_commit.py
+++ b/conans/test/unittests/tools/scm/test_git_get_commit.py
@@ -14,6 +14,7 @@ def test_change_branch_in_root_commit():
     conanfile = MockConanfile({})
     c.save({"root.txt": "", "subfolder/subfolder.txt": ""})
     c.run_command("git init .")
+    c.run_command("git checkout -B master")
     c.run_command('git config user.name myname')
     c.run_command('git config user.email myname@mycompany.com')
     c.run_command("git add .")
diff --git a/conans/test/unittests/tools/scm/test_version.py b/conans/test/unittests/tools/scm/test_version.py
index 7c52bb49e..2f3ab2428 100644
--- a/conans/test/unittests/tools/scm/test_version.py
+++ b/conans/test/unittests/tools/scm/test_version.py
@@ -1,6 +1,7 @@
 import textwrap
 
 from conans.test.utils.tools import TestClient
+from conan.tools.scm import Version
 
 
 def test_version():
@@ -30,3 +31,18 @@ def test_version():
     assert "The patch of 1.2.3 is 3" in c.out
 
     c.run("create . {} -s compiler.version=9".format(settings), assert_error=True)
+
+
+def test_version_comparison():
+    v = Version("1.2")
+    assert v == "1.2"
+    assert v > 1
+    assert v > "1.1"
+    assert v > "1.1.1"
+    assert v >= 1
+    assert v >= "1.1"
+    assert v < 2
+    assert v < "1.3"
+    assert v < "1.2.2"
+    assert v <= 2
+    assert v <= "1.7"