Repository: conan-io/conan
Pull request #11823 (2022-08-09 12:05:27)

tools.scm.Version in develop as is in develop2
Changelog: Bugfix: The `tool.scm.Version` model has been ported from 2.X to keep the same behavior in Conan 1.X
Docs: omit

Close https://github.com/conan-io/conan/issues/11821


Patch:
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 e5f3f3a22..4681fa55c 100644
--- a/conan/tools/cmake/cmakedeps/templates/macros.py
+++ b/conan/tools/cmake/cmakedeps/templates/macros.py
@@ -41,7 +41,7 @@ class MacrosTemplate(CMakeDepsFileTemplate):
            endif()
        endmacro()
 
-       function(conan_package_library_targets libraries package_libdir deps out_libraries_target config package_name)
+       function(conan_package_library_targets libraries package_libdir deps_target out_libraries_target config package_name)
            set(_out_libraries "")
            set(_out_libraries_target "")
            set(_CONAN_ACTUAL_TARGETS "")
@@ -73,10 +73,9 @@ class MacrosTemplate(CMakeDepsFileTemplate):
                unset(CONAN_FOUND_LIBRARY CACHE)
            endforeach()
 
-           # Add all dependencies to all targets
-           string(REPLACE " " ";" deps_list "${deps}")
+           # Add the dependencies target for all the imported libraries
            foreach(_CONAN_ACTUAL_TARGET ${_CONAN_ACTUAL_TARGETS})
-               set_property(TARGET ${_CONAN_ACTUAL_TARGET} PROPERTY INTERFACE_LINK_LIBRARIES $<$<CONFIG:${config}>:${deps_list}> APPEND)
+               set_property(TARGET ${_CONAN_ACTUAL_TARGET} PROPERTY INTERFACE_LINK_LIBRARIES ${deps_target} APPEND)
            endforeach()
 
            # ONLY FOR DEBUGGING PURPOSES
diff --git a/conan/tools/cmake/cmakedeps/templates/target_configuration.py b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
index 21bfa56ff..66d6ffe25 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_configuration.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_configuration.py
@@ -40,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+'}'}}
@@ -60,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)
-        # FIXME: Why is needed to pass all the dependencies to link with the micro-targets?
-        set(_{{ pkg_name }}_DEPENDENCIES{{ config_suffix }} "{{ deps_targets_names }}")
-
         set({{ pkg_name }}_LIBRARIES_TARGETS{{ config_suffix }} "") # Will be filled later
+
+
+        ######## 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()
+
+        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)
+
+        ####### 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 }}_DEPENDENCIES{{ config_suffix }}}" # deps
+                                      {{ pkg_name + '_DEPS_TARGET'}}
                                       {{ pkg_name }}_LIBRARIES_TARGETS  # out_libraries_targets
                                       "{{ config }}" # DEBUG, RELEASE ...
                                       "{{ pkg_name }}")    # package_name
 
-        # The XXXX_LIBRARIES_RELEASE/DEBUG is used for the module (FindXXX.cmake)
-        foreach(_FRAMEWORK {{ '${' }}{{ pkg_name }}_FRAMEWORKS_FOUND{{ config_suffix }}})
-            list(APPEND {{ pkg_name }}_LIBRARIES{{ config_suffix }} ${_FRAMEWORK})
-        endforeach()
-
-        foreach(_SYSTEM_LIB {{ '${' }}{{ pkg_name }}_SYSTEM_LIBS{{ config_suffix }}})
-            list(APPEND {{ pkg_name }}_LIBRARIES{{ config_suffix }} ${_SYSTEM_LIB})
-        endforeach()
-
-        # We need to add our requirements too
-        set({{ pkg_name }}_LIBRARIES{{ config_suffix }} "")
-        list(APPEND {{ pkg_name }}_LIBRARIES{{ config_suffix }} {{ deps_targets_names }})
-
         # 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})
 
         {% 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:{{configuration}}>:${{'{'}}_{{pkg_name}}_DEPENDENCIES{{config_suffix}}}>
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_FRAMEWORKS_FOUND{{config_suffix}}}>
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_SYSTEM_LIBS{{config_suffix}}}>
-                     APPEND)
+            set_property(TARGET {{root_target_name}}
+                         PROPERTY INTERFACE_LINK_LIBRARIES
+                         $<$<CONFIG:{{configuration}}>:{{ '${'+pkg_name+'_OBJECTS'+config_suffix+'}' }}>
+                         ${{'{'}}{{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_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 %}
 
         ########## COMPONENTS TARGET PROPERTIES {{ configuration }} ########################################
 
-        {%- for comp_variable_name, comp_target_name in components_names %}
+            {%- for comp_variable_name, comp_target_name in components_names %}
 
-        ########## COMPONENT {{ comp_target_name }} FIND LIBRARIES & FRAMEWORKS / DYNAMIC VARS #############
 
-        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+'}' }}")
+            ########## COMPONENT {{ comp_target_name }} #############
 
-        set({{ pkg_name }}_{{ comp_variable_name }}_LIBRARIES_TARGETS "")
+                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+'}' }}")
 
-        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+'_DEPENDENCIES'+config_suffix+'}' }}"
-                                      {{ pkg_name }}_{{ comp_variable_name }}_LIBRARIES_TARGETS
-                                      "{{ config }}" # DEBUG, RELEASE...
-                                      "{{ pkg_name }}_{{ comp_variable_name }}")
+                set({{ pkg_name }}_{{ comp_variable_name }}_LIBRARIES_TARGETS "")
 
-        ########## COMPONENT {{ comp_target_name }} TARGET PROPERTIES #####################################
-        set_property(TARGET {{comp_target_name}}
-                     PROPERTY INTERFACE_LINK_LIBRARIES
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_{{comp_variable_name}}_OBJECTS{{config_suffix}}}>
-                     ${{'{'}}{{pkg_name}}_{{comp_variable_name}}_LIBRARIES_TARGETS}
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_{{comp_variable_name}}_DEPENDENCIES{{config_suffix}}}>
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_{{comp_variable_name}}_FRAMEWORKS_FOUND{{config_suffix}}}>
-                     $<$<CONFIG:{{configuration}}>:${{'{'}}{{pkg_name}}_{{comp_variable_name}}_SYSTEM_LIBS{{config_suffix}}}>
-                     APPEND)
+                ######## 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 {{ 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_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)
 
-        {%- endif %}
-        {%- endfor %}
+                ####### 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 }}" # DEBUG, RELEASE...
+                                              "{{ 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+'}' }}>
+                             ${{'{'}}{{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()
 
+                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)
 
-        ########## AGGREGATED GLOBAL TARGET WITH THE COMPONENTS #####################
-        {%- for comp_variable_name, comp_target_name in components_names %}
+                {%- 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)
 
-        target_link_libraries({{root_target_name}} INTERFACE {{ comp_target_name }})
+                {%- 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..84c2fcd42 100644
--- a/conan/tools/cmake/cmakedeps/templates/target_data.py
+++ b/conan/tools/cmake/cmakedeps/templates/target_data.py
@@ -108,7 +108,9 @@ class ConfigDataTemplate(CMakeDepsFileTemplate):
 
               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 }})
diff --git a/conan/tools/cmake/layout.py b/conan/tools/cmake/layout.py
index 6a464f5c3..6124a04fc 100644
--- a/conan/tools/cmake/layout.py
+++ b/conan/tools/cmake/layout.py
@@ -24,14 +24,14 @@ def cmake_layout(conanfile, generator=None, src_folder="."):
     build_folder = "build" if not subproject else os.path.join(subproject, "build")
     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/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/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/system/package_manager.py b/conan/tools/system/package_manager.py
index 435350a4b..a416d2db5 100644
--- a/conan/tools/system/package_manager.py
+++ b/conan/tools/system/package_manager.py
@@ -221,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/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/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/migrations_settings.py b/conans/client/migrations_settings.py
index da3cbaad1..3ade307f4 100644
--- a/conans/client/migrations_settings.py
+++ b/conans/client/migrations_settings.py
@@ -3716,5 +3716,6 @@ settings_1_50_0 = settings_1_49_0
 settings_1_50_1 = settings_1_50_0
 
 settings_1_51_0 = settings_1_50_1
+settings_1_51_1 = settings_1_51_0
 
-settings_1_52_0 = settings_1_51_0
+settings_1_52_0 = settings_1_51_1
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/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/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/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
index 4e4f7b9f7..7e6d86dd4 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps.py
@@ -141,6 +141,10 @@ 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 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"]:
@@ -157,10 +161,136 @@ def test_system_libs():
             assert "System libs debug: %s" % library_name in client.out
             assert "Libraries to Link debug: lib1" in client.out
 
-        # FIXME: This assert is ugly, empty configs comes from empty _OBJECTS, FRAMEWORKS etc
-        target_libs = f"$<$<CONFIG:{build_type}>:>;CONAN_LIB::Test_lib1;$<$<CONFIG:{build_type}>" \
-                      f":>;$<$<CONFIG:{build_type}>:>;$<$<CONFIG:{build_type}>:{library_name}>"
-        assert target_libs in client.out
+        assert f"Target libs: $<$<CONFIG:{build_type}>:>;CONAN_LIB::Test_lib1" 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}>:>;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}>:>;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
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 e2b4a0cdc..da0f0d015 100644
--- a/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py
+++ b/conans/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_components.py
@@ -198,15 +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")
-    # FIXME: This assert is ugly, empty configs comes from empty _OBJECTS, FRAMEWORKS etc
-    assert 'component libs: $<$<CONFIG:Release>:>;$<$<CONFIG:Release>:>;$<$<CONFIG:Release>:>' \
-           ';$<$<CONFIG:Release>:system_lib_component>' in t.out
+    assert 'component libs: $<$<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>:>;'
@@ -322,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>:>;boost_boost_B_DEPS_TARGET" in t.out
+    assert "BOOST_A LINKED: $<$<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..02198a048 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>:>;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/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/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/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/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/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/cmake/cmakedeps/test_cmakedeps.py b/conans/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
index 558c1c83f..5b7ee09fe 100644
--- a/conans/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
+++ b/conans/test/integration/toolchains/cmake/cmakedeps/test_cmakedeps.py
@@ -105,16 +105,15 @@ def test_cpp_info_component_objects():
     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_LIBRARIES_TARGETS}""" in content
+                     PROPERTY INTERFACE_LINK_LIBRARIES
+                     $<$<CONFIG:Release>:${hello_hello_say_OBJECTS_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}""" 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()
diff --git a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 1bb64565e..08262873f 100644
--- a/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/conans/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -585,6 +585,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/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/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)