Repository: conan-io/conan
Pull request #15287 (2023-12-17 18:33:32)

Backport `<host_version:track ref>` to Conan v1
Changelog: Feature: Add tracking of different ref to `<host_version>`
Changelog: Bugfix: Make `<host_version>` only track for same user/channel
Docs: TODO

Need to check with the team if we want the bugfix. Conan v2 behaves similarly


Patch:
diff --git a/conan/tools/gnu/pkgconfigdeps.py b/conan/tools/gnu/pkgconfigdeps.py
index 30782d847..c7ed3f719 100644
--- a/conan/tools/gnu/pkgconfigdeps.py
+++ b/conan/tools/gnu/pkgconfigdeps.py
@@ -288,10 +288,10 @@ class _PCGenerator:
         requires = self._get_cpp_info_requires_names(self._dep.cpp_info)
         # If we have found some component requires it would be enough
         if not requires:
-            # If no requires were found, let's try to get all the direct dependencies,
+            # If no requires were found, let's try to get all the direct visible dependencies,
             # e.g., requires = "other_pkg/1.0"
             requires = [_get_package_name(req, self._build_context_suffix)
-                        for req in self._dep.dependencies.direct_host.values()]
+                        for dep, req in self._dep.dependencies.direct_host.items() if dep.visible]
         description = "Conan package: %s" % pkg_name
         aliases = _get_package_aliases(self._dep)
         cpp_info = self._dep.cpp_info
diff --git a/conan/tools/google/bazeldeps.py b/conan/tools/google/bazeldeps.py
index 8d0cd37e1..233b4bb32 100644
--- a/conan/tools/google/bazeldeps.py
+++ b/conan/tools/google/bazeldeps.py
@@ -95,11 +95,13 @@ def _get_libs(dep, cpp_info=None) -> list:
         return default_value
 
     def _save_lib_path(lib_, lib_path_):
-        _, ext_ = os.path.splitext(lib_path_)
+        """Add each lib with its full library path"""
+        formatted_path = lib_path_.replace("\\", "/")
+        _, ext_ = os.path.splitext(formatted_path)
         if is_shared and ext_ == ".lib":  # Windows interface library
-            interface_lib_paths[lib_] = lib_path_
+            interface_lib_paths[lib_] = formatted_path
         else:
-            lib_paths[lib_] = lib_path_
+            lib_paths[lib_] = formatted_path
 
     cpp_info = cpp_info or dep.cpp_info
     is_shared = _is_shared()
@@ -119,23 +121,21 @@ def _get_libs(dep, cpp_info=None) -> list:
             # Users may not name their libraries in a conventional way. For example, directly
             # use the basename of the lib file as lib name.
             if f in libs:
-                lib = f
-                # libs.remove(f)
-                lib_path = full_path
-                _save_lib_path(lib, lib_path)
+                _save_lib_path(f, full_path)
                 continue
             name, ext = os.path.splitext(f)
             if name not in libs and name.startswith("lib"):
-                name = name[3:]
-            if name in libs:
-                # FIXME: Should it read a conf variable to know unexpected extensions?
-                if (is_shared and ext in (".so", ".dylib", ".lib", ".dll")) or \
-                   (not is_shared and ext in (".a", ".lib")):
-                    lib = name
-                    # libs.remove(name)
-                    lib_path = full_path
-                    _save_lib_path(lib, lib_path)
+                name = name[3:]  # libpkg -> pkg
+             # FIXME: Should it read a conf variable to know unexpected extensions?
+            if (is_shared and ext in (".so", ".dylib", ".lib", ".dll")) or \
+               (not is_shared and ext in (".a", ".lib")):
+                if name in libs:
+                    _save_lib_path(name, full_path)
                     continue
+                else:  # last chance: some cases the name could be pkg.if instead of pkg
+                    name = name.split(".", maxsplit=1)[0]
+                    if name in libs:
+                        _save_lib_path(name, full_path)
 
     libraries = []
     for lib, lib_path in lib_paths.items():
diff --git a/conan/tools/microsoft/nmakedeps.py b/conan/tools/microsoft/nmakedeps.py
index fe77e9480..62a347563 100644
--- a/conan/tools/microsoft/nmakedeps.py
+++ b/conan/tools/microsoft/nmakedeps.py
@@ -50,9 +50,9 @@ class NMakeDeps(object):
                     # https://learn.microsoft.com/en-us/cpp/build/reference/cl-environment-variables
                     macro, value = define.split("=", 1)
                     if value and not value.isnumeric():
-                        value = f'\\"{value}\\"'
+                        value = f'\"{value}\"'
                     define = f"{macro}#{value}"
-                return f"/D{define}"
+                return f"/D\"{define}\""
 
             cl_flags = [f'-I"{p}"' for p in cpp_info.includedirs or []]
             cl_flags.extend(cpp_info.cflags or [])
diff --git a/conan/tools/microsoft/nmaketoolchain.py b/conan/tools/microsoft/nmaketoolchain.py
index c9c1c666f..c4a34a6ec 100644
--- a/conan/tools/microsoft/nmaketoolchain.py
+++ b/conan/tools/microsoft/nmaketoolchain.py
@@ -36,7 +36,7 @@ class NMakeToolchain(object):
                 if value and not value.isnumeric():
                     value = f'\\"{value}\\"'
                 define = f"{macro}#{value}"
-            formated_defines.append(f"/D{define}")
+            formated_defines.append(f"/D\"{define}\"")
         return formated_defines
 
     @property
diff --git a/conans/assets/templates/new_v2_bazel.py b/conans/assets/templates/new_v2_bazel.py
index 8c6c6e4d7..dba49a8bb 100644
--- a/conans/assets/templates/new_v2_bazel.py
+++ b/conans/assets/templates/new_v2_bazel.py
@@ -55,7 +55,10 @@ class {package_name}Conan(ConanFile):
              os.path.join(self.package_folder, "include"), keep_path=False)
 
     def package_info(self):
-        self.cpp_info.libs = ["{name}"]
+        if self.options.shared and self.settings.os != "Linux":
+            self.cpp_info.libs = ["{name}_shared"]
+        else:
+            self.cpp_info.libs = ["{name}"]
 """
 
 
@@ -77,7 +80,7 @@ class {package_name}TestConan(ConanFile):
 
     def build(self):
         bazel = Bazel(self)
-        bazel.build()
+        bazel.build(target="//main:example")
 
     def layout(self):
         # DEPRECATED: Default generators folder will be "conan" in Conan 2.x
@@ -125,7 +128,7 @@ cc_library(
 
 cc_shared_library(
     name = "{name}_shared",
-    shared_lib_name = "lib{name}.{ext}",
+    shared_lib_name = "lib{name}_shared.{ext}",
     deps = [":{name}"],
 )
 """
diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py
index 4eae5b5e2..9893b7516 100644
--- a/conans/client/conf/__init__.py
+++ b/conans/client/conf/__init__.py
@@ -59,7 +59,8 @@ _t_default_settings_yml = Template(textwrap.dedent("""
             sdk_version: [None, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4",
                           "13.0", "13.1", "13.2", "13.4", "14.0", "14.2", "14.3", "14.5", "15.0", "15.2", "15.4", "16.0", "16.1"]
         Macos:
-            version: [None, "10.6", "10.7", "10.8", "10.9", "10.10", "10.11", "10.12", "10.13", "10.14", "10.15", "11.0", "12.0", "13.0"]
+            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",
+                      "14.0", "14.1"]
             sdk: [None, "macosx"]
             sdk_version: [None, "10.13", "10.14", "10.15", "11.0", "11.1", "11.3", "12.0", "12.1", "12.3", "13.0", "13.1"]
             subsystem:
diff --git a/conans/client/graph/graph_builder.py b/conans/client/graph/graph_builder.py
index e13be7137..efe94da82 100644
--- a/conans/client/graph/graph_builder.py
+++ b/conans/client/graph/graph_builder.py
@@ -404,18 +404,29 @@ class DepsGraphBuilder(object):
 
     def _resolve_recipe(self, current_node, dep_graph, requirement, check_updates,
                         update, remotes, profile, graph_lock, original_ref=None):
-
         ref = requirement.ref
-        if ref.version == "<host_version>":
+        ref_version = str(ref.version)
+        if ref_version.startswith("<host_version") and ref_version.endswith(">"):
             if not requirement.build_require:
                 raise ConanException(f"{current_node.ref} uses '<host_version>' in requires, "
                                      "it is only allowed in tool_requires")
+            search_ref_name = ref.name
+            tracking_ref = ref_version.split(":", 1)
+            if len(tracking_ref) == 2:
+                search_ref_name = tracking_ref[1][:-1]  # Remove trailing '>'
             transitive = next((dep for dep in current_node.dependencies if
-                  not dep.build_require and dep.require.ref.name == ref.name), None)
+                               not dep.build_require and
+                               dep.require.ref.name == search_ref_name and
+                               dep.require.ref.user == ref.user and
+                               dep.require.ref.channel == ref.channel), None)
             if transitive is None:
                 raise ConanException(
-                    f"{current_node.ref} require '{ref}': didn't find a matching host dependency")
-            requirement.ref = transitive.require.ref
+                    f"{current_node.ref} require '{search_ref_name}/{ref_version}': didn't find a matching host dependency")
+            new_ref = transitive.require.ref
+            # Final ref is the one from the transitive dependency, but with the version from the
+            # tracked requirement, if any
+            requirement.ref = ConanFileReference(ref.name, new_ref.version,
+                                                 new_ref.user, new_ref.channel)
 
         try:
             result = self._proxy.get_recipe(requirement.ref, check_updates, update,
diff --git a/conans/client/migrations_settings.py b/conans/client/migrations_settings.py
index 3b3cbebf9..3085197e9 100644
--- a/conans/client/migrations_settings.py
+++ b/conans/client/migrations_settings.py
@@ -4814,4 +4814,159 @@ build_type: [None, Debug, Release, RelWithDebInfo, MinSizeRel]
 cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]  # Deprecated, use compiler.cppstd
 """
 
-settings_1_63_0 = settings_1_62_0
+settings_1_63_0 = """
+# Only for cross building, 'os_build/arch_build' is the system that runs Conan
+os_build: [Windows, WindowsStore, Linux, Macos, FreeBSD, SunOS, AIX, VxWorks]
+arch_build: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7]
+
+# Only for building cross compilation tools, 'os_target/arch_target' is the system for
+# which the tools generate code
+os_target: [Windows, Linux, Macos, Android, iOS, watchOS, tvOS, FreeBSD, SunOS, AIX, Arduino, Neutrino]
+arch_target: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7, xtensalx6, xtensalx106, xtensalx7]
+
+# Rest of the settings are "host" settings:
+# - For native building/cross building: Where the library/program will run.
+# - For building cross compilation tools: Where the cross compiler will run.
+os:
+    Windows:
+        subsystem: [None, cygwin, msys, msys2, wsl]
+    WindowsStore:
+        version: ["8.1", "10.0"]
+    WindowsCE:
+        platform: ANY
+        version: ["5.0", "6.0", "7.0", "8.0"]
+    Linux:
+    iOS:
+        version: &ios_version
+                 ["7.0", "7.1", "8.0", "8.1", "8.2", "8.3", "9.0", "9.1", "9.2", "9.3", "10.0", "10.1", "10.2", "10.3",
+                  "11.0", "11.1", "11.2", "11.3", "11.4", "12.0", "12.1", "12.2", "12.3", "12.4",
+                  "13.0", "13.1", "13.2", "13.3", "13.4", "13.5", "13.6", "13.7",
+                  "14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7", "14.8",
+                  "15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6", "16.0", "16.1"]
+        sdk: [None, "iphoneos", "iphonesimulator"]
+        sdk_version: [None, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4",
+                      "13.0", "13.1", "13.2", "13.4", "13.5", "13.6", "13.7",
+                      "14.0", "14.1", "14.2", "14.3", "14.4", "14.5", "15.0", "15.2", "15.4", "15.5", "16.0", "16.1"]
+    watchOS:
+        version: ["4.0", "4.1", "4.2", "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2",
+                  "7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6", "8.0", "8.1", "8.3", "8.4", "8.5", "8.6", "8.7", "9.0", "9.1"]
+        sdk: [None, "watchos", "watchsimulator"]
+        sdk_version: [None, "4.3", "5.0", "5.1", "5.2", "5.3", "6.0", "6.1", "6.2",
+                      "7.0", "7.1", "7.2", "7.4", "8.0", "8.0.1", "8.3", "8.5", "9.0", "9.1"]
+    tvOS:
+        version: ["11.0", "11.1", "11.2", "11.3", "11.4", "12.0", "12.1", "12.2", "12.3", "12.4",
+                  "13.0", "13.2", "13.3", "13.4", "14.0", "14.2", "14.3", "14.4", "14.5", "14.6", "14.7",
+                  "15.0", "15.1", "15.2", "15.3", "15.4", "15.5", "15.6", "16.0", "16.1"]
+        sdk: [None, "appletvos", "appletvsimulator"]
+        sdk_version: [None, "11.3", "11.4", "12.0", "12.1", "12.2", "12.4",
+                      "13.0", "13.1", "13.2", "13.4", "14.0", "14.2", "14.3", "14.5", "15.0", "15.2", "15.4", "16.0", "16.1"]
+    Macos:
+        version: [None, "10.6", "10.7", "10.8", "10.9", "10.10", "10.11", "10.12", "10.13", "10.14", "10.15", "11.0", "12.0", "13.0",
+                  "14.0", "14.1"]
+        sdk: [None, "macosx"]
+        sdk_version: [None, "10.13", "10.14", "10.15", "11.0", "11.1", "11.3", "12.0", "12.1", "12.3", "13.0", "13.1"]
+        subsystem:
+            None:
+            catalyst:
+                ios_version: *ios_version
+    Android:
+        api_level: ANY
+    FreeBSD:
+    SunOS:
+    AIX:
+    Arduino:
+        board: ANY
+    Emscripten:
+    Neutrino:
+        version: ["6.4", "6.5", "6.6", "7.0", "7.1"]
+    baremetal:
+    VxWorks:
+        version: ["7"]
+arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64, armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, sparc, sparcv9, mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le, e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7, xtensalx6, xtensalx106, xtensalx7]
+compiler:
+    sun-cc:
+        version: ["5.10", "5.11", "5.12", "5.13", "5.14", "5.15"]
+        threads: [None, posix]
+        libcxx: [libCstd, libstdcxx, libstlport, libstdc++]
+    gcc: &gcc
+        version: ["4.1", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9",
+                  "5", "5.1", "5.2", "5.3", "5.4", "5.5",
+                  "6", "6.1", "6.2", "6.3", "6.4", "6.5",
+                  "7", "7.1", "7.2", "7.3", "7.4", "7.5",
+                  "8", "8.1", "8.2", "8.3", "8.4", "8.5",
+                  "9", "9.1", "9.2", "9.3", "9.4", "9.5",
+                  "10", "10.1", "10.2", "10.3", "10.4", "10.5",
+                  "11", "11.1", "11.2", "11.3", "11.4",
+                  "12", "12.1", "12.2", "12.3",
+                  "13", "13.1", "13.2"]
+        libcxx: [libstdc++, libstdc++11]
+        threads: [None, posix, win32]  # Windows MinGW
+        exception: [None, dwarf2, sjlj, seh]  # Windows MinGW
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+    Visual Studio: &visual_studio
+        runtime: [MD, MT, MTd, MDd]
+        version: ["8", "9", "10", "11", "12", "14", "15", "16", "17"]
+        toolset: [None, v90, v100, v110, v110_xp, v120, v120_xp,
+                  v140, v140_xp, v140_clang_c2, LLVM-vs2012, LLVM-vs2012_xp,
+                  LLVM-vs2013, LLVM-vs2013_xp, LLVM-vs2014, LLVM-vs2014_xp,
+                  LLVM-vs2017, LLVM-vs2017_xp, v141, v141_xp, v141_clang_c2, v142,
+                  llvm, ClangCL, v143]
+        cppstd: [None, 14, 17, 20, 23]
+    msvc:
+        version: [170, 180, 190, 191, 192, 193]
+        update: [None, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+        runtime: [static, dynamic]
+        runtime_type: [Debug, Release]
+        cppstd: [98, 14, 17, 20, 23]
+        toolset: [None, v110_xp, v120_xp, v140_xp, v141_xp]
+    clang:
+        version: ["3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0",
+                  "5.0", "6.0", "7.0", "7.1",
+                  "8", "9", "10", "11", "12", "13", "14", "15", "16", "17"]
+        libcxx: [None, libstdc++, libstdc++11, libc++, c++_shared, c++_static]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        runtime: [None, MD, MT, MTd, MDd, static, dynamic]
+        runtime_type: [None, Debug, Release]
+        runtime_version: [None, v140, v141, v142, v143]
+    apple-clang: &apple_clang
+        version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", "9.1",
+                  "10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", "14.0", "15", "15.0"]
+        libcxx: [libstdc++, libc++]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+    intel:
+        version: ["11", "12", "13", "14", "15", "16", "17", "18", "19", "19.1"]
+        update: [None, ANY]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exception: [None]
+            Visual Studio:
+                <<: *visual_studio
+            apple-clang:
+                <<: *apple_clang
+    intel-cc:
+        version: ["2021.1", "2021.2", "2021.3"]
+        update: [None, ANY]
+        mode: ["icx", "classic", "dpcpp"]
+        libcxx: [None, libstdc++, libstdc++11, libc++]
+        cppstd: [None, 98, gnu98, 03, gnu03, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+        runtime: [None, static, dynamic]
+        runtime_type: [None, Debug, Release]
+    qcc:
+        version: ["4.4", "5.4", "8.3"]
+        libcxx: [cxx, gpp, cpp, cpp-ne, accp, acpp-ne, ecpp, ecpp-ne]
+        cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17]
+    mcst-lcc:
+        version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]
+        base:
+            gcc:
+                <<: *gcc
+                threads: [None]
+                exceptions: [None]
+
+build_type: [None, Debug, Release, RelWithDebInfo, MinSizeRel]
+
+
+cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]  # Deprecated, use compiler.cppstd
+"""
diff --git a/conans/model/new_build_info.py b/conans/model/new_build_info.py
index b05b026d6..34aae693e 100644
--- a/conans/model/new_build_info.py
+++ b/conans/model/new_build_info.py
@@ -263,7 +263,8 @@ class NewCppInfo(object):
 
 def from_old_cppinfo(old):
     ret = NewCppInfo()
-    ret.merge(old)
+    if old is not None:
+        ret.merge(old)
     ret.clear_none()
     return ret
 
diff --git a/conans/model/ref.py b/conans/model/ref.py
index 9361a68ef..c9a550f42 100644
--- a/conans/model/ref.py
+++ b/conans/model/ref.py
@@ -153,7 +153,8 @@ class ConanName(object):
     @staticmethod
     def validate_version(version, pkg_name):
         ConanName.validate_string(version)
-        if version == "*" or version == "<host_version>":
+        version_str = str(version)
+        if version == "*" or (version_str.startswith("<host_version") and version_str.endswith(">")):
             return
         if ConanName._validation_pattern.match(version) is None:
             if (


Test patch:
diff --git a/conans/test/functional/build_helpers/autotools_apple_test.py b/conans/test/functional/build_helpers/autotools_apple_test.py
index e68127762..727d91a5c 100644
--- a/conans/test/functional/build_helpers/autotools_apple_test.py
+++ b/conans/test/functional/build_helpers/autotools_apple_test.py
@@ -87,11 +87,13 @@ class AutoToolsAppleTest(unittest.TestCase):
             include(default)
             [settings]
             os = Macos
-            os.version = 12.0
+            os.version = 14.0
             os.sdk = macosx
             os.subsystem = catalyst
-            os.subsystem.ios_version = 13.1
+            os.subsystem.ios_version = 16.1
             arch = {arch}
+            [buildenv]
+            DEVELOPER_DIR=/Applications/conan/xcode/15.1
             """).format(arch=arch)
 
         self.t = TestClient()
@@ -135,6 +137,6 @@ class AutoToolsAppleTest(unittest.TestCase):
         self.t.run_command('lipo -info "%s"' % app)
         self.assertIn("architecture: %s" % expected_arch, self.t.out)
 
-        if arch == "x86_64":
-            self.t.run_command('"%s"' % app)
-            self.assertIn("running catalyst 130100", self.t.out)
+        # FIXME: recover when ci is fixed for M2
+        #self.t.run_command('"%s"' % app)
+        #self.assertIn("running catalyst 130100", self.t.out)
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 c9217eac7..8ff2253ee 100644
--- a/conans/test/functional/toolchains/gnu/autotools/test_apple_toolchain.py
+++ b/conans/test/functional/toolchains/gnu/autotools/test_apple_toolchain.py
@@ -85,11 +85,13 @@ def test_catalyst(arch):
         include(default)
         [settings]
         os = Macos
-        os.version = 13.0
+        os.version = 14.0
         os.sdk = macosx
         os.subsystem = catalyst
-        os.subsystem.ios_version = 13.1
+        os.subsystem.ios_version = 16.1
         arch = {arch}
+        [buildenv]
+        DEVELOPER_DIR=/Applications/conan/xcode/15.1
         """).format(arch=arch)
 
     t = TestClient()
@@ -133,6 +135,6 @@ def test_catalyst(arch):
     t.run_command('lipo -info "%s"' % app)
     assert "architecture: %s" % expected_arch in t.out
 
-    if arch == "x86_64":
-        t.run_command('"%s"' % app)
-        assert "running catalyst 130100" in t.out
+    #FIXME: recover when ci is fixed for M2
+    #t.run_command('"%s"' % app)
+    #assert "running catalyst 130100" in t.out
diff --git a/conans/test/functional/toolchains/google/test_bazel.py b/conans/test/functional/toolchains/google/test_bazel.py
index da78fb19a..b4ce17c3c 100644
--- a/conans/test/functional/toolchains/google/test_bazel.py
+++ b/conans/test/functional/toolchains/google/test_bazel.py
@@ -135,7 +135,7 @@ def test_transitive_libs_consuming(shared):
 
         cc_shared_library(
             name = "mysecondlib_shared",
-            shared_lib_name = "libmysecondlib.{}",
+            shared_lib_name = "libmysecondlib_shared.{}",
             deps = [":mysecondlib"],
         )
         """.format("dylib" if os_ == "Darwin" else "dll"))
diff --git a/conans/test/functional/toolchains/test_nmake_toolchain.py b/conans/test/functional/toolchains/test_nmake_toolchain.py
index f45b97592..827fcfbc2 100644
--- a/conans/test/functional/toolchains/test_nmake_toolchain.py
+++ b/conans/test/functional/toolchains/test_nmake_toolchain.py
@@ -13,7 +13,8 @@ from conans.test.utils.tools import TestClient
     [
         ("msvc", "190", "dynamic", "14", "Release", [], [], [], [], []),
         ("msvc", "190", "dynamic", "14", "Release",
-         ["TEST_DEFINITION1", "TEST_DEFINITION2=0", "TEST_DEFINITION3=", "TEST_DEFINITION4=TestPpdValue4"],
+         ["TEST_DEFINITION1", "TEST_DEFINITION2=0", "TEST_DEFINITION3=", "TEST_DEFINITION4=TestPpdValue4",
+          "TEST_DEFINITION5=__declspec(dllexport)", "TEST_DEFINITION6=foo bar"],
          ["/GL"], ["/GL"], ["/LTCG"], ["/LTCG"]),
         ("msvc", "191", "static", "17", "Debug", [], [], [], [], []),
     ],
diff --git a/conans/test/integration/build_requires/build_requires_test.py b/conans/test/integration/build_requires/build_requires_test.py
index 0c9d4dd1b..0f66efcc5 100644
--- a/conans/test/integration/build_requires/build_requires_test.py
+++ b/conans/test/integration/build_requires/build_requires_test.py
@@ -616,7 +616,7 @@ class TestBuildTrackHost:
         c.save({"conanfile.py":
                 GenConanfile("pkg").with_build_requirement("protobuf/<host_version>")})
         c.run(f"install . {build_profile}", assert_error=True)
-        assert "'protobuf/<host_version>': didn't find a matching host dependency" in c.out
+        assert "pkg/None require 'protobuf/<host_version>': didn't find a matching host dependency" in c.out
 
     @pytest.mark.parametrize("build_profile", [False, True])
     def test_track_host_error_wrong_context(self, build_profile):
@@ -670,3 +670,56 @@ class TestBuildTrackHost:
         # This used to fail
         c.run(f"create pkg {build_profile}")
         assert "protobuf/1.0 from local cache - Cache" in c.out
+
+    @pytest.mark.parametrize("host_version, assert_error, assert_msg", [
+        ("libgettext>", False, "gettext/0.2:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache"),
+        # Error cases, just checking that we fail gracefully - no tracebacks
+        ("foo>", True, "app/1.0 require 'foo/<host_version:foo>': didn't find a matching host dependency"),
+        ("libgettext", True, "Package gettext has an invalid version number: '<host_version:libgettext'"),
+        (":>", True, "app/1.0 require ':/<host_version::>': didn't find a matching host dependency"),
+        (">", True, "app/1.0 require '/<host_version:>': didn't find a matching host dependency"),
+        (":", True, " Package gettext has an invalid version number: '<host_version::'"),
+        ("", True, " Package gettext has an invalid version number: '<host_version:'")
+    ])
+    def test_host_version_different_ref(self, host_version, assert_error, assert_msg):
+        tc = TestClient()
+        tc.save({"gettext/conanfile.py": GenConanfile("gettext"),
+                 "libgettext/conanfile.py": GenConanfile("libgettext"),
+                 "app/conanfile.py": GenConanfile("app", "1.0").with_requires("libgettext/[>0.1]")
+                .with_build_requires(f"gettext/<host_version:{host_version}")})
+        tc.run("create libgettext libgettext/0.2@")
+        tc.run("create gettext gettext/0.1@ --build-require")
+        tc.run("create gettext gettext/0.2@ --build-require")
+
+        tc.run("create app app/1.0@", assert_error=assert_error)
+        assert assert_msg in tc.out
+
+    @pytest.mark.parametrize("requires_tag,tool_requires_tag,fails", [
+        ("user/channel", "user/channel", False),
+        ("", "user/channel", True),
+        ("auser/achannel", "anotheruser/anotherchannel", True),
+    ])
+    def test_overriden_host_version_user_channel(self, requires_tag, tool_requires_tag, fails):
+        """
+        Make the tool_requires follow the regular require with the expression "<host_version>"
+        """
+        c = TestClient()
+        pkg = textwrap.dedent(f"""
+                from conan import ConanFile
+                class ProtoBuf(ConanFile):
+                    name = "pkg"
+                    version = "0.1"
+                    def requirements(self):
+                        self.requires("protobuf/1.0@{requires_tag}")
+                    def build_requirements(self):
+                        self.tool_requires("protobuf/<host_version>@{tool_requires_tag}")
+                """)
+        c.save({"protobuf/conanfile.py": GenConanfile("protobuf"),
+                "pkg/conanfile.py": pkg})
+        c.run(f"create protobuf 1.0@{requires_tag}")
+
+        c.run("create pkg", assert_error=fails)
+        if fails:
+            assert "pkg/0.1 require 'protobuf/<host_version>': didn't find a matching host dependency" in c.out
+        else:
+            assert "Package '08f50edefe03c3273e386557efc23dc41a9f600b' created" in c.out
diff --git a/conans/test/integration/toolchains/gnu/test_pkgconfigdeps.py b/conans/test/integration/toolchains/gnu/test_pkgconfigdeps.py
index ed49a9651..79f8653c9 100644
--- a/conans/test/integration/toolchains/gnu/test_pkgconfigdeps.py
+++ b/conans/test/integration/toolchains/gnu/test_pkgconfigdeps.py
@@ -770,3 +770,31 @@ def test_error_missing_pc_build_context():
 
     assert "example/1.0: Package '5949422937e5ea462011eb7f38efab5745e4b832' created" in c.out
     assert "example/1.0: Package '03ed74784e8b09eda4f6311a2f461897dea57a7e' created" in c.out
+
+
+def test_pkg_config_deps_and_private_deps():
+    """
+    Testing that no errors are raised when the dependency tree has a private one in the middle
+    of it.
+
+    Issue related: https://github.com/conan-io/conan/issues/15311
+    """
+    client = TestClient()
+    client.save({"conanfile.py": GenConanfile("private", "0.1")})
+    client.run("create .")
+    client.save({"conanfile.py": GenConanfile("pkg", "0.1")
+                .with_require("private/0.1", private=True)}, clean_first=True)
+    client.run("create .")
+    conanfile = textwrap.dedent("""
+    from conan import ConanFile
+    class ConsumerConan(ConanFile):
+        settings = "os", "compiler", "build_type", "arch"
+        generators = "PkgConfigDeps"
+
+        def requirements(self):
+            self.requires("pkg/0.1")
+    """)
+    client.save({"conanfile.py": conanfile}, clean_first=True)
+    # Now, it passes and creates the pc files correctly (the skipped one is not created)
+    client.run("install .")
+    assert "Requires:" not in client.load("pkg.pc")
diff --git a/conans/test/integration/toolchains/microsoft/test_nmakedeps.py b/conans/test/integration/toolchains/microsoft/test_nmakedeps.py
index 3cf032512..08abc81c2 100644
--- a/conans/test/integration/toolchains/microsoft/test_nmakedeps.py
+++ b/conans/test/integration/toolchains/microsoft/test_nmakedeps.py
@@ -28,7 +28,10 @@ def test_nmakedeps():
                 self.cpp_info.components["pkg-3"].defines = ["TEST_DEFINITION3="]
                 self.cpp_info.components["pkg-3"].requires = ["pkg-1", "pkg-2"]
                 self.cpp_info.components["pkg-4"].libs = ["pkg-4"]
-                self.cpp_info.components["pkg-4"].defines = ["TEST_DEFINITION4=foo"]
+                self.cpp_info.components["pkg-4"].defines = ["TEST_DEFINITION4=foo",
+                                                            "TEST_DEFINITION5=__declspec(dllexport)",
+                                                            "TEST_DEFINITION6=foo bar",
+                                                            "TEST_DEFINITION7=7"]
     """)
     client.save({"conanfile.py": conanfile})
     client.run("create . -s arch=x86_64")
@@ -37,8 +40,11 @@ def test_nmakedeps():
     bat_file = client.load("conannmakedeps.bat")
     # Checking that defines are added to CL
     for flag in (
-        r"/DTEST_DEFINITION1", r"/DTEST_DEFINITION2#0",
-        r"/DTEST_DEFINITION3#", r'/DTEST_DEFINITION4#\\"foo\\"',
+        '/D"TEST_DEFINITION1"', '/D"TEST_DEFINITION2#0"',
+        '/D"TEST_DEFINITION3#"', '/D"TEST_DEFINITION4#"foo""',
+        '/D"TEST_DEFINITION5#"__declspec\(dllexport\)""',
+        '/D"TEST_DEFINITION6#"foo bar""',
+        '/D"TEST_DEFINITION7#7"'
     ):
         assert re.search(fr'set "CL=%CL%.*\s{flag}(?:\s|")', bat_file)
     # Checking that libs and system libs are added to _LINK_
diff --git a/conans/test/unittests/tools/google/test_bazel.py b/conans/test/unittests/tools/google/test_bazel.py
index fa9c88db8..64172d413 100644
--- a/conans/test/unittests/tools/google/test_bazel.py
+++ b/conans/test/unittests/tools/google/test_bazel.py
@@ -17,15 +17,17 @@ def cpp_info():
     bindirs = os.path.join(folder, "bin")
     libdirs = os.path.join(folder, "lib")
     save(ConanFileMock(), os.path.join(bindirs, "mylibwin.dll"), "")
+    save(ConanFileMock(), os.path.join(bindirs, "mylibwin2.dll"), "")
     save(ConanFileMock(), os.path.join(bindirs, "myliblin.so"), "")
     save(ConanFileMock(), os.path.join(bindirs, "mylibmac.dylib"), "")
     save(ConanFileMock(), os.path.join(libdirs, "myliblin.a"), "")
     save(ConanFileMock(), os.path.join(libdirs, "mylibmac.a"), "")
     save(ConanFileMock(), os.path.join(libdirs, "mylibwin.lib"), "")
+    save(ConanFileMock(), os.path.join(libdirs, "mylibwin2.if.lib"), "")
     save(ConanFileMock(), os.path.join(libdirs, "libmylib.so"), "")
     save(ConanFileMock(), os.path.join(libdirs, "subfolder", "libmylib.a"), "")  # recursive
     cpp_info_mock = MagicMock(_base_folder=None, libdirs=None, bindirs=None, libs=None)
-    cpp_info_mock._base_folder = folder
+    cpp_info_mock._base_folder = folder.replace("\\", "/")
     cpp_info_mock.libdirs = [libdirs]
     cpp_info_mock.bindirs = [bindirs]
     return cpp_info_mock
@@ -81,9 +83,13 @@ def test_bazeldeps_relativize_path(path, pattern, expected):
     (["mylibwin"], False, [('mylibwin', False, '{base_folder}/lib/mylibwin.lib', None)]),
     # Win + shared
     (["mylibwin"], True, [('mylibwin', True, '{base_folder}/bin/mylibwin.dll', '{base_folder}/lib/mylibwin.lib')]),
+    # Win + shared (interface with another ext)
+    (["mylibwin2"], True,
+     [('mylibwin2', True, '{base_folder}/bin/mylibwin2.dll', '{base_folder}/lib/mylibwin2.if.lib')]),
     # Win + Mac + shared
     (["mylibwin", "mylibmac"], True, [('mylibmac', True, '{base_folder}/bin/mylibmac.dylib', None),
-                                      ('mylibwin', True, '{base_folder}/bin/mylibwin.dll', '{base_folder}/lib/mylibwin.lib')]),
+                                      ('mylibwin', True, '{base_folder}/bin/mylibwin.dll',
+                                       '{base_folder}/lib/mylibwin.lib')]),
     # Linux + Mac + static
     (["myliblin", "mylibmac"], False, [('mylibmac', False, '{base_folder}/lib/mylibmac.a', None),
                                        ('myliblin', False, '{base_folder}/lib/myliblin.a', None)]),
@@ -105,4 +111,8 @@ def test_bazeldeps_get_libs(cpp_info, libs, is_shared, expected):
         if interface_lib_path:
             interface_lib_path = interface_lib_path.format(base_folder=cpp_info._base_folder)
         ret.append((lib, is_shared, lib_path, interface_lib_path))
-    assert _get_libs(ConanFileMock(options_values={"shared": is_shared}), cpp_info).sort() == ret.sort()
+    found_libs = _get_libs(ConanFileMock(options_values={"shared": is_shared}),
+                           cpp_info)
+    found_libs.sort()
+    ret.sort()
+    assert found_libs == ret