Repository: conan-io/conan
Pull request #11708 (2022-07-26 10:56:31)

add legacy mingw test
Changelog: Omit
Docs: Omit


Patch:
diff --git a/conan/__init__.py b/conan/__init__.py
index 2a9a6c1d1..eb3d6eeb0 100644
--- a/conan/__init__.py
+++ b/conan/__init__.py
@@ -1,1 +1,6 @@
 from conans.model.conan_file import ConanFile
+from conan.tools.scm import Version
+from conans import __version__
+
+
+conan_version = Version(__version__)
diff --git a/conan/tools/apple/__init__.py b/conan/tools/apple/__init__.py
index 3ad2091bc..22f18bb12 100644
--- a/conan/tools/apple/__init__.py
+++ b/conan/tools/apple/__init__.py
@@ -1,11 +1,9 @@
 # Keep everything private until we review what is really needed and refactor passing "conanfile"
 # from conan.tools.apple.apple import XCRun
 # from conan.tools.apple.apple import apple_dot_clean
-# from conan.tools.apple.apple import is_apple_os
 # from conan.tools.apple.apple import apple_sdk_name
 # from conan.tools.apple.apple import apple_deployment_target_flag
-# from conan.tools.apple.apple import to_apple_arch
-from conan.tools.apple.apple import fix_apple_shared_install_name
+from conan.tools.apple.apple import fix_apple_shared_install_name, is_apple_os, to_apple_arch
 from conan.tools.apple.xcodedeps import XcodeDeps
 from conan.tools.apple.xcodebuild import XcodeBuild
 from conan.tools.apple.xcodetoolchain import XcodeToolchain
diff --git a/conan/tools/apple/apple.py b/conan/tools/apple/apple.py
index 8fd7fd569..b796de342 100644
--- a/conan/tools/apple/apple.py
+++ b/conan/tools/apple/apple.py
@@ -3,23 +3,19 @@
 import os
 
 from conans.util.runners import check_output_runner
+from conans.client.tools.apple import to_apple_arch as _to_apple_arch
 
 
-def is_apple_os(os_):
+def is_apple_os(conanfile):
     """returns True if OS is Apple one (Macos, iOS, watchOS or tvOS"""
+    os_ = conanfile.settings.get_safe("os")
     return str(os_) in ['Macos', 'iOS', 'watchOS', 'tvOS']
 
 
-def to_apple_arch(arch):
+def to_apple_arch(conanfile):
     """converts conan-style architecture into Apple-style arch"""
-    return {'x86': 'i386',
-            'x86_64': 'x86_64',
-            'armv7': 'armv7',
-            'armv8': 'arm64',
-            'armv8_32': 'arm64_32',
-            'armv8.3': 'arm64e',
-            'armv7s': 'armv7s',
-            'armv7k': 'armv7k'}.get(str(arch))
+    arch_ = conanfile.settings.get_safe("arch")
+    return _to_apple_arch(arch_)
 
 
 def _guess_apple_sdk_name(os_, arch):
@@ -176,7 +172,7 @@ def fix_apple_shared_install_name(conanfile):
 
     substitutions = {}
 
-    if is_apple_os(conanfile.settings.get_safe("os")) and conanfile.options.get_safe("shared", False):
+    if is_apple_os(conanfile) and conanfile.options.get_safe("shared", False):
         libdirs = getattr(conanfile.cpp.package, "libdirs")
         for libdir in libdirs:
             full_folder = os.path.join(conanfile.package_folder, libdir)
diff --git a/conan/tools/apple/xcodebuild.py b/conan/tools/apple/xcodebuild.py
index a822a57a7..10403d753 100644
--- a/conan/tools/apple/xcodebuild.py
+++ b/conan/tools/apple/xcodebuild.py
@@ -1,6 +1,6 @@
 import os
 
-from conan.tools.apple.apple import to_apple_arch
+from conan.tools.apple import to_apple_arch
 from conans.errors import ConanException
 
 
@@ -8,7 +8,7 @@ class XcodeBuild(object):
     def __init__(self, conanfile):
         self._conanfile = conanfile
         self._build_type = conanfile.settings.get_safe("build_type")
-        self._arch = to_apple_arch(conanfile.settings.get_safe("arch"))
+        self._arch = to_apple_arch(self._conanfile)
         self._sdk = conanfile.settings.get_safe("os.sdk") or ""
         self._sdk_version = conanfile.settings.get_safe("os.sdk_version") or ""
 
diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py
index a15c533d1..8a1c7cd35 100644
--- a/conan/tools/apple/xcodedeps.py
+++ b/conan/tools/apple/xcodedeps.py
@@ -7,7 +7,7 @@ from jinja2 import Template
 from conan.tools._check_build_profile import check_using_build_profile
 from conans.errors import ConanException
 from conans.util.files import load, save
-from conan.tools.apple.apple import to_apple_arch
+from conans.client.tools.apple import to_apple_arch
 
 GLOBAL_XCCONFIG_TEMPLATE = textwrap.dedent("""\
     // Includes both the toolchain and the dependencies
@@ -230,6 +230,7 @@ class XcodeDeps(object):
 
                 sorted_components = dep.cpp_info.get_sorted_components().items()
                 for comp_name, comp_cpp_info in sorted_components:
+                    comp_name = _format_name(comp_name)
 
                     # returns: ("list of cpp infos from required components in same package",
                     #           "list of names from required components from other packages")
@@ -266,8 +267,17 @@ class XcodeDeps(object):
                     include_components_names.append((dep_name, comp_name))
                     result.update(component_content)
             else:
-                public_deps = [(_format_name(d.ref.name),) * 2 for r, d in
-                               dep.dependencies.direct_host.items() if r.visible]
+                public_deps = []
+                for r, d in dep.dependencies.direct_host.items():
+                    if not r.visible:
+                        continue
+                    if d.cpp_info.has_components:
+                        sorted_components = d.cpp_info.get_sorted_components().items()
+                        for comp_name, comp_cpp_info in sorted_components:
+                            public_deps.append((_format_name(d.ref.name), _format_name(comp_name)))
+                    else:
+                        public_deps.append((_format_name(d.ref.name),) * 2)
+
                 required_components = dep.cpp_info.required_components if dep.cpp_info.required_components else public_deps
                 root_content = self.get_content_for_component(dep_name, dep_name, [dep.cpp_info],
                                                               required_components)
diff --git a/conan/tools/apple/xcodetoolchain.py b/conan/tools/apple/xcodetoolchain.py
index bc08b2a3e..892aac9f4 100644
--- a/conan/tools/apple/xcodetoolchain.py
+++ b/conan/tools/apple/xcodetoolchain.py
@@ -2,7 +2,7 @@ import textwrap
 
 from conan.tools._check_build_profile import check_using_build_profile
 from conan.tools._compilers import cppstd_flag
-from conan.tools.apple.apple import to_apple_arch
+from conan.tools.apple import to_apple_arch
 from conan.tools.apple.xcodedeps import GLOBAL_XCCONFIG_FILENAME, GLOBAL_XCCONFIG_TEMPLATE, \
     _add_includes_to_file_or_create, _xcconfig_settings_filename, _xcconfig_conditional
 from conans.util.files import save
@@ -36,7 +36,7 @@ class XcodeToolchain(object):
     def __init__(self, conanfile):
         self._conanfile = conanfile
         arch = conanfile.settings.get_safe("arch")
-        self.architecture = to_apple_arch(arch) or arch
+        self.architecture = to_apple_arch(self._conanfile) or arch
         self.configuration = conanfile.settings.build_type
         self.sdk = conanfile.settings.get_safe("os.sdk")
         self.sdk_version = conanfile.settings.get_safe("os.sdk_version")
diff --git a/conan/tools/cmake/cmake.py b/conan/tools/cmake/cmake.py
index d30e4274f..716e6afd1 100644
--- a/conan/tools/cmake/cmake.py
+++ b/conan/tools/cmake/cmake.py
@@ -56,7 +56,7 @@ class CMake(object):
         configure_preset = get_configure_preset(cmake_presets, conanfile)
 
         self._generator = configure_preset["generator"]
-        self._toolchain_file = configure_preset["toolchainFile"]
+        self._toolchain_file = configure_preset.get("toolchainFile")
         self._cache_variables = configure_preset["cacheVariables"]
 
         self._cmake_program = "cmake"  # Path to CMake should be handled by environment
diff --git a/conan/tools/cmake/cmakedeps/templates/macros.py b/conan/tools/cmake/cmakedeps/templates/macros.py
index 9d3965c0e..17d96f88d 100644
--- a/conan/tools/cmake/cmakedeps/templates/macros.py
+++ b/conan/tools/cmake/cmakedeps/templates/macros.py
@@ -41,17 +41,14 @@ class MacrosTemplate(CMakeDepsFileTemplate):
            endif()
        endmacro()
 
-       function(conan_package_library_targets libraries package_libdir deps out_libraries out_libraries_target config_suffix package_name)
-           set(_out_libraries "")
+       function(conan_package_library_targets libraries package_libdir deps_target out_libraries_target config_suffix package_name)
            set(_out_libraries_target "")
-           set(_CONAN_ACTUAL_TARGETS "")
 
            foreach(_LIBRARY_NAME ${libraries})
                find_library(CONAN_FOUND_LIBRARY NAMES ${_LIBRARY_NAME} PATHS ${package_libdir}
                             NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
                if(CONAN_FOUND_LIBRARY)
                    message(VERBOSE "Conan: Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")
-                   list(APPEND _out_libraries ${CONAN_FOUND_LIBRARY})
 
                    # Create a micro-target for each lib/a found
                    # Allow only some characters for the target name
@@ -60,11 +57,9 @@ class MacrosTemplate(CMakeDepsFileTemplate):
                    if(NOT TARGET ${_LIB_NAME})
                        # Create a micro-target for each lib/a found
                        add_library(${_LIB_NAME} UNKNOWN IMPORTED)
-                       set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${CONAN_FOUND_LIBRARY})
-                       list(APPEND _CONAN_ACTUAL_TARGETS ${_LIB_NAME})
-                   else()
-                       message(VERBOSE "Conan: Skipping already existing target: ${_LIB_NAME}")
                    endif()
+                   # Link library file
+                   set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${CONAN_FOUND_LIBRARY})
                    list(APPEND _out_libraries_target ${_LIB_NAME})
                    message(VERBOSE "Conan: Found: ${CONAN_FOUND_LIBRARY}")
                else()
@@ -73,13 +68,11 @@ class MacrosTemplate(CMakeDepsFileTemplate):
                unset(CONAN_FOUND_LIBRARY CACHE)
            endforeach()
 
-           # Add all dependencies to all targets
-           string(REPLACE " " ";" deps_list "${deps}")
-           foreach(_CONAN_ACTUAL_TARGET ${_CONAN_ACTUAL_TARGETS})
-               set_property(TARGET ${_CONAN_ACTUAL_TARGET} PROPERTY INTERFACE_LINK_LIBRARIES "${deps_list}" APPEND)
+           # Add the dependencies target for all the imported libraries
+           foreach(_T ${_out_libraries_target})
+               set_property(TARGET ${_T} PROPERTY INTERFACE_LINK_LIBRARIES ${deps_target} APPEND)
            endforeach()
 
-           set(${out_libraries} ${_out_libraries} PARENT_SCOPE)
            set(${out_libraries_target} ${_out_libraries_target} PARENT_SCOPE)
        endfunction()
 
diff --git a/conan/tools/cmake/cmakedeps/templates/target_configuration.py b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
index f969bdd25..132a43692 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_configuration.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
@@ -31,6 +31,7 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
         return {"pkg_name": self.pkg_name,
                 "root_target_name": self.root_target_name,
                 "config_suffix": self.config_suffix,
+                "config": self.configuration.upper(),
                 "deps_targets_names": ";".join(deps_targets_names),
                 "components_names": components_names,
                 "configuration": self.cmakedeps.configuration,
@@ -39,6 +40,8 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
     @property
     def template(self):
         return textwrap.dedent("""\
+        # Avoid multiple calls to find_package to append duplicated properties to the targets
+        include_guard()
 
         {%- macro tvalue(pkg_name, comp_name, var, config_suffix) -%}
             {{'${'+pkg_name+'_'+comp_name+'_'+var+config_suffix+'}'}}
@@ -59,127 +62,161 @@ class TargetConfigurationTemplate(CMakeDepsFileTemplate):
         set({{ pkg_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "") # Will be filled later
         conan_find_apple_frameworks({{ pkg_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "{{ '${' }}{{ pkg_name }}_FRAMEWORKS{{ config_suffix }}}" "{{ '${' }}{{ pkg_name }}_FRAMEWORK_DIRS{{ config_suffix }}}")
 
-        # Gather all the libraries that should be linked to the targets (do not touch existing variables)
-        set(_{{ pkg_name }}_DEPENDENCIES{{ config_suffix }} "{{ '${' }}{{ pkg_name }}_FRAMEWORKS_FOUND{{ config_suffix }}} {{ '${' }}{{ pkg_name }}_SYSTEM_LIBS{{ config_suffix }}} {{ deps_targets_names }}")
+        set({{ pkg_name }}_LIBRARIES_TARGETS "") # Will be filled later
 
-        set({{ pkg_name }}_LIBRARIES_TARGETS{{ config_suffix }} "") # Will be filled later
-        set({{ pkg_name }}_LIBRARIES{{ config_suffix }} "") # Will be filled later
-        conan_package_library_targets("{{ '${' }}{{ pkg_name }}_LIBS{{ config_suffix }}}"    # libraries
-                                      "{{ '${' }}{{ pkg_name }}_LIB_DIRS{{ config_suffix }}}" # package_libdir
-                                      "{{ '${' }}_{{ pkg_name }}_DEPENDENCIES{{ config_suffix }}}" # deps
-                                      {{ pkg_name }}_LIBRARIES{{ config_suffix }}   # out_libraries
-                                      {{ pkg_name }}_LIBRARIES_TARGETS{{ config_suffix }}  # out_libraries_targets
-                                      "{{ config_suffix }}"  # config_suffix
-                                      "{{ pkg_name }}")    # package_name
 
-        foreach(_FRAMEWORK {{ '${' }}{{ pkg_name }}_FRAMEWORKS_FOUND{{ config_suffix }}})
-            list(APPEND {{ pkg_name }}_LIBRARIES_TARGETS{{ config_suffix }} ${_FRAMEWORK})
-            list(APPEND {{ pkg_name }}_LIBRARIES{{ config_suffix }} ${_FRAMEWORK})
-        endforeach()
+        ######## Create an interface target to contain all the dependencies (frameworks, system and conan deps)
+        if(NOT TARGET {{ pkg_name+'_DEPS_TARGET'}})
+            add_library({{ pkg_name+'_DEPS_TARGET'}} INTERFACE)
+        endif()
 
-        foreach(_SYSTEM_LIB {{ '${' }}{{ pkg_name }}_SYSTEM_LIBS{{ config_suffix }}})
-            list(APPEND {{ pkg_name }}_LIBRARIES_TARGETS{{ config_suffix }} ${_SYSTEM_LIB})
-            list(APPEND {{ pkg_name }}_LIBRARIES{{ config_suffix }} ${_SYSTEM_LIB})
-        endforeach()
+        set_property(TARGET {{ pkg_name + '_DEPS_TARGET'}}
+                     PROPERTY INTERFACE_LINK_LIBRARIES
+                     $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_FRAMEWORKS_FOUND'+config_suffix+'}' }}>
+                     $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_SYSTEM_LIBS'+config_suffix+'}' }}>
+                     $<$<CONFIG:{{configuration}}>:{{ deps_targets_names }}>
+                     APPEND)
 
-        # We need to add our requirements too
-        set({{ pkg_name }}_LIBRARIES_TARGETS{{ config_suffix }} {{ '"${' }}{{ pkg_name }}_LIBRARIES_TARGETS{{ config_suffix }}{{ '};' }}{{ deps_targets_names }}")
-        set({{ pkg_name }}_LIBRARIES{{ config_suffix }} {{ '"${' }}{{ pkg_name }}_LIBRARIES{{ config_suffix }}{{ '};' }}{{ deps_targets_names }}")
+        ####### Find the libraries declared in cpp_info.libs, create an IMPORTED target for each one and link the
+        ####### {{pkg_name}}_DEPS_TARGET to all of them
+        conan_package_library_targets("{{ '${' }}{{ pkg_name }}_LIBS{{ config_suffix }}}"    # libraries
+                                      "{{ '${' }}{{ pkg_name }}_LIB_DIRS{{ config_suffix }}}" # package_libdir
+                                      {{ pkg_name + '_DEPS_TARGET'}}
+                                      {{ pkg_name }}_LIBRARIES_TARGETS  # out_libraries_targets
+                                      "{{ config_suffix }}"
+                                      "{{ pkg_name }}")    # package_name
 
         # 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})
         set(CMAKE_PREFIX_PATH {{ '${' }}{{ pkg_name }}_BUILD_DIRS{{ config_suffix }}} {{ '${' }}CMAKE_PREFIX_PATH})
 
-        {%- for comp_variable_name, comp_target_name in components_names %}
+        {% if not components_names %}
 
-        ########## COMPONENT {{ comp_target_name }} FIND LIBRARIES & FRAMEWORKS / DYNAMIC VARS #############
+        ########## GLOBAL TARGET PROPERTIES {{ configuration }} ########################################
+            set_property(TARGET {{root_target_name}}
+                         PROPERTY INTERFACE_LINK_LIBRARIES
+                         $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_OBJECTS'+config_suffix+'}' }}>
+                         $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_LIBRARIES_TARGETS}>
+                         APPEND)
+
+            if("{{ '${' }}{{ pkg_name }}_LIBS{{ config_suffix }}}" STREQUAL "")
+                # If the package is not declaring any "cpp_info.libs" the package deps, system libs,
+                # frameworks etc are not linked to the imported targets and we need to do it to the
+                # global target
+                set_property(TARGET {{root_target_name}}
+                             PROPERTY INTERFACE_LINK_LIBRARIES
+                             {{pkg_name}}_DEPS_TARGET
+                             APPEND)
+            endif()
+
+            set_property(TARGET {{root_target_name}}
+                         PROPERTY INTERFACE_LINK_OPTIONS
+                         $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_LINKER_FLAGS{{config_suffix}}}> APPEND)
+            set_property(TARGET {{root_target_name}}
+                         PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+                         $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_INCLUDE_DIRS{{config_suffix}}}> APPEND)
+            set_property(TARGET {{root_target_name}}
+                         PROPERTY INTERFACE_COMPILE_DEFINITIONS
+                         $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_COMPILE_DEFINITIONS{{config_suffix}}}> APPEND)
+            set_property(TARGET {{root_target_name}}
+                         PROPERTY INTERFACE_COMPILE_OPTIONS
+                         $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_COMPILE_OPTIONS{{config_suffix}}}> APPEND)
+
+            {%- if set_interface_link_directories %}
+
+            # This is only used for '#pragma comment(lib, "foo")' (automatic link)
+            set_property(TARGET {{root_target_name}}
+                         PROPERTY INTERFACE_LINK_DIRECTORIES
+                         $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_LIB_DIRS{{config_suffix}}}> APPEND)
+            {%- endif %}
 
-        set({{ pkg_name }}_{{ comp_variable_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "")
-        conan_find_apple_frameworks({{ pkg_name }}_{{ comp_variable_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "{{ '${'+pkg_name+'_'+comp_variable_name+'_FRAMEWORKS'+config_suffix+'}' }}" "{{ '${'+pkg_name+'_'+comp_variable_name+'_FRAMEWORK_DIRS'+config_suffix+'}' }}")
 
-        set({{ pkg_name }}_{{ comp_variable_name }}_LIB_TARGETS{{ config_suffix }} "")
-        set({{ pkg_name }}_{{ comp_variable_name }}_NOT_USED{{ config_suffix }} "")
-        set({{ pkg_name }}_{{ comp_variable_name }}_LIBS_FRAMEWORKS_DEPS{{ config_suffix }} {{ '${'+pkg_name+'_'+comp_variable_name+'_FRAMEWORKS_FOUND'+config_suffix+'}' }} {{ '${'+pkg_name+'_'+comp_variable_name+'_SYSTEM_LIBS'+config_suffix+'}' }} {{ '${'+pkg_name+'_'+comp_variable_name+'_DEPENDENCIES'+config_suffix+'}' }})
-        conan_package_library_targets("{{ '${'+pkg_name+'_'+comp_variable_name+'_LIBS'+config_suffix+'}' }}"
-                                      "{{ '${'+pkg_name+'_'+comp_variable_name+'_LIB_DIRS'+config_suffix+'}' }}"
-                                      "{{ '${'+pkg_name+'_'+comp_variable_name+'_LIBS_FRAMEWORKS_DEPS'+config_suffix+'}' }}"
-                                      {{ pkg_name }}_{{ comp_variable_name }}_NOT_USED{{ config_suffix }}
-                                      {{ pkg_name }}_{{ comp_variable_name }}_LIB_TARGETS{{ config_suffix }}
-                                      "{{ config_suffix }}"
-                                      "{{ pkg_name }}_{{ comp_variable_name }}")
+        {%- else %}
 
-        set({{ pkg_name }}_{{ comp_variable_name }}_LINK_LIBS{{ config_suffix }} {{ '${'+pkg_name+'_'+comp_variable_name+'_LIB_TARGETS'+config_suffix+'}' }} {{ '${'+pkg_name+'_'+comp_variable_name+'_LIBS_FRAMEWORKS_DEPS'+config_suffix+'}' }})
-        {%- endfor %}
+        ########## COMPONENTS TARGET PROPERTIES {{ configuration }} ########################################
 
+            {%- for comp_variable_name, comp_target_name in components_names %}
 
-        {% if not components_names %}
-        ########## GLOBAL TARGET PROPERTIES {{ configuration }} ########################################
-        set_property(TARGET {{root_target_name}}
-                     PROPERTY INTERFACE_LINK_LIBRARIES
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_OBJECTS{{config_suffix}}}
-                     ${{'{'}}{{pkg_name}}_LIBRARIES_TARGETS{{config_suffix}}}> APPEND)
-
-        set_property(TARGET {{root_target_name}}
-                     PROPERTY INTERFACE_LINK_OPTIONS
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_LINKER_FLAGS{{config_suffix}}}> APPEND)
-        set_property(TARGET {{root_target_name}}
-                     PROPERTY INTERFACE_INCLUDE_DIRECTORIES
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_INCLUDE_DIRS{{config_suffix}}}> APPEND)
-        set_property(TARGET {{root_target_name}}
-                     PROPERTY INTERFACE_COMPILE_DEFINITIONS
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_COMPILE_DEFINITIONS{{config_suffix}}}> APPEND)
-        set_property(TARGET {{root_target_name}}
-                     PROPERTY INTERFACE_COMPILE_OPTIONS
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_COMPILE_OPTIONS{{config_suffix}}}> APPEND)
-
-        {%- if set_interface_link_directories %}
-
-        # This is only used for '#pragma comment(lib, "foo")' (automatic link)
-        set_property(TARGET {{root_target_name}}
-                     PROPERTY INTERFACE_LINK_DIRECTORIES
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_LIB_DIRS{{config_suffix}}}> APPEND)
-        {%- endif %}
 
-        {%- else %}
+            ########## COMPONENT {{ comp_target_name }} #############
 
-        ########## COMPONENTS TARGET PROPERTIES {{ configuration }} ########################################
+                set({{ pkg_name }}_{{ comp_variable_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "")
+                conan_find_apple_frameworks({{ pkg_name }}_{{ comp_variable_name }}_FRAMEWORKS_FOUND{{ config_suffix }} "{{ '${'+pkg_name+'_'+comp_variable_name+'_FRAMEWORKS'+config_suffix+'}' }}" "{{ '${'+pkg_name+'_'+comp_variable_name+'_FRAMEWORK_DIRS'+config_suffix+'}' }}")
 
-        {%- for comp_variable_name, comp_target_name in components_names %}
-
-        ########## COMPONENT {{ comp_target_name }} TARGET PROPERTIES ######################################
-        set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_LINK_LIBRARIES
-                     $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'OBJECTS', config_suffix)}}
-                     {{tvalue(pkg_name, comp_variable_name, 'LINK_LIBS', config_suffix)}}> APPEND)
-        set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_LINK_OPTIONS
-                     $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'LINKER_FLAGS', config_suffix)}}> APPEND)
-        set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_INCLUDE_DIRECTORIES
-                     $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'INCLUDE_DIRS', config_suffix)}}> APPEND)
-        set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_COMPILE_DEFINITIONS
-                     $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'COMPILE_DEFINITIONS', config_suffix)}}> APPEND)
-        set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_COMPILE_OPTIONS
-                     $<$<CONFIG:{{ configuration }}>:
-                     {{tvalue(pkg_name, comp_variable_name, 'COMPILE_OPTIONS_C', config_suffix)}}
-                     {{tvalue(pkg_name, comp_variable_name, 'COMPILE_OPTIONS_CXX', config_suffix)}}> APPEND)
-        set({{ pkg_name }}_{{ comp_variable_name }}_TARGET_PROPERTIES TRUE)
-
-        {%- if set_interface_link_directories %}
-        # This is only used for '#pragma comment(lib, "foo")' (automatic link)
-        set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_LINK_DIRECTORIES
-                     $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'LIB_DIRS', config_suffix)}}> APPEND)
+                set({{ pkg_name }}_{{ comp_variable_name }}_LIBRARIES_TARGETS "")
 
-        {%- endif %}
-        {%- endfor %}
+                ######## Create an interface target to contain all the dependencies (frameworks, system and conan deps)
+                if(NOT TARGET {{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}})
+                    add_library({{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}} INTERFACE)
+                endif()
+
+                set_property(TARGET {{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}}
+                             PROPERTY INTERFACE_LINK_LIBRARIES
+                             $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_'+comp_variable_name+'_FRAMEWORKS_FOUND'+config_suffix+'}' }}>
+                             $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_'+comp_variable_name+'_SYSTEM_LIBS'+config_suffix+'}' }}>
+                             $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_'+comp_variable_name+'_DEPENDENCIES'+config_suffix+'}' }}>
+                             APPEND)
+
+                ####### Find the libraries declared in cpp_info.component["xxx"].libs,
+                ####### create an IMPORTED target for each one and link the '{{pkg_name}}_{{comp_variable_name}}_DEPS_TARGET' to all of them
+                conan_package_library_targets("{{ '${'+pkg_name+'_'+comp_variable_name+'_LIBS'+config_suffix+'}' }}"
+                                              "{{ '${'+pkg_name+'_'+comp_variable_name+'_LIB_DIRS'+config_suffix+'}' }}"
+                                              {{ pkg_name + '_' + comp_variable_name + '_DEPS_TARGET'}}
+                                              {{ pkg_name }}_{{ comp_variable_name }}_LIBRARIES_TARGETS
+                                              "{{ config_suffix }}"
+                                              "{{ pkg_name }}_{{ comp_variable_name }}")
+
+                ########## TARGET PROPERTIES #####################################
+                set_property(TARGET {{comp_target_name}}
+                             PROPERTY INTERFACE_LINK_LIBRARIES
+                             $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_'+comp_variable_name+'_OBJECTS'+config_suffix+'}' }}>
+                             $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_{{comp_variable_name}}_LIBRARIES_TARGETS}>
+                             APPEND)
 
+                if("{{ '${' }}{{ pkg_name }}_{{comp_variable_name}}_LIBS{{ config_suffix }}}" STREQUAL "")
+                    # If the component is not declaring any "cpp_info.components['foo'].libs" the system, frameworks etc are not
+                    # linked to the imported targets and we need to do it to the global target
+                    set_property(TARGET {{comp_target_name}}
+                                 PROPERTY INTERFACE_LINK_LIBRARIES
+                                 {{pkg_name}}_{{comp_variable_name}}_DEPS_TARGET
+                                 APPEND)
+                endif()
 
-        ########## AGGREGATED GLOBAL TARGET WITH THE COMPONENTS #####################
-        {%- for comp_variable_name, comp_target_name in components_names %}
+                set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_LINK_OPTIONS
+                             $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'LINKER_FLAGS', config_suffix)}}> APPEND)
+                set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+                             $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'INCLUDE_DIRS', config_suffix)}}> APPEND)
+                set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_COMPILE_DEFINITIONS
+                             $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'COMPILE_DEFINITIONS', config_suffix)}}> APPEND)
+                set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_COMPILE_OPTIONS
+                             $<$<CONFIG:{{ configuration }}>:
+                             {{tvalue(pkg_name, comp_variable_name, 'COMPILE_OPTIONS_C', config_suffix)}}
+                             {{tvalue(pkg_name, comp_variable_name, 'COMPILE_OPTIONS_CXX', config_suffix)}}> APPEND)
+                set({{ pkg_name }}_{{ comp_variable_name }}_TARGET_PROPERTIES TRUE)
 
-        target_link_libraries({{root_target_name}} INTERFACE {{ comp_target_name }})
+                {%- if set_interface_link_directories %}
+                # This is only used for '#pragma comment(lib, "foo")' (automatic link)
+                set_property(TARGET {{ comp_target_name }} PROPERTY INTERFACE_LINK_DIRECTORIES
+                             $<$<CONFIG:{{ configuration }}>:{{tvalue(pkg_name, comp_variable_name, 'LIB_DIRS', config_suffix)}}> APPEND)
+
+                {%- endif %}
+            {%endfor %}
+
+
+            ########## AGGREGATED GLOBAL TARGET WITH THE COMPONENTS #####################
+            {%- for comp_variable_name, comp_target_name in components_names %}
+
+            set_property(TARGET {{root_target_name}} PROPERTY INTERFACE_LINK_LIBRARIES {{ comp_target_name }} APPEND)
+
+            {%- endfor %}
 
-        {%- endfor %}
 
         {%- endif %}
 
+
+        ########## For the modules (FindXXX)
+        set({{ pkg_name }}_LIBRARIES{{ config_suffix }} {{root_target_name}})
+
         """)
 
     def get_declared_components_targets_names(self):
diff --git a/conan/tools/cmake/cmakedeps/templates/target_data.py b/conan/tools/cmake/cmakedeps/templates/target_data.py
index f3c2671b4..61011bb0c 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_data.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_data.py
@@ -87,7 +87,6 @@ class ConfigDataTemplate(CMakeDepsFileTemplate):
               set({{ pkg_name }}_PACKAGE_FOLDER{{ config_suffix }} "{{ package_folder }}")
               set({{ pkg_name }}_BUILD_MODULES_PATHS{{ config_suffix }} {{ global_cpp.build_modules_paths }})
 
-              {% if not has_components %}
 
               set({{ pkg_name }}_INCLUDE_DIRS{{ config_suffix }} {{ global_cpp.include_paths }})
               set({{ pkg_name }}_RES_DIRS{{ config_suffix }} {{ global_cpp.res_paths }})
@@ -104,11 +103,13 @@ class ConfigDataTemplate(CMakeDepsFileTemplate):
               set({{ pkg_name }}_FRAMEWORK_DIRS{{ config_suffix }} {{ global_cpp.framework_paths }})
               set({{ pkg_name }}_FRAMEWORKS{{ config_suffix }} {{ global_cpp.frameworks }})
               set({{ pkg_name }}_BUILD_DIRS{{ config_suffix }} {{ global_cpp.build_paths }})
-              {% else %}
+
 
               set({{ pkg_name }}_COMPONENTS{{ config_suffix }} {{ components_names }})
               {%- for comp_variable_name, comp_target_name, cpp in components_cpp %}
-              ########### COMPONENT {{ comp_target_name }} VARIABLES #############################################
+
+              ########### COMPONENT {{ comp_target_name }} VARIABLES ############################################
+
               set({{ pkg_name }}_{{ comp_variable_name }}_INCLUDE_DIRS{{ config_suffix }} {{ cpp.include_paths }})
               set({{ pkg_name }}_{{ comp_variable_name }}_LIB_DIRS{{ config_suffix }} {{ cpp.lib_paths }})
               set({{ pkg_name }}_{{ comp_variable_name }}_RES_DIRS{{ config_suffix }} {{ cpp.res_paths }})
@@ -129,16 +130,16 @@ class ConfigDataTemplate(CMakeDepsFileTemplate):
                       $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>{{ ':${' }}{{ pkg_name }}_{{ comp_variable_name }}_SHARED_LINK_FLAGS{{ config_suffix }}}>
                       $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>{{ ':${' }}{{ pkg_name }}_{{ comp_variable_name }}_EXE_LINK_FLAGS{{ config_suffix }}}>
               )
-              {%- endfor %}
 
-              {%- endif %}
+
+              {%- endfor %}
           """)
         return ret
 
     def _get_global_cpp_cmake(self):
+        global_cppinfo = self.conanfile.cpp_info.aggregated_components()
         pfolder_var_name = "{}_PACKAGE_FOLDER{}".format(self.pkg_name, self.config_suffix)
-        return _TargetDataContext(self.conanfile.cpp_info, pfolder_var_name,
-                                  self.conanfile.package_folder)
+        return _TargetDataContext(global_cppinfo, pfolder_var_name, self.conanfile.package_folder)
 
     def _get_required_components_cpp(self):
         """Returns a list of (component_name, DepsCppCMake)"""
diff --git a/conan/tools/cmake/layout.py b/conan/tools/cmake/layout.py
index 6a464f5c3..f39ef6974 100644
--- a/conan/tools/cmake/layout.py
+++ b/conan/tools/cmake/layout.py
@@ -3,7 +3,7 @@ import os
 from conans.errors import ConanException
 
 
-def cmake_layout(conanfile, generator=None, src_folder="."):
+def cmake_layout(conanfile, generator=None, src_folder=".", build_folder="build"):
     gen = conanfile.conf.get("tools.cmake.cmaketoolchain:generator", default=generator)
     if gen:
         multi = "Visual" in gen or "Xcode" in gen or "Multi-Config" in gen
@@ -21,17 +21,17 @@ def cmake_layout(conanfile, generator=None, src_folder="."):
     except ConanException:
         raise ConanException("'build_type' setting not defined, it is necessary for cmake_layout()")
 
-    build_folder = "build" if not subproject else os.path.join(subproject, "build")
+    build_folder = build_folder if not subproject else os.path.join(subproject, build_folder)
     custom_conf = get_build_folder_custom_vars(conanfile)
     if custom_conf:
-        build_folder = "{}/{}".format(build_folder, custom_conf)
+        build_folder = os.path.join(build_folder, custom_conf)
 
     if multi:
         conanfile.folders.build = build_folder
     else:
-        conanfile.folders.build = "{}/{}".format(build_folder, build_type)
+        conanfile.folders.build = os.path.join(build_folder, build_type)
 
-    conanfile.folders.generators = "{}/{}".format(build_folder, "generators")
+    conanfile.folders.generators = os.path.join(build_folder, "generators")
 
     conanfile.cpp.source.includedirs = ["include"]
 
diff --git a/conan/tools/cmake/presets.py b/conan/tools/cmake/presets.py
index 03449a059..2b710d190 100644
--- a/conan/tools/cmake/presets.py
+++ b/conan/tools/cmake/presets.py
@@ -133,7 +133,8 @@ def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables):
         if "CMAKE_SH" not in cache_variables:
             cache_variables["CMAKE_SH"] = "CMAKE_SH-NOTFOUND"
 
-        cmake_make_program = conanfile.conf.get("tools.gnu:make_program", default=cache_variables.get("CMAKE_MAKE_PROGRAM"))
+        cmake_make_program = conanfile.conf.get("tools.gnu:make_program",
+                                                default=cache_variables.get("CMAKE_MAKE_PROGRAM"))
         if cmake_make_program:
             cmake_make_program = cmake_make_program.replace("\\", "/")
             cache_variables["CMAKE_MAKE_PROGRAM"] = cmake_make_program
@@ -141,6 +142,10 @@ def write_cmake_presets(conanfile, toolchain_file, generator, cache_variables):
     if "CMAKE_POLICY_DEFAULT_CMP0091" not in cache_variables:
         cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] = "NEW"
 
+    if "BUILD_TESTING" not in cache_variables:
+        if conanfile.conf.get("tools.build:skip_test", check_type=bool):
+            cache_variables["BUILD_TESTING"] = "OFF"
+
     preset_path = os.path.join(conanfile.generators_folder, "CMakePresets.json")
     multiconfig = is_multi_configuration(generator)
 
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 5db4af04e..52608545e 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -313,7 +313,7 @@ class AndroidSystemBlock(Block):
         android_ndk_path = android_ndk_path.replace("\\", "/")
 
         ctxt_toolchain = {
-            'android_platform': self._conanfile.settings.os.api_level,
+            'android_platform': 'android-' + str(self._conanfile.settings.os.api_level),
             'android_abi': android_abi,
             'android_stl': libcxx_str,
             'android_ndk_path': android_ndk_path,
@@ -402,11 +402,10 @@ class AppleSystemBlock(Block):
 
     def context(self):
         os_ = self._conanfile.settings.get_safe("os")
-        if not is_apple_os(os_):
+        if not is_apple_os(self._conanfile):
             return None
 
-        arch = self._conanfile.settings.get_safe("arch")
-        host_architecture = to_apple_arch(arch)
+        host_architecture = to_apple_arch(self._conanfile)
         host_os_version = self._conanfile.settings.get_safe("os.version")
         host_sdk_name = self._apple_sdk_name()
         is_debug = self._conanfile.settings.get_safe('build_type') == "Debug"
@@ -522,7 +521,7 @@ class FindFiles(Block):
             find_package_prefer_config = "OFF"
 
         os_ = self._conanfile.settings.get_safe("os")
-        is_apple_ = is_apple_os(os_)
+        is_apple_ = is_apple_os(self._conanfile)
 
         # Read information from host context
         host_req = self._conanfile.dependencies.host.values()
@@ -808,7 +807,7 @@ class GenericSystemBlock(Block):
                     system_name = {'Macos': 'Darwin'}.get(os_host, os_host)
                     #  CMAKE_SYSTEM_VERSION for Apple sets the sdk version, not the os version
                     _system_version = self._conanfile.settings.get_safe("os.sdk_version")
-                    _system_processor = to_apple_arch(arch_host)
+                    _system_processor = to_apple_arch(self._conanfile)
                 elif os_host != 'Android':
                     system_name = self._get_generic_system_name()
                     _system_version = self._conanfile.settings.get_safe("os.version")
diff --git a/conan/tools/files/files.py b/conan/tools/files/files.py
index 3f69573b9..e46e02b2f 100644
--- a/conan/tools/files/files.py
+++ b/conan/tools/files/files.py
@@ -15,7 +15,6 @@ from urllib.parse import urlparse
 from urllib.request import url2pathname
 
 from conan.tools import CONAN_TOOLCHAIN_ARGS_FILE, CONAN_TOOLCHAIN_ARGS_SECTION
-from conan.tools.apple.apple import is_apple_os
 from conans.client.downloaders.download import run_downloader
 from conans.errors import ConanException
 from conans.util.files import rmdir as _internal_rmdir
@@ -79,7 +78,7 @@ def rm(conanfile, pattern, folder, recursive=False):
             break
 
 
-def get(conanfile, url, md5='', sha1='', sha256='', destination=".", filename="",
+def get(conanfile, url, md5=None, sha1=None, sha256=None, destination=".", filename="",
         keep_permissions=False, pattern=None, verify=True, retry=None, retry_wait=None,
         auth=None, headers=None, strip_root=False):
     """ high level downloader + unzipper + (optional hash checker) + delete temporary zip
@@ -125,7 +124,7 @@ def ftp_download(conanfile, ip, filename, login='', password=''):
 
 
 def download(conanfile, url, filename, verify=True, retry=None, retry_wait=None,
-             auth=None, headers=None, md5='', sha1='', sha256=''):
+             auth=None, headers=None, md5=None, sha1=None, sha256=None):
     """Retrieves a file from a given URL into a file with a given filename.
        It uses certificates from a list of known verifiers for https downloads,
        but this can be optionally disabled.
@@ -168,7 +167,8 @@ def download(conanfile, url, filename, verify=True, retry=None, retry_wait=None,
     def _download_file(file_url):
         # The download cache is only used if a checksum is provided, otherwise, a normal download
         if file_url.startswith("file:"):
-            _copy_local_file_from_uri(conanfile, url=file_url, file_path=filename, md5=md5, sha1=sha1, sha256=sha256)
+            _copy_local_file_from_uri(conanfile, url=file_url, file_path=filename, md5=md5,
+                                      sha1=sha1, sha256=sha256)
         else:
             run_downloader(requester=requester, output=out, verify=verify, download_cache=download_cache,
                         user_download=True, url=file_url,
@@ -189,17 +189,19 @@ def download(conanfile, url, filename, verify=True, retry=None, retry_wait=None,
         else:
             raise ConanException("All downloads from ({}) URLs have failed.".format(len(url)))
 
+
 def _copy_local_file_from_uri(conanfile, url, file_path, md5=None, sha1=None, sha256=None):
     file_origin = _path_from_file_uri(url)
     shutil.copyfile(file_origin, file_path)
 
-    if md5:
+    if md5 is not None:
         check_md5(conanfile, file_path, md5)
-    if sha1:
+    if sha1 is not None:
         check_sha1(conanfile, file_path, sha1)
-    if sha256:
+    if sha256 is not None:
         check_sha256(conanfile, file_path, sha256)
 
+
 def _path_from_file_uri(uri):
     path = urlparse(uri).path
     return url2pathname(path)
@@ -514,24 +516,29 @@ def collect_libs(conanfile, folder=None):
     else:
         lib_folders = [os.path.join(conanfile.package_folder, folder)
                        for folder in conanfile.cpp_info.libdirs]
-    result = []
+
+    ref_libs = {}
     for lib_folder in lib_folders:
         if not os.path.exists(lib_folder):
             conanfile.output.warn("Lib folder doesn't exist, can't collect libraries: "
                                   "{0}".format(lib_folder))
             continue
+        # In case of symlinks, only keep shortest file name in the same "group"
         files = os.listdir(lib_folder)
         for f in files:
             name, ext = os.path.splitext(f)
             if ext in (".so", ".lib", ".a", ".dylib", ".bc"):
-                if ext != ".lib" and name.startswith("lib"):
-                    name = name[3:]
-                if name in result:
-                    conanfile.output.warn("Library '%s' was either already found in a previous "
-                                          "'conanfile.cpp_info.libdirs' folder or appears several "
-                                          "times with a different file extension" % name)
-                else:
-                    result.append(name)
+                real_lib = os.path.basename(os.path.realpath(os.path.join(lib_folder, f)))
+                if real_lib not in ref_libs or len(f) < len(ref_libs[real_lib]):
+                    ref_libs[real_lib] = f
+
+    result = []
+    for f in ref_libs.values():
+        name, ext = os.path.splitext(f)
+        if ext != ".lib" and name.startswith("lib"):
+            name = name[3:]
+        if name not in result:
+            result.append(name)
     result.sort()
     return result
 
diff --git a/conan/tools/files/patches.py b/conan/tools/files/patches.py
index dd3084be9..7c5587e61 100644
--- a/conan/tools/files/patches.py
+++ b/conan/tools/files/patches.py
@@ -110,8 +110,9 @@ def apply_conandata_patches(conanfile):
     for it in entries:
         if "patch_file" in it:
             # The patch files are located in the root src
-            patch_file = os.path.join(conanfile.folders.base_source, it.pop("patch_file"))
-            patch(conanfile, patch_file=patch_file, **it)
+            entry = it.copy()
+            patch_file = os.path.join(conanfile.folders.base_source, entry.pop("patch_file"))
+            patch(conanfile, patch_file=patch_file, **entry)
         elif "patch_string" in it:
             patch(conanfile, **it)
         else:
diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py
index d10f36d3b..c747f7903 100644
--- a/conan/tools/gnu/autotoolstoolchain.py
+++ b/conan/tools/gnu/autotoolstoolchain.py
@@ -2,7 +2,7 @@ from conan.tools._check_build_profile import check_using_build_profile
 from conan.tools._compilers import architecture_flag, build_type_flags, cppstd_flag, \
     build_type_link_flags
 from conan.tools.apple.apple import apple_min_version_flag, to_apple_arch, \
-    apple_sdk_path, is_apple_os
+    apple_sdk_path
 from conan.tools.build.cross_building import cross_building, get_cross_building_settings
 from conan.tools.env import Environment
 from conan.tools.files.files import save_toolchain_args
@@ -63,7 +63,7 @@ class AutotoolsToolchain:
             # Apple Stuff
             if os_build == "Macos":
                 sdk_path = apple_sdk_path(conanfile)
-                apple_arch = to_apple_arch(self._conanfile.settings.get_safe("arch"))
+                apple_arch = to_apple_arch(self._conanfile)
                 # https://man.archlinux.org/man/clang.1.en#Target_Selection_Options
                 self.apple_arch_flag = "-arch {}".format(apple_arch) if apple_arch else None
                 # -isysroot makes all includes for your library relative to the build directory
diff --git a/conan/tools/gnu/gnudeps_flags.py b/conan/tools/gnu/gnudeps_flags.py
index 2546c7831..052711afd 100644
--- a/conan/tools/gnu/gnudeps_flags.py
+++ b/conan/tools/gnu/gnudeps_flags.py
@@ -46,7 +46,7 @@ class GnuDepsFlags(object):
         or an empty array, if Apple Frameworks aren't supported by the given compiler
         """
         os_ = self._conanfile.settings.get_safe("os")
-        if not frameworks or not is_apple_os(os_):
+        if not frameworks or not is_apple_os(self._conanfile):
             return []
         compiler = self._conanfile.settings.get_safe("compiler")
         if str(compiler) not in self._GCC_LIKE:
diff --git a/conan/tools/meson/helpers.py b/conan/tools/meson/helpers.py
index 28cb09822..f3da633ee 100644
--- a/conan/tools/meson/helpers.py
+++ b/conan/tools/meson/helpers.py
@@ -58,7 +58,7 @@ _cppstd_map = {
     '11': "c++11", 'gnu11': "gnu++11",
     '14': "c++14", 'gnu14': "gnu++14",
     '17': "c++17", 'gnu17': "gnu++17",
-    '20': "c++1z", 'gnu20': "gnu++1z"
+    '20': "c++20", 'gnu20': "gnu++20"
 }
 
 
diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py
index d0e264227..2daa47d2a 100644
--- a/conan/tools/meson/toolchain.py
+++ b/conan/tools/meson/toolchain.py
@@ -87,7 +87,7 @@ class MesonToolchain(object):
     def __init__(self, conanfile, backend=None):
         self._conanfile = conanfile
         self._os = self._conanfile.settings.get_safe("os")
-        self._is_apple_system = is_apple_os(self._os)
+        self._is_apple_system = is_apple_os(self._conanfile)
 
         # Values are kept as Python built-ins so users can modify them more easily, and they are
         # only converted to Meson file syntax for rendering
@@ -147,7 +147,7 @@ class MesonToolchain(object):
                 os_target = settings_target.get_safe("os")
                 arch_target = settings_target.get_safe("arch")
                 self.cross_build["target"] = to_meson_machine(os_target, arch_target)
-            if is_apple_os(os_host):  # default cross-compiler in Apple is common
+            if is_apple_os(self._conanfile):  # default cross-compiler in Apple is common
                 default_comp = "clang"
                 default_comp_cpp = "clang++"
         else:
@@ -244,7 +244,7 @@ class MesonToolchain(object):
             raise ConanException("Please, specify a suitable value for os.sdk.")
 
         # Calculating the main Apple flags
-        arch = to_apple_arch(self._conanfile.settings.get_safe("arch"))
+        arch = to_apple_arch(self._conanfile)
         self.apple_arch_flag = ["-arch", arch] if arch else []
         self.apple_isysroot_flag = ["-isysroot", sdk_path] if sdk_path else []
         self.apple_min_version_flag = [apple_min_version_flag(self._conanfile)]
diff --git a/conan/tools/microsoft/msbuilddeps.py b/conan/tools/microsoft/msbuilddeps.py
index 8b1165823..009395802 100644
--- a/conan/tools/microsoft/msbuilddeps.py
+++ b/conan/tools/microsoft/msbuilddeps.py
@@ -1,16 +1,17 @@
 import fnmatch
 import os
+import re
 import textwrap
 from xml.dom import minidom
 
 from jinja2 import Template
 
 from conan.tools._check_build_profile import check_using_build_profile
-from conans.client.graph.graph import CONTEXT_BUILD
 from conans.errors import ConanException
 from conans.util.files import load, save
 
 VALID_LIB_EXTENSIONS = (".so", ".lib", ".a", ".dylib", ".bc")
+EXCLUDED_SYMBOLS_PATTERN = re.compile(r"[\.+\-]")
 
 
 class MSBuildDeps(object):
@@ -126,10 +127,13 @@ class MSBuildDeps(object):
     @staticmethod
     def _dep_name(dep, build):
         dep_name = dep.ref.name
-        dep_name = dep_name.replace(".", "_")
         if build:  # dep.context == CONTEXT_BUILD:
             dep_name += "_build"
-        return dep_name
+        return MSBuildDeps._get_valid_xml_format(dep_name)
+
+    @staticmethod
+    def _get_valid_xml_format(name):
+        return EXCLUDED_SYMBOLS_PATTERN.sub("_", name)
 
     def _vars_props_file(self, dep, name, cpp_info, deps, build):
         """
@@ -224,7 +228,6 @@ class MSBuildDeps(object):
             </Project>
             """)
             content_multi = Template(content_multi).render({"name": dep_name})
-
         # parse the multi_file and add new import statement if needed
         dom = minidom.parseString(content_multi)
         import_vars = dom.getElementsByTagName('ImportGroup')[0]
@@ -283,7 +286,7 @@ class MSBuildDeps(object):
             for comp_name, comp_info in dep.cpp_info.components.items():
                 if comp_name is None:
                     continue
-                full_comp_name = "{}_{}".format(dep_name, comp_name)
+                full_comp_name = "{}_{}".format(dep_name, self._get_valid_xml_format(comp_name))
                 vars_filename = "conan_%s_vars%s.props" % (full_comp_name, conf_name)
                 activate_filename = "conan_%s%s.props" % (full_comp_name, conf_name)
                 comp_filename = "conan_%s.props" % full_comp_name
diff --git a/conan/tools/scm/__init__.py b/conan/tools/scm/__init__.py
index 9d4097bc7..59846cc18 100644
--- a/conan/tools/scm/__init__.py
+++ b/conan/tools/scm/__init__.py
@@ -1,2 +1,200 @@
 from conan.tools.scm.git import Git
-from conans.model.version import Version
+# develop2 uncomment the next line
+# from conans.model.version import Version
+
+
+# ######## DEVELOP2: Delete all the contents from here, this is copy-paste from the Version model
+# ######## at conans.model.version (for an easier migration)
+from functools import total_ordering
+from conans.errors import ConanException
+
+
+@total_ordering
+class _VersionItem:
+    """ a single "digit" in a version, like X.Y.Z all X and Y and Z are VersionItems
+    They can be int or strings
+    """
+    def __init__(self, item):
+        try:
+            self._v = int(item)
+        except ValueError:
+            self._v = item
+
+    @property
+    def value(self):
+        return self._v
+
+    def __str__(self):
+        return str(self._v)
+
+    def __add__(self, other):
+        # necessary for the "bump()" functionality. Other aritmetic operations are missing
+        return self._v + other
+
+    def __eq__(self, other):
+        if not isinstance(other, _VersionItem):
+            other = _VersionItem(other)
+        return self._v == other._v
+
+    def __hash__(self):
+        return hash(self._v)
+
+    def __lt__(self, other):
+        """
+        @type other: _VersionItem
+        """
+        if not isinstance(other, _VersionItem):
+            other = _VersionItem(other)
+        try:
+            return self._v < other._v
+        except TypeError:
+            return str(self._v) < str(other._v)
+
+
+@total_ordering
+class Version:
+    """
+    This is NOT an implementation of semver, as users may use any pattern in their versions.
+    It is just a helper to parse "." or "-" and compare taking into account integers when possible
+    """
+    def __init__(self, value):
+        value = str(value)
+        self._value = value
+
+        items = value.rsplit("+", 1)  # split for build
+        if len(items) == 2:
+            value, build = items
+            self._build = Version(build)  # This is a nested version by itself
+        else:
+            value = items[0]
+            self._build = None
+
+        items = value.rsplit("-", 1)  # split for pre-release
+        if len(items) == 2:
+            value, pre = items
+            self._pre = Version(pre)  # This is a nested version by itself
+        else:
+            value = items[0]
+            self._pre = None
+        items = value.split(".")
+        items = [_VersionItem(item) for item in items]
+        self._items = tuple(items)
+        while items and items[-1].value == 0:
+            del items[-1]
+        self._nonzero_items = tuple(items)
+
+    def bump(self, index):
+        """
+           Increments by 1 the version field at the specified index, setting to 0 the fields
+            on the right.
+           2.5 => bump(1) => 2.6
+           1.5.7 => bump(0) => 2.0.0
+        """
+        # this method is used to compute version ranges from tilde ~1.2 and caret ^1.2.1 ranges
+        # TODO: at this moment it only works for digits, cannot increment pre-release or builds
+        # better not make it public yet, keep it internal
+        items = list(self._items[:index])
+        try:
+            items.append(self._items[index]+1)
+        except TypeError:
+            raise ConanException(f"Cannot bump '{self._value} version index {index}, not an int")
+        items.extend([0] * (len(items) - index - 1))
+        v = ".".join(str(i) for i in items)
+        # prerelease and build are dropped while bumping digits
+        result = Version(v)
+        return result
+
+    def upper_bound(self, index):
+        items = list(self._items[:index])
+        try:
+            items.append(self._items[index] + 1)
+        except TypeError:
+            raise ConanException(f"Cannot bump '{self._value} version index {index}, not an int")
+        items.extend([0] * (len(items) - index - 1))
+        v = ".".join(str(i) for i in items)
+        v += "-"  # Exclude prereleases
+        result = Version(v)
+        return result
+
+    @property
+    def pre(self):
+        return self._pre
+
+    @property
+    def build(self):
+        return self._build
+
+    @property
+    def main(self):
+        return self._items
+
+    @property
+    def major(self):
+        try:
+            return self.main[0]
+        except IndexError:
+            return None
+
+    @property
+    def minor(self):
+        try:
+            return self.main[1]
+        except IndexError:
+            return None
+
+    @property
+    def patch(self):
+        try:
+            return self.main[2]
+        except IndexError:
+            return None
+
+    @property
+    def micro(self):
+        try:
+            return self.main[3]
+        except IndexError:
+            return None
+
+    def __str__(self):
+        return self._value
+
+    def __repr__(self):
+        return self._value
+
+    def __eq__(self, other):
+        if other is None:
+            return False
+        if isinstance(other, str):
+            other = Version(other)
+
+        return (self._nonzero_items, self._pre, self._build) ==\
+               (other._nonzero_items, other._pre, other._build)
+
+    def __hash__(self):
+        return hash((self._nonzero_items, self._pre, self._build))
+
+    def __lt__(self, other):
+        if other is None:
+            return False
+        if not isinstance(other, Version):
+            other = Version(other)
+
+        if self._pre:
+            if other._pre:  # both are pre-releases
+                return (self._nonzero_items, self._pre, self._build) < \
+                       (other._nonzero_items, other._pre, other._build)
+            else:  # Left hand is pre-release, right side is regular
+                if self._nonzero_items == other._nonzero_items:  # Problem only happens if both equal
+                    return True
+                else:
+                    return self._nonzero_items < other._nonzero_items
+        else:
+            if other._pre:  # Left hand is regular, right side is pre-release
+                if self._nonzero_items == other._nonzero_items:  # Problem only happens if both equal
+                    return False
+                else:
+                    return self._nonzero_items < other._nonzero_items
+            else:  # None of them is pre-release
+                return (self._nonzero_items, self._build) < (other._nonzero_items, other._build)
+
diff --git a/conan/tools/scm/git.py b/conan/tools/scm/git.py
index 9cd8041b9..bdff76981 100644
--- a/conan/tools/scm/git.py
+++ b/conan/tools/scm/git.py
@@ -76,12 +76,13 @@ class Git(object):
         folder = self._run("rev-parse --show-toplevel")
         return folder.replace("\\", "/")
 
-    def clone(self, url, target=""):
+    def clone(self, url, target="", args=None):
+        args = args or []
         if os.path.exists(url):
             url = url.replace("\\", "/")  # Windows local directory
         mkdir(self.folder)
         self._conanfile.output.info("Cloning git repo")
-        self._run('clone "{}" {}'.format(url, target))
+        self._run('clone "{}" {} {}'.format(url, " ".join(args), target))
 
     def checkout(self, commit):
         self._conanfile.output.info("Checkout: {}".format(commit))
diff --git a/conan/tools/system/package_manager.py b/conan/tools/system/package_manager.py
index 52d6e9106..a416d2db5 100644
--- a/conan/tools/system/package_manager.py
+++ b/conan/tools/system/package_manager.py
@@ -103,9 +103,6 @@ class _SystemPackageManagerTool(object):
         raise ConanException("None of the installs for the package substitutes succeeded.")
 
     def _install(self, packages, update=False, check=True, **kwargs):
-        if update:
-            self.update()
-
         if check:
             packages = self.check(packages)
 
@@ -120,6 +117,9 @@ class _SystemPackageManagerTool(object):
                                                                                      self.mode_check,
                                                                                      self.mode_install))
         elif packages:
+            if update:
+                self.update()
+
             packages_arch = [self.get_package_name(package) for package in packages]
             if packages_arch:
                 command = self.install_command.format(sudo=self.sudo_str,
@@ -132,16 +132,11 @@ class _SystemPackageManagerTool(object):
                                         "installed".format(" ".join(packages)))
 
     def _update(self):
-        if self._mode == self.mode_check:
-            raise ConanException("Can't update because tools.system.package_manager:mode is '{0}'."
-                                 "Please update packages manually or set "
-                                 "'tools.system.package_manager:mode' "
-                                 "to '{1}' in the [conf] section of the profile, "
-                                 "or in the command line using "
-                                 "'-c tools.system.package_manager:mode={1}'".format(self.mode_check,
-                                                                                     self.mode_install))
-        command = self.update_command.format(sudo=self.sudo_str, tool=self.tool_name)
-        return self._conanfile_run(command, self.accepted_update_codes)
+        # we just update the package manager database in case we are in 'install mode'
+        # in case we are in check mode just ignore
+        if self._mode == self.mode_install:
+            command = self.update_command.format(sudo=self.sudo_str, tool=self.tool_name)
+            return self._conanfile_run(command, self.accepted_update_codes)
 
     def _check(self, packages):
         missing = [pkg for pkg in packages if self.check_package(self.get_package_name(pkg)) != 0]
@@ -226,7 +221,7 @@ class PkgUtil(_SystemPackageManagerTool):
 
 class Chocolatey(_SystemPackageManagerTool):
     tool_name = "choco"
-    install_command = "{tool} --install --yes {packages}"
+    install_command = "{tool} install --yes {packages}"
     update_command = "{tool} outdated"
     check_command = '{tool} search --local-only --exact {package} | ' \
                     'findstr /c:"1 packages installed."'
diff --git a/conans/__init__.py b/conans/__init__.py
index 87a5a9d81..993b6a958 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.51.0-dev'
+__version__ = '1.52.0-dev'
diff --git a/conans/assets/templates/new_v2_cmake.py b/conans/assets/templates/new_v2_cmake.py
index 891d1634c..9380e33a3 100644
--- a/conans/assets/templates/new_v2_cmake.py
+++ b/conans/assets/templates/new_v2_cmake.py
@@ -131,6 +131,10 @@ void {name}(){{
     std::cout << "  {name}/{version}: _M_IX86 defined\n";
     #endif
 
+    #ifdef _M_ARM64
+    std::cout << "  {name}/{version}: _M_ARM64 defined\n";
+    #endif
+
     #if __i386__
     std::cout << "  {name}/{version}: __i386__ defined\n";
     #endif
@@ -139,6 +143,10 @@ void {name}(){{
     std::cout << "  {name}/{version}: __x86_64__ defined\n";
     #endif
 
+    #if __aarch64__
+    std::cout << "  {name}/{version}: __aarch64__ defined\n";
+    #endif
+
     // Libstdc++
     #if defined _GLIBCXX_USE_CXX11_ABI
     std::cout << "  {name}/{version}: _GLIBCXX_USE_CXX11_ABI "<< _GLIBCXX_USE_CXX11_ABI << "\n";
diff --git a/conans/assets/templates/new_v2_msbuild.py b/conans/assets/templates/new_v2_msbuild.py
index da4329e98..e7f2cc6ee 100644
--- a/conans/assets/templates/new_v2_msbuild.py
+++ b/conans/assets/templates/new_v2_msbuild.py
@@ -311,6 +311,10 @@ void {{name}}(){
     std::cout << "  {{name}}/{{version}}: _M_IX86 defined\n";
     #endif
 
+    #ifdef _M_ARM64
+    std::cout << "  {{name}}/{{version}}: _M_ARM64 defined\n";
+    #endif
+
     #if __i386__
     std::cout << "  {{name}}/{{version}}: __i386__ defined\n";
     #endif
@@ -319,6 +323,10 @@ void {{name}}(){
     std::cout << "  {{name}}/{{version}}: __x86_64__ defined\n";
     #endif
 
+    #if __aarch64__
+    std::cout << "  {{name}}/{{version}}: __aarch64__ defined\n";
+    #endif
+
     // Libstdc++
     #if defined _GLIBCXX_USE_CXX11_ABI
     std::cout << "  {{name}}/{{version}}: _GLIBCXX_USE_CXX11_ABI "<< _GLIBCXX_USE_CXX11_ABI << "\n";
diff --git a/conans/client/build/cppstd_flags.py b/conans/client/build/cppstd_flags.py
index 9b96ce7cd..650ecc89d 100644
--- a/conans/client/build/cppstd_flags.py
+++ b/conans/client/build/cppstd_flags.py
@@ -50,14 +50,10 @@ def cppstd_flag_new(settings):
 
 
 def cppstd_default(settings):
-    if getattr(settings, "get_safe", None):
-        compiler = settings.get_safe("compiler")
-        compiler_version = settings.get_safe("compiler.version")
-        compiler_base = settings.get_safe("compiler.base")
-    else:
-        compiler = str(settings.compiler)
-        compiler_version = str(settings.compiler.version)
-        compiler_base = str(settings.compiler.base)
+
+    compiler = settings.get_safe("compiler")
+    compiler_version = settings.get_safe("compiler.version")
+    compiler_base = settings.get_safe("compiler.base")
     intel_cppstd_default = _intel_visual_cppstd_default if compiler_base == "Visual Studio" \
         else _intel_gcc_cppstd_default
     default = {"gcc": _gcc_cppstd_default(compiler_version),
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
index 4e1212307..25768c904 100644
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -118,7 +118,7 @@ _t_default_settings_yml = Template(textwrap.dedent("""
         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"]
+                      "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]
diff --git a/conans/client/conf/config_installer.py b/conans/client/conf/config_installer.py
index 4e54c6b9b..434868531 100644
--- a/conans/client/conf/config_installer.py
+++ b/conans/client/conf/config_installer.py
@@ -108,9 +108,10 @@ def _process_file(directory, filename, config, cache, output, folder):
         finally:
             _filecopy(directory, filename, cache.cache_folder)
             migrate_registry_file(cache, output)
+    # FIXME: remove in 2.0
     elif filename == "remotes.json":
-        # Fix for Conan 2.0
-        raise ConanException("remotes.json install is not supported yet. Use 'remotes.txt'")
+        output.info("Defining remotes from remotes.json")
+        _filecopy(directory, filename, cache.cache_folder)
     else:
         # This is ugly, should be removed in Conan 2.0
         if filename in ("README.md", "LICENSE.txt") and not directory.startswith("templates"):
@@ -137,6 +138,7 @@ def _process_folder(config, folder, cache, output):
         raise ConanException("No such directory: '%s'" % str(folder))
     if config.source_folder:
         folder = os.path.join(folder, config.source_folder)
+
     for root, dirs, files in walk(folder):
         dirs[:] = [d for d in dirs if d != ".git"]
         for f in files:
diff --git a/conans/client/downloaders/file_downloader.py b/conans/client/downloaders/file_downloader.py
index 659461810..0611d73af 100644
--- a/conans/client/downloaders/file_downloader.py
+++ b/conans/client/downloaders/file_downloader.py
@@ -16,11 +16,11 @@ from conans.util.tracer import log_download
 
 
 def check_checksum(file_path, md5, sha1, sha256):
-    if md5:
+    if md5 is not None:
         check_md5(file_path, md5)
-    if sha1:
+    if sha1 is not None:
         check_sha1(file_path, sha1)
-    if sha256:
+    if sha256 is not None:
         check_sha256(file_path, sha256)
 
 
diff --git a/conans/client/generators/cmake_paths.py b/conans/client/generators/cmake_paths.py
index 1a35dcdde..c9cdd1e1b 100644
--- a/conans/client/generators/cmake_paths.py
+++ b/conans/client/generators/cmake_paths.py
@@ -15,10 +15,12 @@ class CMakePathsGenerator(Generator):
         # The CONAN_XXX_ROOT variables are needed because the FindXXX.cmake or XXXConfig.cmake
         # in a package could have been "patched" with the `cmake.patch_config_paths()`
         # replacing absolute paths with CONAN_XXX_ROOT variables.
+        var_names = []
         for _, dep_cpp_info in self.deps_build_info.dependencies:
             var_name = "CONAN_{}_ROOT".format(dep_cpp_info.get_name(self.name).upper())
-            lines.append('set({} {})'.format(var_name, DepsCppCmake(dep_cpp_info,
-                                                                    self.name).rootpath))
+            rootpath = DepsCppCmake(dep_cpp_info, self.name).rootpath
+            lines.append('set({} {})'.format(var_name, rootpath))
+            var_names.append("${%s}" % var_name)
 
         # We want to prioritize the FindXXX.cmake files:
         # 1. First the files found in the packages
@@ -26,10 +28,11 @@ class CMakePathsGenerator(Generator):
         # 3. The "install_folder" ones, in case there is no FindXXX.cmake, try with the install dir
         #    if the user used the "cmake_find_package" will find the auto-generated
         # 4. The CMake installation dir/Modules ones.
+        var_names = " ".join(var_names)
         deps = DepsCppCmake(self.deps_build_info, self.name)
-        lines.append("set(CMAKE_MODULE_PATH {deps.build_paths} ${{CMAKE_MODULE_PATH}} "
-                     "${{CMAKE_CURRENT_LIST_DIR}})".format(deps=deps))
-        lines.append("set(CMAKE_PREFIX_PATH {deps.build_paths} ${{CMAKE_PREFIX_PATH}} "
-                     "${{CMAKE_CURRENT_LIST_DIR}})".format(deps=deps))
+        lines.append("set(CMAKE_MODULE_PATH {deps.build_paths} {var_names} ${{CMAKE_MODULE_PATH}} "
+                     "${{CMAKE_CURRENT_LIST_DIR}})".format(deps=deps, var_names=var_names))
+        lines.append("set(CMAKE_PREFIX_PATH {deps.build_paths} {var_names} ${{CMAKE_PREFIX_PATH}} "
+                     "${{CMAKE_CURRENT_LIST_DIR}})".format(deps=deps, var_names=var_names))
 
         return "\n".join(lines)
diff --git a/conans/client/installer.py b/conans/client/installer.py
index 260c7dcdd..5f9faddde 100644
--- a/conans/client/installer.py
+++ b/conans/client/installer.py
@@ -218,10 +218,10 @@ class _PackageBuilder(object):
                 conanfile.folders.set_base_build(base_build)
                 conanfile.folders.set_base_imports(base_build)
                 conanfile.folders.set_base_package(base_package)
+                # In local cache, generators folder always in build_folder
+                conanfile.folders.set_base_generators(base_build)
 
                 if not skip_build:
-                    # In local cache, generators folder always in build_folder
-                    conanfile.folders.set_base_generators(base_build)
                     # In local cache, install folder always is build_folder
                     conanfile.folders.set_base_install(base_build)
                     self._build(conanfile, pref)
@@ -680,6 +680,12 @@ class BinaryInstaller(object):
                         # Old cpp info without defaults (the defaults are in the new one)
                         conanfile.cpp_info = CppInfo(conanfile.name, package_folder,
                                                      default_values=CppInfoDefaultValues())
+                        # Note: Remember that this is not needed for Conan 2.x
+                        # Let's avoid losing this information.
+                        conanfile.cpp_info.version = conanfile.version
+                        conanfile.cpp_info.description = conanfile.description
+                        conanfile.cpp_info.public_deps = public_deps
+
                         if not is_editable:
                             # Copy the infos.package into the old cppinfo
                             fill_old_cppinfo(conanfile.cpp.package, conanfile.cpp_info)
diff --git a/conans/client/loader.py b/conans/client/loader.py
index d1d89130d..804d73b50 100644
--- a/conans/client/loader.py
+++ b/conans/client/loader.py
@@ -2,6 +2,7 @@ import fnmatch
 import imp
 import inspect
 import os
+import re
 import sys
 import types
 import uuid
@@ -436,13 +437,20 @@ def _parse_conanfile(conan_file_path):
         old_modules = list(sys.modules.keys())
         with chdir(current_dir):
             old_dont_write_bytecode = sys.dont_write_bytecode
-            sys.dont_write_bytecode = True
-            loaded = imp.load_source(module_id, conan_file_path)
-            sys.dont_write_bytecode = old_dont_write_bytecode
-
-        required_conan_version = getattr(loaded, "required_conan_version", None)
-        if required_conan_version:
-            validate_conan_version(required_conan_version)
+            try:
+                sys.dont_write_bytecode = True
+                # FIXME: imp is deprecated in favour of implib
+                loaded = imp.load_source(module_id, conan_file_path)
+                sys.dont_write_bytecode = old_dont_write_bytecode
+            except ImportError:
+                version_txt = _get_required_conan_version_without_loading(conan_file_path)
+                if version_txt:
+                    validate_conan_version(version_txt)
+                raise
+
+            required_conan_version = getattr(loaded, "required_conan_version", None)
+            if required_conan_version:
+                validate_conan_version(required_conan_version)
 
         # These lines are necessary, otherwise local conanfile imports with same name
         # collide, but no error, and overwrite other packages imports!!
@@ -475,3 +483,20 @@ def _parse_conanfile(conan_file_path):
         sys.path.pop(0)
 
     return loaded, module_id
+
+
+def _get_required_conan_version_without_loading(conan_file_path):
+    # First, try to detect the required_conan_version in "text" mode
+    # https://github.com/conan-io/conan/issues/11239
+    contents = load(conan_file_path)
+
+    txt_version = None
+
+    try:
+        found = re.search(r"required_conan_version\s*=\s*(.*)", contents)
+        if found:
+            txt_version = found.group(1).replace('"', "")
+    except:
+        pass
+
+    return txt_version
diff --git a/conans/client/manager.py b/conans/client/manager.py
index 620d58a92..f27fba832 100644
--- a/conans/client/manager.py
+++ b/conans/client/manager.py
@@ -77,6 +77,16 @@ def deps_install(app, ref_or_path, install_folder, base_folder, graph_info, remo
     except ConanException:  # Setting os doesn't exist
         pass
 
+    if hasattr(conanfile, "layout") and not test:
+        conanfile.folders.set_base_folders(conanfile_path, output_folder)
+    else:
+        conanfile.folders.set_base_install(install_folder)
+        conanfile.folders.set_base_imports(install_folder)
+        conanfile.folders.set_base_generators(base_folder)
+
+    if hasattr(conanfile, "layout") and test:
+        install_folder = conanfile.generators_folder
+
     installer = BinaryInstaller(app, recorder=recorder)
     # TODO: Extract this from the GraphManager, reuse same object, check args earlier
     build_modes = BuildMode(build_modes, out)
@@ -95,13 +105,6 @@ def deps_install(app, ref_or_path, install_folder, base_folder, graph_info, remo
                                      interactive=manifest_interactive)
         manifest_manager.print_log()
 
-    if hasattr(conanfile, "layout") and not test:
-        conanfile.folders.set_base_folders(conanfile_path, output_folder)
-    else:
-        conanfile.folders.set_base_install(install_folder)
-        conanfile.folders.set_base_imports(install_folder)
-        conanfile.folders.set_base_generators(base_folder)
-
     output = conanfile.output if root_node.recipe != RECIPE_VIRTUAL else out
 
     if conanfile.info.invalid:
@@ -142,3 +145,5 @@ def deps_install(app, ref_or_path, install_folder, base_folder, graph_info, remo
             deploy_conanfile = neighbours[0].conanfile
             if hasattr(deploy_conanfile, "deploy") and callable(deploy_conanfile.deploy):
                 run_deploy(deploy_conanfile, install_folder)
+
+    return install_folder
diff --git a/conans/client/migrations_settings.py b/conans/client/migrations_settings.py
index db79c4f07..48c1a322a 100644
--- a/conans/client/migrations_settings.py
+++ b/conans/client/migrations_settings.py
@@ -3713,5 +3713,163 @@ cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
 """
 
 settings_1_50_0 = settings_1_49_0
+settings_1_50_1 = settings_1_50_0
+settings_1_50_2 = settings_1_50_1
 
-settings_1_51_0 = settings_1_50_0
+settings_1_51_0 = settings_1_50_2
+settings_1_51_1 = settings_1_51_0
+settings_1_51_2 = settings_1_51_1
+settings_1_51_3 = settings_1_51_2
+
+settings_1_52_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"]
+        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"]
+    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"]
+        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"]
+    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"]
+        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"]
+    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"]
+        subsystem:
+            None:
+            catalyst:
+                ios_version: *ios_version
+    Android:
+        api_level: ANY
+    FreeBSD:
+    SunOS:
+    AIX:
+    Arduino:
+        board: ANY
+    Emscripten:
+    Neutrino:
+        version: ["6.4", "6.5", "6.6", "7.0", "7.1"]
+    baremetal:
+    VxWorks:
+        version: ["7"]
+arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7, xtensalx6, xtensalx106, xtensalx7]
+compiler:
+    sun-cc:
+        version: ["5.10", "5.11", "5.12", "5.13", "5.14", "5.15"]
+        threads: [None, posix]
+        libcxx: [libCstd, libstdcxx, libstlport, libstdc++]
+    gcc: &gcc
+        version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9",
+                  "5", "5.1", "5.2", "5.3", "5.4", "5.5",
+                  "6", "6.1", "6.2", "6.3", "6.4", "6.5",
+                  "7", "7.1", "7.2", "7.3", "7.4", "7.5",
+                  "8", "8.1", "8.2", "8.3", "8.4",
+                  "9", "9.1", "9.2", "9.3", "9.4",
+                  "10", "10.1", "10.2", "10.3",
+                  "11", "11.1", "11.2",
+                  "12"]
+        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]
+    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"]
+        libcxx: [libstdc++, libc++]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20]
+    intel:
+        version: ["11", "12", "13", "14", "15", "16", "17", "18", "19", "19.1"]
+        update: [None, ANY]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exception: [None]
+            Visual Studio:
+                <<: *visual_studio
+            apple-clang:
+                <<: *apple_clang
+    intel-cc:
+        version: ["2021.1", "2021.2", "2021.3"]
+        update: [None, ANY]
+        mode: ["icx", "classic", "dpcpp"]
+        libcxx: [None, libstdc++, libstdc++11, libc++]
+        cppstd: [None, 98, gnu98, 03, gnu03, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        runtime: [None, static, dynamic]
+        runtime_type: [None, Debug, Release]
+    qcc:
+        version: ["4.4", "5.4", "8.3"]
+        libcxx: [cxx, gpp, cpp, cpp-ne, accp, acpp-ne, ecpp, ecpp-ne]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17]
+    mcst-lcc:
+        version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exceptions: [None]
+
+build_type: [None, Debug, Release, RelWithDebInfo, MinSizeRel]
+
+
+cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]  # Deprecated, use compiler.cppstd
+"""
diff --git a/conans/client/tools/files.py b/conans/client/tools/files.py
index 199581c0e..a8444b23c 100644
--- a/conans/client/tools/files.py
+++ b/conans/client/tools/files.py
@@ -351,24 +351,29 @@ def collect_libs(conanfile, folder=None):
     else:
         lib_folders = [os.path.join(conanfile.package_folder, folder)
                        for folder in conanfile.cpp_info.libdirs]
-    result = []
+
+    ref_libs = {}
     for lib_folder in lib_folders:
         if not os.path.exists(lib_folder):
             conanfile.output.warn("Lib folder doesn't exist, can't collect libraries: "
                                   "{0}".format(lib_folder))
             continue
+        # In case of symlinks, only keep shortest file name in the same "group"
         files = os.listdir(lib_folder)
         for f in files:
             name, ext = os.path.splitext(f)
             if ext in VALID_LIB_EXTENSIONS:
-                if ext != ".lib" and name.startswith("lib"):
-                    name = name[3:]
-                if name in result:
-                    conanfile.output.warn("Library '%s' was either already found in a previous "
-                                          "'conanfile.cpp_info.libdirs' folder or appears several "
-                                          "times with a different file extension" % name)
-                else:
-                    result.append(name)
+                real_lib = os.path.basename(os.path.realpath(os.path.join(lib_folder, f)))
+                if real_lib not in ref_libs or len(f) < len(ref_libs[real_lib]):
+                    ref_libs[real_lib] = f
+
+    result = []
+    for f in ref_libs.values():
+        name, ext = os.path.splitext(f)
+        if ext != ".lib" and name.startswith("lib"):
+            name = name[3:]
+        if name not in result:
+            result.append(name)
     result.sort()
     return result
 
diff --git a/conans/client/tools/net.py b/conans/client/tools/net.py
index c11bb9961..f6ba4c562 100644
--- a/conans/client/tools/net.py
+++ b/conans/client/tools/net.py
@@ -6,7 +6,7 @@ from conans.errors import ConanException
 from conans.util.fallbacks import default_output, default_requester
 
 
-def get(url, md5='', sha1='', sha256='', destination=".", filename="", keep_permissions=False,
+def get(url, md5=None, sha1=None, sha256=None, destination=".", filename="", keep_permissions=False,
         pattern=None, requester=None, output=None, verify=True, retry=None, retry_wait=None,
         overwrite=False, auth=None, headers=None, strip_root=False):
     """ high level downloader + unzipper + (optional hash checker) + delete temporary zip
@@ -51,7 +51,7 @@ def ftp_download(ip, filename, login='', password=''):
 
 
 def download(url, filename, verify=True, out=None, retry=None, retry_wait=None, overwrite=False,
-             auth=None, headers=None, requester=None, md5='', sha1='', sha256=''):
+             auth=None, headers=None, requester=None, md5=None, sha1=None, sha256=None):
     """Retrieves a file from a given URL into a file with a given filename.
        It uses certificates from a list of known verifiers for https downloads,
        but this can be optionally disabled.
diff --git a/conans/model/build_info.py b/conans/model/build_info.py
index ee5478825..e27d432d5 100644
--- a/conans/model/build_info.py
+++ b/conans/model/build_info.py
@@ -144,7 +144,7 @@ class _CppInfo(object):
 
     def _filter_paths(self, paths):
         abs_paths = [os.path.join(self.rootpath, p)
-                     if not os.path.isabs(p) else p for p in paths]
+                     if not os.path.isabs(p) else p for p in paths if p is not None]
         if self.filter_empty:
             return [p for p in abs_paths if os.path.isdir(p)]
         else:
diff --git a/conans/model/conanfile_interface.py b/conans/model/conanfile_interface.py
index fd9c8b5d1..21353ee7e 100644
--- a/conans/model/conanfile_interface.py
+++ b/conans/model/conanfile_interface.py
@@ -26,6 +26,10 @@ class ConanFileInterface:
     def __ne__(self, other):
         return not self.__eq__(other)
 
+    @property
+    def recipe_folder(self):
+        return self._conanfile.recipe_folder
+
     @property
     def package_folder(self):
         return self._conanfile.package_folder
@@ -82,3 +86,23 @@ class ConanFileInterface:
     @property
     def is_build_context(self):
         return self._conanfile.context == CONTEXT_BUILD
+
+    @property
+    def conan_data(self):
+        return self._conanfile.conan_data
+
+    @property
+    def license(self):
+        return self._conanfile.license
+
+    @property
+    def description(self):
+        return self._conanfile.description
+
+    @property
+    def homepage(self):
+        return self._conanfile.homepage
+
+    @property
+    def url(self):
+        return self._conanfile.url
diff --git a/conans/model/manifest.py b/conans/model/manifest.py
index d323df770..1b260beaf 100644
--- a/conans/model/manifest.py
+++ b/conans/model/manifest.py
@@ -25,7 +25,8 @@ def gather_files(folder):
     symlinks = {}
     keep_python = get_env("CONAN_KEEP_PYTHON_FILES", False)
     for root, dirs, files in walk(folder):
-        dirs[:] = [d for d in dirs if d != "__pycache__"]  # Avoid recursing pycache
+        if not keep_python:
+            dirs[:] = [d for d in dirs if d != "__pycache__"]  # Avoid recursing pycache
         for d in dirs:
             abs_path = os.path.join(root, d)
             if os.path.islink(abs_path):
diff --git a/conans/model/options.py b/conans/model/options.py
index 1b29d8957..642c4afe2 100644
--- a/conans/model/options.py
+++ b/conans/model/options.py
@@ -226,6 +226,11 @@ class OptionsValues(object):
     def __contains__(self, item):
         return item in self._package_values
 
+    def get_safe(self, attr):
+        if attr not in self._package_values:
+            return None
+        return getattr(self._package_values, attr)
+
     def __getitem__(self, item):
         return self._reqs_options.setdefault(item, PackageOptionValues())
 
diff --git a/conans/model/requires.py b/conans/model/requires.py
index 7f577236f..e36cfabe9 100644
--- a/conans/model/requires.py
+++ b/conans/model/requires.py
@@ -180,7 +180,7 @@ class Requirements(OrderedDict):
             new_reqs[name] = req
         return new_reqs
 
-    def __call__(self, reference, private=False, override=False):
+    def __call__(self, reference, private=False, override=False, **kwargs):
         self.add(reference, private, override)
 
     def __repr__(self):
diff --git a/conans/model/values.py b/conans/model/values.py
index 8fa335312..20391ca86 100644
--- a/conans/model/values.py
+++ b/conans/model/values.py
@@ -8,6 +8,10 @@ class Values(object):
         self._dict = {}  # {key: Values()}
         self._modified = {}  # {"compiler.version.arch": (old_value, old_reference)}
 
+    def get_safe(self, attr):
+        values = [v[1] for v in self.as_list() if v[0] == attr]
+        return values[0] if values else None
+
     def __getattr__(self, attr):
         if attr not in self._dict:
             return None
diff --git a/conans/server/conf/__init__.py b/conans/server/conf/__init__.py
index 9ee1c2e81..2b484447d 100644
--- a/conans/server/conf/__init__.py
+++ b/conans/server/conf/__init__.py
@@ -53,6 +53,7 @@ class ConanServerConfigParser(ConfigParser):
                            "public_port": get_env("CONAN_SERVER_PUBLIC_PORT", None, environment),
                            "host_name": get_env("CONAN_HOST_NAME", None, environment),
                            "custom_authenticator": get_env("CONAN_CUSTOM_AUTHENTICATOR", None, environment),
+                           "custom_authorizer": get_env("CONAN_CUSTOM_AUTHORIZER", None, environment),
                            # "user:pass,user2:pass2"
                            "users": get_env("CONAN_SERVER_USERS", None, environment)}
 
@@ -168,6 +169,13 @@ class ConanServerConfigParser(ConfigParser):
         except ConanException:
             return None
 
+    @property
+    def custom_authorizer(self):
+        try:
+            return self._get_conf_server_string("custom_authorizer")
+        except ConanException:
+            return None
+
     @property
     def users(self):
         def validate_pass_encoding(password):
diff --git a/conans/server/conf/default_server_conf.py b/conans/server/conf/default_server_conf.py
index ac09bae96..41510240f 100644
--- a/conans/server/conf/default_server_conf.py
+++ b/conans/server/conf/default_server_conf.py
@@ -27,6 +27,12 @@ updown_secret: {updown_secret}
 #
 # custom_authenticator: my_authenticator
 
+# Check docs.conan.io to implement a different authorizer plugin for conan_server
+# if custom_authorizer is not specified, the [read_permissions] and [write_permissions]
+# sections will be used to grant/reject access.
+#
+# custom_authorizer: my_authorizer
+
 # name/version@user/channel: user1, user2, user3
 #
 # The rules are applied in order. 
diff --git a/conans/server/launcher.py b/conans/server/launcher.py
index e424b407b..ce663e6ba 100644
--- a/conans/server/launcher.py
+++ b/conans/server/launcher.py
@@ -9,7 +9,7 @@ from conans.server.conf import get_server_store
 from conans.server.crypto.jwt.jwt_credentials_manager import JWTCredentialsManager
 from conans.server.crypto.jwt.jwt_updown_manager import JWTUpDownAuthManager
 from conans.server.migrate import migrate_and_get_server_config
-from conans.server.plugin_loader import load_authentication_plugin
+from conans.server.plugin_loader import load_authentication_plugin, load_authorization_plugin
 from conans.server.rest.server import ConanServer
 
 from conans.server.service.authorize import BasicAuthorizer, BasicAuthenticator
@@ -29,14 +29,19 @@ class ServerLauncher(object):
         server_config = migrate_and_get_server_config(
             user_folder, self.force_migration, server_dir is not None
         )
-        custom_auth = server_config.custom_authenticator
-        if custom_auth:
-            authenticator = load_authentication_plugin(server_folder, custom_auth)
+        custom_authn = server_config.custom_authenticator
+        if custom_authn:
+            authenticator = load_authentication_plugin(server_folder, custom_authn)
         else:
             authenticator = BasicAuthenticator(dict(server_config.users))
 
-        authorizer = BasicAuthorizer(server_config.read_permissions,
-                                     server_config.write_permissions)
+        custom_authz = server_config.custom_authorizer
+        if custom_authz:
+            authorizer = load_authorization_plugin(server_folder, custom_authz)
+        else:
+            authorizer = BasicAuthorizer(server_config.read_permissions,
+                                         server_config.write_permissions)
+
         credentials_manager = JWTCredentialsManager(server_config.jwt_secret,
                                                     server_config.jwt_expire_time)
 
diff --git a/conans/server/plugin_loader.py b/conans/server/plugin_loader.py
index f266c8c6a..255c30249 100644
--- a/conans/server/plugin_loader.py
+++ b/conans/server/plugin_loader.py
@@ -1,18 +1,26 @@
 import os
 
 
-def load_authentication_plugin(server_folder, plugin_name):
+def load_plugin(server_folder, plugin_type, plugin_name):
     try:
         from pluginbase import PluginBase
-        plugin_base = PluginBase(package="plugins/authenticator")
-        plugins_dir = os.path.join(server_folder, "plugins", "authenticator")
+        plugin_base = PluginBase(package="plugins/%s" % plugin_type)
+        plugins_dir = os.path.join(server_folder, "plugins", plugin_type)
         plugin_source = plugin_base.make_plugin_source(
                         searchpath=[plugins_dir])
-        auth = plugin_source.load_plugin(plugin_name).get_class()
+        plugin = plugin_source.load_plugin(plugin_name).get_class()
         # it is necessary to keep a reference to the plugin, otherwise it is removed
         # and some imports fail
-        auth.plugin_source = plugin_source
-        return auth
+        plugin.plugin_source = plugin_source
+        return plugin
     except Exception:
-        print("Error loading authenticator plugin '%s'" % plugin_name)
+        print("Error loading %s plugin '%s'" % (plugin_type, plugin_name))
         raise
+
+
+def load_authentication_plugin(server_folder, plugin_name):
+    return load_plugin(server_folder, "authenticator", plugin_name)
+
+
+def load_authorization_plugin(server_folder, plugin_name):
+    return load_plugin(server_folder, "authorizer", plugin_name)
diff --git a/conans/server/service/authorize.py b/conans/server/service/authorize.py
index 1456133d1..56636f29b 100644
--- a/conans/server/service/authorize.py
+++ b/conans/server/service/authorize.py
@@ -43,6 +43,14 @@ class Authorizer(object):
         """
         raise NotImplemented()
 
+    @abstractmethod
+    def check_delete_conan(self, username, ref):
+        """
+        username: User requesting a recipe's deletion
+        ref: ConanFileReference
+        """
+        raise NotImplemented()
+
     @abstractmethod
     def check_read_package(self, username, pref):
         """
@@ -59,6 +67,14 @@ class Authorizer(object):
         """
         raise NotImplemented()
 
+    @abstractmethod
+    def check_delete_package(self, username, pref):
+        """
+        username: User requesting a package's deletion
+        pref: PackageReference
+        """
+        raise NotImplemented()
+
 
 @six.add_metaclass(ABCMeta)
 class Authenticator(object):
diff --git a/pyinstaller.py b/pyinstaller.py
index b3e17251f..61f020fca 100644
--- a/pyinstaller.py
+++ b/pyinstaller.py
@@ -90,15 +90,17 @@ def pyinstall(source_folder):
     hidden = ("--hidden-import=glob "  # core stdlib
               "--hidden-import=pathlib "
               "--hidden-import=distutils.dir_util "
-              # The conan.tools integration
+              # Modules that can be imported in ConanFile conan.tools and errors
+              "--hidden-import=conan.errors "
               "--hidden-import=conan.tools.microsoft "
               "--hidden-import=conan.tools.gnu --hidden-import=conan.tools.cmake "
               "--hidden-import=conan.tools.meson --hidden-import=conan.tools.apple "
               "--hidden-import=conan.tools.build --hidden-import=conan.tools.env "
-              "--hidden-import=conan.tools.files --hidden-import=conan.tools.gnu "
+              "--hidden-import=conan.tools.files "
               "--hidden-import=conan.tools.google --hidden-import=conan.tools.intel "
               "--hidden-import=conan.tools.layout --hidden-import=conan.tools.premake "
-              "--hidden-import=conan.tools.qbs --hidden-import=conan.tools.scm")
+              "--hidden-import=conan.tools.qbs --hidden-import=conan.tools.scm "
+              "--hidden-import=conan.tools.system --hidden-import=conan.tools.system.package_manager")
     if platform.system() != "Windows":
         hidden += " --hidden-import=setuptools.msvc"
         win_ver = ""


Test patch:
diff --git a/conans/client/cmd/test.py b/conans/client/cmd/test.py
index e7f031bda..4c2f580dd 100644
--- a/conans/client/cmd/test.py
+++ b/conans/client/cmd/test.py
@@ -32,28 +32,28 @@ def install_build_and_test(app, conanfile_abs_path, reference, graph_info,
     if build_modes is None:
         build_modes = ["never"]
     try:
-        deps_install(app=app,
-                     create_reference=reference,
-                     ref_or_path=conanfile_abs_path,
-                     install_folder=test_build_folder,
-                     base_folder=test_build_folder,
-                     remotes=remotes,
-                     graph_info=graph_info,
-                     update=update,
-                     build_modes=build_modes,
-                     manifest_folder=manifest_folder,
-                     manifest_verify=manifest_verify,
-                     manifest_interactive=manifest_interactive,
-                     keep_build=keep_build,
-                     recorder=recorder,
-                     require_overrides=require_overrides,
-                     conanfile_path=os.path.dirname(conanfile_abs_path),
-                     test=True  # To keep legacy test_package_layout
-                     )
+        install_folder = deps_install(app=app,
+                                      create_reference=reference,
+                                      ref_or_path=conanfile_abs_path,
+                                      install_folder=test_build_folder,
+                                      base_folder=test_build_folder,
+                                      remotes=remotes,
+                                      graph_info=graph_info,
+                                      update=update,
+                                      build_modes=build_modes,
+                                      manifest_folder=manifest_folder,
+                                      manifest_verify=manifest_verify,
+                                      manifest_interactive=manifest_interactive,
+                                      keep_build=keep_build,
+                                      recorder=recorder,
+                                      require_overrides=require_overrides,
+                                      conanfile_path=os.path.dirname(conanfile_abs_path),
+                                      test=True  # To keep legacy test_package_layout
+                                      )
         cmd_build(app, conanfile_abs_path, test_build_folder,
                   source_folder=base_folder, build_folder=test_build_folder,
                   package_folder=os.path.join(test_build_folder, "package"),
-                  install_folder=test_build_folder, test=reference)
+                  install_folder=install_folder, test=reference)
     finally:
         if delete_after_build:
             # Required for windows where deleting the cwd is not possible.
diff --git a/conans/test/assets/sources.py b/conans/test/assets/sources.py
index 052e96b90..91e386870 100644
--- a/conans/test/assets/sources.py
+++ b/conans/test/assets/sources.py
@@ -27,6 +27,10 @@ int {{name}}(){
     std::cout << "  {{ msg or name }} _M_IX86 defined\n";
     #endif
 
+    #ifdef _M_ARM64
+    std::cout << "   {{ msg or name }} _M_ARM64 defined\n";
+    #endif
+
     #if __i386__
     std::cout << "  {{ msg or name }} __i386__ defined\n";
     #endif
@@ -34,6 +38,10 @@ int {{name}}(){
     #if __x86_64__
     std::cout << "  {{ msg or name }} __x86_64__ defined\n";
     #endif
+  
+    #if __aarch64__
+    std::cout << "  {{ msg or name }} __aarch64__ defined\n";
+    #endif
 
     // Libstdc++
     #if defined _GLIBCXX_USE_CXX11_ABI
diff --git a/conans/test/conftest.py b/conans/test/conftest.py
index 5a8716836..5c0cc4996 100644
--- a/conans/test/conftest.py
+++ b/conans/test/conftest.py
@@ -34,6 +34,9 @@ tools_locations = {
 }
 """
 
+MacOS_arm = all([platform.system() == "Darwin", platform.machine() == "arm64"])
+homebrew_root = "/opt/homebrew" if MacOS_arm else "/usr/local"
+
 
 tools_locations = {
     "clang": {"disabled": True},
@@ -47,7 +50,9 @@ tools_locations = {
         "0.28": {
             "path": {
                 # Using chocolatey in Windows -> choco install pkgconfiglite --version 0.28
-                'Windows': "C:/ProgramData/chocolatey/lib/pkgconfiglite/tools/pkg-config-lite-0.28-1/bin"
+                'Windows': "C:/ProgramData/chocolatey/lib/pkgconfiglite/tools/pkg-config-lite-0.28-1/bin",
+                'Darwin': f"{homebrew_root}/bin/pkg-config",
+                'Linux': "/usr/bin/pkg-config"
             }
         }},
     'autotools': {"exe": "autoconf"},
@@ -86,6 +91,14 @@ tools_locations = {
             "path": {'Windows': 'C:/Tools/ninja/1.10.2'}
         }
     },
+    # This is the non-msys2 mingw, which is 32 bits x86 arch
+    'mingw': {
+        "disabled": True,
+        "platform": "Windows",
+        "default": "system",
+        "exe": "mingw32-make",
+        "system": {"path": {'Windows': "C:/mingw"}},
+    },
     'mingw32': {
         "platform": "Windows",
         "default": "system",
@@ -174,12 +187,13 @@ try:
 except ImportError as e:
     user_tool_locations = None
 
+
 tools_environments = {
     'mingw32': {'Windows': {'MSYSTEM': 'MINGW32'}},
     'mingw64': {'Windows': {'MSYSTEM': 'MINGW64'}},
     'ucrt64': {'Windows': {'MSYSTEM': 'UCRT64'}},
     'msys2_clang64': {"Windows": {"MSYSTEM": "CLANG64"}},
-    'android_ndk': {'Darwin': {'TEST_CONAN_ANDROID_NDK': '/usr/local/share/android-ndk'}}
+    'android_ndk': {'Darwin': {'TEST_CONAN_ANDROID_NDK': f"{homebrew_root}/share/android-ndk"}}
 }
 
 
diff --git a/conans/test/functional/command/config_install_test.py b/conans/test/functional/command/config_install_test.py
index 7d438307e..400ea596d 100644
--- a/conans/test/functional/command/config_install_test.py
+++ b/conans/test/functional/command/config_install_test.py
@@ -333,13 +333,56 @@ class Pkg(ConanFile):
         self.client.run("remote list")
         self.assertEqual("conan.io: https://server.conan.io [Verify SSL: True]\n", self.client.out)
 
-    def test_install_remotes_json_error(self):
+    def test_install_remotes_json(self):
         folder = temp_folder()
-        save_files(folder, {"remotes.json": ""})
-        self.client.run('config install "%s"' % folder, assert_error=True)
-        self.assertIn("ERROR: Failed conan config install: "
-                      "remotes.json install is not supported yet. Use 'remotes.txt'",
-                      self.client.out)
+
+        remotes_json = textwrap.dedent("""
+            {
+                "remotes": [
+                    { "name": "repojson1", "url": "https://repojson1.net", "verify_ssl": false },
+                    { "name": "repojson2", "url": "https://repojson2.com", "verify_ssl": true }
+                ]
+            }
+        """)
+
+        remotes_txt = textwrap.dedent("""\
+            repotxt1 https://repotxt1.net False
+            repotxt2 https://repotxt2.com True
+        """)
+
+        # remotes.txt and json try to define both the remotes,
+        # could lead to unpredictable results
+        save_files(folder, {"remotes.json": remotes_json,
+                            "remotes.txt": remotes_txt})
+
+        self.client.run(f'config install "{folder}"')
+        assert "Defining remotes from remotes.json" in self.client.out
+        assert "Defining remotes from remotes.txt" in self.client.out
+
+        # If there's only a remotes.txt it's the one installed
+        folder = temp_folder()
+        save_files(folder, {"remotes.txt": remotes_txt})
+
+        self.client.run(f'config install "{folder}"')
+
+        assert "Defining remotes from remotes.txt" in self.client.out
+
+        self.client.run('remote list')
+
+        assert "repotxt1: https://repotxt1.net [Verify SSL: False]" in self.client.out
+        assert "repotxt2: https://repotxt2.com [Verify SSL: True]" in self.client.out
+
+        # If there's only a remotes.json it's the one installed
+        folder = temp_folder()
+        save_files(folder, {"remotes.json": remotes_json})
+
+        self.client.run(f'config install "{folder}"')
+        assert "Defining remotes from remotes.json" in self.client.out
+
+        self.client.run('remote list')
+
+        assert "repojson1: https://repojson1.net [Verify SSL: False]" in self.client.out
+        assert "repojson2: https://repojson2.com [Verify SSL: True]" in self.client.out
 
     def test_without_profile_folder(self):
         shutil.rmtree(self.client.cache.profiles_path)
diff --git a/conans/test/functional/command/test_command_test.py b/conans/test/functional/command/test_command_test.py
index ff97e0b37..970e50aaf 100644
--- a/conans/test/functional/command/test_command_test.py
+++ b/conans/test/functional/command/test_command_test.py
@@ -1,3 +1,4 @@
+import os
 import time
 import unittest
 
@@ -25,3 +26,5 @@ 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)
+        assert os.path.exists(os.path.join(client.current_folder, "test_package",
+                                           "build", "generators", "conaninfo.txt"))
diff --git a/conans/test/functional/generators/cmake_paths_test.py b/conans/test/functional/generators/cmake_paths_test.py
index 80cbb0486..3317ec403 100644
--- a/conans/test/functional/generators/cmake_paths_test.py
+++ b/conans/test/functional/generators/cmake_paths_test.py
@@ -25,12 +25,16 @@ class CMakePathsGeneratorTest(unittest.TestCase):
         expected = 'set(CONAN_LIB2_ROOT "{pfolder2}")\r\n' \
                    'set(CONAN_LIB1_ROOT "{pfolder1}")\r\n' \
                    'set(CMAKE_MODULE_PATH "{pfolder2}/"\r\n\t\t\t"{pfolder1}/" ' \
+                   '{root_folders_variables} ' \
                    '${{CMAKE_MODULE_PATH}} ${{CMAKE_CURRENT_LIST_DIR}})\r\n' \
                    'set(CMAKE_PREFIX_PATH "{pfolder2}/"\r\n\t\t\t"{pfolder1}/" ' \
+                   '{root_folders_variables} ' \
                    '${{CMAKE_PREFIX_PATH}} ${{CMAKE_CURRENT_LIST_DIR}})'
         if platform.system() != "Windows":
             expected = expected.replace("\r", "")
-        self.assertEqual(expected.format(pfolder1=pfolder1, pfolder2=pfolder2), contents)
+        root_folders_variables = '${CONAN_LIB2_ROOT} ${CONAN_LIB1_ROOT}'
+        self.assertEqual(expected.format(pfolder1=pfolder1, pfolder2=pfolder2,
+                                         root_folders_variables=root_folders_variables), contents)
 
     def test_cmake_paths_integration(self):
         """First package with own findHello0.cmake file"""
diff --git a/conans/test/functional/layout/test_build_system_layout_helpers.py b/conans/test/functional/layout/test_build_system_layout_helpers.py
index 25fb7f73d..4bd7c8cd4 100644
--- a/conans/test/functional/layout/test_build_system_layout_helpers.py
+++ b/conans/test/functional/layout/test_build_system_layout_helpers.py
@@ -276,3 +276,22 @@ def test_basic_layout_no_external_sources(with_build_type):
     assert contents == "exported_contents"
     client.run("export-pkg . foo/1.0@ --force")
     assert "Packaged 1 '.txt' file: build.txt" in client.out
+
+
+def test_cmake_layout_custom_build_folder():
+    # https://github.com/conan-io/conan/issues/11838
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import cmake_layout
+        class Pkg(ConanFile):
+            settings = "os", "build_type"
+            generators = "CMakeToolchain"
+            def layout(self):
+                cmake_layout(self, src_folder="src", build_folder="mybuild")
+        """)
+
+    client = TestClient()
+    client.save({"conanfile.py": conanfile})
+    client.run("install .")
+    assert os.path.exists(os.path.join(client.current_folder,
+                                       "mybuild/generators/conan_toolchain.cmake"))
diff --git a/conans/test/functional/layout/test_editable_cmake.py b/conans/test/functional/layout/test_editable_cmake.py
index a7e01b4e1..a6ccef494 100644
--- a/conans/test/functional/layout/test_editable_cmake.py
+++ b/conans/test/functional/layout/test_editable_cmake.py
@@ -110,12 +110,13 @@ def editable_cmake_exe(generator):
         build_dep()
 
     def run_pkg(msg):
+        host_arch = c.get_default_host_profile().settings['arch']
         # FIXME: This only works with ``--install-folder``, layout() will break this
-        cmd_release = environment_wrap_command("conanrunenv-release-x86_64", c.current_folder,
+        cmd_release = environment_wrap_command(f"conanrunenv-release-{host_arch}", c.current_folder,
                                                "dep_app",)
         c.run_command(cmd_release)
         assert "{}: Release!".format(msg) in c.out
-        cmd_release = environment_wrap_command("conanrunenv-debug-x86_64", c.current_folder,
+        cmd_release = environment_wrap_command(f"conanrunenv-debug-{host_arch}", c.current_folder,
                                                "dep_app", )
         c.run_command(cmd_release)
         assert "{}: Debug!".format(msg) in c.out
diff --git a/conans/test/functional/layout/test_in_cache.py b/conans/test/functional/layout/test_in_cache.py
index d53d8a6dc..13c386808 100644
--- a/conans/test/functional/layout/test_in_cache.py
+++ b/conans/test/functional/layout/test_in_cache.py
@@ -268,7 +268,8 @@ def test_cpp_package():
     assert "**includedirs:['foo/include']**" in out
     assert "**libdirs:['foo/libs']**" in out
     assert "**libs:['foo']**" in out
-    cmake = client.load("hello-release-x86_64-data.cmake")
+    arch = client.get_default_host_profile().settings['arch']
+    cmake = client.load(f"hello-release-{arch}-data.cmake")
 
     assert 'set(hello_INCLUDE_DIRS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/foo/include")' in cmake
     assert 'set(hello_LIB_DIRS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/foo/libs")' in cmake
diff --git a/conans/test/functional/subsystems_build_test.py b/conans/test/functional/subsystems_build_test.py
index 4faa08d36..eade2dc34 100644
--- a/conans/test/functional/subsystems_build_test.py
+++ b/conans/test/functional/subsystems_build_test.py
@@ -85,12 +85,12 @@ class TestSubsystems:
 class TestSubsystemsBuild:
 
     @staticmethod
-    def _build(client, static_runtime=None):
+    def _build(client, static_runtime=None, make="make"):
         makefile = gen_makefile(apps=["app"], static_runtime=static_runtime)
         main_cpp = gen_function_cpp(name="main")
         client.save({"Makefile": makefile,
                      "app.cpp": main_cpp})
-        client.run_command("make")
+        client.run_command(make)
         client.run_command("app")
 
     @pytest.mark.parametrize("static", [True, False])
@@ -111,6 +111,22 @@ class TestSubsystemsBuild:
         check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static,
                          subsystem="msys2")
 
+    @pytest.mark.parametrize("static", [True, False])
+    @pytest.mark.tool_mingw
+    def test_mingw(self, static):
+        """
+        This will work if you installed the Mingw toolchain outside msys2, from
+        https://sourceforge.net/projects/mingw/, and installed gcc, autotools, mingw32-make, etc
+
+        But this doesn't contain "make", only "mingw32-make"
+        """
+        client = TestClient()
+        self._build(client, static_runtime=static, make="mingw32-make")
+
+        check_exe_run(client.out, "main", "gcc", None, "Debug", "x86", None, subsystem="mingw32")
+        check_vs_runtime("app.exe", client, "15", "Debug", static_runtime=static,
+                         subsystem="mingw64")
+
     @pytest.mark.parametrize("static", [True, False])
     @pytest.mark.tool_msys2
     @pytest.mark.tool_mingw64
diff --git a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py
index d4898bff1..2a50ab1e0 100644
--- a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py
+++ b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py
@@ -187,9 +187,11 @@ def test_xcodedeps_components():
     assert '#include "conan_network_client.xcconfig"' in chat_xcconfig
     assert '#include "conan_network_server.xcconfig"' not in chat_xcconfig
     assert '#include "conan_network_network.xcconfig"' not in chat_xcconfig
+    host_arch = client.get_default_host_profile().settings['arch']
+    arch = "arm64" if host_arch == "armv8" else host_arch
     client.run_command("xcodegen generate")
-    client.run_command("xcodebuild -project ChatApp.xcodeproj -configuration Release -arch x86_64")
-    client.run_command("xcodebuild -project ChatApp.xcodeproj -configuration Debug -arch x86_64")
+    client.run_command(f"xcodebuild -project ChatApp.xcodeproj -configuration Release -arch {arch}")
+    client.run_command(f"xcodebuild -project ChatApp.xcodeproj -configuration Debug -arch {arch}")
     client.run_command("build/Debug/chat")
     assert "core/1.0: Hello World Debug!" in client.out
     assert "tcp/1.0: Hello World Debug!" in client.out
@@ -220,7 +222,10 @@ def test_xcodedeps_test_require():
         ''')
     client.save({"conanfile.py": conanfile}, clean_first=True)
     client.run("install . -g XcodeDeps")
+    host_arch = client.get_default_host_profile().settings['arch']
+    arch = "arm64" if host_arch == "armv8" else host_arch
     assert os.path.isfile(os.path.join(client.current_folder, "conan_gtest.xcconfig"))
     assert os.path.isfile(os.path.join(client.current_folder, "conan_gtest_gtest.xcconfig"))
-    assert os.path.isfile(os.path.join(client.current_folder, "conan_gtest_gtest_release_x86_64.xcconfig"))
+    assert os.path.isfile(os.path.join(client.current_folder,
+                                       f"conan_gtest_gtest_release_{arch}.xcconfig"))
     assert '#include "conan_gtest.xcconfig"' in client.load("conandeps.xcconfig")
diff --git a/conans/test/functional/toolchains/apple/test_xcodetoolchain.py b/conans/test/functional/toolchains/apple/test_xcodetoolchain.py
index 7590f5adc..6737ff8ea 100644
--- a/conans/test/functional/toolchains/apple/test_xcodetoolchain.py
+++ b/conans/test/functional/toolchains/apple/test_xcodetoolchain.py
@@ -6,15 +6,17 @@ import pytest
 from conans.test.assets.sources import gen_function_cpp
 from conans.test.utils.tools import TestClient
 
-
 test = textwrap.dedent("""
     import os
-    from conans import ConanFile, tools
+    from conan import ConanFile, tools
+    from conan.tools.build import can_run
     class TestApp(ConanFile):
         settings = "os", "compiler", "build_type", "arch"
         generators = "VirtualRunEnv"
+        def requirements(self):
+            self.requires(self.tested_reference_str)
         def test(self):
-            if not tools.cross_building(self):
+            if can_run(self):
                 self.run("app", env="conanrun")
     """)
 
@@ -35,8 +37,8 @@ def test_project_xcodetoolchain(cppstd, cppstd_output, min_version):
     conanfile = textwrap.dedent("""
         import os
         from conan import ConanFile
-        from conan.tools.files import copy
         from conan.tools.apple import XcodeBuild
+        from conan.tools.files import copy
         class MyApplicationConan(ConanFile):
             name = "myapplication"
             version = "1.0"
@@ -44,6 +46,7 @@ def test_project_xcodetoolchain(cppstd, cppstd_output, min_version):
             settings = "os", "compiler", "build_type", "arch"
             generators = "XcodeDeps", "XcodeToolchain"
             exports_sources = "app.xcodeproj/*", "app/*"
+            package_type = "application"
             def build(self):
                 xcode = XcodeBuild(self)
                 xcode.build("app.xcodeproj")
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
index eb78c4fd2..f44aea035 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
@@ -64,7 +64,8 @@ def test_transitive_multi(client):
         # to skip finding first possible FindBye somewhere
         assert "find_dependency(${_DEPENDENCY} REQUIRED ${${_DEPENDENCY}_FIND_MODE})" \
                in client.load("libb-config.cmake")
-        assert 'set(liba_FIND_MODE "NO_MODULE")' in client.load("libb-release-x86_64-data.cmake")
+        arch = client.get_default_host_profile().settings['arch']
+        assert 'set(liba_FIND_MODE "NO_MODULE")' in client.load(f"libb-release-{arch}-data.cmake")
 
         if platform.system() == "Windows":
             client.run_command('cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake')
@@ -141,10 +142,15 @@ def test_system_libs():
         message("Libraries to Link debug: ${Test_LIBS_DEBUG}")
         get_target_property(tmp Test::Test INTERFACE_LINK_LIBRARIES)
         message("Target libs: ${tmp}")
+        get_target_property(tmp CONAN_LIB::Test_lib1_%s INTERFACE_LINK_LIBRARIES)
+        message("Micro-target libs: ${tmp}")
+        get_target_property(tmp Test_DEPS_TARGET INTERFACE_LINK_LIBRARIES)
+        message("Micro-target deps: ${tmp}")
         """)
 
     for build_type in ["Release", "Debug"]:
-        client.save({"conanfile.txt": conanfile, "CMakeLists.txt": cmakelists}, clean_first=True)
+        client.save({"conanfile.txt": conanfile,
+                     "CMakeLists.txt": cmakelists % build_type.upper()}, clean_first=True)
         client.run("install conanfile.txt -s build_type=%s" % build_type)
         client.run_command('cmake . -DCMAKE_BUILD_TYPE={0}'.format(build_type))
 
@@ -153,13 +159,140 @@ def test_system_libs():
         if build_type == "Release":
             assert "System libs release: %s" % library_name in client.out
             assert "Libraries to Link release: lib1" in client.out
-            target_libs = "$<$<CONFIG:Release>:;CONAN_LIB::Test_lib1_RELEASE;sys1;>"
         else:
             assert "System libs debug: %s" % library_name in client.out
             assert "Libraries to Link debug: lib1" in client.out
-            target_libs = "$<$<CONFIG:Debug>:;CONAN_LIB::Test_lib1_DEBUG;sys1d;>"
 
-        assert "Target libs: %s" % target_libs in client.out
+        assert f"Target libs: $<$<CONFIG:{build_type}>:>;$<$<CONFIG:{build_type}>:CONAN_LIB::Test_lib1_{build_type.upper()}>" in client.out
+        assert "Micro-target libs: Test_DEPS_TARGET" in client.out
+        micro_target_deps = f"Micro-target deps: $<$<CONFIG:{build_type}>:>;$<$<CONFIG:{build_type}>:{library_name}>;" \
+                            f"$<$<CONFIG:{build_type}>:>"
+        assert micro_target_deps in client.out
+
+
+@pytest.mark.tool_cmake
+def test_system_libs_no_libs():
+    """If the recipe doesn't declare cpp_info.libs then the target with the system deps, frameworks
+       and transitive deps has to be linked to the global target"""
+    conanfile = textwrap.dedent("""
+        from conans import ConanFile
+        from conans.tools import save
+        import os
+
+        class Test(ConanFile):
+            name = "Test"
+            version = "0.1"
+            settings = "build_type"
+
+            def package_info(self):
+                if self.settings.build_type == "Debug":
+                    self.cpp_info.system_libs.append("sys1d")
+                else:
+                    self.cpp_info.system_libs.append("sys1")
+        """)
+    client = TestClient()
+    client.save({"conanfile.py": conanfile})
+    client.run("create . -s build_type=Release")
+    client.run("create . -s build_type=Debug")
+
+    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)
+        message("System libs Release: ${Test_SYSTEM_LIBS_RELEASE}")
+        message("Libraries to Link release: ${Test_LIBS_RELEASE}")
+        message("System libs Debug: ${Test_SYSTEM_LIBS_DEBUG}")
+        message("Libraries to Link debug: ${Test_LIBS_DEBUG}")
+        get_target_property(tmp Test::Test INTERFACE_LINK_LIBRARIES)
+        message("Target libs: ${tmp}")
+        get_target_property(tmp Test_DEPS_TARGET INTERFACE_LINK_LIBRARIES)
+        message("DEPS TARGET: ${tmp}")
+
+        """)
+
+    for build_type in ["Release", "Debug"]:
+        client.save({"conanfile.txt": conanfile, "CMakeLists.txt": cmakelists}, clean_first=True)
+        client.run("install conanfile.txt -s build_type=%s" % build_type)
+        client.run_command('cmake . -DCMAKE_BUILD_TYPE={0}'.format(build_type))
+
+        library_name = "sys1d" if build_type == "Debug" else "sys1"
+
+        assert f"System libs {build_type}: {library_name}" in client.out
+        assert f"Target libs: $<$<CONFIG:{build_type}>:>;$<$<CONFIG:{build_type}>:>;Test_DEPS_TARGET" in client.out
+        assert f"DEPS TARGET: $<$<CONFIG:{build_type}>:>;" \
+               f"$<$<CONFIG:{build_type}>:{library_name}>" in client.out
+
+
+@pytest.mark.tool_cmake
+def test_system_libs_components_no_libs():
+    """If the recipe doesn't declare cpp_info.libs then the target with the system deps, frameworks
+       and transitive deps has to be linked to the component target"""
+    conanfile = textwrap.dedent("""
+        from conans import ConanFile
+        from conans.tools import save
+        import os
+
+        class Test(ConanFile):
+            name = "Test"
+            version = "0.1"
+            settings = "build_type"
+
+            def package_info(self):
+                if self.settings.build_type == "Debug":
+                    self.cpp_info.components["foo"].system_libs.append("sys1d")
+                else:
+                    self.cpp_info.components["foo"].system_libs.append("sys1")
+        """)
+    client = TestClient()
+    client.save({"conanfile.py": conanfile})
+    client.run("create . -s build_type=Release")
+    client.run("create . -s build_type=Debug")
+
+    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)
+        message("System libs Release: ${Test_Test_foo_SYSTEM_LIBS_RELEASE}")
+        message("Libraries to Link release: ${Test_Test_foo_LIBS_RELEASE}")
+        message("System libs Debug: ${Test_Test_foo_SYSTEM_LIBS_DEBUG}")
+        message("Libraries to Link debug: ${Test_Test_foo_LIBS_DEBUG}")
+
+        get_target_property(tmp Test::foo INTERFACE_LINK_LIBRARIES)
+        message("Target libs: ${tmp}")
+        get_target_property(tmp Test_Test_foo_DEPS_TARGET INTERFACE_LINK_LIBRARIES)
+        message("DEPS TARGET: ${tmp}")
+
+        """)
+
+    for build_type in ["Release", "Debug"]:
+        client.save({"conanfile.txt": conanfile, "CMakeLists.txt": cmakelists}, clean_first=True)
+        client.run("install conanfile.txt -s build_type=%s" % build_type)
+        client.run_command('cmake . -DCMAKE_BUILD_TYPE={0}'.format(build_type))
+
+        library_name = "sys1d" if build_type == "Debug" else "sys1"
+
+        assert f"System libs {build_type}: {library_name}" in client.out
+        assert f"Target libs: $<$<CONFIG:{build_type}>:>;$<$<CONFIG:{build_type}>:>;Test_Test_foo_DEPS_TARGET" in client.out
+        assert f"DEPS TARGET: $<$<CONFIG:{build_type}>:>;" \
+               f"$<$<CONFIG:{build_type}>:{library_name}>" in client.out
 
 
 @pytest.mark.tool_cmake
@@ -226,13 +359,13 @@ def test_custom_configuration(client):
                cmake.build_context_suffix["liba"] = "_build"
                cmake.generate()
        """)
-
+    host_arch = client.get_default_host_profile().settings['arch']
     client.save({"conanfile.py": conanfile})
     client.run("install . -pr:h default -s:b build_type=RelWithDebInfo"
                " -pr:b default -s:b arch=x86 --build missing")
     curdir = client.current_folder
     data_name_context_build = "liba_build-relwithdebinfo-x86-data.cmake"
-    data_name_context_host = "liba-debug-x86_64-data.cmake"
+    data_name_context_host = f"liba-debug-{host_arch}-data.cmake"
     assert os.path.exists(os.path.join(curdir, data_name_context_build))
     assert os.path.exists(os.path.join(curdir, data_name_context_host))
 
@@ -375,7 +508,8 @@ def test_system_dep():
 
     client.run("install consumer")
     if platform.system() != "Windows":
-        data = os.path.join("consumer/build/generators/mylib-release-x86_64-data.cmake")
+        host_arch = client.get_default_host_profile().settings['arch']
+        data = os.path.join(f"consumer/build/generators/mylib-release-{host_arch}-data.cmake")
         contents = client.load(data)
         assert 'set(ZLIB_FIND_MODE "")' in contents
 
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_and_linker_flags.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_and_linker_flags.py
index 825a02082..e03007054 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_and_linker_flags.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_and_linker_flags.py
@@ -4,6 +4,7 @@ import textwrap
 
 import pytest
 
+from conans.test.assets.sources import gen_function_cpp, gen_function_h
 from conans.test.utils.tools import TestClient
 
 
@@ -56,3 +57,90 @@ def test_shared_link_flags():
     assert 'set(hello_SHARED_LINK_FLAGS_RELEASE "-z now;-z relro")' in target_data_cmake_content
     assert 'set(hello_EXE_LINK_FLAGS_RELEASE "-z now;-z relro")' in target_data_cmake_content
     assert "hello/1.0: Hello World Release!" in client.out
+
+
+def test_not_mixed_configurations():
+    # https://github.com/conan-io/conan/issues/11852
+
+    client = TestClient()
+    client.run("new foo/1.0 -m cmake_lib")
+
+    conanfile = client.load("conanfile.py")
+    conanfile.replace("package_info(self)", "invalid(self)")
+    conanfile += """
+    def package_info(self):
+        self.cpp_info.libs = ["foo" if self.settings.build_type == "Release" else "foo_d"]
+    """
+
+    cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(foo CXX)
+
+            add_library(foo "src/foo.cpp")
+            target_include_directories(foo PUBLIC include)
+            set_target_properties(foo PROPERTIES PUBLIC_HEADER "include/foo.h")
+
+            # Different name for Release or Debug
+            set_target_properties(foo PROPERTIES OUTPUT_NAME_DEBUG foo_d)
+            set_target_properties(foo PROPERTIES OUTPUT_NAME_RELEASE foo)
+            install(TARGETS foo)
+    """)
+
+    client.save({"CMakeLists.txt": cmake, "conanfile.py": conanfile})
+    client.run("create .")
+    client.run("create . -s build_type=Debug")
+    if platform.system() != "Windows":
+        assert "libfoo_d.a" in client.out  # Just to make sure we built the foo_d
+
+    # Now create a consumer of foo with CMakeDeps locally
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout
+
+        class ConsumerConan(ConanFile):
+            name = "consumer"
+            version = "1.0"
+            settings = "os", "compiler", "build_type", "arch"
+            requires = "foo/1.0"
+            generators = "CMakeDeps"
+
+            def layout(self):
+                cmake_layout(self)
+
+            def generate(self):
+                tc = CMakeToolchain(self)
+                tc.cache_variables["CMAKE_VERBOSE_MAKEFILE:BOOL"] = "ON"
+                tc.generate()
+
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+                cmake.build()
+
+            """)
+    cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(consumer CXX)
+
+            find_package(foo)
+
+            add_executable(consumer src/consumer.cpp)
+            target_include_directories(consumer PUBLIC include)
+            target_link_libraries(consumer foo::foo)
+
+            set_target_properties(consumer PROPERTIES PUBLIC_HEADER "include/consumer.h")""")
+    consumer_cpp = gen_function_cpp(name="main", includes=["foo"], calls=["foo"])
+    consumer_h = gen_function_h(name="consumer")
+
+    client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmake,
+                 "src/consumer.cpp": consumer_cpp, "src/consumer.h": consumer_h})
+
+    client.run("install . -s build_type=Debug")
+    client.run("install . -s build_type=Release")
+    # With the bug, this build only fail on windows
+    client.run("build .")
+
+    # But we inspect the output for Macos/Linux to check that the library is not linked
+    if platform.system() != "Windows":
+        assert "libfoo_d.a" not in client.out
+        assert "libfoo.a" 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 e2919cf0d..44b0565f5 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py
@@ -67,8 +67,8 @@ class PropagateSpecificComponents(unittest.TestCase):
     def test_cmakedeps_multi(self):
         t = TestClient(cache_folder=self.cache_folder)
         t.run('install middle/version@ -g CMakeDeps')
-
-        content = t.load('middle-release-x86_64-data.cmake')
+        arch = t.get_default_host_profile().settings['arch']
+        content = t.load(f'middle-release-{arch}-data.cmake')
         self.assertIn("list(APPEND middle_FIND_DEPENDENCY_NAMES top)", content)
 
         content = t.load('middle-Target-release.cmake')
@@ -198,13 +198,16 @@ def test_components_system_libs():
         find_package(requirement)
         get_target_property(tmp_libs requirement::component INTERFACE_LINK_LIBRARIES)
         get_target_property(tmp_options requirement::component INTERFACE_LINK_OPTIONS)
+        get_target_property(tmp_deps requirement_requirement_component_DEPS_TARGET INTERFACE_LINK_LIBRARIES)
         message("component libs: ${tmp_libs}")
         message("component options: ${tmp_options}")
+        message("component deps: ${tmp_deps}")
     """)
 
     t.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists})
     t.run("create . --build missing -s build_type=Release")
-    assert 'component libs: $<$<CONFIG:Release>:;system_lib_component>' in t.out
+    assert 'component libs: $<$<CONFIG:Release>:>;$<$<CONFIG:Release>:>;requirement_requirement_component_DEPS_TARGET' in t.out
+    assert 'component deps: $<$<CONFIG:Release>:>;$<$<CONFIG:Release>:system_lib_component>;' in t.out
     assert ('component options: '
             '$<$<CONFIG:Release>:'
             '$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;'
@@ -320,3 +323,84 @@ def test_components_sharedlinkflags():
             '$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>') in t.out
     # NOTE: If there is no "conan install -s build_type=Debug", the properties won't contain the
     #       <CONFIG:Debug>
+
+
+@pytest.mark.tool_cmake
+def test_cmake_add_subdirectory():
+    """https://github.com/conan-io/conan/issues/11743
+       https://github.com/conan-io/conan/issues/11755"""
+
+    t = TestClient()
+    boost = textwrap.dedent("""
+        from conan import ConanFile
+
+        class Consumer(ConanFile):
+            name = "boost"
+            version = "1.0"
+
+            def package_info(self):
+                self.cpp_info.set_property("cmake_file_name", "Boost")
+                self.cpp_info.components["A"].system_libs = ["A_1", "A_2"]
+                self.cpp_info.components["B"].system_libs = ["B_1", "B_2"]
+    """)
+    t.save({"conanfile.py": boost})
+    t.run("create .")
+    conanfile = textwrap.dedent("""
+            from conans import ConanFile
+            from conan.tools.cmake import CMake, cmake_layout
+
+            class Consumer(ConanFile):
+                name = "consumer"
+                version = "0.1"
+                requires = "boost/1.0"
+                generators = "CMakeDeps", "CMakeToolchain"
+                settings = "os", "arch", "compiler", "build_type"
+
+                def layout(self):
+                    cmake_layout(self)
+
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+        """)
+
+    cmakelists = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(hello CXX)
+            find_package(Boost CONFIG)
+            add_subdirectory(src)
+
+    """)
+    sub_cmakelists = textwrap.dedent("""
+            find_package(Boost REQUIRED COMPONENTS exception headers)
+
+            message("AGGREGATED LIBS: ${Boost_LIBRARIES}")
+            get_target_property(tmp boost::boost INTERFACE_LINK_LIBRARIES)
+            message("AGGREGATED LINKED: ${tmp}")
+
+            get_target_property(tmp boost::B INTERFACE_LINK_LIBRARIES)
+            message("BOOST_B LINKED: ${tmp}")
+
+            get_target_property(tmp boost::A INTERFACE_LINK_LIBRARIES)
+            message("BOOST_A LINKED: ${tmp}")
+
+            get_target_property(tmp boost_boost_B_DEPS_TARGET INTERFACE_LINK_LIBRARIES)
+            message("BOOST_B_DEPS LINKED: ${tmp}")
+
+            get_target_property(tmp boost_boost_A_DEPS_TARGET INTERFACE_LINK_LIBRARIES)
+            message("BOOST_A_DEPS LINKED: ${tmp}")
+
+    """)
+
+    t.save({"conanfile.py": conanfile,
+            "CMakeLists.txt": cmakelists, "src/CMakeLists.txt": sub_cmakelists})
+    t.run("install .")
+    # only doing the configure failed before #11743 fix
+    t.run("build .")
+    # The boost::boost target has linked the two components
+    assert "AGGREGATED LIBS: boost::boost" in t.out
+    assert "AGGREGATED LINKED: boost::B;boost::A" in t.out
+    assert "BOOST_B LINKED: $<$<CONFIG:Release>:>;$<$<CONFIG:Release>:>;boost_boost_B_DEPS_TARGET" in t.out
+    assert "BOOST_A LINKED: $<$<CONFIG:Release>:>;$<$<CONFIG:Release>:>;boost_boost_A_DEPS_TARGET" in t.out
+    assert "BOOST_B_DEPS LINKED: $<$<CONFIG:Release>:>;$<$<CONFIG:Release>:B_1;B_2>" in t.out
+    assert "BOOST_A_DEPS LINKED: $<$<CONFIG:Release>:>;$<$<CONFIG:Release>:A_1;A_2>;" in t.out
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_find_module_and_config.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_find_module_and_config.py
index 71fcbdb73..d9a4eca45 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_find_module_and_config.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_find_module_and_config.py
@@ -167,6 +167,13 @@ def test_transitive_modules_found(find_mode_PKGA, find_mode_PKGB, find_mode_cons
         message("MYPKGB_INCLUDE_DIRS: ${{MYPKGB_INCLUDE_DIRS}}")
         message("MYPKGB_INCLUDE_DIR: ${{MYPKGB_INCLUDE_DIR}}")
         message("MYPKGB_LIBRARIES: ${{MYPKGB_LIBRARIES}}")
+
+        get_target_property(linked_libs pkgb::pkgb INTERFACE_LINK_LIBRARIES)
+        message("MYPKGB_LINKED_LIBRARIES: '${{linked_libs}}'")
+
+        get_target_property(linked_deps pkgb_DEPS_TARGET INTERFACE_LINK_LIBRARIES)
+        message("MYPKGB_DEPS_LIBRARIES: '${{linked_deps}}'")
+
         message("MYPKGB_DEFINITIONS: ${{MYPKGB_DEFINITIONS}}")
         """)
 
@@ -183,9 +190,16 @@ def test_transitive_modules_found(find_mode_PKGA, find_mode_PKGB, find_mode_cons
     assert "MYPKGB_VERSION_STRING: 1.0" in client.out
     assert "MYPKGB_INCLUDE_DIRS:" in client.out
     assert "MYPKGB_INCLUDE_DIR:" in client.out
-    assert "MYPKGB_LIBRARIES: pkga::pkga" in client.out
+    # The MYPKG_LIBRARIES contains the target for the current package, but the target is linked
+    # with the dependencies also:
+    assert "MYPKGB_LIBRARIES: pkgb::pkgb" in client.out
+    assert "MYPKGB_LINKED_LIBRARIES: '$<$<CONFIG:Release>:>;$<$<CONFIG:Release>:>;pkgb_DEPS_TARGET'" in client.out
+    assert "MYPKGB_DEPS_LIBRARIES: '$<$<CONFIG:Release>:>;$<$<CONFIG:Release>:>;" \
+           "$<$<CONFIG:Release>:pkga::pkga>'" in client.out
+
     assert "MYPKGB_DEFINITIONS: -DDEFINE_MYPKGB" in client.out
     assert "Conan: Target declared 'pkga::pkga'"
 
     if find_mode_PKGA == "module":
         assert 'Found unicorns: 1.0 (found version "1.0")' in client.out
+
diff --git a/conans/test/functional/toolchains/cmake/cmakedeps/test_link_order.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_link_order.py
index bbfb66c3b..07b16e742 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_link_order.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_link_order.py
@@ -1,5 +1,6 @@
 import os
 import platform
+import re
 import textwrap
 
 import pytest
@@ -257,12 +258,19 @@ def _get_link_order_from_cmake(content):
 
 def _get_link_order_from_xcode(content):
     libs = []
-    start_key = '-headerpad_max_install_names",'
+
+    # Find the right Release block in the XCode file
+    results = re.finditer('/\* Release \*/ = {', content)
+    for r in results:
+        release_section = content[r.start():].split("name = Release;", 1)[0]
+        if "-headerpad_max_install_names" in release_section:
+            break
+    else:
+        raise Exception("Cannot find the Release block linking the expected libraries")
+
+    start_key = '-Wl,-headerpad_max_install_names'
     end_key = ');'
-    libs_content = content.split(start_key, 1)[1].split(end_key, 1)[0]
-    if libs_content == '"$(inherited)"':
-        # FIXME: Dirty hack, sometimes the library list is not at the 1 but at 2
-        libs_content = content.split(start_key, 1)[2].split(end_key, 1)[0]
+    libs_content = release_section.split(start_key, 1)[1].split(end_key, 1)[0]
     libs_unstripped = libs_content.split(",")
     for lib in libs_unstripped:
         if ".a" in lib:
@@ -303,7 +311,10 @@ def _run_and_get_lib_order(t, generator):
     if generator == "Xcode":
         t.run_command("cmake . -G Xcode -DCMAKE_VERBOSE_MAKEFILE:BOOL=True"
                       " -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake")
+        # This is building by default the Debug configuration that contains nothing, so it works
         t.run_command("cmake --build .")
+        # This is building the release and fails because invented system libraries are missing
+        t.run_command("cmake --build . --config Release", assert_error=True)
         # Get the actual link order from the CMake call
         libs = _get_link_order_from_xcode(t.load(os.path.join('executable.xcodeproj',
                                                               'project.pbxproj')))
diff --git a/conans/test/functional/toolchains/cmake/test_cmake.py b/conans/test/functional/toolchains/cmake/test_cmake.py
index e84fc0981..7b5fde432 100644
--- a/conans/test/functional/toolchains/cmake/test_cmake.py
+++ b/conans/test/functional/toolchains/cmake/test_cmake.py
@@ -436,17 +436,27 @@ class AppleTest(Base):
         vals = {"CMAKE_CXX_STANDARD": cppstd,
                 "CMAKE_CXX_EXTENSIONS": extensions_str,
                 "CMAKE_BUILD_TYPE": build_type,
-                "CMAKE_CXX_FLAGS": "-m64 -stdlib=libc++",
                 "CMAKE_CXX_FLAGS_DEBUG": "-g",
                 "CMAKE_CXX_FLAGS_RELEASE": "-O3 -DNDEBUG",
-                "CMAKE_C_FLAGS": "-m64",
                 "CMAKE_C_FLAGS_DEBUG": "-g",
                 "CMAKE_C_FLAGS_RELEASE": "-O3 -DNDEBUG",
-                "CMAKE_SHARED_LINKER_FLAGS": "-m64",
-                "CMAKE_EXE_LINKER_FLAGS": "-m64",
                 "CMAKE_INSTALL_NAME_DIR": ""
                 }
 
+        host_arch = self.client.get_default_host_profile().settings['arch']
+
+        if host_arch == "x86_64":
+            vals.update({
+                "CMAKE_C_FLAGS": "-m64",
+                "CMAKE_CXX_FLAGS": "-m64 -stdlib=libc++",
+                "CMAKE_SHARED_LINKER_FLAGS": "-m64",
+                "CMAKE_EXE_LINKER_FLAGS": "-m64",
+            })
+        else:
+            vals.update({
+                "CMAKE_CXX_FLAGS": "-stdlib=libc++",
+            })
+
         def _verify_out(marker=">>"):
             if shared:
                 self.assertIn("libapp_lib.dylib", self.client.out)
diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
index c4b25b272..01453c25b 100644
--- a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
+++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
@@ -814,6 +814,15 @@ def test_cmake_presets_multiple_settings_multi_config():
     assert "MSVC_LANG2017" in client.out
 
 
+@pytest.mark.tool_cmake(version="3.23")
+def test_max_schema_version2_build():
+    client = TestClient(path_with_spaces=False)
+    client.run("new hello/0.1 --template=cmake_exe")
+    configs = ["-c tools.cmake.cmaketoolchain.presets:max_schema_version=2"]
+    client.run("install . {} -s compiler.cppstd=14".format(" ".join(configs)))
+    client.run("build .")
+
+
 @pytest.mark.tool_cmake(version="3.23")
 def test_user_presets_version2():
     client = TestClient(path_with_spaces=False)
diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain_m1.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain_m1.py
index 615bd76de..f81d04228 100644
--- a/conans/test/functional/toolchains/cmake/test_cmake_toolchain_m1.py
+++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain_m1.py
@@ -64,8 +64,13 @@ def test_m1(op_system):
     assert "CMAKE_SYSTEM_PROCESSOR: arm64" in client.out
     main_path = "./build/Release/main.app/main" if op_system == "iOS" \
         else "./build/Release/main"
-    client.run_command(main_path, assert_error=True)
-    assert "Bad CPU type in executable" in client.out
     client.run_command("lipo -info {}".format(main_path))
     assert "Non-fat file" in client.out
     assert "is architecture: arm64" in client.out
+    client.run_command(f"vtool -show-build {main_path}")
+
+    if op_system == "Macos":
+        assert "platform MACOS"
+    elif op_system == "iOS":
+        assert "platform IOS"
+        assert "minos 12.0"
\ No newline at end of file
diff --git a/conans/test/functional/toolchains/gnu/autotools/test_apple_toolchain.py b/conans/test/functional/toolchains/gnu/autotools/test_apple_toolchain.py
index 5836c8e04..c9217eac7 100644
--- a/conans/test/functional/toolchains/gnu/autotools/test_apple_toolchain.py
+++ b/conans/test/functional/toolchains/gnu/autotools/test_apple_toolchain.py
@@ -4,7 +4,7 @@ import platform
 
 import pytest
 
-from conan.tools.apple.apple import to_apple_arch
+from conans.client.tools.apple import to_apple_arch
 from conans.test.assets.autotools import gen_makefile
 from conans.test.assets.sources import gen_function_h, gen_function_cpp
 from conans.test.utils.tools import TestClient
diff --git a/conans/test/functional/toolchains/gnu/autotools/test_basic.py b/conans/test/functional/toolchains/gnu/autotools/test_basic.py
index b7c507c21..51b397fd6 100644
--- a/conans/test/functional/toolchains/gnu/autotools/test_basic.py
+++ b/conans/test/functional/toolchains/gnu/autotools/test_basic.py
@@ -53,8 +53,9 @@ def test_autotools():
     client.run("build .")
     client.run_command("./main")
     cxx11_abi = 0 if platform.system() == "Linux" else None
-    compiler = "gcc" if platform.system() == "Linux" else "clang"
-    check_exe_run(client.out, "main", compiler, None, "Release", "x86_64", None, cxx11_abi=cxx11_abi)
+    compiler = "gcc" if platform.system() == "Linux" else "apple-clang"
+    host_arch = client.get_default_host_profile().settings['arch']
+    check_exe_run(client.out, "main", compiler, None, "Release", host_arch, None, cxx11_abi=cxx11_abi)
     assert "hello/0.1: Hello World Release!" in client.out
 
 
diff --git a/conans/test/functional/toolchains/gnu/autotools/test_ios.py b/conans/test/functional/toolchains/gnu/autotools/test_ios.py
index 51f17f3c0..565e67da0 100644
--- a/conans/test/functional/toolchains/gnu/autotools/test_ios.py
+++ b/conans/test/functional/toolchains/gnu/autotools/test_ios.py
@@ -70,18 +70,21 @@ def test_ios():
                  "m1": profile}, clean_first=True)
     client.run("install . --profile:build=default --profile:host=m1")
     client.run("build .")
-    client.run_command("./main", assert_error=True)
-    assert "Bad CPU type in executable" in client.out
     client.run_command("lipo -info main")
     assert "Non-fat file: main is architecture: arm64" in client.out
+    client.run_command("vtool -show-build main")
+    assert "platform IOS" in client.out
+    assert "minos 12.0" in client.out
 
     conanbuild = load_toolchain_args(client.current_folder)
     configure_args = conanbuild["configure_args"]
     make_args = conanbuild["make_args"]
     autoreconf_args = conanbuild["autoreconf_args"]
+    build_arch = client.get_default_build_profile().settings['arch']
+    build_arch = "aarch64" if build_arch == "armv8" else build_arch
     assert configure_args == "'--prefix=/' '--bindir=${prefix}/bin' '--sbindir=${prefix}/bin' " \
                              "'--libdir=${prefix}/lib' '--includedir=${prefix}/include' " \
                              "'--oldincludedir=${prefix}/include' '--datarootdir=${prefix}/res' " \
-                             "'--host=aarch64-apple-ios' '--build=x86_64-apple-darwin'"
+                             f"'--host=aarch64-apple-ios' '--build={build_arch}-apple-darwin'"
     assert make_args == ""
     assert autoreconf_args == "'--force' '--install'"
diff --git a/conans/test/functional/toolchains/gnu/test_v2_autotools_template.py b/conans/test/functional/toolchains/gnu/test_v2_autotools_template.py
index 0e72f4d03..81685594a 100644
--- a/conans/test/functional/toolchains/gnu/test_v2_autotools_template.py
+++ b/conans/test/functional/toolchains/gnu/test_v2_autotools_template.py
@@ -93,7 +93,7 @@ def test_autotools_relocatable_libs_darwin():
     shutil.move(os.path.join(package_folder, "lib"), os.path.join(client.current_folder, "tempfolder"))
     # will fail because rpath does not exist
     client.run_command("test_package/build-release/main", assert_error=True)
-    assert "Library not loaded: @rpath/libhello.0.dylib" in client.out
+    assert "Library not loaded: @rpath/libhello.0.dylib" in str(client.out).replace("'", "")
 
     # Use DYLD_LIBRARY_PATH and should run
     client.run_command("DYLD_LIBRARY_PATH={} test_package/build-release/main".format(os.path.join(client.current_folder, "tempfolder")))
diff --git a/conans/test/functional/toolchains/meson/_base.py b/conans/test/functional/toolchains/meson/_base.py
index 3200a6aaf..41c2d6858 100644
--- a/conans/test/functional/toolchains/meson/_base.py
+++ b/conans/test/functional/toolchains/meson/_base.py
@@ -17,22 +17,29 @@ class TestMesonBase(unittest.TestCase):
 
     @property
     def _settings(self):
+        interpreter_arch = platform.machine()
+        if interpreter_arch in ["x86_64", "AMD64"]:
+            host_arch = "x86_64"
+        elif interpreter_arch in ["arm64", "aarch64", "ARM64"]:
+            host_arch = "armv8"
+        else:
+            host_ach = interpreter_arch
         settings_macosx = {"compiler": "apple-clang",
                            "compiler.libcxx": "libc++",
-                           "compiler.version": "13.0",
-                           "arch": "x86_64",
+                           "compiler.version": "13",
+                           "arch": host_arch,
                            "build_type": "Release"}
 
         settings_windows = {"compiler": "Visual Studio",
                             "compiler.version": "15",
                             "compiler.runtime": "MD",
-                            "arch": "x86_64",
+                            "arch": host_arch,
                             "build_type": "Release"}
 
         settings_linux = {"compiler": "gcc",
                           "compiler.version": "5",
                           "compiler.libcxx": "libstdc++",
-                          "arch": "x86_64",
+                          "arch": host_arch,
                           "build_type": "Release"}
 
         return {"Darwin": settings_macosx,
@@ -44,17 +51,23 @@ class TestMesonBase(unittest.TestCase):
         return " ".join('-s %s="%s"' % (k, v) for k, v in self._settings.items() if v)
 
     def _check_binary(self):
+        # FIXME: Some values are hardcoded to match the CI setup
+        host_arch =  self.t.get_default_host_profile().settings['arch']
+        arch_macro = {
+            "gcc": {"armv8": "__aarch64__", "x86_64": "__x86_64__"},
+            "msvc": {"armv8": "_M_ARM64", "x86_64": "_M_X64"}
+        }
         if platform.system() == "Darwin":
-            self.assertIn("main __x86_64__ defined", self.t.out)
+            self.assertIn(f"main {arch_macro['gcc'][host_arch]} defined", self.t.out)
             self.assertIn("main __apple_build_version__", self.t.out)
             self.assertIn("main __clang_major__13", self.t.out)
             # TODO: check why __clang_minor__ seems to be not defined in XCode 12
             # commented while migrating to XCode12 CI
             # self.assertIn("main __clang_minor__0", self.t.out)
         elif platform.system() == "Windows":
-            self.assertIn("main _M_X64 defined", self.t.out)
+            self.assertIn(f"main {arch_macro['msvc'][host_arch]} defined", self.t.out)
             self.assertIn("main _MSC_VER19", self.t.out)
             self.assertIn("main _MSVC_LANG2014", self.t.out)
         elif platform.system() == "Linux":
-            self.assertIn("main __x86_64__ defined", self.t.out)
+            self.assertIn(f"main {arch_macro['gcc'][host_arch]} defined", self.t.out)
             self.assertIn("main __GNUC__5", self.t.out)
diff --git a/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py b/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py
index e950df38e..9c6a9120b 100644
--- a/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py
+++ b/conans/test/functional/toolchains/microsoft/test_msbuilddeps.py
@@ -672,6 +672,7 @@ def test_exclude_code_analysis(pattern, exclude_a, exclude_b):
         """)
     profile = textwrap.dedent("""
         include(default)
+        [settings]
         build_type=Release
         arch=x86_64
         [conf]
diff --git a/conans/test/functional/tools/old/vcvars/vcvars_test.py b/conans/test/functional/tools/old/vcvars/vcvars_test.py
index a99fbff8b..90871d2d4 100644
--- a/conans/test/functional/tools/old/vcvars/vcvars_test.py
+++ b/conans/test/functional/tools/old/vcvars/vcvars_test.py
@@ -127,6 +127,8 @@ class VCVarsTest(unittest.TestCase):
     def test_vcvars_raises_when_not_found(self):
         text = """
 os: [Windows]
+arch: [x86_64]
+arch_build: [x86_64]
 compiler:
     Visual Studio:
         version: ["5"]
@@ -135,6 +137,8 @@ compiler:
         settings.os = "Windows"
         settings.compiler = "Visual Studio"
         settings.compiler.version = "5"
+        settings.arch = "x86_64"
+        settings.arch_build = "x86_64"
         with six.assertRaisesRegex(self, ConanException,
                                    "VS non-existing installation: Visual Studio 5"):
             output = ConanOutput(StringIO())
diff --git a/conans/test/functional/tools/scm/test_git.py b/conans/test/functional/tools/scm/test_git.py
index c92d968ea..535c46449 100644
--- a/conans/test/functional/tools/scm/test_git.py
+++ b/conans/test/functional/tools/scm/test_git.py
@@ -209,6 +209,60 @@ class TestGitBasicClone:
         assert c.load("source/CMakeLists.txt") == "mycmake"
 
 
+class TestGitCloneWithArgs:
+    """ Git cloning passing additional arguments
+    """
+    conanfile = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        from conan.tools.scm import Git
+        from conan.tools.files import load
+
+        class Pkg(ConanFile):
+            name = "pkg"
+            version = "0.1"
+
+            def layout(self):
+                self.folders.source = "source"
+
+            def source(self):
+                git = Git(self)
+                git.clone(url="{url}", target=".", args={args})
+                self.output.info("MYCMAKE: {{}}".format(load(self, "CMakeLists.txt")))
+                self.output.info("MYFILE: {{}}".format(load(self, "src/myfile.h")))
+        """)
+
+    def test_clone_specify_branch_or_tag(self):
+        folder = os.path.join(temp_folder(), "myrepo")
+        url, commit = create_local_git_repo(files={"src/myfile.h": "myheader!",
+                                                   "CMakeLists.txt": "mycmake"}, folder=folder,
+                                                   commits=3, branch="main", tags=["v1.2.3"])
+
+        c = TestClient()
+        git_args = ['--branch', 'main']
+        c.save({"conanfile.py": self.conanfile.format(url=url, commit=commit, args=str(git_args))})
+        c.run("create .")
+        assert "pkg/0.1: MYCMAKE: mycmake" in c.out
+        assert "pkg/0.1: MYFILE: myheader!" in c.out
+
+        git_args = ['--branch', 'v1.2.3']
+        c.save({"conanfile.py": self.conanfile.format(url=url, commit=commit, args=str(git_args))})
+        c.run("create .")
+        assert "pkg/0.1: MYCMAKE: mycmake" in c.out
+        assert "pkg/0.1: MYFILE: myheader!" in c.out
+
+    def test_clone_invalid_branch_argument(self):
+        folder = os.path.join(temp_folder(), "myrepo")
+        url, commit = create_local_git_repo(files={"src/myfile.h": "myheader!",
+                                                   "CMakeLists.txt": "mycmake"}, folder=folder,
+                                                   commits=3, branch="main", tags=["v1.2.3"])
+        c = TestClient()
+        git_args = ['--branch', 'foobar']
+        c.save({"conanfile.py": self.conanfile.format(url=url, commit=commit, args=str(git_args))})
+        with pytest.raises(Exception):
+            c.run("create .")
+            assert "Remote branch foobar not found" in c.out
+
 @pytest.mark.skipif(six.PY2, reason="Only Py3")
 class TestGitBasicSCMFlow:
     """ Build the full new SCM approach:
diff --git a/conans/test/functional/utils.py b/conans/test/functional/utils.py
index b4d121735..ddcda2346 100644
--- a/conans/test/functional/utils.py
+++ b/conans/test/functional/utils.py
@@ -86,6 +86,8 @@ def check_exe_run(output, names, compiler, version, build_type, arch, cppstd, de
                 assert "{} _M_IX86 defined".format(name) in output
             elif arch == "x86_64":
                 assert "{} _M_X64 defined".format(name) in output
+            elif arch == "armv8":
+                assert "{} _M_ARM64 defined".format(name) in output
             else:
                 assert arch is None, "checked don't know how to validate this architecture"
 
diff --git a/conans/test/integration/command/create_test.py b/conans/test/integration/command/create_test.py
index 048a366e7..8fcb36c7c 100644
--- a/conans/test/integration/command/create_test.py
+++ b/conans/test/integration/command/create_test.py
@@ -583,8 +583,6 @@ def test_default_framework_dirs_with_layout():
     assert "FRAMEWORKS: []" in client.out
 
 
-import pytest
-import re
 @pytest.mark.parametrize("with_layout", [True, False])
 def test_defaults_in_components_without_layout(with_layout):
     lib_conan_file = textwrap.dedent("""
@@ -659,3 +657,30 @@ def test_defaults_in_components_without_layout(with_layout):
         assert "FOO LIBDIRS: ['lib']" in client.out
         assert "FOO INCLUDEDIRS: ['include']" in client.out
         assert "FOO RESDIRS: ['res']" in client.out
+
+
+def test_create_keep_build_sets_generators_folder_even_with_cmake_layout_defined():
+    """
+    Issue related: https://github.com/conan-io/conan/issues/11785
+    """
+    conanfile = textwrap.dedent("""
+    from conan import ConanFile
+    from conan.tools.cmake import cmake_layout
+
+    class LibConan(ConanFile):
+        settings = 'os', 'arch', 'compiler', 'build_type'
+        name = "lib"
+        version = "1.0"
+
+        def layout(self):
+            cmake_layout(self)
+
+        def package(self):
+            self.output.info("GENERATORS FOLDER: {}".format(self.generators_folder))
+    """)
+    client = TestClient()
+    client.save({"conanfile.py": conanfile})
+    client.run("create . -s build_type=Release")
+    client.run("create -kb . -s build_type=Release")
+    # self.generators_folder should be not None when -kb is used
+    assert re.search(r"GENERATORS FOLDER: .*generators", str(client.out))
diff --git a/conans/test/integration/command/install/test_install_transitive.py b/conans/test/integration/command/install/test_install_transitive.py
index 86e3c3179..442a58a5c 100644
--- a/conans/test/integration/command/install/test_install_transitive.py
+++ b/conans/test/integration/command/install/test_install_transitive.py
@@ -15,7 +15,7 @@ from conans.util.files import save
 @pytest.fixture()
 def client():
     c = TestClient()
-    save(c.cache.settings_path, "os: [Windows, Macos, Linux, FreeBSD]\nos_build: [Windows, Macos]")
+    save(c.cache.settings_path, "os: [Windows, Macos, Linux, FreeBSD]\nos_build: [Windows, Macos]\narch_build: [x86_64]")
     save(c.cache.default_profile_path, "[settings]\nos=Windows")
 
     def base_conanfile(name):
@@ -205,12 +205,12 @@ def test_change_option_txt(client):
 
 def test_cross_platform_msg(client):
     # Explicit with os_build and os_arch settings
-    client.run("install Hello0/0.1@lasote/stable -s os_build=Macos -s os=Windows", assert_error=True)
+    client.run("install Hello0/0.1@lasote/stable -s os_build=Macos -s arch_build=x86_64 -s os=Windows", assert_error=True)
     assert "Cross-build from 'Macos:x86_64' to 'Windows:None'" in client.out
     assert "ERROR: Missing binary: Hello0" in client.out
 
     bad_os = "Windows" if platform.system() != "Windows" else "Macos"
-    client.run("install Hello0/0.1@lasote/stable -s os={}".format(bad_os), assert_error=True)
+    client.run("install Hello0/0.1@lasote/stable -s os={} -s arch_build=x86_64".format(bad_os), assert_error=True)
     # Implicit detection when not available (retrocompatibility)
     message = "Cross-build from '{}:x86_64' to '{}:None'".format(detected_os(), bad_os)
     assert message in client.out
diff --git a/conans/test/integration/conan_v2/test_requires_traits.py b/conans/test/integration/conan_v2/test_requires_traits.py
new file mode 100644
index 000000000..17414a3ea
--- /dev/null
+++ b/conans/test/integration/conan_v2/test_requires_traits.py
@@ -0,0 +1,24 @@
+import textwrap
+
+from conans.test.assets.genconanfile import GenConanfile
+from conans.test.utils.tools import TestClient
+
+
+def test_requires_traits():
+    """ traits can be passed to self.requires(), but:
+    - They have absolutely no effect
+    - They are not checked to be correct or match expected 2.0 traits
+    """
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            def requirements(self):
+                self.requires("dep/1.0", transitive_headers=True)
+        """)
+    c.save({"dep/conanfile.py": GenConanfile("dep", "1.0"),
+            "consumer/conanfile.py": conanfile})
+    c.run("create dep")
+    # This should not crash
+    c.run("install consumer")
+    assert "dep/1.0" in c.out
diff --git a/conans/test/integration/conanfile/required_conan_version_test.py b/conans/test/integration/conanfile/required_conan_version_test.py
index 7f0c11f25..f0261c11b 100644
--- a/conans/test/integration/conanfile/required_conan_version_test.py
+++ b/conans/test/integration/conanfile/required_conan_version_test.py
@@ -35,3 +35,45 @@ class RequiredConanVersionTest(unittest.TestCase):
         client.run("install pkg/1.0@", assert_error=True)
         self.assertIn("Current Conan version (%s) does not satisfy the defined one (>=100.0)"
                       % __version__, client.out)
+
+    def test_required_conan_version_with_loading_issues(self):
+        # https://github.com/conan-io/conan/issues/11239
+        client = TestClient()
+        conanfile = textwrap.dedent("""
+                    from conan import missing_import
+
+                    required_conan_version = ">=100.0"
+
+                    class Lib(ConanFile):
+                        pass
+                    """)
+        client.save({"conanfile.py": conanfile})
+        client.run("export . pkg/1.0@", assert_error=True)
+        self.assertIn("Current Conan version (%s) does not satisfy the defined one (>=100.0)"
+                      % __version__, client.out)
+
+        # Assigning required_conan_version without spaces
+        conanfile = textwrap.dedent("""
+                            from conan import missing_import
+
+                            required_conan_version=">=100.0"
+
+                            class Lib(ConanFile):
+                                pass
+                            """)
+        client.save({"conanfile.py": conanfile})
+        client.run("export . pkg/1.0@", assert_error=True)
+        self.assertIn("Current Conan version (%s) does not satisfy the defined one (>=100.0)"
+                      % __version__, client.out)
+
+        # If the range is correct, everything works, of course
+        conanfile = textwrap.dedent("""
+                            from conan import ConanFile
+
+                            required_conan_version = ">1.0.0"
+
+                            class Lib(ConanFile):
+                                pass
+                            """)
+        client.save({"conanfile.py": conanfile})
+        client.run("export . pkg/1.0@")
diff --git a/conans/test/integration/environment/test_env.py b/conans/test/integration/environment/test_env.py
index aad9b27bd..f60c0c4db 100644
--- a/conans/test/integration/environment/test_env.py
+++ b/conans/test/integration/environment/test_env.py
@@ -676,10 +676,8 @@ def test_files_always_created():
     c.run("install consumer -g VirtualBuildEnv -g VirtualRunEnv")
     ext = "bat" if platform.system() == "Windows" else "sh"
 
-    assert os.path.isfile(os.path.join(c.current_folder, "conanbuild.{}".format(ext)))
-    assert os.path.isfile(os.path.join(c.current_folder, "conanrun.{}".format(ext)))
-    assert os.path.isfile(os.path.join(c.current_folder,
-                                       "conanbuildenv-release-x86_64.{}".format(ext)))
-    assert os.path.isfile(os.path.join(c.current_folder,
-                                       "conanbuildenv-release-x86_64.{}".format(ext)))
-
+    arch = c.get_default_host_profile().settings['arch']
+    assert os.path.isfile(os.path.join(c.current_folder, f"conanbuild.{ext}"))
+    assert os.path.isfile(os.path.join(c.current_folder, f"conanrun.{ext}"))
+    assert os.path.isfile(os.path.join(c.current_folder, f"conanbuildenv-release-{arch}.{ext}"))
+    assert os.path.isfile(os.path.join(c.current_folder, f"conanbuildenv-release-{arch}.{ext}"))
diff --git a/conans/test/integration/generators/json_test.py b/conans/test/integration/generators/json_test.py
index 17e835cc7..b3d272030 100644
--- a/conans/test/integration/generators/json_test.py
+++ b/conans/test/integration/generators/json_test.py
@@ -13,7 +13,7 @@ class JsonTest(unittest.TestCase):
 
 class HelloConan(ConanFile):
     exports_sources = "*.h"
-    description = "foo"
+    description = "my desc"
     def layout(self):
         pass
     def package(self):
@@ -30,7 +30,7 @@ class HelloConan(ConanFile):
         conan_json = client.load("conanbuildinfo.json")
         data = json.loads(conan_json)
         self.assertEqual(data["dependencies"][0]["version"], "0.1")
-        self.assertIsNone(data["dependencies"][0]["description"])
+        self.assertEqual(data["dependencies"][0]["description"], "my desc")
         self.assertEqual(data["deps_env_info"]["MY_ENV_VAR"], "foo")
         self.assertEqual(data["deps_user_info"]["Hello"]["my_var"], "my_value")
 
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 2ab6a1a4d..3b4df5c2d 100644
--- a/conans/test/integration/generators/package_info/package_info_test.py
+++ b/conans/test/integration/generators/package_info/package_info_test.py
@@ -504,3 +504,15 @@ class HelloConan(ConanFile):
         self.assertIn("conanfile.py (pkg/1.0): GTEST_INFO: GTest", client.out)
         self.assertIn("conanfile.py (pkg/1.0): GTEST_FILEINFO: GtesT", client.out)
 
+    def test_none_folders(self):
+        # https://github.com/conan-io/conan/issues/11856
+        client = TestClient()
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            class pkgConan(ConanFile):
+                def package_info(self):
+                    self.cpp_info.resdirs = [None]
+            """)
+        client.save({"conanfile.py": conanfile})
+        client.run("create . pkg/1.0@")
+        assert "Created package revision" in client.out
diff --git a/conans/test/integration/graph/test_dependencies_visit.py b/conans/test/integration/graph/test_dependencies_visit.py
index d2065c6f1..ddbc11eba 100644
--- a/conans/test/integration/graph/test_dependencies_visit.py
+++ b/conans/test/integration/graph/test_dependencies_visit.py
@@ -97,3 +97,41 @@ def test_dependencies_visit_build_requires_profile():
     # generate time, build-requires already available
     assert "conanfile.py: GENERATE REQUIRE: cmake/0.1!!!" in client.out
     assert "conanfile.py: GENERATE CMAKE: cmake/0.1!!!" in client.out
+
+
+def test_dependency_interface():
+    """
+    Quick test for the ConanFileInterface exposed
+    """
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        from conans import ConanFile
+        class Pkg(ConanFile):
+            name = "dep"
+            version = "1.0"
+            homepage = "myhome"
+            url = "myurl"
+            license = "MIT"
+        """)
+    user = textwrap.dedent("""
+        from conan import ConanFile
+        class User(ConanFile):
+            requires = "dep/1.0"
+            def generate(self):
+                self.output.info("HOME: {}".format(self.dependencies["dep"].homepage))
+                self.output.info("URL: {}".format(self.dependencies["dep"].url))
+                self.output.info("LICENSE: {}".format(self.dependencies["dep"].license))
+                self.output.info("RECIPE: {}".format(self.dependencies["dep"].recipe_folder))
+                self.output.info("CONANDATA: {}".format(self.dependencies["dep"].conan_data))
+
+            """)
+    c.save({"dep/conanfile.py": conanfile,
+            "dep/conandata.yml": "",
+            "user/conanfile.py": user})
+    c.run("create dep")
+    c.run("install user")
+    assert "conanfile.py: HOME: myhome" in c.out
+    assert "conanfile.py: URL: myurl" in c.out
+    assert "conanfile.py: LICENSE: MIT" in c.out
+    assert "conanfile.py: RECIPE:" in c.out
+    assert "conanfile.py: CONANDATA: {}" in c.out
diff --git a/conans/test/integration/layout/test_legacy_cpp_info_and_layout.py b/conans/test/integration/layout/test_legacy_cpp_info_and_layout.py
new file mode 100644
index 000000000..e8e110f5f
--- /dev/null
+++ b/conans/test/integration/layout/test_legacy_cpp_info_and_layout.py
@@ -0,0 +1,36 @@
+import textwrap
+
+import pytest
+
+from conans.test.utils.tools import TestClient
+
+
+# TODO: This test does not make sense for Conan v2. Please, remove/skip it in that case.
+@pytest.mark.parametrize("declare_layout", [True, False])
+def test_legacy_deps_cpp_info_deps_version_using_or_not_layout(declare_layout):
+    conanfile = textwrap.dedent("""
+    from conan import ConanFile
+
+    class HelloConan(ConanFile):
+        name = "hello"
+        version = "1.0"
+        {}
+        def package_info(self):
+            self.cpp_info.libs = ["hello"]
+    """.format("def layout(self):pass" if declare_layout else ""))
+    test_conanfile = textwrap.dedent("""
+    from conan import ConanFile
+
+    class HelloTestConan(ConanFile):
+        settings = "os", "compiler", "build_type", "arch"
+
+        def build(self):
+            self.output.info(self.deps_cpp_info["hello"].version)
+
+        def test(self):
+            pass
+    """)
+    client = TestClient()
+    client.save({"conanfile.py": conanfile, "test_package/conanfile.py": test_conanfile})
+    client.run("create .")
+    assert "hello/1.0 (test package): 1.0" in client.out
diff --git a/conans/test/integration/package_id/package_id_test.py b/conans/test/integration/package_id/package_id_test.py
index 568a6325e..cb8a51028 100644
--- a/conans/test/integration/package_id/package_id_test.py
+++ b/conans/test/integration/package_id/package_id_test.py
@@ -129,8 +129,8 @@ def test_build_type_remove_windows():
         """)
     client.save({"conanfile.py": conanfile})
     client.run('create . pkg/0.1@ -s os=Windows -s compiler="Visual Studio" '
-               '-s compiler.version=14 -s build_type=Release')
+               '-s compiler.version=14 -s build_type=Release -s arch=x86_64')
     assert "pkg/0.1:e1f7c8ffe5f9342d04ab704810faf93060ae3d70 - Build" in client.out
     client.run('install pkg/0.1@ -s os=Windows -s compiler="Visual Studio" '
-               '-s compiler.version=14 -s build_type=Debug')
+               '-s compiler.version=14 -s build_type=Debug -s arch=x86_64')
     assert "pkg/0.1:e1f7c8ffe5f9342d04ab704810faf93060ae3d70 - Cache" in client.out
diff --git a/conans/test/integration/package_id/test_validate.py b/conans/test/integration/package_id/test_validate.py
index d273fe335..60b644872 100644
--- a/conans/test/integration/package_id/test_validate.py
+++ b/conans/test/integration/package_id/test_validate.py
@@ -1,4 +1,5 @@
 import json
+import re
 import textwrap
 import unittest
 
@@ -39,6 +40,59 @@ class TestValidate(unittest.TestCase):
         self.assertEqual(myjson[0]["binary"], BINARY_INVALID)
         self.assertEqual(myjson[0]["id"], 'INVALID')
 
+    def test_validate_header_only(self):
+        client = TestClient()
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.errors import ConanInvalidConfiguration
+            from conan.tools.build import check_min_cppstd
+            class Pkg(ConanFile):
+                settings = "os", "compiler"
+                options = {"shared": [True, False], "header_only": [True, False],}
+                default_options = {"shared": False, "header_only": True}
+
+                def package_id(self):
+                   if self.info.options.header_only:
+                       self.info.clear()
+
+                def validate(self):
+                    if self.info.options.get_safe("header_only") == "False":
+                        if self.info.settings.get_safe("compiler.version") == "12":
+                          raise ConanInvalidConfiguration("This package cannot exist in gcc 12")
+                        check_min_cppstd(self, 11)
+                        # These configurations are impossible
+                        if self.info.settings.os != "Windows" and self.info.options.shared:
+                            raise ConanInvalidConfiguration("shared is only supported under windows")
+
+                    # HOW CAN WE VALIDATE CPPSTD > 11 WHEN HEADER ONLY?
+
+            """)
+
+        client.save({"conanfile.py": conanfile})
+
+        client.run("create . pkg/0.1@ -s os=Linux -s compiler=gcc "
+                   "-s compiler.version=11 -s compiler.libcxx=libstdc++11")
+        assert re.search(r"Package '(.*)' created", str(client.out))
+
+        client.run("create . pkg/0.1@ -o header_only=False -s os=Linux -s compiler=gcc "
+                   "-s compiler.version=12 -s compiler.libcxx=libstdc++11", assert_error=True)
+
+        assert "Invalid ID: This package cannot exist in gcc 12" in client.out
+
+        client.run("create . pkg/0.1@ -o header_only=False -s os=Macos -s compiler=gcc "
+                   "-s compiler.version=11 -s compiler.libcxx=libstdc++11 -s compiler.cppstd=98",
+                   assert_error=True)
+
+        assert "Invalid ID: Current cppstd (98) is lower than the required C++ " \
+               "standard (11)" in client.out
+
+        client.run("create . pkg/0.1@ -o header_only=False -o shared=True "
+                   "-s os=Macos -s compiler=gcc "
+                   "-s compiler.version=11 -s compiler.libcxx=libstdc++11 -s compiler.cppstd=11",
+                   assert_error=True)
+
+        assert "Invalid ID: shared is only supported under windows" in client.out
+
     def test_validate_compatible(self):
         client = TestClient()
         conanfile = textwrap.dedent("""
diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py
index 3467b7da2..68d4d1991 100644
--- a/conans/test/integration/toolchains/apple/test_xcodedeps.py
+++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py
@@ -155,7 +155,10 @@ def test_xcodedeps_aggregate_components():
     component7_entry = client.load("conan_libb_libb_comp7.xcconfig")
     assert '#include "conan_liba_liba.xcconfig"' in component7_entry
 
-    component7_vars = client.load("conan_libb_libb_comp7_release_x86_64.xcconfig")
+    arch_setting = client.get_default_host_profile().settings['arch']
+    arch = "arm64" if arch_setting == "armv8" else arch_setting
+
+    component7_vars = client.load(f"conan_libb_libb_comp7_release_{arch}.xcconfig")
 
     # all of the transitive required components and the component itself are added
     for index in range(1, 8):
@@ -163,7 +166,7 @@ def test_xcodedeps_aggregate_components():
 
     assert "mylibdir" in component7_vars
 
-    component4_vars = client.load("conan_libb_libb_comp4_release_x86_64.xcconfig")
+    component4_vars = client.load(f"conan_libb_libb_comp4_release_{arch}.xcconfig")
 
     # all of the transitive required components and the component itself are added
     for index in range(1, 5):
@@ -193,7 +196,10 @@ def test_xcodedeps_frameworkdirs():
 
     client.run("install lib_a/1.0@ -g XcodeDeps")
 
-    lib_a_xcconfig = client.load("conan_lib_a_lib_a_release_x86_64.xcconfig")
+    arch_setting = client.get_default_host_profile().settings['arch']
+    arch = "arm64" if arch_setting == "armv8" else arch_setting
+
+    lib_a_xcconfig = client.load(f"conan_lib_a_lib_a_release_{arch}.xcconfig")
 
     assert "lib_a_frameworkdir" in lib_a_xcconfig
 
@@ -280,3 +286,48 @@ def test_xcodedeps_cppinfo_requires():
     assert "cmp2" in lib_c
     assert "cmp3" not in lib_c
     assert "cmp4" not in lib_c
+
+
+@pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS")
+def test_dependency_of_dependency_components():
+    # testing: https://github.com/conan-io/conan/pull/11772
+
+    """
+    When a dependency of a dependency would have components, only the default
+    name conan_dep_dep.xconfig would be included. However, this file was never
+    generated, as they are in the form conan_dep_component.xconfig.
+
+    lib_a -> lib_b -> lib_c (with components)
+    """
+    client = TestClient()
+    lib_a = GenConanfile("lib_a", "1.0").with_require("lib_b/1.0").with_settings("os", "arch", "build_type", "compiler")
+    lib_b = GenConanfile("lib_b", "1.0").with_require("lib_c/1.0").with_settings("os", "arch", "build_type", "compiler")
+
+    lib_c = textwrap.dedent("""
+        from conan import ConanFile
+        class lib_aConan(ConanFile):
+            name = "lib_c"
+            version = "1.0"
+            settings = "os", "compiler", "build_type", "arch"
+            def package_info(self):
+                self.cpp_info.components["cmp1"].includedirs = ["include_cmp1"]
+                self.cpp_info.components["cmp2"].includedirs = ["include_cmp2"]
+        """)
+
+    client.save({
+        'lib_a/conanfile.py': lib_a,
+        'lib_b/conanfile.py': lib_b,
+        'lib_c/conanfile.py': lib_c,
+    })
+
+    client.run("create lib_c")
+
+    client.run("create lib_b")
+
+    client.run("install lib_a -g XcodeDeps")
+
+    lib_b_xconfig = client.load("conan_lib_b_lib_b.xcconfig")
+
+    assert '#include "conan_lib_c_cmp1.xcconfig"' in lib_b_xconfig
+    assert '#include "conan_lib_c_cmp1.xcconfig"' in lib_b_xconfig
+    assert '#include "conan_lib_c_lib_c.xcconfig"' not in lib_b_xconfig
diff --git a/conans/test/integration/toolchains/apple/test_xcodetoolchain.py b/conans/test/integration/toolchains/apple/test_xcodetoolchain.py
index 4aef8e16d..457c15a17 100644
--- a/conans/test/integration/toolchains/apple/test_xcodetoolchain.py
+++ b/conans/test/integration/toolchains/apple/test_xcodetoolchain.py
@@ -36,6 +36,7 @@ def test_toolchain_files(configuration, os_version, cppstd, libcxx, arch, sdk_na
     cmd = cmd + " -s compiler.cppstd={}".format(cppstd) if cppstd else cmd
     cmd = cmd + " -s os.sdk={}".format(sdk_name) if sdk_name else cmd
     cmd = cmd + " -s os.sdk_version={}".format(sdk_version) if sdk_version else cmd
+    cmd = cmd + " -s arch={}".format(arch) if arch else cmd
     client.run(cmd)
     filename = _get_filename(configuration, arch, sdk_name, sdk_version)
     condition = _condition(configuration, arch, sdk_name, sdk_version)
diff --git a/conans/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py b/conans/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
index a94672945..5e147de51 100644
--- a/conans/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
+++ b/conans/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
@@ -37,7 +37,8 @@ def test_package_from_system():
     assert os.path.exists(os.path.join(client.current_folder, "dep1-config.cmake"))
     assert not os.path.exists(os.path.join(client.current_folder, "dep2-config.cmake"))
     assert not os.path.exists(os.path.join(client.current_folder, "custom_dep2-config.cmake"))
-    dep1_contents = client.load("dep1-release-x86_64-data.cmake")
+    host_arch = client.get_default_host_profile().settings['arch']
+    dep1_contents = client.load(f"dep1-release-{host_arch}-data.cmake")
     assert 'list(APPEND dep1_FIND_DEPENDENCY_NAMES custom_dep2)' in dep1_contents
     assert 'set(custom_dep2_FIND_MODE "")' in dep1_contents
 
@@ -61,7 +62,7 @@ def test_test_package():
             requires = "pkg/1.0"
         """)
     client.save({"conanfile.py": consumer})
-    client.run("install . -s:b os=Windows -s:h os=Linux --build=missing")
+    client.run("install . -s:b os=Windows -s:h os=Linux -s:h arch=x86_64 --build=missing")
     cmake_data = client.load("pkg-release-x86_64-data.cmake")
     assert "gtest" not in cmake_data
 
@@ -104,22 +105,23 @@ def test_cpp_info_component_objects():
     client.run("install hello/1.0@ -g CMakeDeps -s arch=x86_64 -s build_type=Release")
     with open(os.path.join(client.current_folder, "hello-Target-release.cmake")) as f:
         content = f.read()
-        assert """set_property(TARGET hello::say PROPERTY INTERFACE_LINK_LIBRARIES
-             $<$<CONFIG:Release>:${hello_hello_say_OBJECTS_RELEASE}
-             ${hello_hello_say_LINK_LIBS_RELEASE}> APPEND)""" in content
+        assert """set_property(TARGET hello::say
+                     PROPERTY INTERFACE_LINK_LIBRARIES
+                     $<$<CONFIG:Release>:${hello_hello_say_OBJECTS_RELEASE}>
+                     $<$<CONFIG:Release>:${hello_hello_say_LIBRARIES_TARGETS}>
+                     APPEND)""" in content
         # If there are componets, there is not a global cpp so this is not generated
-        assert """set_property(TARGET hello::hello
-             PROPERTY INTERFACE_LINK_LIBRARIES
-             $<$<CONFIG:Release>:${hello_OBJECTS_RELEASE}
-             ${hello_LIBRARIES_TARGETS_RELEASE}> APPEND)""" not in content
+        assert "hello_OBJECTS_RELEASE" not in content
         # But the global target is linked with the targets from the components
-        assert "target_link_libraries(hello::hello INTERFACE hello::say)" in content
+        assert "set_property(TARGET hello::hello PROPERTY INTERFACE_LINK_LIBRARIES " \
+               "hello::say APPEND)" in content
 
     with open(os.path.join(client.current_folder, "hello-release-x86_64-data.cmake")) as f:
         content = f.read()
-        # Not global variables
+        # https://github.com/conan-io/conan/issues/11862
+        # Global variables
         assert 'set(hello_OBJECTS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/mycomponent.o")' \
-               not in content
+               in content
         # But component variables
         assert 'set(hello_hello_say_OBJECTS_RELEASE "${hello_PACKAGE_FOLDER_RELEASE}/' \
                'mycomponent.o")' in content
@@ -179,7 +181,8 @@ def test_cmakedeps_cppinfo_complex_strings():
     client.run("export . hello/1.0@")
     client.save({"conanfile.txt": "[requires]\nhello/1.0\n"}, clean_first=True)
     client.run("install . --build=missing -g CMakeDeps")
-    deps = client.load("hello-release-x86_64-data.cmake")
+    arch = client.get_default_host_profile().settings['arch']
+    deps = client.load(f"hello-release-{arch}-data.cmake")
     assert r"escape=partially \"escaped\"" in deps
     assert r"spaces=me you" in deps
     assert r"foobar=bazbuz" in deps
diff --git a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 1bb64565e..8b6f35791 100644
--- a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -466,7 +466,7 @@ def test_toolchain_cache_variables():
     client.save({"conanfile.py": conanfile})
     with mock.patch("platform.system", mock.MagicMock(return_value="Windows")):
         client.run("install . mylib/1.0@ -c tools.cmake.cmaketoolchain:generator='MinGW Makefiles' "
-                   "-c tools.gnu:make_program='MyMake'")
+                   "-c tools.gnu:make_program='MyMake' -c tools.build:skip_test=True")
     presets = json.loads(client.load("CMakePresets.json"))
     cache_variables = presets["configurePresets"][0]["cacheVariables"]
     assert cache_variables["foo"] == 'ON'
@@ -475,6 +475,7 @@ def test_toolchain_cache_variables():
     assert cache_variables["CMAKE_SH"] == "THIS VALUE HAS PRIORITY"
     assert cache_variables["CMAKE_POLICY_DEFAULT_CMP0091"] == "THIS VALUE HAS PRIORITY"
     assert cache_variables["CMAKE_MAKE_PROGRAM"] == "MyMake"
+    assert cache_variables["BUILD_TESTING"] == 'OFF'
 
 
 def test_android_c_library():
@@ -491,7 +492,16 @@ def test_android_c_library():
 
         """)
     client.save({"conanfile.py": conanfile})
-    client.run("create . foo/1.0@ -s os=Android -s os.api_level=23 -c tools.android:ndk_path=/foo")
+    # Settings
+    settings = "-s arch=x86_64 -s os=Android -s os.api_level=23 -c tools.android:ndk_path=/foo"
+    # Checking the Android variables created
+    # Issue: https://github.com/conan-io/conan/issues/11798
+    client.run("install . " + settings)
+    conan_toolchain = client.load(os.path.join(client.current_folder, "conan_toolchain.cmake"))
+    assert "set(ANDROID_PLATFORM android-23)" in conan_toolchain
+    assert "set(ANDROID_ABI x86_64)" in conan_toolchain
+    assert "include(/foo/build/cmake/android.toolchain.cmake)" in conan_toolchain
+    client.run("create . foo/1.0@ " + settings)
 
 
 def test_user_presets_version2():
@@ -585,6 +595,29 @@ def test_presets_paths_correct():
                                                                                                "/")
 
 
+@pytest.mark.skipif(platform.system() != "Windows", reason="Only Windows")
+def test_presets_paths_normalization():
+    # https://github.com/conan-io/conan/issues/11795
+    client = TestClient()
+    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"
+
+                def layout(self):
+                    cmake_layout(self)
+            """)
+    client.save({"conanfile.py": conanfile, "CMakeLists.txt": "foo"})
+    client.run("install .")
+
+    presets = json.loads(client.load("CMakeUserPresets.json"))
+
+    assert "/" not in presets["include"]
+
+
 def test_presets_updated():
     """If a preset file is generated more than once, the values are always added and, in case the
     configurePreset or buildPreset already exist, the new preset is updated """
diff --git a/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py b/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py
index 94cea9522..55f7f9174 100644
--- a/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py
+++ b/conans/test/integration/toolchains/microsoft/test_msbuilddeps.py
@@ -1,4 +1,5 @@
 import os
+import textwrap
 
 import pytest
 
@@ -21,3 +22,28 @@ def test_msbuilddeps_maps_architecture_to_platform(arch, exp_platform):
     toolchain = client.load(os.path.join("conan", "conantoolchain.props"))
     expected_import = f"""<Import Condition="'$(Configuration)' == 'Release' And '$(Platform)' == '{exp_platform}'" Project="conantoolchain_release_{exp_platform.lower()}.props"/>"""
     assert expected_import in toolchain
+
+
+def test_msbuilddeps_format_names():
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            name = "pkg"
+            version = "1.0"
+
+            def package_info(self):
+                self.cpp_info.components["libmpdecimal++"].libs = ["libmp++"]
+        """)
+    c.save({"conanfile.py": conanfile})
+    c.run("create . -s arch=x86_64")
+    # Issue: https://github.com/conan-io/conan/issues/11822
+    c.run("install pkg/1.0@ -g MSBuildDeps -s build_type=Release -s arch=x86_64")
+    # Checking that MSBuildDeps builds correctly the XML file
+    props = c.load("conan_pkg_libmpdecimal__.props")
+    assert "<conan_pkg_libmpdecimal___props_imported>" in props
+    props = c.load("conan_pkg_libmpdecimal___release_x64.props")
+    assert "Conanpkg_libmpdecimal__IncludeDirectories" in props
+    props = c.load("conan_pkg_libmpdecimal___vars_release_x64.props")
+    assert "<Conanpkg_libmpdecimal__RootFolder>" in props
diff --git a/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py b/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py
index c7f8fe903..9432f4b51 100644
--- a/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py
+++ b/conans/test/integration/toolchains/microsoft/test_msbuildtoolchain.py
@@ -11,6 +11,8 @@ def test_msbuildtoolchain_props_with_extra_flags():
     """
     profile = textwrap.dedent("""\
     include(default)
+    [settings]
+    arch=x86_64
     [conf]
     tools.build:cxxflags=["--flag1", "--flag2"]
     tools.build:cflags+=["--flag3", "--flag4"]
diff --git a/conans/test/integration/tools/conan_version_test.py b/conans/test/integration/tools/conan_version_test.py
new file mode 100644
index 000000000..c65be48dd
--- /dev/null
+++ b/conans/test/integration/tools/conan_version_test.py
@@ -0,0 +1,26 @@
+import textwrap
+
+from conans.test.utils.tools import TestClient
+from conans import __version__
+
+
+def test_conan_version():
+
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan import conan_version
+        from conan.tools.scm import Version
+        from conans import __version__
+
+        class pkg(ConanFile):
+
+            def generate(self):
+                assert __version__ == str(conan_version)
+                assert isinstance(conan_version, Version)
+                print(f"current version: {conan_version}")
+        """)
+
+    client = TestClient()
+    client.save({"conanfile.py": conanfile})
+    client.run("install .")
+    assert f"current version: {__version__}" in client.out
diff --git a/conans/test/integration/tools/system/package_manager_test.py b/conans/test/integration/tools/system/package_manager_test.py
index dcc54fd69..f63da31ec 100644
--- a/conans/test/integration/tools/system/package_manager_test.py
+++ b/conans/test/integration/tools/system/package_manager_test.py
@@ -130,27 +130,8 @@ def test_tools_install_mode_check(tool_class):
                                          "'-c tools.system.package_manager:mode=install'"
 
 
-@pytest.mark.parametrize("tool_class",
-                         [Apt, Yum, Dnf, Brew, Pkg, PkgUtil, Chocolatey, PacMan, Zypper])
-def test_tools_update_mode_check(tool_class):
-    conanfile = ConanFileMock()
-    conanfile.conf = Conf()
-    conanfile.settings = Settings()
-    conanfile.conf["tools.system.package_manager:tool"] = tool_class.tool_name
-    conanfile.conf["tools.system.package_manager:mode"] = "check"
-    with mock.patch('conans.ConanFile.context', new_callable=PropertyMock) as context_mock:
-        context_mock.return_value = "host"
-        tool = tool_class(conanfile)
-        with pytest.raises(ConanException) as exc_info:
-            tool.update()
-        assert exc_info.value.args[0] == "Can't update because tools.system.package_manager:mode is " \
-                                         "'check'.Please update packages manually or set " \
-                                         "'tools.system.package_manager:mode' to 'install' in the [conf] " \
-                                         "section of the profile, or in the command line using " \
-                                         "'-c tools.system.package_manager:mode=install'"
-
-
-@pytest.mark.parametrize("tool_class, result", [
+@pytest.mark.parametrize("tool_class, result",
+[
     (Apt, "apt-get update"),
     (Yum, "yum check-update -y"),
     (Dnf, "dnf check-update -y"),
@@ -166,12 +147,17 @@ def test_tools_update_mode_install(tool_class, result):
     conanfile.conf = Conf()
     conanfile.settings = Settings()
     conanfile.conf["tools.system.package_manager:tool"] = tool_class.tool_name
-    conanfile.conf["tools.system.package_manager:mode"] = "install"
-    with mock.patch('conans.ConanFile.context', new_callable=PropertyMock) as context_mock:
-        context_mock.return_value = "host"
-        tool = tool_class(conanfile)
-        tool.update()
-    assert tool._conanfile.command == result
+    for mode in ["check", "install"]:
+        conanfile.conf["tools.system.package_manager:mode"] = mode
+        with mock.patch('conans.ConanFile.context', new_callable=PropertyMock) as context_mock:
+            context_mock.return_value = "host"
+            tool = tool_class(conanfile)
+            tool.update()
+            if mode == "install":
+                assert tool._conanfile.command == result
+            else:
+                # does not run the update when mode check
+                assert tool._conanfile.command is None
 
 
 @pytest.mark.parametrize("tool_class, result", [
diff --git a/conans/test/unittests/client/build/autotools_environment_test.py b/conans/test/unittests/client/build/autotools_environment_test.py
index 36c09d1e5..666fff793 100644
--- a/conans/test/unittests/client/build/autotools_environment_test.py
+++ b/conans/test/unittests/client/build/autotools_environment_test.py
@@ -495,9 +495,10 @@ class AutoToolsConfigureTest(unittest.TestCase):
             self.assertIn("./configure  --build=x86_64-linux-gnu --host=x86_64-w64-mingw32",
                           runner.command_called)
         else:
+            build_arch = "aarch64" if platform.machine() == "arm64" else platform.machine()
             self.assertIn("x86_64-w64-mingw32", ab.host)
-            self.assertIn("x86_64-apple-darwin", ab.build)
-            self.assertIn("./configure  --build=x86_64-apple-darwin --host=x86_64-w64-mingw32",
+            self.assertIn(f"{build_arch}-apple-darwin", ab.build)
+            self.assertIn(f"./configure  --build={build_arch}-apple-darwin --host=x86_64-w64-mingw32",
                           runner.command_called)
 
         ab.configure(build="fake_build_triplet", host="fake_host_triplet")
diff --git a/conans/test/unittests/client/generators/cmake_paths_test.py b/conans/test/unittests/client/generators/cmake_paths_test.py
index 82b11c56d..86afb8582 100644
--- a/conans/test/unittests/client/generators/cmake_paths_test.py
+++ b/conans/test/unittests/client/generators/cmake_paths_test.py
@@ -52,9 +52,9 @@ class CMakePathsGeneratorTest(unittest.TestCase):
         custom_dir = custom_dir.replace('\\', '/')
         cmake_lines = generator.content.replace('\\', '/').replace("\n\t\t\t", " ").splitlines()
         self.assertEqual('set(CONAN_MYLIB_ROOT "%s")' % path, cmake_lines[0])
-        self.assertEqual('set(CMAKE_MODULE_PATH "%s/" "%s" ${CMAKE_MODULE_PATH} '
+        self.assertEqual('set(CMAKE_MODULE_PATH "%s/" "%s" ${CONAN_MYLIB_ROOT} ${CMAKE_MODULE_PATH} '
                          '${CMAKE_CURRENT_LIST_DIR})' % (path, custom_dir), cmake_lines[1])
-        self.assertEqual('set(CMAKE_PREFIX_PATH "%s/" "%s" ${CMAKE_PREFIX_PATH} '
+        self.assertEqual('set(CMAKE_PREFIX_PATH "%s/" "%s" ${CONAN_MYLIB_ROOT} ${CMAKE_PREFIX_PATH} '
                          '${CMAKE_CURRENT_LIST_DIR})' % (path, custom_dir), cmake_lines[2])
 
     def test_cpp_info_name(self):
diff --git a/conans/test/unittests/client/tools/oss/cross_building_test.py b/conans/test/unittests/client/tools/oss/cross_building_test.py
index 7374c9778..3eb27b7cd 100644
--- a/conans/test/unittests/client/tools/oss/cross_building_test.py
+++ b/conans/test/unittests/client/tools/oss/cross_building_test.py
@@ -16,6 +16,7 @@ class CrossBuildingTest(unittest.TestCase):
         settings = Settings.loads(get_default_settings_yml())
         settings.os = "FreeBSD"
         settings.arch = "x86_64"
+        settings.arch_build = "x86_64"
         self.assertFalse(cross_building(settings, self_os="FreeBSD", self_arch="x86_64"))
 
         with mock.patch("platform.system", mock.MagicMock(return_value='FreeBSD')),\
diff --git a/conans/test/unittests/model/manifest_test.py b/conans/test/unittests/model/manifest_test.py
index 0945a0650..4a88b65b1 100644
--- a/conans/test/unittests/model/manifest_test.py
+++ b/conans/test/unittests/model/manifest_test.py
@@ -1,6 +1,6 @@
 import os
 
-
+from conans.client.tools import environment_append
 from conans.model.manifest import FileTreeManifest
 from conans.test.utils.test_files import temp_folder
 from conans.util.files import load, md5, save
@@ -49,3 +49,17 @@ class TestManifest:
         save(os.path.join(tmp_dir, "conanmanifest.txt"), "1478122267\nsome: file.py: 123\n")
         read_manifest = FileTreeManifest.load(tmp_dir)
         assert read_manifest.file_sums["some: file.py"] == "123"
+
+
+def test_pycache_included():
+    tmp_dir = temp_folder()
+    files = {"__pycache__/damn.py": "binarythings",
+             "pythonfile.pyc": "binarythings3"}
+    for filename, content in files.items():
+        save(os.path.join(tmp_dir, filename), content)
+
+    with environment_append({"CONAN_KEEP_PYTHON_FILES": "1"}):
+        manifest = FileTreeManifest.create(tmp_dir)
+    manifest = repr(manifest)
+    assert "pythonfile.pyc" in manifest
+    assert "__pycache__/damn.py" in manifest
diff --git a/conans/test/unittests/model/options_test.py b/conans/test/unittests/model/options_test.py
index 4d5a1db40..5fa45bf2a 100644
--- a/conans/test/unittests/model/options_test.py
+++ b/conans/test/unittests/model/options_test.py
@@ -1,6 +1,7 @@
 import sys
 import unittest
 
+import pytest
 import six
 
 from conans.errors import ConanException
@@ -280,6 +281,14 @@ class OptionsValuesTest(unittest.TestCase):
         Boost:thread.multi=off
         """)
 
+    def test_get_safe(self):
+        option_values = OptionsValues(self.sut.as_list())
+        assert option_values.get_safe("missing") is None
+        assert option_values.get_safe("optimized") == 3
+        with pytest.raises(ConanException):
+            # This is not supported at the moment
+            option_values["Boost"].get_safe("thread")
+
     def test_from_list(self):
         option_values = OptionsValues(self.sut.as_list())
         self.assertEqual(option_values.dumps(), self.sut.dumps())
diff --git a/conans/test/unittests/model/other_settings_test.py b/conans/test/unittests/model/other_settings_test.py
index 4933a9105..51d68f36e 100644
--- a/conans/test/unittests/model/other_settings_test.py
+++ b/conans/test/unittests/model/other_settings_test.py
@@ -242,7 +242,7 @@ class SayConan(ConanFile):
 """
         client = TestClient()
         client.save({CONANFILE: content})
-        client.run("install . -s os=Windows --build missing")
+        client.run("install . -s os=Windows -s arch=x86_64 --build missing")
         conan_info = ConanInfo.loads(client.load(CONANINFO))
         self.assertEqual(conan_info.settings.os,  "Windows")
         self.assertEqual(conan_info.settings.fields, ["arch", "os"])
diff --git a/conans/test/unittests/tools/apple/test_apple_tools.py b/conans/test/unittests/tools/apple/test_apple_tools.py
new file mode 100644
index 000000000..4146d0e50
--- /dev/null
+++ b/conans/test/unittests/tools/apple/test_apple_tools.py
@@ -0,0 +1,24 @@
+from conans.test.utils.mocks import ConanFileMock, MockSettings
+from conan.tools.apple import is_apple_os, to_apple_arch
+
+def test_tools_apple_is_apple_os():
+    conanfile = ConanFileMock()
+    
+    conanfile.settings = MockSettings({"os": "Macos"})
+    assert is_apple_os(conanfile) == True
+
+    conanfile.settings = MockSettings({"os": "watchOS"})
+    assert is_apple_os(conanfile) == True
+
+    conanfile.settings = MockSettings({"os": "Windows"})
+    assert is_apple_os(conanfile) == False
+
+    
+def test_tools_apple_to_apple_arch():
+    conanfile = ConanFileMock()
+    
+    conanfile.settings = MockSettings({"arch": "armv8"})
+    assert to_apple_arch(conanfile) == "arm64"
+
+    conanfile.settings = MockSettings({"arch": "x86_64"})
+    assert to_apple_arch(conanfile) == "x86_64"
diff --git a/conans/test/unittests/tools/cmake/test_cmakedeps.py b/conans/test/unittests/tools/cmake/test_cmakedeps.py
index 8be95874d..de54b412e 100644
--- a/conans/test/unittests/tools/cmake/test_cmakedeps.py
+++ b/conans/test/unittests/tools/cmake/test_cmakedeps.py
@@ -82,11 +82,12 @@ def test_cpp_info_name_cmakedeps_components():
         cmakedeps = CMakeDeps(conanfile)
         files = cmakedeps.content
         assert "TARGET GlobalPkgName1::MySuperPkg1" in files["ComplexFileName1-Target-debug.cmake"]
-        # No global variables for the packages
+        # Global variables for the packages
+        # https://github.com/conan-io/conan/issues/11862
         assert 'set(OriginalDepName_INCLUDE_DIRS_DEBUG ' \
                '"${OriginalDepName_PACKAGE_FOLDER_DEBUG}/include")' \
-               not in files["ComplexFileName1-debug-x64-data.cmake"]
-        # But components
+               in files["ComplexFileName1-debug-x64-data.cmake"]
+        # AND components
         assert 'set(OriginalDepName_GlobalPkgName1_MySuperPkg1_INCLUDE_DIRS_DEBUG ' \
                '"${OriginalDepName_PACKAGE_FOLDER_DEBUG}/include")' \
                in files["ComplexFileName1-debug-x64-data.cmake"]
diff --git a/conans/test/unittests/tools/files/collect_lib_test.py b/conans/test/unittests/tools/files/collect_lib_test.py
index e862ce75b..854ea3747 100644
--- a/conans/test/unittests/tools/files/collect_lib_test.py
+++ b/conans/test/unittests/tools/files/collect_lib_test.py
@@ -1,4 +1,7 @@
 import os
+import platform
+
+import pytest
 
 from conan.tools.files import check_md5, check_sha1, check_sha256, collect_libs
 from conans.model.build_info import CppInfo
@@ -43,7 +46,7 @@ def test_collect_libs():
     result = collect_libs(conanfile, folder="custom_folder")
     assert ["customlib"] == result
 
-    # Warn same lib different folders
+    # Unicity of lib names
     conanfile = ConanFileMock()
     conanfile.folders.set_base_package(temp_folder())
     conanfile.cpp_info = CppInfo(conanfile.name, "")
@@ -54,9 +57,6 @@ def test_collect_libs():
     conanfile.cpp_info.libdirs = ["lib", "custom_folder"]
     result = collect_libs(conanfile)
     assert ["mylib"] == result
-    assert "Library 'mylib' was either already found in a previous "\
-           "'conanfile.cpp_info.libdirs' folder or appears several times with a "\
-           "different file extension" in conanfile.output
 
     # Warn lib folder does not exist with correct result
     conanfile = ConanFileMock()
@@ -70,3 +70,23 @@ def test_collect_libs():
     assert ["mylib"] == result
     assert "WARN: Lib folder doesn't exist, can't collect libraries: %s" % no_folder_path \
            in conanfile.output
+
+@pytest.mark.skipif(platform.system() == "Windows", reason="Needs symlinks support")
+def test_collect_libs_symlinks():
+    # Keep only the shortest lib name per group of symlinks
+    conanfile = ConanFileMock()
+    conanfile.folders.set_base_package(temp_folder())
+    conanfile.cpp_info = CppInfo(conanfile.name, "")
+    version_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.1.0.0.dylib")
+    soversion_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.1.dylib")
+    lib_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.dylib")
+    lib_mylib2_path = os.path.join(conanfile.package_folder, "lib", "libmylib.2.dylib")
+    lib_mylib3_path = os.path.join(conanfile.package_folder, "custom_folder", "libmylib.3.dylib")
+    save(version_mylib_path, "")
+    os.symlink(version_mylib_path, soversion_mylib_path)
+    os.symlink(soversion_mylib_path, lib_mylib_path)
+    save(lib_mylib2_path, "")
+    save(lib_mylib3_path, "")
+    conanfile.cpp_info.libdirs = ["lib", "custom_folder"]
+    result = collect_libs(conanfile)
+    assert ["mylib", "mylib.2", "mylib.3"] == result
diff --git a/conans/test/unittests/tools/files/test_patches.py b/conans/test/unittests/tools/files/test_patches.py
index 7f2958aea..ec1661d1d 100644
--- a/conans/test/unittests/tools/files/test_patches.py
+++ b/conans/test/unittests/tools/files/test_patches.py
@@ -175,7 +175,7 @@ def test_multiple_no_version(mock_patch_ng):
 def test_multiple_with_version(mock_patch_ng):
     conanfile = ConanFileMock()
     conanfile.display_name = 'mocked/ref'
-    conanfile.conan_data = {'patches': {
+    conandata_contents = {'patches': {
         "1.11.0": [
             {'patch_file': 'patches/0001-buildflatbuffers-cmake.patch',
              'base_path': 'source_subfolder', },
@@ -190,6 +190,8 @@ def test_multiple_with_version(mock_patch_ng):
              'base_path': 'source_subfolder', },
         ]}}
 
+    conanfile.conan_data = conandata_contents.copy()
+
     with pytest.raises(AssertionError) as excinfo:
         apply_conandata_patches(conanfile)
     assert 'Can only be applied if conanfile.version is already defined' == str(excinfo.value)
@@ -202,3 +204,6 @@ def test_multiple_with_version(mock_patch_ng):
     apply_conandata_patches(conanfile)
     assert 'Apply patch (backport): Needed to build with modern clang compilers.\n' \
            == str(conanfile.output)
+    
+    # Ensure the function is not mutating the `conan_data` structure
+    assert conanfile.conan_data == conandata_contents
diff --git a/conans/test/unittests/tools/gnu/gnudepsflags_test.py b/conans/test/unittests/tools/gnu/gnudepsflags_test.py
index b8e314e15..35836a946 100644
--- a/conans/test/unittests/tools/gnu/gnudepsflags_test.py
+++ b/conans/test/unittests/tools/gnu/gnudepsflags_test.py
@@ -26,7 +26,7 @@ def test_framework_flags_only_for_apple_os(os_):
     gnudepsflags = GnuDepsFlags(conanfile, cpp_info)
     expected_framework = []
     expected_framework_path = []
-    if is_apple_os(os_):
+    if is_apple_os(conanfile):
         expected_framework = ["-framework Foundation"]
         expected_framework_path = ["-F Framework"]
     assert gnudepsflags.frameworks == expected_framework
diff --git a/conans/test/unittests/tools/scm/test_version.py b/conans/test/unittests/tools/scm/test_version.py
index bdb83344a..7c52bb49e 100644
--- a/conans/test/unittests/tools/scm/test_version.py
+++ b/conans/test/unittests/tools/scm/test_version.py
@@ -16,8 +16,17 @@ def test_version():
             def configure(self):
                 v = Version(self.settings.compiler.version)
                 assert v > "10"
+
+                v = Version("1.2.3")
+                self.output.warning(f"The major of 1.2.3 is {v.major}")
+                self.output.warning(f"The minor of 1.2.3 is {v.minor}")
+                self.output.warning(f"The patch of 1.2.3 is {v.patch}")
         """)
     c.save({"conanfile.py": conanfile})
     settings = "-s compiler=gcc -s compiler.libcxx=libstdc++11"
     c.run("create . {} -s compiler.version=11".format(settings))
+    assert "The major of 1.2.3 is 1" in c.out
+    assert "The minor of 1.2.3 is 2" in c.out
+    assert "The patch of 1.2.3 is 3" in c.out
+
     c.run("create . {} -s compiler.version=9".format(settings), assert_error=True)
diff --git a/conans/test/unittests/util/tools_test.py b/conans/test/unittests/util/tools_test.py
index 2be7e00e8..cc4c9bcd0 100644
--- a/conans/test/unittests/util/tools_test.py
+++ b/conans/test/unittests/util/tools_test.py
@@ -817,7 +817,7 @@ class CollectLibTestCase(unittest.TestCase):
         result = tools.collect_libs(conanfile, folder="custom_folder")
         self.assertEqual(["customlib"], result)
 
-        # Warn same lib different folders
+        # Unicity of lib names
         conanfile = ConanFileMock()
         conanfile.folders.set_base_package(temp_folder())
         conanfile.cpp_info = CppInfo(conanfile.name, "")
@@ -828,9 +828,6 @@ class CollectLibTestCase(unittest.TestCase):
         conanfile.cpp_info.libdirs = ["lib", "custom_folder"]
         result = tools.collect_libs(conanfile)
         self.assertEqual(["mylib"], result)
-        self.assertIn("Library 'mylib' was either already found in a previous "
-                      "'conanfile.cpp_info.libdirs' folder or appears several times with a "
-                      "different file extension", conanfile.output)
 
         # Warn lib folder does not exist with correct result
         conanfile = ConanFileMock()
@@ -845,6 +842,26 @@ class CollectLibTestCase(unittest.TestCase):
         self.assertIn("WARN: Lib folder doesn't exist, can't collect libraries: %s"
                       % no_folder_path, conanfile.output)
 
+    @pytest.mark.skipif(platform.system() == "Windows", reason="Needs symlinks support")
+    def test_collect_libs_symlinks(self):
+        # Keep only the shortest lib name per group of symlinks
+        conanfile = ConanFileMock()
+        conanfile.folders.set_base_package(temp_folder())
+        conanfile.cpp_info = CppInfo(conanfile.name, "")
+        version_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.1.0.0.dylib")
+        soversion_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.1.dylib")
+        lib_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.dylib")
+        lib_mylib2_path = os.path.join(conanfile.package_folder, "lib", "libmylib.2.dylib")
+        lib_mylib3_path = os.path.join(conanfile.package_folder, "custom_folder", "libmylib.3.dylib")
+        save(version_mylib_path, "")
+        os.symlink(version_mylib_path, soversion_mylib_path)
+        os.symlink(soversion_mylib_path, lib_mylib_path)
+        save(lib_mylib2_path, "")
+        save(lib_mylib3_path, "")
+        conanfile.cpp_info.libdirs = ["lib", "custom_folder"]
+        result = tools.collect_libs(conanfile)
+        self.assertEqual(["mylib", "mylib.2", "mylib.3"], result)
+
     def test_self_collect_libs(self):
         conanfile = ConanFileMock()
         # Without package_folder
@@ -880,7 +897,7 @@ class CollectLibTestCase(unittest.TestCase):
         result = conanfile.collect_libs(folder="custom_folder")
         self.assertEqual(["customlib"], result)
 
-        # Warn same lib different folders
+        # Unicity of lib names
         conanfile = ConanFileMock()
         conanfile.folders.set_base_package(temp_folder())
         conanfile.cpp_info = CppInfo("", "")
@@ -891,9 +908,6 @@ class CollectLibTestCase(unittest.TestCase):
         conanfile.cpp_info.libdirs = ["lib", "custom_folder"]
         result = conanfile.collect_libs()
         self.assertEqual(["mylib"], result)
-        self.assertIn("Library 'mylib' was either already found in a previous "
-                      "'conanfile.cpp_info.libdirs' folder or appears several times with a "
-                      "different file extension", conanfile.output)
 
         # Warn lib folder does not exist with correct result
         conanfile = ConanFileMock()
@@ -907,3 +921,23 @@ class CollectLibTestCase(unittest.TestCase):
         self.assertEqual(["mylib"], result)
         self.assertIn("WARN: Lib folder doesn't exist, can't collect libraries: %s"
                       % no_folder_path, conanfile.output)
+
+    @pytest.mark.skipif(platform.system() == "Windows", reason="Needs symlinks support")
+    def test_self_collect_libs_symlinks(self):
+        # Keep only the shortest lib name per group of symlinks
+        conanfile = ConanFileMock()
+        conanfile.folders.set_base_package(temp_folder())
+        conanfile.cpp_info = CppInfo("", "")
+        version_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.1.0.0.dylib")
+        soversion_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.1.dylib")
+        lib_mylib_path = os.path.join(conanfile.package_folder, "lib", "libmylib.dylib")
+        lib_mylib2_path = os.path.join(conanfile.package_folder, "lib", "libmylib.2.dylib")
+        lib_mylib3_path = os.path.join(conanfile.package_folder, "custom_folder", "libmylib.3.dylib")
+        save(version_mylib_path, "")
+        os.symlink(version_mylib_path, soversion_mylib_path)
+        os.symlink(soversion_mylib_path, lib_mylib_path)
+        save(lib_mylib2_path, "")
+        save(lib_mylib3_path, "")
+        conanfile.cpp_info.libdirs = ["lib", "custom_folder"]
+        result = conanfile.collect_libs()
+        self.assertEqual(["mylib", "mylib.2", "mylib.3"], result)
diff --git a/conans/test/utils/tools.py b/conans/test/utils/tools.py
index f46111f92..b9553bf24 100644
--- a/conans/test/utils/tools.py
+++ b/conans/test/utils/tools.py
@@ -532,6 +532,12 @@ class TestClient(object):
         else:
             return self.get_conan_api_v1()
 
+    def get_default_host_profile(self):
+        return self.cache.default_profile
+
+    def get_default_build_profile(self):
+        return self.cache.default_profile
+
     def run_cli(self, command_line, assert_error=False):
         conan = self.get_conan_api()
         self.api = conan