Repository: conan-io/conan
Pull request #12156 (2022-09-20 21:54:40)

Adding libcxx support to MesonToolchain
Changelog: Bugfix: implement correct ``libcxx`` support in ``MesonToolchain``
Docs: Omit

Close https://github.com/conan-io/conan/issues/12009



Patch:
diff --git a/.gitignore b/.gitignore
index b4fd19089..c30249731 100644
--- a/.gitignore
+++ b/.gitignore
@@ -90,9 +90,10 @@ conan.conf
 #Generated certificate file
 cacert.pem
 
-#linux backup files
+#linux backup and vim files
 *~
-.*.swp
+.*.sw?
+Session.vim
 
 #Pyinstaller generated binaries
 /pyinstaller
diff --git a/conan/tools/_compilers.py b/conan/tools/_compilers.py
index 5a4cc410c..689072adc 100644
--- a/conan/tools/_compilers.py
+++ b/conan/tools/_compilers.py
@@ -57,6 +57,39 @@ def architecture_flag(settings):
     return ""
 
 
+def libcxx_flags(conanfile):
+    libcxx = conanfile.settings.get_safe("compiler.libcxx")
+    if not libcxx:
+        return None, None
+    compiler = conanfile.settings.get_safe("compiler")
+    lib = stdlib11 = None
+    if compiler == "apple-clang":
+        # In apple-clang 2 only values atm are "libc++" and "libstdc++"
+        lib = "-stdlib={}".format(libcxx)
+    elif compiler == "clang" or compiler == "intel-cc":
+        if libcxx == "libc++":
+            lib = "-stdlib=libc++"
+        elif libcxx == "libstdc++" or libcxx == "libstdc++11":
+            lib = "-stdlib=libstdc++"
+        # FIXME, something to do with the other values? Android c++_shared?
+    elif compiler == "sun-cc":
+        lib = {"libCstd": "-library=Cstd",
+               "libstdcxx": "-library=stdcxx4",
+               "libstlport": "-library=stlport4",
+               "libstdc++": "-library=stdcpp"
+               }.get(libcxx)
+    elif compiler == "qcc":
+        lib = "-Y _{}".format(libcxx)
+
+    if compiler in ['clang', 'apple-clang', 'gcc']:
+        if libcxx == "libstdc++":
+            stdlib11 = "_GLIBCXX_USE_CXX11_ABI=0"
+        elif libcxx == "libstdc++11" and conanfile.conf.get("tools.gnu:define_libcxx11_abi",
+                                                            check_type=bool):
+            stdlib11 = "_GLIBCXX_USE_CXX11_ABI=1"
+    return lib, stdlib11
+
+
 def build_type_link_flags(settings):
     """
     returns link flags specific to the build type (Debug, Release, etc.)
diff --git a/conan/tools/apple/xcodedeps.py b/conan/tools/apple/xcodedeps.py
index 9ea6e03ce..fb79a0259 100644
--- a/conan/tools/apple/xcodedeps.py
+++ b/conan/tools/apple/xcodedeps.py
@@ -77,9 +77,8 @@ class XcodeDeps(object):
     _dep_xconfig = textwrap.dedent("""\
         // Conan XcodeDeps generated file for {{pkg_name}}::{{comp_name}}
         // Includes all configurations for each dependency
-        {% for dep in deps %}
-        // Includes for {{dep[0]}}::{{dep[1]}} dependency
-        #include "conan_{{format_name(dep[0])}}_{{format_name(dep[1])}}.xcconfig"
+        {% for include in deps_includes %}
+        #include "{{include}}"
         {% endfor %}
         #include "{{dep_xconfig_filename}}"
 
@@ -160,11 +159,18 @@ class XcodeDeps(object):
             content_multi = load(multi_path)
         else:
             content_multi = self._dep_xconfig
+
+            def _get_includes(components):
+                # if we require the root component dep::dep include conan_dep.xcconfig
+                # for components (dep::component) include conan_dep_component.xcconfig
+                return [f"conan_{_format_name(component[0])}.xcconfig" if component[0] == component[1]
+                        else f"conan_{_format_name(component[0])}_{_format_name(component[1])}.xcconfig"
+                        for component in components]
+
             content_multi = Template(content_multi).render({"pkg_name": pkg_name,
                                                             "comp_name": comp_name,
                                                             "dep_xconfig_filename": dep_xconfig_filename,
-                                                            "deps": reqs,
-                                                            "format_name": _format_name})
+                                                            "deps_includes": _get_includes(reqs)})
 
         if dep_xconfig_filename not in content_multi:
             content_multi = content_multi.replace('.xcconfig"',
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 3eb5865e5..74b274727 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -5,7 +5,7 @@ from collections import OrderedDict
 
 from jinja2 import Template
 
-from conan.tools._compilers import architecture_flag
+from conan.tools._compilers import architecture_flag, libcxx_flags
 from conan.tools.apple.apple import is_apple_os, to_apple_arch
 from conan.tools.build import build_jobs
 from conan.tools.build.cross_building import cross_building
@@ -159,41 +159,13 @@ class GLibCXXBlock(Block):
         string(APPEND CONAN_CXX_FLAGS " {{ set_libcxx }}")
         {% endif %}
         {% if glibcxx %}
-        add_compile_definitions(_GLIBCXX_USE_CXX11_ABI={{ glibcxx }})
+        add_compile_definitions({{ glibcxx }})
         {% endif %}
         """)
 
     def context(self):
-        libcxx = self._conanfile.settings.get_safe("compiler.libcxx")
-        if not libcxx:
-            return None
-        compiler = self._conanfile.settings.get_safe("compiler")
-        lib = glib = None
-        if compiler == "apple-clang":
-            # In apple-clang 2 only values atm are "libc++" and "libstdc++"
-            lib = "-stdlib={}".format(libcxx)
-        elif compiler == "clang" or compiler == "intel-cc":
-            if libcxx == "libc++":
-                lib = "-stdlib=libc++"
-            elif libcxx == "libstdc++" or libcxx == "libstdc++11":
-                lib = "-stdlib=libstdc++"
-            # FIXME, something to do with the other values? Android c++_shared?
-        elif compiler == "sun-cc":
-            lib = {"libCstd": "Cstd",
-                   "libstdcxx": "stdcxx4",
-                   "libstlport": "stlport4",
-                   "libstdc++": "stdcpp"
-                   }.get(libcxx)
-            if lib:
-                lib = "-library={}".format(lib)
-
-        if compiler in ['clang', 'apple-clang', 'gcc']:
-            if libcxx == "libstdc++":
-                glib = "0"
-            elif libcxx == "libstdc++11" and self._conanfile.conf.get("tools.gnu:define_libcxx11_abi",
-                                                                      check_type=bool):
-                glib = "1"
-        return {"set_libcxx": lib, "glibcxx": glib}
+        libcxx, stdlib11 = libcxx_flags(self._conanfile)
+        return {"set_libcxx": libcxx, "glibcxx": stdlib11}
 
 
 class SkipRPath(Block):
diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py
index c747f7903..7269fa2f7 100644
--- a/conan/tools/gnu/autotoolstoolchain.py
+++ b/conan/tools/gnu/autotoolstoolchain.py
@@ -1,6 +1,6 @@
 from conan.tools._check_build_profile import check_using_build_profile
 from conan.tools._compilers import architecture_flag, build_type_flags, cppstd_flag, \
-    build_type_link_flags
+    build_type_link_flags, libcxx_flags
 from conan.tools.apple.apple import apple_min_version_flag, to_apple_arch, \
     apple_sdk_path
 from conan.tools.build.cross_building import cross_building, get_cross_building_settings
@@ -28,7 +28,6 @@ class AutotoolsToolchain:
         self.extra_defines = []
 
         # Defines
-        self.gcc_cxx11_abi = self._get_cxx11_abi_define()
         self.ndebug = None
         build_type = self._conanfile.settings.get_safe("build_type")
         if build_type in ['Release', 'RelWithDebInfo', 'MinSizeRel']:
@@ -40,7 +39,7 @@ class AutotoolsToolchain:
 
         self.cppstd = cppstd_flag(self._conanfile.settings)
         self.arch_flag = architecture_flag(self._conanfile.settings)
-        self.libcxx = self._get_libcxx_flag()
+        self.libcxx, self.gcc_cxx11_abi = libcxx_flags(self._conanfile)
         self.fpic = self._conanfile.options.get_safe("fPIC")
         self.msvc_runtime_flag = self._get_msvc_runtime_flag()
 
@@ -75,49 +74,12 @@ class AutotoolsToolchain:
 
         check_using_build_profile(self._conanfile)
 
-    def _get_cxx11_abi_define(self):
-        # https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
-        # The default is libstdc++11, only specify the contrary '_GLIBCXX_USE_CXX11_ABI=0'
-        settings = self._conanfile.settings
-        libcxx = settings.get_safe("compiler.libcxx")
-        if not libcxx:
-            return
-
-        compiler = settings.get_safe("compiler.base") or settings.get_safe("compiler")
-        if compiler in ['clang', 'apple-clang', 'gcc']:
-            if libcxx == 'libstdc++':
-                return '_GLIBCXX_USE_CXX11_ABI=0'
-            elif libcxx == "libstdc++11" and self._conanfile.conf.get("tools.gnu:define_libcxx11_abi",
-                                                                      check_type=bool):
-                return '_GLIBCXX_USE_CXX11_ABI=1'
-
     def _get_msvc_runtime_flag(self):
         flag = msvc_runtime_flag(self._conanfile)
         if flag:
             flag = "-{}".format(flag)
         return flag
 
-    def _get_libcxx_flag(self):
-        settings = self._conanfile.settings
-        libcxx = settings.get_safe("compiler.libcxx")
-        if not libcxx:
-            return
-
-        compiler = settings.get_safe("compiler.base") or settings.get_safe("compiler")
-
-        if compiler in ['clang', 'apple-clang']:
-            if libcxx in ['libstdc++', 'libstdc++11']:
-                return '-stdlib=libstdc++'
-            elif libcxx == 'libc++':
-                return '-stdlib=libc++'
-        elif compiler == 'sun-cc':
-            return ({"libCstd": "-library=Cstd",
-                     "libstdcxx": "-library=stdcxx4",
-                     "libstlport": "-library=stlport4",
-                     "libstdc++": "-library=stdcpp"}.get(libcxx))
-        elif compiler == "qcc":
-            return "-Y _%s" % str(libcxx)
-
     @staticmethod
     def _filter_list_empty_fields(v):
         return list(filter(bool, v))
diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py
index 2daa47d2a..d97116943 100644
--- a/conan/tools/meson/toolchain.py
+++ b/conan/tools/meson/toolchain.py
@@ -4,6 +4,7 @@ import textwrap
 from jinja2 import Template
 
 from conan.tools._check_build_profile import check_using_build_profile
+from conan.tools._compilers import libcxx_flags
 from conan.tools.apple.apple import to_apple_arch, is_apple_os, apple_min_version_flag
 from conan.tools.build.cross_building import cross_building, get_cross_building_settings
 from conan.tools.env import VirtualBuildEnv
@@ -131,6 +132,7 @@ class MesonToolchain(object):
 
         self.preprocessor_definitions = {}
         self.pkg_config_path = self._conanfile.generators_folder
+        self.libcxx, self.gcc_cxx11_abi = libcxx_flags(self._conanfile)
 
         check_using_build_profile(self._conanfile)
 
@@ -313,6 +315,11 @@ class MesonToolchain(object):
         self.objc_link_args.extend(apple_flags + extra_flags["ldflags"])
         self.objcpp_link_args.extend(apple_flags + extra_flags["ldflags"])
 
+        if self.libcxx:
+            self.cpp_args.append(self.libcxx)
+        if self.gcc_cxx11_abi:
+            self.cpp_args.append("-D{}".format(self.gcc_cxx11_abi))
+
         return {
             # https://mesonbuild.com/Machine-files.html#properties
             "properties": {k: to_meson_value(v) for k, v in self.properties.items()},
diff --git a/conan/tools/microsoft/visual.py b/conan/tools/microsoft/visual.py
index 307efff1e..961e72460 100644
--- a/conan/tools/microsoft/visual.py
+++ b/conan/tools/microsoft/visual.py
@@ -198,6 +198,11 @@ def vcvars_arch(conanfile):
                 'x86_64': 'x86_amd64',
                 'armv7': 'x86_arm',
                 'armv8': 'x86_arm64'}.get(arch_host)
+    elif arch_build == 'armv8':
+        arch = {'x86': 'arm64_x86',
+                'x86_64': 'arm64_x64',
+                'armv7': 'arm64_arm',
+                'armv8': 'arm64'}.get(arch_host)
 
     if not arch:
         raise ConanException('vcvars unsupported architectures %s-%s' % (arch_build, arch_host))
diff --git a/conan/tools/scm/git.py b/conan/tools/scm/git.py
index bdff76981..4a5c8194e 100644
--- a/conan/tools/scm/git.py
+++ b/conan/tools/scm/git.py
@@ -11,24 +11,24 @@ class Git(object):
         self._conanfile = conanfile
         self.folder = folder
 
-    def _run(self, cmd):
+    def run(self, cmd):
         with chdir(self._conanfile, self.folder):
             return check_output_runner("git {}".format(cmd)).strip()
 
     def get_commit(self):
         try:
-            # commit = self._run("rev-parse HEAD") For the whole repo
+            # commit = self.run("rev-parse HEAD") For the whole repo
             # This rev-list knows to capture the last commit for the folder
             # --full-history is needed to not avoid wrong commits:
             # https://github.com/conan-io/conan/issues/10971
             # https://git-scm.com/docs/git-rev-list#Documentation/git-rev-list.txt-Defaultmode
-            commit = self._run('rev-list HEAD -n 1 --full-history -- "."')
+            commit = self.run('rev-list HEAD -n 1 --full-history -- "."')
             return commit
         except Exception as e:
             raise ConanException("Unable to get git commit in '%s': %s" % (self.folder, str(e)))
 
     def get_remote_url(self, remote="origin"):
-        remotes = self._run("remote -v")
+        remotes = self.run("remote -v")
         for r in remotes.splitlines():
             name, url = r.split(maxsplit=1)
             if name == remote:
@@ -41,13 +41,13 @@ class Git(object):
         if not remote:
             return False
         try:
-            branches = self._run("branch -r --contains {}".format(commit))
+            branches = self.run("branch -r --contains {}".format(commit))
             return "{}/".format(remote) in branches
         except Exception as e:
             raise ConanException("Unable to check remote commit in '%s': %s" % (self.folder, str(e)))
 
     def is_dirty(self):
-        status = self._run("status -s").strip()
+        status = self.run("status -s").strip()
         return bool(status)
 
     def get_url_and_commit(self, remote="origin"):
@@ -73,7 +73,7 @@ class Git(object):
         return self.get_repo_root(), commit
 
     def get_repo_root(self):
-        folder = self._run("rev-parse --show-toplevel")
+        folder = self.run("rev-parse --show-toplevel")
         return folder.replace("\\", "/")
 
     def clone(self, url, target="", args=None):
@@ -82,8 +82,8 @@ class Git(object):
             url = url.replace("\\", "/")  # Windows local directory
         mkdir(self.folder)
         self._conanfile.output.info("Cloning git repo")
-        self._run('clone "{}" {} {}'.format(url, " ".join(args), target))
+        self.run('clone "{}" {} {}'.format(url, " ".join(args), target))
 
     def checkout(self, commit):
         self._conanfile.output.info("Checkout: {}".format(commit))
-        self._run('checkout {}'.format(commit))
+        self.run('checkout {}'.format(commit))
diff --git a/conans/client/cmd/build.py b/conans/client/cmd/build.py
index 6cda8eb6c..1a4207bfa 100644
--- a/conans/client/cmd/build.py
+++ b/conans/client/cmd/build.py
@@ -12,7 +12,7 @@ from conans.util.log import logger
 def cmd_build(app, conanfile_path, base_path, source_folder, build_folder, package_folder,
               install_folder, test=False, should_configure=True, should_build=True,
               should_install=True, should_test=True, layout_source_folder=None,
-              layout_build_folder=None):
+              layout_build_folder=None, conf=None):
     """ Call to build() method saved on the conanfile.py
     param conanfile_path: path to a conanfile.py
     """
@@ -29,6 +29,8 @@ def cmd_build(app, conanfile_path, base_path, source_folder, build_folder, packa
                              "requirements and generators from '%s' file"
                              % (CONANFILE, CONANFILE, CONANFILE_TXT))
 
+    if conf:
+        conan_file.conf.compose_conf(conf)
     if test:
         try:
             conan_file.requires.add_ref(test)
diff --git a/conans/client/manager.py b/conans/client/manager.py
index f27fba832..d0160ce5c 100644
--- a/conans/client/manager.py
+++ b/conans/client/manager.py
@@ -146,4 +146,4 @@ def deps_install(app, ref_or_path, install_folder, base_folder, graph_info, remo
             if hasattr(deploy_conanfile, "deploy") and callable(deploy_conanfile.deploy):
                 run_deploy(deploy_conanfile, install_folder)
 
-    return install_folder
+    return install_folder, conanfile
diff --git a/conans/client/tools/win.py b/conans/client/tools/win.py
index 618cd8a84..fc51b1a20 100644
--- a/conans/client/tools/win.py
+++ b/conans/client/tools/win.py
@@ -442,6 +442,11 @@ def vcvars_command(conanfile=None, arch=None, compiler_version=None, force=False
                        'x86_64': 'x86_amd64',
                        'armv7': 'x86_arm',
                        'armv8': 'x86_arm64'}.get(arch_setting)
+    elif arch_build == 'armv8':
+        vcvars_arch = {'x86': 'arm64_x86',
+                       'x86_64': 'arm64_x64',
+                       'armv7': 'arm64_arm',
+                       'armv8': 'arm64'}.get(arch_setting)
 
     if not vcvars_arch:
         raise ConanException('unsupported architecture %s' % arch_setting)


Test patch:
diff --git a/conans/client/cmd/test.py b/conans/client/cmd/test.py
index 4c2f580dd..996ff39b1 100644
--- a/conans/client/cmd/test.py
+++ b/conans/client/cmd/test.py
@@ -32,7 +32,7 @@ def install_build_and_test(app, conanfile_abs_path, reference, graph_info,
     if build_modes is None:
         build_modes = ["never"]
     try:
-        install_folder = deps_install(app=app,
+        install_folder, conanfile = deps_install(app=app,
                                       create_reference=reference,
                                       ref_or_path=conanfile_abs_path,
                                       install_folder=test_build_folder,
@@ -53,7 +53,7 @@ def install_build_and_test(app, conanfile_abs_path, reference, graph_info,
         cmd_build(app, conanfile_abs_path, test_build_folder,
                   source_folder=base_folder, build_folder=test_build_folder,
                   package_folder=os.path.join(test_build_folder, "package"),
-                  install_folder=install_folder, test=reference)
+                  install_folder=install_folder, test=reference, conf=conanfile.conf)
     finally:
         if delete_after_build:
             # Required for windows where deleting the cwd is not possible.
diff --git a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py
index 85a962e2f..978b3e40d 100644
--- a/conans/test/functional/toolchains/apple/test_xcodedeps_components.py
+++ b/conans/test/functional/toolchains/apple/test_xcodedeps_components.py
@@ -204,6 +204,78 @@ def test_xcodedeps_components():
     assert "chat/1.0: Hello World Release!" in client.out
 
 
+@pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS")
+@pytest.mark.tool_cmake
+def test_cpp_info_require_whole_package():
+    """
+    https://github.com/conan-io/conan/issues/12089
+
+    liba has two components liba::cmp1 liba::cmp2
+
+    libb has not components and requires liba::liba so should generate the same info as
+    if it was requiring liba::cmp1 and liba::cmp2
+
+    libc has components and one component requires liba::liba so should generate the same info as if
+    it was requiring liba::cmp1 and liba::cmp2
+    """
+    client = TestClient(path_with_spaces=False)
+
+    liba = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        class LibConan(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            name = "liba"
+            version = "1.0"
+            def package_info(self):
+                self.cpp_info.components["cmp1"].includedirs.append("cmp1")
+                self.cpp_info.components["cmp2"].includedirs.append("cmp2")
+        """)
+
+    libb = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        class LibConan(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            name = "libb"
+            version = "1.0"
+            requires = "liba/1.0"
+            def package_info(self):
+                self.cpp_info.requires = ["liba::liba"]
+        """)
+
+    libc = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        class LibConan(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            name = "libc"
+            version = "1.0"
+            requires = "liba/1.0"
+            def package_info(self):
+                self.cpp_info.components["cmp1"].includedirs.append("cmp1")
+                self.cpp_info.components["cmp2"].includedirs.append("cmp2")
+                self.cpp_info.components["cmp1"].requires = ["liba::liba"]
+        """)
+
+    client.save({"liba.py": liba, "libb.py": libb, "libc.py": libc})
+
+    client.run("create liba.py")
+    client.run("create libb.py")
+    client.run("create libc.py")
+    client.run("install libb/1.0@ -g XcodeDeps --install-folder=libb")
+
+    libb_xcconfig = client.load(os.path.join("libb", "conan_libb_libb.xcconfig"))
+    assert '#include "conan_liba.xcconfig"' in libb_xcconfig
+    assert '#include "conan_liba_liba.xcconfig"' not in libb_xcconfig
+
+    client.run("install libc/1.0@ -g XcodeDeps --install-folder=libc")
+
+    libc_comp1_xcconfig = client.load(os.path.join("libc", "conan_libc_cmp1.xcconfig"))
+    assert '#include "conan_liba.xcconfig"' in libc_comp1_xcconfig
+    assert '#include "conan_liba_liba.xcconfig"' not in libc_comp1_xcconfig
+
+
 @pytest.mark.skipif(platform.system() != "Darwin", reason="Only for MacOS")
 @pytest.mark.tool_cmake
 def test_xcodedeps_test_require():
diff --git a/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py b/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py
index 8c3d0c018..924f59f0a 100644
--- a/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py
+++ b/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py
@@ -142,5 +142,7 @@ class TestMesonToolchainAndGnuFlags(TestMesonBase):
                "".format(folder=client.current_folder.replace("\\", "/")) in meson_log
         # Flags/Defines from deps and consumer are appearing in meson-log.txt as part
         # of the command-line
-        assert '%s -DVAR="VALUE" -DVAR2="VALUE2" %s' % (flags, deps_flags) in meson_log
+        assert flags in meson_log
+        assert '-DVAR="VALUE" -DVAR2="VALUE2"' in meson_log
+        assert deps_flags in meson_log
         assert '-DDEF3=simple_string -DDEF1=one_string -DDEF2=other_string' in meson_log
diff --git a/conans/test/functional/tools/old/vcvars/vcvars_arch_test.py b/conans/test/functional/tools/old/vcvars/vcvars_arch_test.py
index c8ddb3570..01ddb370e 100644
--- a/conans/test/functional/tools/old/vcvars/vcvars_arch_test.py
+++ b/conans/test/functional/tools/old/vcvars/vcvars_arch_test.py
@@ -53,6 +53,17 @@ class VCVarsArchTest(unittest.TestCase):
         settings.arch = 'x86'
         self.assert_vcvars_command(settings, "amd64_x86")
 
+        settings.arch_build = 'armv8'
+        settings.arch = 'armv8'
+
+        self.assert_vcvars_command(settings, "arm64")
+
+        settings.arch = 'x86'
+        self.assert_vcvars_command(settings, "arm64_x86")
+
+        settings.arch = 'x86_64'
+        self.assert_vcvars_command(settings, "arm64_x64")
+
     def test_arch_override(self):
         settings = Settings.loads(get_default_settings_yml())
         settings.compiler = 'Visual Studio'
diff --git a/conans/test/functional/tools/scm/test_git.py b/conans/test/functional/tools/scm/test_git.py
index 535c46449..cd1e47c06 100644
--- a/conans/test/functional/tools/scm/test_git.py
+++ b/conans/test/functional/tools/scm/test_git.py
@@ -565,3 +565,23 @@ class TestConanFileSubfolder:
         c.run("create conan")
         assert "pkg/0.1: MYCMAKE: mycmakelists" in c.out
         assert "pkg/0.1: MYFILE: myheader" in c.out
+
+    def test_git_run(self):
+        conanfile = textwrap.dedent("""
+            import os
+            from conan import ConanFile
+            from conan.tools.scm import Git
+
+            class Pkg(ConanFile):
+                name = "pkg"
+                version = "0.1"
+                def export(self):
+                    git = Git(self)
+                    self.output.info(git.run("--version"))
+            """)
+
+        c = TestClient()
+        c.save({"conan/conanfile.py": conanfile})
+        c.init_git_repo()
+        c.run("export conan")
+        assert "pkg/0.1: git version" in c.out
diff --git a/conans/test/integration/package_id/compatible_test.py b/conans/test/integration/package_id/compatible_test.py
index fb9393812..305dba427 100644
--- a/conans/test/integration/package_id/compatible_test.py
+++ b/conans/test/integration/package_id/compatible_test.py
@@ -4,7 +4,7 @@ import unittest
 
 
 from conans.model.ref import ConanFileReference
-from conans.test.utils.tools import TestClient, GenConanfile
+from conans.test.utils.tools import TestClient, GenConanfile, TestServer
 from conans.util.files import save
 
 
@@ -87,6 +87,53 @@ class CompatibleIDsTest(unittest.TestCase):
         self.assertIn("pkg/0.1@user/stable:53f56fbd582a1898b3b9d16efd6d3c0ec71e7cfb - Build",
                       client.out)
 
+    def test_compatible_setting_debug_release(self):
+        # From issue https://github.com/conan-io/conan/issues/9398
+        client = TestClient(default_server_user=True)
+        conanfile = textwrap.dedent("""\
+            from conan import ConanFile
+            class Pkg(ConanFile):
+                name = "pkga"
+                version = "0.1"
+                settings = "build_type"
+
+                def package_id(self):
+                    compatible_pkg = self.info.clone()
+                    compatible_pkg.settings.build_type = "Release"
+                    self.compatible_packages.append(compatible_pkg)
+            """)
+        client.save({"conanfile.py": conanfile})
+        # Create the recipe and upload it into the remote
+        client.run("create . -s build_type=Release")
+        client.run("upload pkg* -r=default --confirm --all")
+        client.run("remove * -f")
+
+        # Install locally the uploaded package
+        client.run("install pkga/0.1@")
+
+        # Create a middle package and export it
+        conanfile = textwrap.dedent("""\
+            from conan import ConanFile
+
+            class PkgB(ConanFile):
+                name = "pkgb"
+                version = "0.1"
+                build_requires = "pkga/0.1"
+               """)
+        client.save({"conanfile.py": conanfile}, clean_first=True)
+        client.run("export .")
+
+        # Create a final package and install it changing the "build_type"
+        conanfile = textwrap.dedent("""\
+            from conan import ConanFile
+
+            class PkgC(ConanFile):
+               requires = "pkgb/0.1"
+               build_requires = "pkga/0.1"
+               """)
+        client.save({"conanfile.py": conanfile}, clean_first=True)
+        client.run("install . -s build_type=Debug --build=missing")
+
     def test_compatible_setting_no_user_channel(self):
         client = TestClient()
         conanfile = textwrap.dedent("""
diff --git a/conans/test/integration/toolchains/apple/test_xcodedeps.py b/conans/test/integration/toolchains/apple/test_xcodedeps.py
index 68d4d1991..6ec5f1c86 100644
--- a/conans/test/integration/toolchains/apple/test_xcodedeps.py
+++ b/conans/test/integration/toolchains/apple/test_xcodedeps.py
@@ -153,7 +153,7 @@ def test_xcodedeps_aggregate_components():
         assert f"conan_libb_libb_comp{index}.xcconfig" in lib_entry
 
     component7_entry = client.load("conan_libb_libb_comp7.xcconfig")
-    assert '#include "conan_liba_liba.xcconfig"' in component7_entry
+    assert '#include "conan_liba.xcconfig"' in component7_entry
 
     arch_setting = client.get_default_host_profile().settings['arch']
     arch = "arm64" if arch_setting == "armv8" else arch_setting
diff --git a/conans/test/integration/toolchains/env/test_virtualenv_winbash.py b/conans/test/integration/toolchains/env/test_virtualenv_winbash.py
index e79fdbd0f..dc231f5d8 100644
--- a/conans/test/integration/toolchains/env/test_virtualenv_winbash.py
+++ b/conans/test/integration/toolchains/env/test_virtualenv_winbash.py
@@ -1,9 +1,11 @@
 import os
 import platform
+import textwrap
 
 import pytest
 
 from conans.test.assets.genconanfile import GenConanfile
+from conans.test.conftest import tools_locations
 from conans.test.utils.tools import TestClient
 from conans.tools import save
 
@@ -166,3 +168,54 @@ def test_nowinbash_virtual_cygwin(client):
     assert not os.path.exists(os.path.join(client.current_folder, "conanrunenv.bat"))
     run_contents = client.load("conanrunenv.sh")
     assert 'export RUNTIME_VAR="/cygdrive/c/path/to/exe"' in run_contents
+
+
+@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows")
+@pytest.mark.tool_msys2
+def test_conf_inherited_in_test_package():
+    client = TestClient()
+    bash_path = tools_locations["msys2"]["system"]["path"]["Windows"] + "/bash.exe"
+    conanfile = textwrap.dedent("""
+            from conan import ConanFile
+
+            class Recipe(ConanFile):
+                name="msys2"
+                version="1.0"
+
+                def package_info(self):
+                    self.conf_info.define("tools.microsoft.bash:subsystem", "msys2")
+                    self.conf_info.define("tools.microsoft.bash:path", "{}")
+    """.format(bash_path))
+    client.save({"conanfile.py": conanfile})
+    client.run("create .")
+
+    conanfile = textwrap.dedent("""
+                from conan import ConanFile
+
+                class Recipe(ConanFile):
+                    name="consumer"
+                    version="1.0"
+        """)
+    test_package = textwrap.dedent("""
+                    from conan import ConanFile
+
+                    class Recipe(ConanFile):
+                        name="test"
+                        version="1.0"
+                        win_bash = True
+
+                        def build_requirements(self):
+                            self.tool_requires(self.tested_reference_str)
+                            self.tool_requires("msys2/1.0")
+
+                        def build(self):
+                            self.output.warning(self.conf.get("tools.microsoft.bash:subsystem"))
+                            self.run("aclocal --version")
+
+                        def test(self):
+                            pass
+            """)
+    client.save({"conanfile.py": conanfile, "test_package/conanfile.py": test_package})
+    client.run("create . -s:b os=Windows -s:h os=Windows")
+    assert "are needed to run commands in a Windows subsystem" not in client.out
+    assert "aclocal (GNU automake)" in client.out
diff --git a/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py b/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py
index fb9ba0231..acbe860bb 100644
--- a/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py
+++ b/conans/test/unittests/client/toolchain/autotools/autotools_toolchain_test.py
@@ -152,7 +152,7 @@ def test_ndebug():
     ("clang", 'libstdc++11', '-stdlib=libstdc++'),
     ("clang", 'libc++', '-stdlib=libc++'),
     ("apple-clang", 'libstdc++', '-stdlib=libstdc++'),
-    ("apple-clang", 'libstdc++11', '-stdlib=libstdc++'),
+    # ("apple-clang", 'libstdc++11', '-stdlib=libstdc++'), # this is invalid input
     ("apple-clang", 'libc++', '-stdlib=libc++'),
     ("sun-cc", 'libCstd', '-library=Cstd'),
     ("sun-cc", 'libstdcxx', '-library=stdcxx4'),
diff --git a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
index 123fb38b9..2fac1acfd 100644
--- a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
+++ b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
@@ -402,7 +402,7 @@ def test_libcxx_abi_flag():
     # by default, no flag is output anymore, it is assumed the compiler default
     assert 'GLIBCXX_USE_CXX11_ABI' not in content
     # recipe workaround for older distros
-    toolchain.blocks["libcxx"].values["glibcxx"] = "1"
+    toolchain.blocks["libcxx"].values["glibcxx"] = "_GLIBCXX_USE_CXX11_ABI=1"
     content = toolchain.content
     assert '_GLIBCXX_USE_CXX11_ABI=1' in content