Repository: conan-io/conan
Pull request #18402 (2025-06-02 20:39:01)

do not call generators for editables not being built
Changelog: BugFix: Do not call generators on editable packages not being built with ``--build=editable``
Docs: https://github.com/conan-io/docs/pull/XXXX




Patch:
diff --git a/conan/api/subapi/local.py b/conan/api/subapi/local.py
index d8b2ef386..11c6d5c1f 100644
--- a/conan/api/subapi/local.py
+++ b/conan/api/subapi/local.py
@@ -82,7 +82,9 @@ class LocalAPI:
             with conanfile_exception_formatter(conanfile, "layout"):
                 conanfile.layout()
 
-        folder = conanfile.recipe_folder
+        folder = conanfile.recipe_folder if conanfile.folders.root is None else \
+            os.path.normpath(os.path.join(conanfile.recipe_folder, conanfile.folders.root))
+
         conanfile.folders.set_base_source(folder)
         conanfile.folders.set_base_export_sources(folder)
         conanfile.folders.set_base_recipe_metadata(os.path.join(folder, "metadata"))
diff --git a/conan/cli/command.py b/conan/cli/command.py
index 4a7e80971..b4e0ba610 100644
--- a/conan/cli/command.py
+++ b/conan/cli/command.py
@@ -1,4 +1,5 @@
 import argparse
+import os
 import textwrap
 from contextlib import redirect_stdout
 
@@ -96,6 +97,8 @@ class BaseConanCommand:
                 formatarg, ", ".join(self._help_formatters)))
 
         if out_file:
+            if os.path.dirname(out_file):
+                os.makedirs(os.path.dirname(out_file), exist_ok=True)
             with open(out_file, 'w') as f:
                 with redirect_stdout(f):
                     formatter(info)
diff --git a/conan/cli/commands/audit.py b/conan/cli/commands/audit.py
index ddddad029..9bbe1fff5 100644
--- a/conan/cli/commands/audit.py
+++ b/conan/cli/commands/audit.py
@@ -3,7 +3,7 @@ import os
 
 from conan.api.conan_api import ConanAPI
 from conan.api.input import UserInput
-from conan.api.model import MultiPackagesList
+from conan.api.model import MultiPackagesList, RecipeReference
 from conan.api.output import cli_out_write, ConanOutput
 from conan.api.subapi.audit import CONAN_CENTER_AUDIT_PROVIDER_NAME
 from conan.cli import make_abs_path
@@ -14,6 +14,7 @@ from conan.cli.formatters.audit.vulnerabilities import text_vuln_formatter, json
 from conan.cli.printers import print_profiles
 from conan.cli.printers.graph import print_graph_basic
 from conan.errors import ConanException
+from conan.internal.util.files import load
 
 
 def _add_provider_arg(subparser):
@@ -108,18 +109,15 @@ def audit_list(conan_api: ConanAPI, parser, subparser, *args):
     """
     List the vulnerabilities of the given reference.
     """
-    subparser.add_argument("reference", help="Reference to list vulnerabilities for", nargs="?")
-    subparser.add_argument("-l", "--list", help="pkglist file to list vulnerabilities for")
+    input_group = subparser.add_mutually_exclusive_group(required=True)
+    input_group.add_argument("reference", help="Reference to list vulnerabilities for", nargs="?")
+    input_group.add_argument("-l", "--list", help="pkglist file to list vulnerabilities for")
+    input_group.add_argument("-s", "--sbom", help="sbom file to list vulnerabilities for")
+    input_group.add_argument("-lock", "--lockfile", help="lockfile file to list vulnerabilities for")
     subparser.add_argument("-r", "--remote", help="Remote to use for listing")
     _add_provider_arg(subparser)
     args = parser.parse_args(*args)
 
-    if not args.reference and not args.list:
-        raise ConanException("Please specify a reference or a pkglist file")
-
-    if args.reference and args.list:
-        raise ConanException("Please specify a reference or a pkglist file, not both")
-
     provider = conan_api.audit.get_provider(args.provider or CONAN_CENTER_AUDIT_PROVIDER_NAME)
 
     if args.list:
@@ -130,7 +128,19 @@ def audit_list(conan_api: ConanAPI, parser, subparser, *args):
         refs_to_list = package_list.serialize()
         references = list(refs_to_list.keys())
         if not references:  # the package list might contain only refs, no revs
-            ConanOutput().warning("Nothing to list, package list do not contain recipe revisions")
+            ConanOutput().warning("Nothing to list, package list does not contain recipe revisions")
+    elif args.sbom:
+        sbom_file = make_abs_path(args.sbom)
+        sbom = json.loads(load(sbom_file))
+        if sbom.get("bomFormat") != "CycloneDX":
+            raise ConanException(f"Unsupported SBOM format, only CycloneDX is supported.")
+        purls = [component["purl"] for component in sbom["components"]]
+        references = [purl.split("pkg:conan/")[1].replace("@", "/") for purl in purls]
+    elif args.lockfile:
+        lock_file = make_abs_path(args.lockfile)
+        lockfile = conan_api.lockfile.get_lockfile(lock_file).serialize()
+        references = [str(RecipeReference.loads(ref[0] if isinstance(ref, tuple) else ref))
+                      for ref in lockfile["requires"]]
     else:
         references = [args.reference]
     return conan_api.audit.list(references, provider)
diff --git a/conan/cli/commands/cache.py b/conan/cli/commands/cache.py
index 1f1240caf..52abdb58b 100644
--- a/conan/cli/commands/cache.py
+++ b/conan/cli/commands/cache.py
@@ -187,5 +187,6 @@ def cache_backup_upload(conan_api: ConanAPI, parser, subparser, *args):
     """
     Upload all the source backups present in the cache
     """
+    args = parser.parse_args(*args)
     files = conan_api.cache.get_backup_sources()
     conan_api.upload.upload_backup_sources(files)
diff --git a/conan/cli/commands/editable.py b/conan/cli/commands/editable.py
index 1653845be..23679fc65 100644
--- a/conan/cli/commands/editable.py
+++ b/conan/cli/commands/editable.py
@@ -77,5 +77,6 @@ def editable_list(conan_api, parser, subparser, *args):
     """
     List all the packages in editable mode.
     """
+    parser.parse_args(*args)
     editables = conan_api.local.editable_list()
     return editables
diff --git a/conan/cli/commands/export_pkg.py b/conan/cli/commands/export_pkg.py
index e61c5ce72..aa9d55917 100644
--- a/conan/cli/commands/export_pkg.py
+++ b/conan/cli/commands/export_pkg.py
@@ -59,7 +59,7 @@ def export_pkg(conan_api, parser, *args):
 
     # TODO: Maybe we want to be able to export-pkg it as --build-require
     deps_graph = conan_api.graph.load_graph_consumer(path,
-                                                     ref.name, ref.version, ref.user, ref.channel,
+                                                     ref.name, str(ref.version), ref.user, ref.channel,
                                                      profile_host=profile_host,
                                                      profile_build=profile_build,
                                                      lockfile=lockfile, remotes=remotes, update=None,
diff --git a/conan/cli/commands/profile.py b/conan/cli/commands/profile.py
index 68c32b943..236ef3f4f 100644
--- a/conan/cli/commands/profile.py
+++ b/conan/cli/commands/profile.py
@@ -103,6 +103,7 @@ def profile_list(conan_api, parser, subparser, *args):  # noqa
     """
     List all profiles in the cache.
     """
+    parser.parse_args(*args)
     result = conan_api.profiles.list()
     return result
 
diff --git a/conan/cli/commands/remote.py b/conan/cli/commands/remote.py
index 3cb5ab50b..671ecf75b 100644
--- a/conan/cli/commands/remote.py
+++ b/conan/cli/commands/remote.py
@@ -170,6 +170,7 @@ def remote_list_users(conan_api, parser, subparser, *args):  # noqa
     """
     List the users logged into all the remotes.
     """
+    parser.parse_args(*args)
     remotes = conan_api.remotes.list()
     ret = OrderedDict()
     if not remotes:
diff --git a/conan/cli/commands/upload.py b/conan/cli/commands/upload.py
index 696cda874..0338002c9 100644
--- a/conan/cli/commands/upload.py
+++ b/conan/cli/commands/upload.py
@@ -23,6 +23,7 @@ def summary_upload_list(results):
                     v.pop("info", None)
                     v.pop("timestamp", None)
                     v.pop("files", None)
+                    v.pop("upload-urls", None)
                     upload_value = v.pop("upload", None)
                     if upload_value is not None:
                         msg = "Uploaded" if upload_value else "Skipped, already in server"
diff --git a/conan/cli/commands/version.py b/conan/cli/commands/version.py
index b2509afef..f7b8ee7ee 100644
--- a/conan/cli/commands/version.py
+++ b/conan/cli/commands/version.py
@@ -11,6 +11,7 @@ def version(conan_api, parser, *args):
     """
     Give information about the Conan client version.
     """
+    parser.parse_args(*args)
 
     return {
             'version': str(conan_version),
diff --git a/conan/cli/commands/workspace.py b/conan/cli/commands/workspace.py
index f1ea664e1..9704ad2df 100644
--- a/conan/cli/commands/workspace.py
+++ b/conan/cli/commands/workspace.py
@@ -18,6 +18,7 @@ def workspace_root(conan_api: ConanAPI, parser, subparser, *args):  # noqa
     """
     Return the folder containing the conanws.py/conanws.yml workspace file
     """
+    parser.parse_args(*args)
     ws = conan_api.workspace
     if not ws.folder():
         raise ConanException("No workspace defined, conanws.py file not found")
@@ -101,6 +102,7 @@ def workspace_info(conan_api: ConanAPI, parser, subparser, *args):  # noqa
     """
     Display info for current workspace
     """
+    parser.parse_args(*args)
     return {"info": conan_api.workspace.info()}
 
 
diff --git a/conan/internal/api/detect/detect_api.py b/conan/internal/api/detect/detect_api.py
index 0f96ebcb2..4b19c3615 100644
--- a/conan/internal/api/detect/detect_api.py
+++ b/conan/internal/api/detect/detect_api.py
@@ -488,13 +488,13 @@ def _cc_compiler(compiler_exe="cc"):
         compiler = "clang" if "clang" in out else "gcc"
         # clang and gcc have version after a space, first try to find that to skip extra numbers
         # that might appear in the first line of the output before the version
-        installed_version = re.search(r" ([0-9]+(\.[0-9])+)", out)
+        installed_version = re.search(r" ([0-9]+(\.[0-9]+)+)", out)
         # Try only major but with spaces next
-        installed_version = installed_version or re.search(r" ([0-9]+(\.[0-9])?)", out)
+        installed_version = installed_version or re.search(r" ([0-9]+(\.[0-9]+)?)", out)
         # Fallback to the first number we find optionally followed by other version fields
-        installed_version = installed_version or re.search(r"([0-9]+(\.[0-9])?)", out)
-        if installed_version and installed_version.group():
-            installed_version = installed_version.group()
+        installed_version = installed_version or re.search(r"([0-9]+(\.[0-9]+)?)", out)
+        if installed_version and installed_version.group(1):
+            installed_version = installed_version.group(1)
             ConanOutput(scope="detect_api").info("Found cc=%s-%s" % (compiler, installed_version))
             return compiler, Version(installed_version), compiler_exe
     except (Exception,):  # to disable broad-except
@@ -515,7 +515,7 @@ def detect_gcc_compiler(compiler_exe="gcc"):
         if ret != 0:
             return None, None, None
         compiler = "gcc"
-        installed_version = re.search(r"([0-9]+(\.[0-9])?)", out).group()
+        installed_version = re.search(r"([0-9]+(\.[0-9]+)?)", out).group()
         if installed_version:
             ConanOutput(scope="detect_api").info("Found %s %s" % (compiler, installed_version))
             return compiler, Version(installed_version), compiler_exe
@@ -628,9 +628,13 @@ def default_compiler_version(compiler, version):
     if compiler == "clang" and major >= 8:
         output.info("clang>=8, using the major as version")
         return major
-    elif compiler == "gcc" and major >= 5:
-        output.info("gcc>=5, using the major as version")
-        return major
+    elif compiler == "gcc":
+        if major >= 5:
+            output.info("gcc>=5, using the major as version")
+            return major
+        else:
+            output.info("gcc<5, using the major.minor as version")
+            return Version(f"{major}.{minor}")
     elif compiler == "apple-clang" and major >= 13:
         output.info("apple-clang>=13, using the major as version")
         return major
diff --git a/conan/internal/default_settings.py b/conan/internal/default_settings.py
index e9c974c77..68c19ba0b 100644
--- a/conan/internal/default_settings.py
+++ b/conan/internal/default_settings.py
@@ -91,7 +91,7 @@ os:
 arch: [x86, x86_64, ppc32be, ppc32, ppc64le, ppc64,
        armv4, armv4i, armv5el, armv5hf, armv6, armv7, armv7hf, armv7s, armv7k, armv8, armv8_32, armv8.3, arm64ec,
        sparc, sparcv9,
-       mips, mips64, avr, s390, s390x, asm.js, wasm, sh4le,
+       mips, mips64, avr, s390, s390x, asm.js, wasm, wasm64, sh4le,
        e2k-v2, e2k-v3, e2k-v4, e2k-v5, e2k-v6, e2k-v7,
        riscv64, riscv32,
        xtensalx6, xtensalx106, xtensalx7,
@@ -163,6 +163,13 @@ compiler:
         version: ["1.19", "1.20", "1.21", "1.22", "1.23", "1.24", "1.25"]
         libcxx: [libstdc++, libstdc++11]
         cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23]
+    emcc:
+        # From https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md
+        # There is no ABI compatibility guarantee between versions
+        version: [ANY]
+        libcxx: [null, libstdc++, libstdc++11, libc++]
+        cppstd: [null, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20, 23, gnu23, 26, gnu26]
+        cstd: [null, 99, gnu99, 11, gnu11, 17, gnu17, 23, gnu23]
 
 build_type: [null, Debug, Release, RelWithDebInfo, MinSizeRel]
 """
diff --git a/conan/internal/graph/installer.py b/conan/internal/graph/installer.py
index 7eeb51099..fa09f90ba 100644
--- a/conan/internal/graph/installer.py
+++ b/conan/internal/graph/installer.py
@@ -355,12 +355,12 @@ class BinaryInstaller:
         base_path = os.path.dirname(conanfile_path)
 
         conanfile.folders.set_base_folders(base_path, output_folder)
-        output = conanfile.output
-        output.info("Rewriting files of editable package "
-                    "'{}' at '{}'".format(conanfile.name, conanfile.generators_folder))
-        write_generators(conanfile, self._hook_manager, self._home_folder)
 
         if node.binary == BINARY_EDITABLE_BUILD:
+            output = conanfile.output
+            output.info("Rewriting files of editable package "
+                        "'{}' at '{}'".format(conanfile.name, conanfile.generators_folder))
+            write_generators(conanfile, self._hook_manager, self._home_folder)
             run_build_method(conanfile, self._hook_manager)
 
         rooted_base_path = base_path if conanfile.folders.root is None else \
diff --git a/conan/internal/model/conf.py b/conan/internal/model/conf.py
index 044fda018..8f186e28c 100644
--- a/conan/internal/model/conf.py
+++ b/conan/internal/model/conf.py
@@ -86,7 +86,7 @@ BUILT_IN_CONFS = {
     "tools.cmake.cmake_layout:test_folder": "(Experimental) Allow configuring the base folder of the build for test_package",
     "tools.cmake:cmake_program": "Path to CMake executable",
     "tools.cmake.cmakedeps:new": "Use the new CMakeDeps generator",
-    "tools.cmake:install_strip": "Add --strip to cmake.install()",
+    "tools.cmake:install_strip": "(Deprecated) Add --strip to cmake.install(). Use tools.build:install_strip instead",
     "tools.deployer:symlinks": "Set to False to disable deployers copying symlinks",
     "tools.files.download:retry": "Number of retries in case of failure when downloading",
     "tools.files.download:retry_wait": "Seconds to wait between download attempts",
@@ -135,6 +135,8 @@ BUILT_IN_CONFS = {
     "tools.build:sharedlinkflags": "List of extra flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain",
     "tools.build:exelinkflags": "List of extra flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain",
     "tools.build:linker_scripts": "List of linker script files to pass to the linker used by different toolchains like CMakeToolchain, AutotoolsToolchain, and MesonToolchain",
+    # Toolchain installation
+    "tools.build:install_strip": "(boolean) Strip the binaries when installing them with CMake and Meson",
     # Package ID composition
     "tools.info.package_id:confs": "List of existing configuration to be part of the package ID",
 }
diff --git a/conan/internal/model/cpp_info.py b/conan/internal/model/cpp_info.py
index c3f522715..ebb4c0f85 100644
--- a/conan/internal/model/cpp_info.py
+++ b/conan/internal/model/cpp_info.py
@@ -13,7 +13,7 @@ from conan.internal.util.files import load, save
 _DIRS_VAR_NAMES = ["_includedirs", "_srcdirs", "_libdirs", "_resdirs", "_bindirs", "_builddirs",
                    "_frameworkdirs", "_objects"]
 _FIELD_VAR_NAMES = ["_system_libs", "_package_framework", "_frameworks", "_libs", "_defines",
-                    "_cflags", "_cxxflags", "_sharedlinkflags", "_exelinkflags"]
+                    "_cflags", "_cxxflags", "_sharedlinkflags", "_exelinkflags", "_sources"]
 _ALL_NAMES = _DIRS_VAR_NAMES + _FIELD_VAR_NAMES
 
 
@@ -81,6 +81,7 @@ class _Component:
         self._sharedlinkflags = None  # linker flags
         self._exelinkflags = None  # linker flags
         self._objects = None  # linker flags
+        self._sources = None  # source files
         self._exe = None  # application executable, only 1 allowed, following CPS
         self._languages = None
 
@@ -120,6 +121,7 @@ class _Component:
             "sharedlinkflags": self._sharedlinkflags,
             "exelinkflags": self._exelinkflags,
             "objects": self._objects,
+            "sources": self._sources,
             "sysroot": self._sysroot,
             "requires": self._requires,
             "properties": self._properties,
@@ -380,6 +382,16 @@ class _Component:
     def objects(self, value):
         self._objects = value
 
+    @property
+    def sources(self):
+        if self._sources is None:
+            self._sources = []
+        return self._sources
+
+    @sources.setter
+    def sources(self, value):
+        self._sources = value
+
     @property
     def sysroot(self):
         if self._sysroot is None:
diff --git a/conan/internal/rest/remote_manager.py b/conan/internal/rest/remote_manager.py
index d87f3d849..98ca71c68 100644
--- a/conan/internal/rest/remote_manager.py
+++ b/conan/internal/rest/remote_manager.py
@@ -38,11 +38,13 @@ class RemoteManager:
     def upload_recipe(self, ref, files_to_upload, remote):
         assert isinstance(ref, RecipeReference)
         assert ref.revision, "upload_recipe requires RREV"
+        remote.invalidate_cache()
         self._call_remote(remote, "upload_recipe", ref, files_to_upload)
 
     def upload_package(self, pref, files_to_upload, remote):
         assert pref.ref.revision, "upload_package requires RREV"
         assert pref.revision, "upload_package requires PREV"
+        remote.invalidate_cache()
         self._call_remote(remote, "upload_package", pref, files_to_upload)
 
     def get_recipe(self, ref, remote, metadata=None):
@@ -204,12 +206,15 @@ class RemoteManager:
         return packages
 
     def remove_recipe(self, ref, remote):
+        remote.invalidate_cache()
         return self._call_remote(remote, "remove_recipe", ref)
 
     def remove_packages(self, prefs, remote):
+        remote.invalidate_cache()
         return self._call_remote(remote, "remove_packages", prefs)
 
     def remove_all_packages(self, ref, remote):
+        remote.invalidate_cache()
         return self._call_remote(remote, "remove_all_packages", ref)
 
     def authenticate(self, remote, name, password):
@@ -243,10 +248,19 @@ class RemoteManager:
 
         cached_method = remote._caching.setdefault("get_latest_package_reference", {})
         try:
-            return cached_method[pref]
+            result = cached_method[pref]
         except KeyError:
-            result = self._call_remote(remote, "get_latest_package_reference", pref, headers=headers)
-            cached_method[pref] = result
+            try:
+                result = self._call_remote(remote, "get_latest_package_reference", pref,
+                                           headers=headers)
+                cached_method[pref] = result
+                return result
+            except Exception as e:
+                cached_method[pref] = e
+                raise e
+        else:
+            if isinstance(result, Exception):
+                raise result
             return result
 
     def get_recipe_revision_reference(self, ref, remote) -> bool:
@@ -263,9 +277,9 @@ class RemoteManager:
         if remote.disabled and enforce_disabled:
             raise ConanException("Remote '%s' is disabled" % remote.name)
         local_folder_remote = self._local_folder_remote(remote)
-        if local_folder_remote is not None:
-            return local_folder_remote.call_method(method, *args, **kwargs)
         try:
+            if local_folder_remote is not None:
+                return local_folder_remote.call_method(method, *args, **kwargs)
             return self._auth_manager.call_rest_api_method(remote, method, *args, **kwargs)
         except ConnectionError as exc:
             raise ConanConnectionError(("%s\n\nUnable to connect to remote %s=%s\n"
diff --git a/conan/internal/rest/rest_client_local_recipe_index.py b/conan/internal/rest/rest_client_local_recipe_index.py
index 33082ca13..bde8e2ac4 100644
--- a/conan/internal/rest/rest_client_local_recipe_index.py
+++ b/conan/internal/rest/rest_client_local_recipe_index.py
@@ -82,7 +82,9 @@ class RestApiClientLocalRecipesIndex:
         except ConanReferenceDoesNotExistInDB as e:
             # This can happen when there a local-recipes-index is being queried for sources it
             # doesn't contain
-            raise NotFoundException(str(e))
+            # If that is the case, check if they are in the repo, try to export
+            exported_ref = self._export_recipe(ref)  # This will raise NotFound if non existing
+            export_sources = self._app.cache.recipe_layout(exported_ref).export_sources()
         return self._copy_files(export_sources, dest_folder)
 
     def get_package(self, pref, dest_folder, metadata, only_metadata):
@@ -197,6 +199,9 @@ class _LocalRecipesIndexLayout:
     def get_recipes_references(self, pattern):
         name_pattern = pattern.split("/", 1)[0]
         recipes_dir = os.path.join(self._base_folder, "recipes")
+        if not os.path.isdir(recipes_dir):
+            raise ConnectionError("Cannot connect to 'local-recipes-index' repository, missing "
+                                  f"'recipes' folder: {recipes_dir}")
         recipes = os.listdir(recipes_dir)
         recipes.sort()
         ret = []
@@ -210,6 +215,8 @@ class _LocalRecipesIndexLayout:
             pattern = f"{pattern_ref.name}/{pattern_ref.version}"
         except:
             # pattern = pattern
+            pattern = f"{name_pattern}/*"
+            original_pattern = pattern
             pass
 
         loader = ConanFileLoader(None)
diff --git a/conan/tools/build/cppstd.py b/conan/tools/build/cppstd.py
index 43c3e9da4..b7c182276 100644
--- a/conan/tools/build/cppstd.py
+++ b/conan/tools/build/cppstd.py
@@ -104,6 +104,7 @@ def supported_cppstd(conanfile, compiler=None, compiler_version=None):
             "clang": _clang_supported_cppstd,
             "mcst-lcc": _mcst_lcc_supported_cppstd,
             "qcc": _qcc_supported_cppstd,
+            "emcc": _emcc_supported_cppstd,
             }.get(compiler)
     if func:
         return func(Version(compiler_version))
@@ -267,3 +268,16 @@ def _qcc_supported_cppstd(version):
         return ["98", "gnu98"]
     else:
         return ["98", "gnu98", "11", "gnu11", "14", "gnu14", "17", "gnu17"]
+
+def _emcc_supported_cppstd(version):
+    """
+    emcc is based on clang but follow different versioning scheme.
+    """
+    if version <= "3.0.1":
+        return _clang_supported_cppstd(Version("14"))
+    if version <= "3.1.50":
+        return _clang_supported_cppstd(Version("18"))
+    if version <= "4.0.1":
+        return _clang_supported_cppstd(Version("20"))
+    # Since emcc 4.0.2 clang version is 21
+    return _clang_supported_cppstd(Version("21"))
diff --git a/conan/tools/build/cstd.py b/conan/tools/build/cstd.py
index 2a762d775..59e3f1145 100644
--- a/conan/tools/build/cstd.py
+++ b/conan/tools/build/cstd.py
@@ -110,6 +110,7 @@ def supported_cstd(conanfile, compiler=None, compiler_version=None):
             "gcc": _gcc_supported_cstd,
             "msvc": _msvc_supported_cstd,
             "clang": _clang_supported_cstd,
+            "emcc": _emcc_supported_cstd,
             }.get(compiler)
     if func:
         return func(Version(compiler_version))
@@ -190,3 +191,18 @@ def _clang_supported_cstd(version):
     if version < "18":
         return ["99", "gnu99", "11", "gnu11", "17", "gnu17"]
     return ["99", "gnu99", "11", "gnu11", "17", "gnu17", "23", "gnu23"]
+
+def _emcc_supported_cstd(version):
+    """
+    emcc is based on clang but follow different versioning scheme.
+    """
+    if version <= "3.0.1":
+        return _clang_supported_cstd(Version("14"))
+    if version <= "3.1.50":
+        return _clang_supported_cstd(Version("18"))
+    if version <= "4.0.1":
+        return _clang_supported_cstd(Version("20"))
+    # Since emcc 4.0.2 clang version is 21
+    return _clang_supported_cstd(Version("21"))
+
+
diff --git a/conan/tools/build/flags.py b/conan/tools/build/flags.py
index 98d068252..138ea97a1 100644
--- a/conan/tools/build/flags.py
+++ b/conan/tools/build/flags.py
@@ -66,6 +66,13 @@ def architecture_flag(conanfile):
                 "e2k-v5": "-march=elbrus-v5",
                 "e2k-v6": "-march=elbrus-v6",
                 "e2k-v7": "-march=elbrus-v7"}.get(arch, "")
+    elif compiler == "emcc":
+        # Emscripten default output is WASM since 1.37.x (long time ago)
+        if arch == "wasm64":
+            return "-sMEMORY64=1"
+        # Deactivate WASM output forcing asm.js output instead
+        elif arch == "asm.js":
+            return "-sWASM=0"
     return ""
 
 
@@ -78,7 +85,7 @@ def libcxx_flags(conanfile):
     if compiler == "apple-clang":
         # In apple-clang 2 only values atm are "libc++" and "libstdc++"
         lib = f'-stdlib={libcxx}'
-    elif compiler == "clang" or compiler == "intel-cc":
+    elif compiler in ("clang", "intel-cc", "emcc"):
         if libcxx == "libc++":
             lib = "-stdlib=libc++"
         elif libcxx == "libstdc++" or libcxx == "libstdc++11":
@@ -93,7 +100,7 @@ def libcxx_flags(conanfile):
     elif compiler == "qcc":
         lib = f'-Y _{libcxx}'
 
-    if compiler in ['clang', 'apple-clang', 'gcc']:
+    if compiler in ['clang', 'apple-clang', 'gcc', 'emcc']:
         if libcxx == "libstdc++":
             stdlib11 = "_GLIBCXX_USE_CXX11_ABI=0"
         elif libcxx == "libstdc++11" and conanfile.conf.get("tools.gnu:define_libcxx11_abi",
diff --git a/conan/tools/cmake/cmake.py b/conan/tools/cmake/cmake.py
index 4a6a5eca7..5680f89a2 100644
--- a/conan/tools/cmake/cmake.py
+++ b/conan/tools/cmake/cmake.py
@@ -209,8 +209,13 @@ class CMake:
             arg_list.extend(["--component", component])
         arg_list.extend(self._compilation_verbosity_arg)
 
-        do_strip = self._conanfile.conf.get("tools.cmake:install_strip", check_type=bool)
-        if do_strip:
+        deprecated_install_strip = self._conanfile.conf.get("tools.cmake:install_strip", check_type=bool)
+        if deprecated_install_strip:
+            self._conanfile.output.warning("The 'tools.cmake:install_strip' configuration is deprecated, "
+                                           "use 'tools.build:install_strip' instead.", warn_tag="deprecated")
+
+        do_strip = self._conanfile.conf.get("tools.build:install_strip", check_type=bool)
+        if do_strip or deprecated_install_strip:
             arg_list.append("--strip")
 
         if cli_args:
diff --git a/conan/tools/cmake/cmakedeps2/target_configuration.py b/conan/tools/cmake/cmakedeps2/target_configuration.py
index 3572174e9..0b87a00ef 100644
--- a/conan/tools/cmake/cmakedeps2/target_configuration.py
+++ b/conan/tools/cmake/cmakedeps2/target_configuration.py
@@ -180,7 +180,7 @@ class TargetConfigurationTemplate2:
         # FIXME: Filter by lib traits!!!!!
         if not self._require.headers:  # If not depending on headers, paths and
             includedirs = defines = None
-        system_libs = " ".join(info.system_libs)
+        sources = [self._path(source, pkg_folder, pkg_folder_var) for source in info.sources]
         target = {"type": "INTERFACE",
                   "includedirs": includedirs,
                   "defines": defines,
@@ -189,7 +189,8 @@ class TargetConfigurationTemplate2:
                   "cflags": " ".join(info.cflags),
                   "sharedlinkflags": " ".join(info.sharedlinkflags),
                   "exelinkflags": " ".join(info.exelinkflags),
-                  "system_libs": system_libs
+                  "system_libs": " ".join(info.system_libs),
+                  "sources": " ".join(sources)
         }
         # System frameworks (only Apple OS)
         if info.frameworks:
@@ -400,7 +401,8 @@ class TargetConfigurationTemplate2:
         {% endif %}
 
         {% if lib_info.get("system_libs") %}
-        target_link_libraries({{lib}} INTERFACE {{lib_info["system_libs"]}})
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_LINK_LIBRARIES
+                     {{config_wrapper(config, lib_info["system_libs"])}})
         {% endif %}
         {% if lib_info.get("frameworks") %}
         set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_LINK_LIBRARIES
@@ -417,6 +419,11 @@ class TargetConfigurationTemplate2:
                          $<$<COMPILE_LANGUAGE:C>:-F{{lib_info["package_framework"]["frameworkdir"]}}>)
         endif()
         {% endif %}
+
+        {% if lib_info.get("sources") %}
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_SOURCES
+                     {{config_wrapper(config, lib_info["sources"] )}})
+        {% endif %}
         {% endfor %}
 
         ################# Global variables for try compile and legacy ##############
diff --git a/conan/tools/cmake/cmakedeps2/targets.py b/conan/tools/cmake/cmakedeps2/targets.py
index e02d2926d..fba8092de 100644
--- a/conan/tools/cmake/cmakedeps2/targets.py
+++ b/conan/tools/cmake/cmakedeps2/targets.py
@@ -32,6 +32,7 @@ class TargetsTemplate2:
     @property
     def _template(self):
         return textwrap.dedent("""\
+            include_guard()
             message(STATUS "Conan: Configuring Targets for {{ ref }}")
 
             # Load information for each installed configuration.
diff --git a/conan/tools/cmake/presets.py b/conan/tools/cmake/presets.py
index 0d35f80f8..6ebe55a02 100644
--- a/conan/tools/cmake/presets.py
+++ b/conan/tools/cmake/presets.py
@@ -5,7 +5,7 @@ import textwrap
 
 from conan.api.output import ConanOutput, Color
 from conan.tools.cmake.layout import get_build_folder_custom_vars
-from conan.tools.cmake.toolchain.blocks import GenericSystemBlock, CompilersBlock
+from conan.tools.cmake.toolchain.blocks import GenericSystemBlock
 from conan.tools.cmake.utils import is_multi_configuration
 from conan.tools.build import build_jobs
 from conan.tools.microsoft import is_msvc
@@ -307,6 +307,9 @@ class _IncludingPresets:
         if not absolute_paths:
             try:  # Make it relative to the CMakeUserPresets.json if possible
                 preset_path = os.path.relpath(preset_path, output_dir)
+                # If we don't normalize, path will be removed in Linux shared folders
+                # https://github.com/conan-io/conan/issues/18434
+                preset_path = preset_path.replace("\\", "/")
             except ValueError:
                 pass
         data = _IncludingPresets._append_user_preset_path(data, preset_path, output_dir)
diff --git a/conan/tools/gnu/get_gnu_triplet.py b/conan/tools/gnu/get_gnu_triplet.py
index dc7e3b68d..9b5eb7a86 100644
--- a/conan/tools/gnu/get_gnu_triplet.py
+++ b/conan/tools/gnu/get_gnu_triplet.py
@@ -10,6 +10,7 @@ def _get_gnu_arch(os_, arch):
                "armv8.3": "aarch64",
                "asm.js": "asmjs",
                "wasm": "wasm32",
+               "wasm64": "wasm64",
                }.get(arch, None)
 
     if not machine:
diff --git a/conan/tools/google/bazeldeps.py b/conan/tools/google/bazeldeps.py
index f2202b417..ad77246f3 100644
--- a/conan/tools/google/bazeldeps.py
+++ b/conan/tools/google/bazeldeps.py
@@ -1,121 +1,28 @@
 import os
 import re
 import textwrap
-from collections import namedtuple, defaultdict
 
 from jinja2 import Template, StrictUndefined
 
-from conan.errors import ConanException
 from conan.internal import check_duplicated_generator
 from conan.internal.model.dependencies import get_transitive_requires
 from conan.internal.model.pkg_type import PackageType
 from conan.internal.util.files import save
 
-_BazelTargetInfo = namedtuple("DepInfo", ['repository_name', 'name', 'ref_name', 'requires', 'cpp_info'])
 
-
-def _get_name_with_namespace(namespace, name):
-    """
-    Build a name with a namespace, e.g., openssl-crypto
-    """
-    return f"{namespace}-{name}"
-
-
-def _get_package_reference_name(dep):
-    """
-    Get the reference name for the given package
-    """
-    return dep.ref.name
-
-
-def _get_repository_name(dep, is_build_require=False):
-    pkg_name = dep.cpp_info.get_property("bazel_repository_name") or _get_package_reference_name(dep)
-    return f"build-{pkg_name}" if is_build_require else pkg_name
-
-
-def _get_target_name(dep):
-    pkg_name = dep.cpp_info.get_property("bazel_target_name") or _get_package_reference_name(dep)
-    return pkg_name
-
-
-def _get_component_name(dep, comp_ref_name):
-    pkg_name = _get_target_name(dep)
-    if comp_ref_name not in dep.cpp_info.components:
-        # foo::foo might be referencing the root cppinfo
-        if _get_package_reference_name(dep) == comp_ref_name:
-            return pkg_name
-        raise ConanException("Component '{name}::{cname}' not found in '{name}' "
-                             "package requirement".format(name=_get_package_reference_name(dep),
-                                                          cname=comp_ref_name))
-    comp_name = dep.cpp_info.components[comp_ref_name].get_property("bazel_target_name")
-    # If user did not set bazel_target_name, let's create a component name
-    # with a namespace, e.g., dep-comp1
-    return comp_name or _get_name_with_namespace(pkg_name, comp_ref_name)
-
-
-# FIXME: This function should be a common one to be used by PkgConfigDeps, CMakeDeps?, etc.
-def _get_requirements(conanfile, build_context_activated):
-    """
-    Simply save the activated requirements (host + build + test), and the deactivated ones
-    """
-    # All the requirements
-    host_req = conanfile.dependencies.host
-    build_req = conanfile.dependencies.direct_build  # tool_requires
-    test_req = conanfile.dependencies.test
-
-    for require, dep in list(host_req.items()) + list(build_req.items()) + list(test_req.items()):
-        # Require is not used at the moment, but its information could be used,
-        # and will be used in Conan 2.0
-        # Filter the build_requires not activated with self.build_context_activated
-        if require.build and dep.ref.name not in build_context_activated:
-            continue
-        yield require, dep
-
-
-def _get_headers(cpp_info, package_folder_path):
-    return ['"{}/**"'.format(_relativize_path(path, package_folder_path))
-            for path in cpp_info.includedirs]
-
-
-def _get_includes(cpp_info, package_folder_path):
-    return ['"{}"'.format(_relativize_path(path, package_folder_path))
-            for path in cpp_info.includedirs]
-
-
-def _get_defines(cpp_info):
-    return ['"{}"'.format(define.replace('"', '\\' * 3 + '"'))
-            for define in cpp_info.defines]
-
-
-def _get_linkopts(cpp_info, os_build):
-    link_opt = '/DEFAULTLIB:{}' if os_build == "Windows" else '-l{}'
-    system_libs = [link_opt.format(lib) for lib in cpp_info.system_libs]
-    shared_flags = cpp_info.sharedlinkflags + cpp_info.exelinkflags
-    return [f'"{flag}"' for flag in (system_libs + shared_flags)]
-
-
-def _get_copts(cpp_info):
-    # FIXME: long discussions between copts (-Iflag) vs includes in Bazel. Not sure yet
-    # includedirsflags = ['"-I{}"'.format(_relativize_path(d, package_folder_path))
-    #                     for d in cpp_info.includedirs]
-    cxxflags = [var.replace('"', '\\"') for var in cpp_info.cxxflags]
-    cflags = [var.replace('"', '\\"') for var in cpp_info.cflags]
-    return [f'"{flag}"' for flag in (cxxflags + cflags)]
-
-
-def _relativize_path(path, pattern):
+def _relativize_path(path, start_folder):
     """
-    Returns a relative path with regard to pattern given.
+    Returns a relative path with regard to the given folder.
 
-    :param path: absolute or relative path
-    :param pattern: either a piece of path or a pattern to match the leading part of the path
+    :param path: absolute or relative path.
+    :param start_folder: folder to start relative to.
     :return: Unix-like path relative if matches to the given pattern.
              Otherwise, it returns the original path.
     """
-    if not path or not pattern:
+    if not path or not start_folder:
         return path
     path_ = path.replace("\\", "/").replace("/./", "/")
-    pattern_ = pattern.replace("\\", "/").replace("/./", "/")
+    pattern_ = start_folder.replace("\\", "/").replace("/./", "/")
     match = re.match(pattern_, path_)
     if match:
         matching = match[0]
@@ -125,157 +32,26 @@ def _relativize_path(path, pattern):
     return path
 
 
-class _BazelDependenciesBZLGenerator:
-    """
-    Bazel 6.0 needs to know all the dependencies for its current project. So, the only way
-    to do that is to tell the WORKSPACE file how to load all the Conan ones. This is the goal
-    of the function created by this class, the ``load_conan_dependencies`` one.
-
-    More information:
-        * https://bazel.build/reference/be/workspace#new_local_repository
-
-    Bazel >= 7.1 needs to know all the dependencies as well, but provided via the MODULE.bazel file.
-    Therefor we provide a static repository rule to load the dependencies. This rule is used by a
-    module extension, passing the package path and the BUILD file path to the repository rule.
-    """
-
-    repository_filename = "dependencies.bzl"
-    modules_filename = "conan_deps_module_extension.bzl"
-    repository_rules_filename = "conan_deps_repo_rules.bzl"
-    repository_template = textwrap.dedent("""\
-        # This Bazel module should be loaded by your WORKSPACE file.
-        # Add these lines to your WORKSPACE one (assuming that you're using the "bazel_layout"):
-        # load("@//conan:dependencies.bzl", "load_conan_dependencies")
-        # load_conan_dependencies()
-
-        def load_conan_dependencies():
-        {% for repository_name, pkg_folder, pkg_build_file_path in dependencies %}
-            native.new_local_repository(
-                name="{{repository_name}}",
-                path="{{pkg_folder}}",
-                build_file="{{pkg_build_file_path}}",
-            )
-        {% endfor %}
-        """)
-    module_template = textwrap.dedent("""\
-        # This module provides a repo for each requires-dependency in your conanfile.
-        # It's generated by the BazelDeps, and should be used in your Module.bazel file.
-        load(":conan_deps_repo_rules.bzl", "conan_dependency_repo")
-
-        def _load_dependenies_impl(mctx):
-        {% for repository_name, pkg_folder, pkg_build_file_path in dependencies %}
-            conan_dependency_repo(
-                name = "{{repository_name}}",
-                package_path = "{{pkg_folder}}",
-                build_file_path = "{{pkg_build_file_path}}",
-            )
-        {% endfor %}
-
-            return mctx.extension_metadata(
-                # It will only warn you if any direct
-                # dependency is not imported by the 'use_repo' or even it is imported
-                # but not created. Notice that root_module_direct_dev_deps can not be None as we
-                # are giving 'all' value to root_module_direct_deps.
-                # Fix the 'use_repo' calls by running 'bazel mod tidy'
-                root_module_direct_deps = 'all',
-                root_module_direct_dev_deps = [],
-
-                # Prevent writing function content to lockfiles:
-                # - https://bazel.build/rules/lib/builtins/module_ctx#extension_metadata
-                # Important for remote build. Actually it's not reproducible, as local paths will
-                # be different on different machines. But we assume that conan works correctly here.
-                # IMPORTANT: Not compatible with bazel < 7.1
-                reproducible = True,
-            )
-
-        conan_extension = module_extension(
-            implementation = _load_dependenies_impl,
-            os_dependent = True,
-            arch_dependent = True,
-        )
-        """)
-    repository_rules_content = textwrap.dedent("""\
-        # This bazel repository rule is used to load Conan dependencies into the Bazel workspace.
-        # It's used by a generated module file that provides information about the conan packages.
-        # Each conan package is loaded into a bazel repository rule, with having the name of the
-        # package. The whole method is based on symlinks to not copy the whole package into the
-        # Bazel workspace, which is expensive.
-        def _conan_dependency_repo(rctx):
-            package_path = rctx.workspace_root.get_child(rctx.attr.package_path)
-
-            child_packages = package_path.readdir()
-            for child in child_packages:
-                rctx.symlink(child, child.basename)
-
-            rctx.symlink(rctx.attr.build_file_path, "BUILD.bazel")
-
-        conan_dependency_repo = repository_rule(
-            implementation = _conan_dependency_repo,
-            attrs = {
-                "package_path": attr.string(
-                    mandatory = True,
-                    doc = "The path to the Conan package in conan cache.",
-                ),
-                "build_file_path": attr.string(
-                    mandatory = True,
-                    doc = "The path to the BUILD file.",
-                ),
-            },
-        )
-        """)
-
-    def __init__(self, conanfile, dependencies):
-        self._conanfile = conanfile
-        self._dependencies = dependencies
-
-    def _generate_6x_compatible(self):
-        repository_template = Template(self.repository_template, trim_blocks=True,
-                                       lstrip_blocks=True,
-                                       undefined=StrictUndefined)
-        content = repository_template.render(dependencies=self._dependencies)
-        # dependencies.bzl file (Bazel 6.x compatible)
-        save(self.repository_filename, content)
-
-    def generate(self):
-        # Keeping available Bazel 6.x, but it'll likely be dropped soon
-        self._generate_6x_compatible()
-        # Bazel 7.x files
-        module_template = Template(self.module_template, trim_blocks=True, lstrip_blocks=True,
-                                   undefined=StrictUndefined)
-        content = module_template.render(dependencies=self._dependencies)
-        save(self.modules_filename, content)
-        save(self.repository_rules_filename, self.repository_rules_content)
-        save("BUILD.bazel", "# This is an empty BUILD file.")
-
-
-class _LibInfo:
-    def __init__(self, lib_name, cpp_info_, package_folder_path):
-        self.name = lib_name
-        self.is_shared = cpp_info_.type == PackageType.SHARED
-        self.lib_path = _relativize_path(cpp_info_.location, package_folder_path)
-        self.import_lib_path = _relativize_path(cpp_info_.link_location, package_folder_path)
-
-
-class _BazelBUILDGenerator:
+class _BazelDepBuildGenerator:
     """
     This class creates the BUILD.bazel for each dependency where it's declared all the
     necessary information to load the libraries
     """
     # If both files exist, BUILD.bazel takes precedence over BUILD
     # https://bazel.build/concepts/build-files
-    filename = "BUILD.bazel"
-    template = textwrap.dedent("""\
+    dep_build_filename = "BUILD.bazel"
+    dep_build_template = textwrap.dedent("""\
     {% macro cc_import_macro(libs) %}
     {% for lib_info in libs %}
     cc_import(
-        name = "{{ lib_info.name }}_precompiled",
-        {% if lib_info.is_shared %}
-        shared_library = "{{ lib_info.lib_path }}",
+        name = "{{ lib_info['name'] }}_precompiled",
+        {% if lib_info['is_shared'] %}
+        shared_library = "{{ lib_info['lib_path'] }}",
         {% else %}
-        static_library = "{{ lib_info.lib_path }}",
+        static_library = "{{ lib_info['lib_path'] }}",
         {% endif %}
-        {% if lib_info.import_lib_path %}
-        interface_library = "{{ lib_info.import_lib_path }}",
+        {% if lib_info['import_lib_path'] %}
+        interface_library = "{{ lib_info['import_lib_path'] }}",
         {% endif %}
     )
     {% endfor %}
@@ -319,13 +95,13 @@ class _BazelBUILDGenerator:
         ],
         {% endif %}
         visibility = ["//visibility:public"],
-        {% if obj["libs"] or obj["dependencies"] or obj["component_names"] %}
+        {% if obj["libs"] or obj["dependencies"] or obj.get("component_names", []) %}
         deps = [
             # do not sort
             {% for lib in obj["libs"] %}
             ":{{ lib.name }}_precompiled",
             {% endfor %}
-            {% for name in obj["component_names"] %}
+            {% for name in obj.get("component_names", []) %}
             ":{{ name }}",
             {% endfor %}
             {% for dep in obj["dependencies"] %}
@@ -366,30 +142,30 @@ class _BazelBUILDGenerator:
     {{ filegroup_bindirs_macro(root) }}
     """)
 
-    def __init__(self, conanfile, dep, root_package_info, components_info):
+    def __init__(self, conanfile, dep, require):
         self._conanfile = conanfile
         self._dep = dep
-        self._root_package_info = root_package_info
-        self._components_info = components_info
+        self._is_build_require = require.build
+        self._transitive_reqs = get_transitive_requires(self._conanfile, dep)
 
     @property
-    def build_file_pah(self):
+    def _build_file_path(self):
         """
         Returns the absolute path to the BUILD file created by Conan
         """
-        folder = os.path.join(self._root_package_info.repository_name, self.filename)
+        folder = os.path.join(self._get_repository_name(self._dep), self.dep_build_filename)
         return folder.replace("\\", "/")
 
     @property
-    def absolute_build_file_pah(self):
+    def _absolute_build_file_path(self):
         """
         Returns the absolute path to the BUILD file created by Conan
         """
-        folder = os.path.join(self._conanfile.generators_folder, self.build_file_pah)
+        folder = os.path.join(self._conanfile.generators_folder, self._build_file_path)
         return folder.replace("\\", "/")
 
     @property
-    def package_folder(self):
+    def _package_folder(self):
         """
         Returns the package folder path
         """
@@ -398,105 +174,55 @@ class _BazelBUILDGenerator:
             else self._dep.package_folder
         return root_folder.replace("\\", "/")
 
-    @property
-    def repository_name(self):
-        """
-        Wrapper to get the final name used for the root dependency cc_library declaration
-        """
-        return self._root_package_info.repository_name
-
-    def get_full_libs_info(self):
-        full_libs_info = defaultdict(list)
-        cpp_info = self._dep.cpp_info
-        deduced_cpp_info = cpp_info.deduce_full_cpp_info(self._dep)
-        package_folder_path = self.package_folder
-        # Root
-        if len(cpp_info.libs) > 1:
-            for lib_name in cpp_info.libs:
-                virtual_component = deduced_cpp_info.components.pop(f"_{lib_name}")  # removing it!
-                full_libs_info["root"].append(
-                    _LibInfo(lib_name, virtual_component, package_folder_path)
-                )
-        elif cpp_info.libs:
-            full_libs_info["root"].append(
-                _LibInfo(cpp_info.libs[0], deduced_cpp_info, package_folder_path)
-            )
-        # components
-        for cmp_name, cmp_cpp_info in deduced_cpp_info.components.items():
-            if cmp_name == "_common":  # FIXME: placeholder?
-                continue
-            if len(cmp_cpp_info.libs) > 1:
-                raise ConanException(f"BazelDeps only allows 1 lib per component:\n"
-                                     f"{self._dep}: {cmp_cpp_info.libs}")
-            elif cmp_cpp_info.libs:
-                # Bazel needs to relativize each path
-                full_libs_info[_get_component_name(self._dep, cmp_name)].append(
-                    _LibInfo(cmp_cpp_info.libs[0], cmp_cpp_info, package_folder_path)
-                )
-        return full_libs_info
-
-    def _get_context(self):
-        def fill_info(info, libs_info):
-            ret = {
-                "name": info.name,  # package name and components name
-                "libs": {},
-                "headers": "",
-                "includes": "",
-                "defines": "",
-                "linkopts": "",
-                "copts": "",
-                "dependencies": info.requires,
-                "component_names": []  # filled only by the root
-            }
-            if info.cpp_info is not None:
-                cpp_info = info.cpp_info
-                headers = _get_headers(cpp_info, package_folder_path)
-                includes = _get_includes(cpp_info, package_folder_path)
-                copts = _get_copts(cpp_info)
-                defines = _get_defines(cpp_info)
-                os_build = self._dep.settings_build.get_safe("os")
-                linkopts = _get_linkopts(cpp_info, os_build)
-                bindirs = [_relativize_path(bindir, package_folder_path)
-                           for bindir in cpp_info.bindirs]
-                ret.update({
-                    "libs": libs_info,
-                    "bindirs": bindirs,
-                    "headers": headers,
-                    "includes": includes,
-                    "defines": defines,
-                    "linkopts": linkopts,
-                    "copts": copts
-                })
-            return ret
-
-        package_folder_path = self.package_folder
-        context = dict()
-        full_libs_info = self.get_full_libs_info()
-        context["root"] = fill_info(self._root_package_info, full_libs_info.get("root", []))
-        context["components"] = []
-        for component in self._components_info:
-            component_context = fill_info(component, full_libs_info.get(component.name, []))
-            context["components"].append(component_context)
-            context["root"]["component_names"].append(component_context["name"])
-
-        return context
-
-    def generate(self):
-        context = self._get_context()
-        template = Template(self.template, trim_blocks=True, lstrip_blocks=True,
-                            undefined=StrictUndefined)
-        content = template.render(context)
-        save(self.build_file_pah, content)
-
-
-class _InfoGenerator:
-
-    def __init__(self, conanfile, dep, require):
-        self._conanfile = conanfile
-        self._dep = dep
-        self._req = require
-        self._is_build_require = require.build
-        self._transitive_reqs = get_transitive_requires(self._conanfile, dep)
+    def _get_repository_name(self, dep):
+        pkg_name = dep.cpp_info.get_property("bazel_repository_name") or dep.ref.name
+        return f"build-{pkg_name}" if self._is_build_require else pkg_name
+
+    def _get_target_name(self, dep):
+        pkg_name = dep.cpp_info.get_property("bazel_target_name") or dep.ref.name
+        return pkg_name
+
+    def _get_component_name(self, dep, comp_ref_name):
+        pkg_name = self._get_target_name(dep)
+        if comp_ref_name not in dep.cpp_info.components:
+            # foo::foo might be referencing the root cppinfo
+            if dep.ref.name == comp_ref_name:
+                return pkg_name
+            return f"{pkg_name}-{comp_ref_name}"
+        comp_name = dep.cpp_info.components[comp_ref_name].get_property("bazel_target_name")
+        # If user did not set bazel_target_name, let's create a component name
+        # with a namespace, e.g., dep-comp1
+        return comp_name or f"{pkg_name}-{comp_ref_name}"
+
+    def _get_headers(self, cpp_info):
+        return ['"{}/**"'.format(_relativize_path(path, self._package_folder))
+                for path in cpp_info.includedirs]
+
+    def _get_bindirs(self, cpp_info):
+        return [_relativize_path(bindir, self._package_folder) for bindir in cpp_info.bindirs]
+
+    def _get_includes(self, cpp_info):
+        return ['"{}"'.format(_relativize_path(path, self._package_folder))
+                for path in cpp_info.includedirs]
+
+    def _get_defines(self, cpp_info):
+        return ['"{}"'.format(define.replace('"', '\\' * 3 + '"'))
+                for define in cpp_info.defines]
+
+    def _get_linkopts(self, cpp_info):
+        os_build = self._dep.settings_build.get_safe("os")
+        link_opt = '/DEFAULTLIB:{}' if os_build == "Windows" else '-l{}'
+        system_libs = [link_opt.format(lib) for lib in cpp_info.system_libs]
+        shared_flags = cpp_info.sharedlinkflags + cpp_info.exelinkflags
+        return [f'"{flag}"' for flag in (system_libs + shared_flags)]
+
+    def _get_copts(self, cpp_info):
+        # FIXME: long discussions between copts (-Iflag) vs includes in Bazel. Not sure yet
+        # includedirsflags = ['"-I{}"'.format(_relativize_path(d, package_folder_path))
+        #                     for d in cpp_info.includedirs]
+        cxxflags = [var.replace('"', '\\"') for var in cpp_info.cxxflags]
+        cflags = [var.replace('"', '\\"') for var in cpp_info.cflags]
+        return [f'"{flag}"' for flag in (cxxflags + cflags)]
 
     def _get_component_requirement_names(self, cpp_info):
         """
@@ -518,7 +244,7 @@ class _InfoGenerator:
                 self.cpp_info.components["cmp"].requires = ["other::cmp1"]
         ```
         """
-        dep_ref_name = _get_package_reference_name(self._dep)
+        dep_ref_name = self._dep.ref.name
         ret = []
         for req in cpp_info.requires:
             pkg_ref_name, comp_ref_name = req.split("::") if "::" in req else (dep_ref_name, req)
@@ -528,47 +254,71 @@ class _InfoGenerator:
                 try:
                     req_conanfile = self._transitive_reqs[pkg_ref_name]
                     # Requirements declared in another dependency BUILD file
-                    prefix = f"@{_get_repository_name(req_conanfile, is_build_require=self._is_build_require)}//:"
+                    prefix = f"@{self._get_repository_name(req_conanfile)}//:"
                 except KeyError:
                     continue  # If the dependency is not in the transitive, might be skipped
             else:  # For instance, dep == "hello/1.0" and req == "hello::cmp1" -> hello == hello
                 req_conanfile = self._dep
-            comp_name = _get_component_name(req_conanfile, comp_ref_name)
+            comp_name = self._get_component_name(req_conanfile, comp_ref_name)
             dep_name = f"{prefix}{comp_name}"
             if dep_name not in ret:
                 ret.append(dep_name)
         return ret
 
-    @property
-    def components_info(self):
-        """
-        Get the whole package and its components information like their own requires, names and even
-        the cpp_info for each component.
+    def _get_lib_info(self, cpp_info, deduced_cpp_info, component_name=None):
 
-        :return: `list` of `_BazelTargetInfo` objects with all the components information
-        """
-        if not self._dep.cpp_info.has_components:
-            return []
-        components_info = []
-        # Loop through all the package's components
-        for comp_ref_name, cpp_info in self._dep.cpp_info.get_sorted_components().items():
-            # At first, let's check if we have defined some components requires, e.g., "dep::cmp1"
-            comp_requires_names = self._get_component_requirement_names(cpp_info)
-            comp_name = _get_component_name(self._dep, comp_ref_name)
-            # Save each component information
-            components_info.append(_BazelTargetInfo(None, comp_name, comp_ref_name,
-                                                    comp_requires_names, cpp_info))
-        return components_info
+        def _lib_info(lib_name, virtual_cpp_info):
+            return {
+                "name": lib_name,
+                "is_shared": virtual_cpp_info.type == PackageType.SHARED,
+                "lib_path": _relativize_path(virtual_cpp_info.location, self._package_folder),
+                "import_lib_path": _relativize_path(virtual_cpp_info.link_location, self._package_folder)
+            }
 
-    @property
-    def root_package_info(self):
+        libs = cpp_info.libs
+        libs_info = []
+        if libs:
+            if len(libs) > 1:
+                for lib_name in libs:
+                    name = f'_{component_name}_{lib_name}' if component_name else f'_{lib_name}'
+                    virtual_cpp_info = deduced_cpp_info.components[name]
+                    libs_info.append(_lib_info(lib_name, virtual_cpp_info))
+            else:
+                lib_name = libs[0]
+                virtual_cpp_info = deduced_cpp_info.components[component_name] if component_name else deduced_cpp_info
+                libs_info.append(_lib_info(lib_name, virtual_cpp_info))
+        return libs_info
+
+    def _get_build_file_context(self):
         """
         Get the whole package information
 
         :return: `_BazelTargetInfo` object with the package information
         """
-        repository_name = _get_repository_name(self._dep, is_build_require=self._is_build_require)
-        pkg_name = _get_target_name(self._dep)
+        build_content = {"components": [], "root": {}}
+        component_names = []
+        deduced_cpp_info = self._dep.cpp_info.deduce_full_cpp_info(self._dep)
+
+        if self._dep.cpp_info.has_components:
+            # Loop through all the package's components
+            for comp_ref_name, cmp_cpp_info in self._dep.cpp_info.get_sorted_components().items():
+                # At first, let's check if we have defined some components requires, e.g., "dep::cmp1"
+                comp_requires_names = self._get_component_requirement_names(cmp_cpp_info)
+                comp_name = self._get_component_name(self._dep, comp_ref_name)
+                component_names.append(comp_name)
+                build_content["components"].append({
+                    "name": comp_name,
+                    "libs": self._get_lib_info(cmp_cpp_info, deduced_cpp_info, component_name=comp_ref_name),
+                    "bindirs": self._get_bindirs(cmp_cpp_info),
+                    "headers": self._get_headers(cmp_cpp_info),
+                    "includes": self._get_includes(cmp_cpp_info),
+                    "defines": self._get_defines(cmp_cpp_info),
+                    "linkopts": self._get_linkopts(cmp_cpp_info),
+                    "copts": self._get_copts(cmp_cpp_info),
+                    "dependencies": comp_requires_names,
+                })
+
+        pkg_name = self._get_target_name(self._dep)
         # At first, let's check if we have defined some global requires, e.g., "other::cmp1"
         requires = self._get_component_requirement_names(self._dep.cpp_info)
         # If we have found some component requires it would be enough
@@ -576,12 +326,159 @@ class _InfoGenerator:
             # If no requires were found, let's try to get all the direct dependencies,
             # e.g., requires = "other_pkg/1.0"
             requires = [
-                f"@{_get_repository_name(req, is_build_require=self._is_build_require)}//:{_get_target_name(req)}"
+                f"@{self._get_repository_name(req)}//:{self._get_target_name(req)}"
                 for req in self._transitive_reqs.values()
             ]
         cpp_info = self._dep.cpp_info
-        return _BazelTargetInfo(repository_name, pkg_name, _get_package_reference_name(self._dep),
-                                requires, cpp_info)
+        build_content["root"] = {
+            "name": pkg_name,
+            "libs": self._get_lib_info(cpp_info, deduced_cpp_info),
+            "bindirs": self._get_bindirs(cpp_info),
+            "headers": self._get_headers(cpp_info),
+            "includes": self._get_includes(cpp_info),
+            "defines": self._get_defines(cpp_info),
+            "linkopts": self._get_linkopts(cpp_info),
+            "copts": self._get_copts(cpp_info),
+            "dependencies": requires,
+            "component_names": component_names
+        }
+        return build_content
+
+    @property
+    def dep_context(self):
+        """
+        Return the dependency context to fill later the conan_deps_module_extension.bzl and so on.
+        """
+        return {
+            'repository_name': self._get_repository_name(self._dep),
+            'package_folder': self._package_folder,
+            'package_build_file_path': self._absolute_build_file_path,
+        }
+
+    def items(self):
+        template = Template(self.dep_build_template, trim_blocks=True, lstrip_blocks=True,
+                            undefined=StrictUndefined)
+        content = template.render(self._get_build_file_context())
+        return {self._build_file_path: content}.items()
+
+
+class _BazelPathsGenerator:
+    """
+    Bazel 6.0 needs to know all the dependencies for its current project. So, the only way
+    to do that is to tell the WORKSPACE file how to load all the Conan ones. This is the goal
+    of the function created by this class, the ``load_conan_dependencies`` one.
+
+    More information:
+        * https://bazel.build/reference/be/workspace#new_local_repository
+
+    Bazel >= 7.1 needs to know all the dependencies as well, but provided via the MODULE.bazel file.
+    Therefor we provide a static repository rule to load the dependencies. This rule is used by a
+    module extension, passing the package path and the BUILD file path to the repository rule.
+    """
+    repository_filename = "dependencies.bzl"
+    modules_filename = "conan_deps_module_extension.bzl"
+    repository_rules_filename = "conan_deps_repo_rules.bzl"
+    repository_template = textwrap.dedent("""\
+        # This Bazel module should be loaded by your WORKSPACE file.
+        # Add these lines to your WORKSPACE one (assuming that you're using the "bazel_layout"):
+        # load("@//conan:dependencies.bzl", "load_conan_dependencies")
+        # load_conan_dependencies()
+
+        def load_conan_dependencies():
+        {% for dep_info in dependencies %}
+            native.new_local_repository(
+                name="{{dep_info['repository_name']}}",
+                path="{{dep_info['package_folder']}}",
+                build_file="{{dep_info['package_build_file_path']}}",
+            )
+        {% endfor %}
+        """)
+    module_template = textwrap.dedent("""\
+        # This module provides a repo for each requires-dependency in your conanfile.
+        # It's generated by the BazelDeps, and should be used in your Module.bazel file.
+        load(":conan_deps_repo_rules.bzl", "conan_dependency_repo")
+
+        def _load_dependencies_impl(mctx):
+        {% for dep_info in dependencies %}
+            conan_dependency_repo(
+                name = "{{dep_info['repository_name']}}",
+                package_path = "{{dep_info['package_folder']}}",
+                build_file_path = "{{dep_info['package_build_file_path']}}",
+            )
+        {% endfor %}
+
+            return mctx.extension_metadata(
+                # It will only warn you if any direct
+                # dependency is not imported by the 'use_repo' or even it is imported
+                # but not created. Notice that root_module_direct_dev_deps can not be None as we
+                # are giving 'all' value to root_module_direct_deps.
+                # Fix the 'use_repo' calls by running 'bazel mod tidy'
+                root_module_direct_deps = 'all',
+                root_module_direct_dev_deps = [],
+
+                # Prevent writing function content to lockfiles:
+                # - https://bazel.build/rules/lib/builtins/module_ctx#extension_metadata
+                # Important for remote build. Actually it's not reproducible, as local paths will
+                # be different on different machines. But we assume that conan works correctly here.
+                # IMPORTANT: Not compatible with bazel < 7.1
+                reproducible = True,
+            )
+
+        conan_extension = module_extension(
+            implementation = _load_dependencies_impl,
+            os_dependent = True,
+            arch_dependent = True,
+        )
+        """)
+    repository_rules_content = textwrap.dedent("""\
+        # This bazel repository rule is used to load Conan dependencies into the Bazel workspace.
+        # It's used by a generated module file that provides information about the conan packages.
+        # Each conan package is loaded into a bazel repository rule, with having the name of the
+        # package. The whole method is based on symlinks to not copy the whole package into the
+        # Bazel workspace, which is expensive.
+        def _conan_dependency_repo(rctx):
+            package_path = rctx.workspace_root.get_child(rctx.attr.package_path)
+
+            child_packages = package_path.readdir()
+            for child in child_packages:
+                rctx.symlink(child, child.basename)
+
+            rctx.symlink(rctx.attr.build_file_path, "BUILD.bazel")
+
+        conan_dependency_repo = repository_rule(
+            implementation = _conan_dependency_repo,
+            attrs = {
+                "package_path": attr.string(
+                    mandatory = True,
+                    doc = "The path to the Conan package in conan cache.",
+                ),
+                "build_file_path": attr.string(
+                    mandatory = True,
+                    doc = "The path to the BUILD file.",
+                ),
+            },
+        )
+        """)
+
+    @classmethod
+    def items(cls, dependencies_context):
+        if not dependencies_context:
+            return {}
+        # Bazel 6.x, but it'll likely be dropped soon
+        repository_template = Template(cls.repository_template, trim_blocks=True,
+                                       lstrip_blocks=True,
+                                       undefined=StrictUndefined)
+        content_6x = repository_template.render(dependencies=dependencies_context)
+        # Bazel 7.x files
+        module_template = Template(cls.module_template, trim_blocks=True, lstrip_blocks=True,
+                                   undefined=StrictUndefined)
+        content = module_template.render(dependencies=dependencies_context)
+        return {
+            cls.repository_filename: content_6x,  # bazel 6.x compatible
+            cls.modules_filename: content,
+            cls.repository_rules_filename: cls.repository_rules_content,
+            "BUILD.bazel": "# This is an empty BUILD file."  # Bazel needs this file in each subfolder
+        }.items()
 
 
 class BazelDeps:
@@ -594,6 +491,24 @@ class BazelDeps:
         #: Activates the build context for the specified Conan package names.
         self.build_context_activated = []
 
+    def _get_requirements(self, build_context_activated):
+        """
+        Simply save the activated requirements (host + build + test), and the deactivated ones
+        """
+        # All the requirements
+        host_req = self._conanfile.dependencies.host
+        build_req = self._conanfile.dependencies.direct_build  # tool_requires
+        test_req = self._conanfile.dependencies.test
+
+        for require, dep in list(host_req.items()) + list(build_req.items()) + list(
+            test_req.items()):
+            # Require is not used at the moment, but its information could be used,
+            # and will be used in Conan 2.0
+            # Filter the build_requires not activated with self.build_context_activated
+            if require.build and dep.ref.name not in build_context_activated:
+                continue
+            yield require, dep
+
     def generate(self):
         """
         Generates all the targets <DEP>/BUILD.bazel files, a dependencies.bzl (for bazel<7), a
@@ -620,25 +535,13 @@ class BazelDeps:
             use_repo(load_conan_dependencies, "dep-1", "dep-2", ...)
         """
         check_duplicated_generator(self, self._conanfile)
-        requirements = _get_requirements(self._conanfile, self.build_context_activated)
-        deps_info = []
-        for require, dep in requirements:
+        dependencies_context = []
+        for require, dep in self._get_requirements(self.build_context_activated):
             # Bazel info generator
-            info_generator = _InfoGenerator(self._conanfile, dep, require)
-            root_package_info = info_generator.root_package_info
-            components_info = info_generator.components_info
-            # Generating single BUILD files per dependency
-            bazel_generator = _BazelBUILDGenerator(self._conanfile, dep,
-                                                   root_package_info, components_info)
-            bazel_generator.generate()
-            # Saving pieces of information from each BUILD file
-            deps_info.append((
-                bazel_generator.repository_name,  # Bazel repository name == @repository_name
-                bazel_generator.package_folder,  # path to the Conan dependency folder
-                bazel_generator.absolute_build_file_pah  # path to the BUILD.bazel file created
-            ))
-        if deps_info:
-            # dependencies.bzl has all the information about where to look for the dependencies
-            bazel_dependencies_module_generator = _BazelDependenciesBZLGenerator(self._conanfile,
-                                                                                 deps_info)
-            bazel_dependencies_module_generator.generate()
+            dep_build_generator = _BazelDepBuildGenerator(self._conanfile, dep, require)
+            dependencies_context.append(dep_build_generator.dep_context)
+            for name, content in dep_build_generator.items():
+                save(name, content)
+
+        for name, content in _BazelPathsGenerator.items(dependencies_context):
+            save(name, content)
diff --git a/conan/tools/meson/helpers.py b/conan/tools/meson/helpers.py
index c3e40a806..fcf49fd40 100644
--- a/conan/tools/meson/helpers.py
+++ b/conan/tools/meson/helpers.py
@@ -49,6 +49,7 @@ _meson_cpu_family_map = {
     'sparc': ('sparc', 'sparc', 'big'),
     'sparcv9': ('sparc64', 'sparc64', 'big'),
     'wasm': ('wasm32', 'wasm32', 'little'),
+    'wasm64': ('wasm64', 'wasm64', 'little'),
     'x86': ('x86', 'x86', 'little'),
     'x86_64': ('x86_64', 'x86_64', 'little'),
     'riscv32': ('riscv32', 'riscv32', 'little'),
diff --git a/conan/tools/meson/meson.py b/conan/tools/meson/meson.py
index 17fa59241..9604e5a73 100644
--- a/conan/tools/meson/meson.py
+++ b/conan/tools/meson/meson.py
@@ -82,6 +82,8 @@ class Meson(object):
         verbosity = self._install_verbosity
         if verbosity:
             cmd += " " + verbosity
+        if self._conanfile.conf.get("tools.build:install_strip", check_type=bool):
+            cmd += " --strip"
         self._conanfile.run(cmd)
 
     def test(self):
diff --git a/conan/tools/qbs/common.py b/conan/tools/qbs/common.py
index dd45f434e..bf6486704 100644
--- a/conan/tools/qbs/common.py
+++ b/conan/tools/qbs/common.py
@@ -26,6 +26,7 @@ architecture_map = {
     's390x': 's390x',
     'asm.js': None,
     'wasm': None,
+    'wasm64': None,
     'sh4le': 'sh'
 }
 
@@ -84,4 +85,4 @@ runtime_library_map = {
     'MT': 'static',
     'MDd': 'dynamic',
     'MTd': 'static',
-}
\ No newline at end of file
+}
diff --git a/conan/tools/scm/git.py b/conan/tools/scm/git.py
index 48ad9fe5d..190711e18 100644
--- a/conan/tools/scm/git.py
+++ b/conan/tools/scm/git.py
@@ -88,6 +88,9 @@ class Git:
             name, url = r.split(maxsplit=1)
             if name == remote:
                 url, _ = url.rsplit(None, 1)
+                # if the url still has (fetch) or (push) at the end
+                if url.endswith("(fetch)") or url.endswith("(push)"):
+                    url, _ = url.rsplit(None, 1)
                 if os.path.exists(url):  # Windows local directory
                     url = url.replace("\\", "/")
                 return url


Test patch:
diff --git a/.ci/docker/conan-tests b/.ci/docker/conan-tests
index ef26a5530..5f7ee6f29 100644
--- a/.ci/docker/conan-tests
+++ b/.ci/docker/conan-tests
@@ -25,7 +25,8 @@ ENV PY36=3.6.15 \
     CLANGXX_14=/usr/bin/clang++-14 \
     BAZEL_6=6.5.0 \
     BAZEL_7=7.4.1 \
-    BAZEL_8=8.0.0
+    BAZEL_8=8.0.0 \
+    EMSDK=4.0.10
 
 RUN apt-get update && \
     apt-get install -y --no-install-recommends \
@@ -169,6 +170,21 @@ RUN cd /tmp && \
     mv qbs-linux-x86_64-2.6.0 /usr/share/qbs && \
     rm qbs-linux-x86_64-2.6.0.tar.gz
 
+RUN cd /tmp && \
+    wget https://github.com/emscripten-core/emsdk/archive/refs/tags/${EMSDK}.tar.gz && \
+    tar xzf ${EMSDK}.tar.gz --directory /usr/share && \
+    cd /usr/share/emsdk-${EMSDK} && \
+    ./emsdk update && \
+    ./emsdk install latest && \
+    ./emsdk activate latest --permanent && \
+    . /usr/share/emsdk-${EMSDK}/emsdk_env.sh && \
+    embuilder build MINIMAL && \
+    embuilder build MINIMAL --wasm64
+    # echo "EMSDK_QUIET=1 . /usr/share/emsdk-${EMSDK}/emsdk_env.sh" >> /etc/bash.bashrc
+# Manually add the emsdk binaries to the PATH and set emcc cache directory to a writable location
+ENV PATH="/usr/share/emsdk-$EMSDK:/usr/share/emsdk-$EMSDK/upstream/emscripten:/usr/share/emsdk-$EMSDK/node/22.16.0_64bit/bin:$PATH" \
+    EM_CACHE=$HOME/.emscripten_cache
+
 RUN echo "export QT_NO_GLIB=1" >> /etc/profile.d/qt.sh
 
 USER conan
diff --git a/.github/workflows/osx-tests.yml b/.github/workflows/osx-tests.yml
index c02a16596..f6196ecd2 100644
--- a/.github/workflows/osx-tests.yml
+++ b/.github/workflows/osx-tests.yml
@@ -47,7 +47,7 @@ jobs:
 
       - name: Install homebrew dependencies
         run: |
-          brew install xcodegen make libtool zlib autoconf automake ninja
+          brew install xcodegen make libtool zlib autoconf automake ninja emscripten
 
       - name: Cache CMake and Bazel installations
         id: cache-tools
@@ -168,7 +168,7 @@ jobs:
 
       - name: Install homebrew dependencies
         run: |
-          brew install xcodegen make libtool zlib autoconf automake ninja
+          brew install xcodegen make libtool zlib autoconf automake ninja emscripten
           export PATH=${HOME}/Applications/CMake/3.15.7/bin:$PATH:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin
           cmake --version
           bazel --version
diff --git a/test/conftest.py b/test/conftest.py
index a0f6ead5a..a189d4aaa 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -190,6 +190,8 @@ tools_locations = {
             "path": {'Linux': '/usr/share/qbs/bin'}
         }
     },
+    "emcc": {},
+    "node": {},
     # TODO: Intel oneAPI is not installed in CI yet. Uncomment this line whenever it's done.
     # "intel_oneapi": {
     #     "default": "2021.3",
diff --git a/test/functional/toolchains/cmake/cmakedeps2/test_cmakeconfigdeps_new.py b/test/functional/toolchains/cmake/cmakedeps2/test_cmakeconfigdeps_new.py
index 87124f69d..3bee9360f 100644
--- a/test/functional/toolchains/cmake/cmakedeps2/test_cmakeconfigdeps_new.py
+++ b/test/functional/toolchains/cmake/cmakedeps2/test_cmakeconfigdeps_new.py
@@ -1515,3 +1515,51 @@ class TestCppInfoChecks:
         args = f"-g CMakeDeps -c tools.cmake.cmakedeps:new={new_value}"
         c.run(f"install --requires=dep/0.1 {args}", assert_error=True)
         assert "dep/0.1 cpp_info incorrect .type shared-library for .exe myexe" in c.out
+
+
+
+def test_multiple_find_package_subfolder():
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+    from conan import ConanFile
+    class TestPackage(ConanFile):
+        name = "matrix"
+        version = "1.0"
+        def package_info(self):
+            self.cpp_info.system_libs = ["mysystemlib"]
+        """)
+    c.save({"conanfile.py": conanfile})
+    c.run("create .")
+
+    cmake = textwrap.dedent("""
+        cmake_minimum_required(VERSION 3.15)
+        project(app NONE)
+
+        find_package(matrix CONFIG REQUIRED)
+        add_subdirectory(subdir)
+        """)
+    subcmake = textwrap.dedent("""
+        cmake_minimum_required(VERSION 3.15)
+        project(subdir NONE)
+
+        find_package(matrix CONFIG REQUIRED)
+        """)
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import CMake
+        class Pkg(ConanFile):
+            requires = "matrix/1.0"
+            generators = "CMakeToolchain", "CMakeDeps"
+            settings = "os", "compiler", "build_type", "arch"
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+        """)
+    c.save({"conanfile.py": conanfile,
+            "CMakeLists.txt": cmake,
+            "subdir/CMakeLists.txt": subcmake}, clean_first=True)
+
+    c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+    assert "find_package(matrix)" in c.out
+    assert "target_link_libraries(... matrix::matrix)" in c.out
+    assert "Conan: Target declared imported INTERFACE library 'matrix::matrix'" in c.out
diff --git a/test/functional/toolchains/cmake/cmakedeps2/test_cmakeconfigdeps_sources.py b/test/functional/toolchains/cmake/cmakedeps2/test_cmakeconfigdeps_sources.py
new file mode 100644
index 000000000..7e22f6f81
--- /dev/null
+++ b/test/functional/toolchains/cmake/cmakedeps2/test_cmakeconfigdeps_sources.py
@@ -0,0 +1,91 @@
+import os
+import platform
+import textwrap
+
+import pytest
+
+from conan.tools.files import replace_in_file
+from conan.test.utils.mocks import ConanFileMock
+
+from conan.test.utils.tools import TestClient
+
+new_value = "will_break_next"
+
+
+@pytest.mark.skipif(platform.system() != "Linux", reason="No OS specific test")
+@pytest.mark.tool("cmake")
+def test_cpp_info_sources():
+    c = TestClient()
+    c.run("new cmake_lib -d name=hello -d version=1.0")
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.files import copy
+
+        class HelloConan(ConanFile):
+            name = "hello"
+            version = "1.0"
+            exports_sources = "src/*", "include/*"
+            package_type = "header-library"
+
+            def package(self):
+                copy(self, "*.h", self.source_folder, self.package_folder)
+                copy(self, "*.cpp", self.source_folder, self.package_folder)
+
+            def package_info(self):
+                self.cpp_info.sources = ["src/hello.cpp"]
+    """)
+    c.save({"conanfile.py": conanfile})
+    # Check that the hello library builds in test_package
+    c.run(f"create . -c tools.cmake.cmakedeps:new={new_value}")
+    # Check content of the generated files
+    c.run(f"install --requires=hello/1.0 -g=CMakeConfigDeps "
+          f"-c tools.cmake.cmakedeps:new={new_value}")
+    cmake = c.load("hello-Targets-release.cmake")
+    assert "add_library(hello::hello INTERFACE IMPORTED)" in cmake
+    assert "set_property(TARGET hello::hello APPEND PROPERTY INTERFACE_SOURCES\n"\
+           "             $<$<CONFIG:RELEASE>:${hello_PACKAGE_FOLDER_RELEASE}/src/hello.cpp>)" in cmake
+
+
+@pytest.mark.skipif(platform.system() != "Linux", reason="No OS specific test")
+@pytest.mark.tool("cmake")
+def test_cpp_info_component_sources():
+    c = TestClient()
+    c.run("new cmake_lib -d name=hello -d version=1.0")
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.files import copy
+
+        class HelloConan(ConanFile):
+            name = "hello"
+            version = "1.0"
+            exports_sources = "src/*", "include/*"
+            package_type = "header-library"
+
+            def package(self):
+                copy(self, "*.h", self.source_folder, self.package_folder)
+                copy(self, "*.cpp", self.source_folder, self.package_folder)
+
+            def package_info(self):
+                self.cpp_info.components["my_comp"].sources = ["src/hello.cpp", "src/other.cpp"]
+    """)
+    c.save({
+        "conanfile.py": conanfile,
+        "src/other.cpp": "",
+    })
+
+    # Make test_package link with component's target
+    test_package_cmakelists_path = os.path.join(c.current_folder, "test_package", "CMakeLists.txt")
+    replace_in_file(ConanFileMock(), test_package_cmakelists_path, "hello::hello", "hello::my_comp")
+    test_package_cmakelists_content = c.load(test_package_cmakelists_path)
+    assert "target_link_libraries(example hello::my_comp)" in test_package_cmakelists_content
+    # Check that the hello library builds in test_package
+    c.run(f"create . -c tools.cmake.cmakedeps:new={new_value}")
+    # Check the content of the generated files
+    c.run(f"install --requires=hello/1.0 -g=CMakeConfigDeps "
+          f"-c tools.cmake.cmakedeps:new={new_value}")
+    cmake = c.load("hello-Targets-release.cmake")
+    assert "add_library(hello::hello INTERFACE IMPORTED)" in cmake
+    assert "add_library(hello::my_comp INTERFACE IMPORTED)" in cmake
+    assert "set_property(TARGET hello::my_comp APPEND PROPERTY INTERFACE_SOURCES\n"\
+           "             $<$<CONFIG:RELEASE>:${hello_PACKAGE_FOLDER_RELEASE}/src/hello.cpp"\
+           " ${hello_PACKAGE_FOLDER_RELEASE}/src/other.cpp>)" in cmake
diff --git a/test/functional/toolchains/emscripten/test_emcc.py b/test/functional/toolchains/emscripten/test_emcc.py
new file mode 100644
index 000000000..cce407c9d
--- /dev/null
+++ b/test/functional/toolchains/emscripten/test_emcc.py
@@ -0,0 +1,167 @@
+# Test suite to check conan capabilities for cross compiling to web assembly and asmjs
+import textwrap
+import os
+import platform
+from shutil import rmtree
+import pytest
+
+from conan.test.utils.tools import TestClient
+
+base_emscripten_profile = textwrap.dedent(
+    """
+    [settings]
+    build_type=Release
+    compiler=emcc
+    compiler.cppstd=17
+    compiler.libcxx=libc++
+    compiler.version=4.0.10
+    os=Emscripten
+
+    [conf]
+    tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1']
+    tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1']
+
+    # Define the emcc executable paths
+    tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'}
+
+    # Set Ninja as default generator as it is faster and will sove issues on Windows
+    tools.cmake.cmaketoolchain:generator=Ninja
+    # Verbosity to see emcc invocations
+    tools.compilation:verbosity=verbose
+    # Distinguish between architectures
+    tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch']
+
+    [buildenv]
+    AR=emar
+    NM=emnm
+    RANLIB=emranlib
+    STRIP=emstrip
+"""
+)
+
+wasm32_profile = textwrap.dedent(
+    """
+    include(base_emscripten_profile)
+    [settings]
+    arch=wasm
+
+    [conf]
+    tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB']
+    tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB']
+    """
+)
+
+wasm_64_profile = textwrap.dedent(
+    """
+    include(base_emscripten_profile)
+    [settings]
+    arch=wasm64
+    [conf]
+    tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB']
+    tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB']
+    """
+)
+
+
+asmjs_profile = textwrap.dedent(
+    """
+    include(base_emscripten_profile)
+    [settings]
+    arch=asm.js
+
+    [conf]
+    tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB']
+    tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB']
+    """
+)
+
+
+@pytest.mark.tool("cmake")
+@pytest.mark.tool("emcc")
+@pytest.mark.tool("node")
+@pytest.mark.skipif(platform.system() == "Windows", reason = "Emscripten not installed in Windows")
+def test_cmake_emscripten():
+    client = TestClient()
+
+    client.run("new cmake_exe -d name=hello -d version=0.1")
+    client.save({"wasm32": wasm32_profile, "asmjs": asmjs_profile, "base_emscripten_profile": base_emscripten_profile,})
+
+    client.run("build . -pr:h=wasm32")
+    assert "Conan toolchain: Defining libcxx as C++ flags: -stdlib=libc++" in client.out
+    assert os.path.exists(os.path.join(client.current_folder, "build/release-wasm" , "hello.wasm"))
+
+    # Run JavaScript generated code which uses .wasm file
+    client.run_command("node ./build/release-wasm/hello")
+    assert "Hello World Release!" in client.out
+
+    client.run("build . -pr:h=asmjs")
+    assert "WASM=0" in client.out
+    # No wasm should have been generated for asm.js architecture
+    assert not os.path.exists(os.path.join(client.current_folder, "build/release-asm.js" , "hello.wasm"))
+    client.run_command("node ./build/release-asm.js/hello")
+    assert "Hello World Release!" in client.out
+
+
+@pytest.mark.tool("meson")
+@pytest.mark.tool("emcc")
+@pytest.mark.tool("node")
+@pytest.mark.skipif(platform.system() == "Windows", reason = "Emscripten not installed in Windows")
+def test_meson_emscripten():
+    client = TestClient()
+    client.run("new meson_exe -d name=hello -d version=0.1")
+
+    client.save({"wasm32": wasm32_profile, "wasm64": wasm_64_profile, "asmjs": asmjs_profile, "base_emscripten_profile": base_emscripten_profile,})
+    client.run("build . -pr:h=wasm64")
+    assert "C++ compiler for the host machine: em++" in client.out
+    assert "C++ linker for the host machine: em++ ld.wasm" in client.out
+    assert "Host machine cpu family: wasm64" in client.out
+    assert os.path.exists(os.path.join(client.current_folder, "build", "hello.wasm"))
+    # wasm64 only supported since node v23 so only run in MacOS where it is available
+    if platform.system() == "Darwin":
+        client.run_command("node ./build/hello")
+        assert "Hello World Release!" in client.out
+
+    rmtree(os.path.join(client.current_folder, "build"))
+    client.run("build . -pr:h=asmjs")
+    assert "C++ compiler for the host machine: em++" in client.out
+    assert "C++ linker for the host machine: em++ ld.wasm" in client.out
+    assert "Host machine cpu family: asm.js" in client.out
+    assert "WASM=0" in client.out
+
+    assert not os.path.exists(os.path.join(client.current_folder, "build", "hello.wasm"))
+    client.run_command("node ./build/hello")
+    assert "Hello World Release!" in client.out
+
+
+@pytest.mark.tool("autotools")
+@pytest.mark.tool("emcc")
+@pytest.mark.tool("node")
+@pytest.mark.skipif(platform.system() == "Windows", reason = "Emscripten not installed in Windows")
+def test_autotools_emscripten():
+    client = TestClient(path_with_spaces=False)
+    client.run("new autotools_exe -d name=hello -d version=0.1")
+    client.save({"wasm32": wasm32_profile, "asmjs": asmjs_profile, "base_emscripten_profile": base_emscripten_profile,})
+    client.run("build . -pr:h=wasm32")
+    assert "checking for wasm32-local-emscripten-ranlib... emranlib" in client.out
+    assert "checking for wasm32-local-emscripten-gcc... emcc" in client.out
+    assert "checking for wasm32-local-emscripten-ar... emar" in client.out
+    assert "checking the archiver (emar) interface... ar" in client.out
+    assert "checking for wasm32-local-emscripten-strip... emstrip" in client.out
+
+    assert os.path.exists(os.path.join(client.current_folder, "build-release", "src", "hello.wasm"))
+    # Run JavaScript generated code which uses .wasm file
+    client.run_command("node ./build-release/src/hello")
+    assert "Hello World Release!" in client.out
+
+    rmtree(os.path.join(client.current_folder, "build-release"))
+    client.run("build . -pr:h=asmjs")
+    assert "WASM=0" in client.out
+    # No wasm should have been generated for asm.js architecture
+    assert not os.path.exists(os.path.join(client.current_folder, "build-release", "hello.wasm"))
+    client.run_command("node ./build-release/src/hello")
+    assert "Hello World Release!" in client.out
+
+
+# TODO: test_bazel_emscripten(): need WIP new bazel toolchain
+# TODO: test_msbuild_emscripten(): give support to msbuild
+# TODO: test_premake_emscripten(): premake tests
diff --git a/test/functional/tools/scm/test_git.py b/test/functional/tools/scm/test_git.py
index 7e0a46d09..89f3c9a1d 100644
--- a/test/functional/tools/scm/test_git.py
+++ b/test/functional/tools/scm/test_git.py
@@ -1253,3 +1253,63 @@ class TestGitShallowTagClone:
             assert "pkg/0.1: URL: {}".format(url) in c.out
             assert "pkg/0.1: COMMIT IN REMOTE: False" in c.out
             assert "pkg/0.1: DIRTY: False" in c.out
+
+
+@pytest.mark.tool("git")
+class TestGitTreelessRemote:
+
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.scm import Git
+        import os
+
+        class Pkg(ConanFile):
+            name = "pkg"
+            version = "0.1"
+
+            def layout(self):
+                self.folders.source = "source"
+
+            def export(self):
+                git = Git(self)
+                git.clone(url="{url}", args=["--filter=tree:0"], target="target")
+                git.folder = "target"
+                cloned_url = git.run("remote -v")
+                self.output.info("git remote: %s ===" % cloned_url)
+                cloned_url = git.get_remote_url()
+                self.output.info("get_remote_url(): %s ===" % cloned_url)
+        """)
+
+    def test_treeless_clone(self):
+        """
+        When cloning a git repository with the `--filter=tree:0` option,
+        the Git.get_remote_url() should only the URL of the repository.
+
+        Validate the issue https://github.com/conan-io/conan/issues/18415
+        """
+        repository = temp_folder(path_with_spaces=False)
+        url, commit = create_local_git_repo(files={"README": "Lumen naturale ratum est"},
+                                            folder=repository)
+
+        client = TestClient()
+        client.save({"conanfile.py": self.conanfile.format(url=url)})
+        client.run("export .")
+        # We expect [tree:0] for regular git remote command. Requires Git +2.43
+        assert f"git remote: origin\t{url} (fetch) [tree:0]" in client.out
+        # Then get_remote_url filters it to only the URL
+        assert f"get_remote_url(): {url} ===" in client.out
+
+    def test_treeless_clone_with_parenthesis(self):
+        """
+        Windows can use C:\Program Files (x86) path, which contains parenthesis.
+        As the URL will have (fetch) or (push), get_remote_url() should be able to parse it.
+        """
+        repository = os.path.join(temp_folder(), "Program Files (x86)", "myrepo")
+        os.makedirs(repository)
+        url, commit = create_local_git_repo(files={"README": "Pacem in maribus."},
+                                            folder=repository)
+
+        client = TestClient()
+        client.save({"conanfile.py": self.conanfile.format(url=url)})
+        client.run("export .")
+        assert f"get_remote_url(): {url} ===" in client.out
diff --git a/test/integration/command/export_pkg_test.py b/test/integration/command/export_pkg_test.py
index 87da54348..a30c60156 100644
--- a/test/integration/command/export_pkg_test.py
+++ b/test/integration/command/export_pkg_test.py
@@ -280,6 +280,19 @@ class TestConan(ConanFile):
         cmakeinfo = client.load("hello1-release-data.cmake")
         self.assertIn("set(hello1_LIBS_RELEASE mycoollib)", cmakeinfo)
 
+    def test_export_pkg_version_type(self):
+        client = TestClient(light=True)
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            class Hello(ConanFile):
+                def requirements(self):
+                    assert type(self.version) is str, "Version should be a string"
+            """)
+        client.save({"conanfile.py": conanfile})
+        client.run("create . --name=hello --version=0.1")
+        # This used to trigger the assertion error
+        client.run("export-pkg . --name=hello --version=0.1")
+
     def test_export_pkg_json(self):
         client = TestClient()
         client.save({"conanfile.py": GenConanfile("pkg", "0.1")})
diff --git a/test/integration/command/help_test.py b/test/integration/command/help_test.py
index 2af1c84a0..25bb560bf 100644
--- a/test/integration/command/help_test.py
+++ b/test/integration/command/help_test.py
@@ -1,4 +1,10 @@
+import argparse
+
+import pytest
+from mock import patch
+
 from conan import __version__
+from conan.test.utils.env import environment_update
 from conan.test.utils.tools import TestClient
 
 
@@ -43,3 +49,30 @@ class TestHelp:
         assert "Perform file operations in the local cache (of recipes and/or packages)" in c.out
         c.run("cache path -h")
         assert "Show the path to the Conan cache for a given reference" in c.out
+
+
+def test_all_commands_call_args_parse():
+    tc = TestClient(light=True)
+    tc.run("-h")
+    commands = tc.api.command.cli._builtin_commands
+    with environment_update({"CONAN_WORKSPACE_ENABLE": "will_break_next"}):
+        for command, info in commands.items():
+            if len(info._subcommands) > 0:
+                for subcommand in info._subcommands.values():
+                    with patch("conan.cli.command.ConanArgumentParser.parse_args",
+                               side_effect=Exception("called")) as mock_run:
+                        try:
+                            tc.run(f"{command} {subcommand.name} -h")
+                        except:
+                            pass
+                        finally:
+                            assert mock_run.called, f'Command "conan {command} {subcommand.name}" did not call parse_args()'
+            else:
+                with patch("conan.cli.command.ConanArgumentParser.parse_args",
+                           side_effect=Exception("called")) as mock_run:
+                    try:
+                        tc.run(f"{command} -h")
+                    except:
+                        pass
+                    finally:
+                        assert mock_run.called, f'Command "conan {command}" did not call parse_args()'
diff --git a/test/integration/command/list/list_test.py b/test/integration/command/list/list_test.py
index fddcacf42..5d04ed535 100644
--- a/test/integration/command/list/list_test.py
+++ b/test/integration/command/list/list_test.py
@@ -10,10 +10,14 @@ import pytest
 
 from conan.internal.errors import ConanConnectionError
 from conan.errors import ConanException
+from conan.test.assets.cmake import gen_cmakelists
 from conan.test.assets.genconanfile import GenConanfile
-from conan.test.utils.tools import TestClient, TestServer, NO_SETTINGS_PACKAGE_ID
+from conan.test.assets.sources import gen_function_h, gen_function_cpp
+from conan.test.utils.file_server import TestFileServer
+from conan.test.utils.test_files import temp_folder
+from conan.test.utils.tools import TestClient, TestServer, NO_SETTINGS_PACKAGE_ID, zipdir
 from conan.test.utils.env import environment_update
-from conan.internal.util.files import save
+from conan.internal.util.files import save, save_files, sha256sum
 
 
 class TestParamErrors:
@@ -947,3 +951,31 @@ def test_overlapping_versions():
     tc.run("list * -c -f=json", redirect_stdout="list.json")
     results = json.loads(tc.load("list.json"))
     assert len(results["Local Cache"]) == 2
+
+def test_list_local_recipe_index():
+    c = TestClient(light=True)
+    c.run(f"new local_recipes_index -d name=pkg -d version=0.1 -d url='https://conan-fake-url.com' ")
+    c.run(f"remote add local '{c.current_folder}'")
+
+    c.run("list '*' -r=local")
+    assert "Found 1 pkg/version recipes matching * in local" in c.out
+    c.run("list '*/*' -r=local")
+    assert "Found 1 pkg/version recipes matching */* in local" in c.out
+    c.run("list '*/0.1' -r=local")
+    assert "Found 1 pkg/version recipes matching */0.1 in local" in c.out
+    c.run("list 'pkg/*' -r=local")
+    assert "Found 1 pkg/version recipes matching pkg/* in local" in c.out
+    c.run("list 'pkg/0.*' -r=local")
+    assert "Found 1 pkg/version recipes matching pkg/0.* in local" in c.out
+    c.run("list 'pkg' -r=local")
+    assert "Found 1 pkg/version recipes matching pkg in local" in c.out
+    c.run("list 'pkg/0.1' -r=local")
+    assert "Found 1 pkg/version recipes matching pkg/0.1 in local" in c.out
+    c.run("list 'foo' -r=local")
+    assert "ERROR: Recipe 'foo' not found" in c.out
+    c.run("list '/#@&%%&@#/' -r=local")
+    assert "ERROR: Recipe '/' not found" in c.out
+    c.run("list 'pkg/0.1@a' -r=local")
+    assert "ERROR: Recipe 'pkg/0.1@a' not found" in c.out
+    c.run("list 'pkg%0.1#a@b/c' -r=local")
+    assert "ERROR: Recipe 'pkg%0.1' not found" in c.out
diff --git a/test/integration/command/source_test.py b/test/integration/command/source_test.py
index 89cd5372f..92fbc708e 100644
--- a/test/integration/command/source_test.py
+++ b/test/integration/command/source_test.py
@@ -142,6 +142,39 @@ class ConanLib(ConanFile):
         self.assertIn("conanfile.py: Running source!", client.out)
         self.assertEqual("Hello World", client.load("file1.txt"))
 
+    def test_local_source_layout_root(self):
+        # Ensure that if a root folder is specified Conan source method
+        # uses it. This is especially important when running with
+        # no_copy_source where both the build()  and source() methods
+        # need to reference source_folder (so the value must be the
+        # same in both methods)
+        conanfile = textwrap.dedent('''
+            from conan import ConanFile
+            from conan.tools.files import save, load
+
+            class ConanLib(ConanFile):
+                
+                def layout(self):
+                    self.folders.root = ".."
+                    self.folders.source = "src"
+                
+                def source(self):
+                    self.output.info(f"In the source() method the Source folder is: {self.source_folder}")
+                    save(self, "source_file.c", "conent")
+
+                def build(self):
+                    self.output.info(f"In the build() method the Source folder is: {self.source_folder}")
+                    load(self, f"{self.source_folder}/source_file.c")
+            ''')
+        client = TestClient(light=True)
+        client.save({CONANFILE: conanfile})
+        
+        client.run("source .")
+        # The build method will fail if source() and build() don't 
+        # both use the correct source_folder
+        client.run("build .")
+        assert "conanfile.py: Calling build()" in client.out  # doesn't fail
+
     def test_retrieve_exports_sources(self):
         # For Conan 2.0 if we install a package from a remote and we want to upload to other
         # remote we need to download the sources, as we consider revisions immutable, let's
diff --git a/test/integration/command/test_audit.py b/test/integration/command/test_audit.py
index 75d5dd19b..ca9433bfa 100644
--- a/test/integration/command/test_audit.py
+++ b/test/integration/command/test_audit.py
@@ -11,6 +11,48 @@ from conan.test.assets.genconanfile import GenConanfile
 from conan.test.utils.env import environment_update
 from conan.test.utils.tools import TestClient
 
+_sbom_zlib_1_2_11 = """
+{
+  "components" : [ {
+    "author" : "<Put your name here> <And your email here>",
+    "bom-ref" : "pkg:conan/zlib@1.2.11?rref=6754320047c5dd54830baaaf9fc733c4",
+    "description" : "<Description of zlib package here>",
+    "licenses" : [ {
+      "license" : {
+        "name" : "<Put the package license here>"
+      }
+    } ],
+    "name" : "zlib",
+    "purl" : "pkg:conan/zlib@1.2.11",
+    "type" : "library",
+    "version" : "1.2.11"
+  } ],
+  "dependencies" : [ {
+    "ref" : "pkg:conan/zlib@1.2.11?rref=6754320047c5dd54830baaaf9fc733c4"
+  } ],
+  "metadata" : {
+    "component" : {
+      "author" : "<Put your name here> <And your email here>",
+      "bom-ref" : "pkg:conan/zlib@1.2.11?rref=6754320047c5dd54830baaaf9fc733c4",
+      "name" : "zlib/1.2.11",
+      "type" : "library"
+    },
+    "timestamp" : "2025-06-10T08:13:11Z",
+    "tools" : [ {
+      "externalReferences" : [ {
+        "type" : "website",
+        "url" : "https://github.com/conan-io/conan"
+      } ],
+      "name" : "Conan-io"
+    } ]
+  },
+  "serialNumber" : "urn:uuid:4f7ce240-4c6d-4a87-bfb6-78d0fbc839e3",
+  "bomFormat" : "CycloneDX",
+  "specVersion" : "1.4",
+  "version" : 1
+}
+"""
+
 
 @contextmanager
 def proxy_response(status, data, retry_after=60):
@@ -63,10 +105,14 @@ def test_conan_audit_proxy():
         "error": None
     }
 
-    tc = TestClient(light=True)
+    tc = TestClient(light=True, default_server_user=True)
 
-    tc.save({"conanfile.py": GenConanfile("zlib", "1.2.11")})
-    tc.run("export .")
+    tc.save({"conanfile.py": GenConanfile("zlib", "1.2.11"),
+             "sbom.cdx.json": _sbom_zlib_1_2_11})
+    tc.run("create . --lockfile-out=conan.lock")
+    tc.run("upload * -c -r=default")
+
+    tc.run("list * -r=default -f=json", redirect_stdout="pkglist_remote.json")
 
     tc.run("list '*' -f=json", redirect_stdout="pkglist.json")
 
@@ -82,6 +128,15 @@ def test_conan_audit_proxy():
         tc.run("audit list -l=pkglist.json")
         assert "zlib/1.2.11 1 vulnerability found" in tc.out
 
+        tc.run("audit list -l=pkglist_remote.json -r=default")
+        assert "zlib/1.2.11 1 vulnerability found" in tc.out
+
+        tc.run("audit list --lockfile=conan.lock")
+        assert "zlib/1.2.11 1 vulnerability found" in tc.out
+
+        tc.run("audit list --sbom=sbom.cdx.json")
+        assert "zlib/1.2.11 1 vulnerability found" in tc.out
+
         tc.run("audit scan --requires=zlib/1.2.11")
         assert "zlib/1.2.11 1 vulnerability found" in tc.out
 
@@ -175,8 +230,9 @@ def test_conan_audit_private():
 
     tc = TestClient(light=True)
 
-    tc.save({"conanfile.py": GenConanfile("zlib", "1.2.11")})
-    tc.run("export .")
+    tc.save({"conanfile.py": GenConanfile("zlib", "1.2.11"),
+             "sbom.cdx.json": _sbom_zlib_1_2_11})
+    tc.run("create . --lockfile-out=conan.lock")
 
     tc.run("list '*' -f=json", redirect_stdout="pkglist.json")
 
@@ -199,6 +255,12 @@ def test_conan_audit_private():
         tc.run("audit list -l=pkglist.json -p=myprivate")
         assert "zlib/1.2.11 1 vulnerability found" in tc.out
 
+        tc.run("audit list --lockfile=conan.lock -p=myprivate")
+        assert "zlib/1.2.11 1 vulnerability found" in tc.out
+
+        tc.run("audit list --sbom=sbom.cdx.json -p=myprivate")
+        assert "zlib/1.2.11 1 vulnerability found" in tc.out
+
         tc.run("audit scan --requires=zlib/1.2.11  -p=myprivate")
         assert "zlib/1.2.11 1 vulnerability found" in tc.out
 
@@ -248,7 +310,7 @@ def test_audit_list_conflicting_args():
     tc = TestClient(light=True)
     tc.save({"pkglist.json": '{"Local Cache": {"zlib/1.2.11": {}}}'})
     tc.run("audit list zlib/1.2.11 -l=pkglist.json", assert_error=True)
-    assert "Please specify a reference or a pkglist file, not both" in tc.out
+    assert "argument -l/--list: not allowed with argument reference" in tc.out
 
 
 def test_audit_provider_add_missing_url():
@@ -266,7 +328,7 @@ def test_audit_provider_remove_nonexistent():
 def test_audit_list_missing_arguments():
     tc = TestClient(light=True)
     tc.run("audit list", assert_error=True)
-    assert "Please specify a reference or a pkglist file" in tc.out
+    assert "one of the arguments reference" in tc.out
 
 
 def test_audit_provider_env_credentials_with_proxy(monkeypatch):
diff --git a/test/integration/command/test_output.py b/test/integration/command/test_output.py
index 52a6b9603..bd383905f 100644
--- a/test/integration/command/test_output.py
+++ b/test/integration/command/test_output.py
@@ -1,6 +1,8 @@
 import json
+import os
 
 from conan.test.assets.genconanfile import GenConanfile
+from conan.test.utils.test_files import temp_folder
 from conan.test.utils.tools import TestClient
 from conan.test.utils.env import environment_update
 
@@ -291,3 +293,18 @@ def test_formatter_redirection_to_file():
     graph = json.loads(c.load("graph.json"))
     assert len(graph["graph"]["nodes"]) == 1
     assert not "nodes" in c.stdout
+
+
+def test_redirect_to_file_create_dir():
+    c = TestClient(light=True)
+    c.save({"conanfile.py": GenConanfile("pkg", "0.1")})
+    c.run("config home --out-file=subdir/cmd_out.txt")
+    cmd_out = c.load("subdir/cmd_out.txt")
+    assert f"{c.cache_folder}" in cmd_out
+
+    base = temp_folder()
+    c = TestClient(light=True, current_folder=os.path.join(base, "sub1"))
+    c.save({"conanfile.py": GenConanfile("pkg", "0.1")})
+    c.run("config home --out-file=../subdir/cmd_out.txt")
+    cmd_out = c.load("../subdir/cmd_out.txt")
+    assert f"{c.cache_folder}" in cmd_out
diff --git a/test/integration/command/upload/upload_test.py b/test/integration/command/upload/upload_test.py
index 633682087..45e64ebe3 100644
--- a/test/integration/command/upload/upload_test.py
+++ b/test/integration/command/upload/upload_test.py
@@ -571,7 +571,7 @@ def test_upload_json_output():
     }
 
 
-def test_upload_dry_run_json_output():
+def test_upload_dry_run_output():
     c = TestClient(default_server_user=True)
     c.save({"conanfile.py": GenConanfile("liba", "0.1").with_settings("os")
                                                        .with_shared_option(False)})
@@ -606,3 +606,9 @@ def test_upload_dry_run_json_output():
             "checksum": sha1sum(prev["files"]["conanmanifest.txt"])
         }
     }
+
+    # check we don't have anything about the upload-urls in the text formatter
+    c.run("upload * -r=default -c --dry-run")
+    assert "upload-urls" not in c.stdout
+    assert "url:" not in c.stdout
+    assert "checksum:" not in c.stdout
diff --git a/test/integration/editable/test_editable_layout.py b/test/integration/editable/test_editable_layout.py
index 8c5321390..1f9beefd2 100644
--- a/test/integration/editable/test_editable_layout.py
+++ b/test/integration/editable/test_editable_layout.py
@@ -40,7 +40,7 @@ def test_editable_folders_root():
             "conanfile.py": app})
 
     c.run("editable add libs/pkg")
-    c.run("install .")
+    c.run("install . --build=editable")
     libdir = os.path.join(c.current_folder, "libs", "mybuild", "mylibdir")
     assert f"conanfile.py: PKG LIBDIR {libdir}" in c.out
     assert f"pkg/0.1: PKG package_folder {c.current_folder}" in c.out
@@ -82,7 +82,7 @@ def test_editable_folders_sibiling_root():
             "app/conanfile.py": app})
 
     c.run("editable add pkg")
-    c.run("install app")
+    c.run("install app --build=editable")
     libdir = os.path.join(c.current_folder, "mybuild", "mylibdir")
     assert f"conanfile.py: PKG LIBDIR {libdir}" in c.out
     assert f"pkg/0.1: PKG source_folder {c.current_folder}" in c.out
@@ -145,6 +145,6 @@ def test_install_editable_build_folder_vars():
             "profile": profile})
     c.run("editable add lib")
     c.run("build lib -pr=profile")
-    c.run("install app -pr=profile")
+    c.run("install app -pr=profile --build=editable")
     path = os.path.join(c.current_folder, "lib", "build", "windows-x86_64", "Release", "generators")
     assert f"lib/0.1: Writing generators to {path}" in c.out
diff --git a/test/integration/remote/test_local_recipes_index.py b/test/integration/remote/test_local_recipes_index.py
index 9ce0f3122..96d803e7a 100644
--- a/test/integration/remote/test_local_recipes_index.py
+++ b/test/integration/remote/test_local_recipes_index.py
@@ -391,6 +391,16 @@ class TestErrorsUx:
         c.run("install --requires=zlib/0.1@myuser/mychannel")
         c.assert_listed_require({"zlib/0.1@myuser/mychannel": "Downloaded (default)"})
 
+    def test_errors_missing_folder(self):
+        folder = temp_folder()
+        repo = os.path.join(folder, "repo")
+        mkdir(repo)
+        c = TestClient(light=True)
+        c.run(f"remote add local '{repo}'")
+        # shutil.rmtree(repo)
+        c.run("install --requires=zlib/[*] --build missing", assert_error=True)
+        assert "Cannot connect to 'local-recipes-index' repository, missing 'recipes'" in c.out
+
 
 class TestPythonRequires:
     @pytest.fixture(scope="class")
@@ -467,3 +477,78 @@ class TestUserChannel:
 
         tc.run(f"graph info --requires=pkg/[<2]", assert_error=True)
         assert f" Package 'pkg/[<2]' not resolved" in tc.out
+
+
+class TestResetRemote:
+    def test_resetting_remote_error(self):
+        # https://github.com/conan-io/conan/issues/18371
+        folder = temp_folder()
+        recipes_folder = os.path.join(folder, "recipes")
+        zlib_config = textwrap.dedent("""
+            versions:
+              "1.2.11":
+                folder: all
+            """)
+        zlib = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.files import load
+            class Zlib(ConanFile):
+                name = "zlib"
+                exports_sources = "*"
+                """)
+        save_files(recipes_folder,
+                   {"zlib/config.yml": zlib_config,
+                    "zlib/all/conanfile.py": zlib,
+                    "zlib/all/conandata.yml": "",
+                    "zlib/all/file.h": "//myheader"})
+
+        client = TestClient(light=True)
+        client.run(f"remote add local '{folder}'")
+        client.run("graph info --requires=zlib/[*]")
+
+        # This second --force destroys the previous remote database
+        client.run(f"remote add local '{folder}' --force")
+        client.run("install --requires=zlib/[*] --build=missing")
+        # It doesn't fail or crash anymore
+
+    def test_changing_revisions(self):
+        # https://github.com/conan-io/conan/issues/18371
+        folder = temp_folder()
+        recipes_folder = os.path.join(folder, "recipes")
+        zlib_config = textwrap.dedent("""
+            versions:
+              "1.2.11":
+                folder: all
+            """)
+        zlib = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.files import load
+            class Zlib(ConanFile):
+                name = "zlib"
+                exports_sources = "*"
+                def build(self):
+                    self.output.info(f"BUILDING: {load(self, 'file.h')}")
+            """)
+        save_files(recipes_folder,
+                   {"zlib/config.yml": zlib_config,
+                    "zlib/all/conanfile.py": zlib,
+                    "zlib/all/conandata.yml": "",
+                    "zlib/all/file.h": "//myheader"})
+
+        c = TestClient(light=True)
+        c.run(f"remote add local '{folder}'")
+        c.run("graph info --requires=zlib/[*]")
+        rev1 = "bd69839cb4c933336fceb32302aaf91f"
+
+        # Modify zlib code
+        save_files(recipes_folder, {"zlib/all/file.h": "//myheader 222"})
+        c.run("graph info --requires=zlib/[*] --update")
+        rev2 = "c912566276abca17d2fb5fb6fc957852"
+
+        c.run(f"remote add local '{folder}' --force")
+        c.run(f"install --requires=zlib/1.2.11#{rev2} --build=missing")  # works
+        c.run(f"install --requires=zlib/1.2.11#{rev1} --build=missing", assert_error=True)
+        assert ("WARN: A specific revision 'zlib/1.2.11#bd69839cb4c933336fceb32302aaf91f' was "
+                "requested, but it doesn't match the current available revision in source") in c.out
+        assert ("ERROR: The 'zlib/1.2.11' package has 'exports_sources' but sources "
+                "not found in local cache") in c.out
diff --git a/test/integration/test_package_vendor.py b/test/integration/test_package_vendor.py
index 08c3e4c35..b0cfe7b34 100644
--- a/test/integration/test_package_vendor.py
+++ b/test/integration/test_package_vendor.py
@@ -109,7 +109,7 @@ def test_package_vendor_editable():
             })
     c.run("create pkga")
     c.run("editable add pkgb")
-    c.run("install app -s os=Linux")
+    c.run("install app -s os=Linux --build=editable")
     assert "pkga" in c.out
     # The environment file of "app" doesn't have any visibility of the "pkga" paths
     envfile_app = c.load("app/conanrunenv.sh")
diff --git a/test/integration/toolchains/cmake/cmakedeps2/test_cmakedeps.py b/test/integration/toolchains/cmake/cmakedeps2/test_cmakedeps.py
index 30228b704..6639dc44f 100644
--- a/test/integration/toolchains/cmake/cmakedeps2/test_cmakedeps.py
+++ b/test/integration/toolchains/cmake/cmakedeps2/test_cmakedeps.py
@@ -234,7 +234,8 @@ def test_system_wrappers():
           f"-c tools.cmake.cmakedeps:new={new_value}")
     cmake = c.load("lib-Targets-release.cmake")
     assert "add_library(lib::lib INTERFACE IMPORTED)" in cmake
-    assert "target_link_libraries(lib::lib INTERFACE my_system_cool_lib)" in cmake
+    assert "set_property(TARGET lib::lib APPEND PROPERTY INTERFACE_LINK_LIBRARIES\n" \
+           '             $<$<CONFIG:RELEASE>:my_system_cool_lib>)' in cmake
 
 
 def test_autolink_pragma():
diff --git a/test/integration/toolchains/cmake/test_cmaketoolchain.py b/test/integration/toolchains/cmake/test_cmaketoolchain.py
index 70b27bf9a..bbd6931d5 100644
--- a/test/integration/toolchains/cmake/test_cmaketoolchain.py
+++ b/test/integration/toolchains/cmake/test_cmaketoolchain.py
@@ -887,24 +887,25 @@ def test_android_legacy_toolchain_with_compileflags(cmake_legacy_toolchain):
 @pytest.mark.skipif(platform.system() != "Windows", reason="Only Windows")
 def test_presets_paths_normalization():
     # https://github.com/conan-io/conan/issues/11795
+    # But then also https://github.com/conan-io/conan/issues/18434
     client = TestClient()
     conanfile = textwrap.dedent("""
-            from conan import ConanFile
-            from conan.tools.cmake import cmake_layout
+        from conan import ConanFile
+        from conan.tools.cmake import cmake_layout
 
-            class Conan(ConanFile):
-                settings = "os", "arch", "compiler", "build_type"
-                generators = "CMakeToolchain"
+        class Conan(ConanFile):
+            settings = "os", "arch", "compiler", "build_type"
+            generators = "CMakeToolchain"
 
-                def layout(self):
-                    cmake_layout(self)
-            """)
+            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"]
+    assert "/" in presets["include"][0]
+    assert "\\" not in presets["include"][0]
 
 
 @pytest.mark.parametrize("arch, arch_toolset", [("x86", "x86_64"), ("x86_64", "x86_64"),
@@ -1115,7 +1116,7 @@ def test_build_folder_vars_editables():
     c.run("editable add dep")
     conf = "tools.cmake.cmake_layout:build_folder_vars='[\"settings.os\", \"settings.build_type\"]'"
     settings = " -s os=FreeBSD -s arch=armv8 -s build_type=Debug"
-    c.run("install app -c={} {}".format(conf, settings))
+    c.run("install app -c={} {} --build=editable".format(conf, settings))
     assert os.path.exists(os.path.join(c.current_folder, "dep", "build", "freebsd-debug"))
 
 
diff --git a/test/integration/toolchains/google/test_bazeldeps.py b/test/integration/toolchains/google/test_bazeldeps.py
index 843174fa8..d243b34cd 100644
--- a/test/integration/toolchains/google/test_bazeldeps.py
+++ b/test/integration/toolchains/google/test_bazeldeps.py
@@ -644,7 +644,7 @@ def test_with_editable_layout():
         # Bazel 7.x
         content = client.load("conan_deps_module_extension.bzl")
         assert textwrap.dedent(f"""\
-        def _load_dependenies_impl(mctx):
+        def _load_dependencies_impl(mctx):
             conan_dependency_repo(
                 name = "dep",
                 package_path = "{recipes_folder}/dep",
diff --git a/test/performance/.gitignore b/test/performance/.gitignore
new file mode 100644
index 000000000..e934adfd1
--- /dev/null
+++ b/test/performance/.gitignore
@@ -0,0 +1,1 @@
+cache/
diff --git a/test/performance/test_large_graph.py b/test/performance/test_large_graph.py
index 8ccc0fed9..866bdbd6a 100644
--- a/test/performance/test_large_graph.py
+++ b/test/performance/test_large_graph.py
@@ -1,5 +1,5 @@
 import cProfile
-import json
+import os
 import pstats
 import time
 from pstats import SortKey
@@ -11,7 +11,7 @@ from conan.test.utils.tools import TestClient
 
 @pytest.mark.skip(reason="This is a performance test, skip for normal runs")
 def test_large_graph():
-    c = TestClient(cache_folder="T:/mycache")
+    c = TestClient(cache_folder=os.path.join(os.path.dirname(__file__), "cache"))
     num_test = 40
     num_pkgs = 40
 
@@ -47,7 +47,7 @@ def test_large_graph():
 
 @pytest.mark.skip(reason="This is a performance test, skip for normal runs")
 def test_large_graph2():
-    c = TestClient(cache_folder="T:/mycache")
+    c = TestClient(cache_folder=os.path.join(os.path.dirname(__file__), "cache"))
     num_test = 20
     num_pkgs = 20
     branches = ["a", "b", "c"]
diff --git a/test/unittests/client/conf/detect/test_gcc_compiler.py b/test/unittests/client/conf/detect/test_gcc_compiler.py
index b7059c600..ae961c6c0 100644
--- a/test/unittests/client/conf/detect/test_gcc_compiler.py
+++ b/test/unittests/client/conf/detect/test_gcc_compiler.py
@@ -1,19 +1,14 @@
-import unittest
 
 import mock
-from parameterized import parameterized
-
+import pytest
 
 from conan.internal.api.detect.detect_api import detect_gcc_compiler
 
-
-class GCCCompilerTestCase(unittest.TestCase):
-
-    @parameterized.expand([("10",), ("4.2",), ('7', )])
-    def test_detect_gcc_10(self, version):
-        with mock.patch("platform.system", return_value="Linux"):
-            with mock.patch("conan.internal.api.detect.detect_api.detect_runner", return_value=(0, version)):
-                compiler, installed_version, compiler_exe = detect_gcc_compiler()
-        self.assertEqual(compiler, 'gcc')
-        self.assertEqual(installed_version, version)
-        self.assertEqual(compiler_exe, 'gcc')
+@pytest.mark.parametrize("version", ["10", "4.2", '7', "8.12"])
+def test_detect_gcc_10(version):
+    with mock.patch("platform.system", return_value="Linux"):
+        with mock.patch("conan.internal.api.detect.detect_api.detect_runner", return_value=(0, version)):
+            compiler, installed_version, compiler_exe = detect_gcc_compiler()
+    assert compiler == 'gcc'
+    assert installed_version == version
+    assert compiler_exe == 'gcc'
diff --git a/test/unittests/model/build_info/test_deduce_locations.py b/test/unittests/model/build_info/test_deduce_locations.py
index 0968bea84..03cbbc244 100644
--- a/test/unittests/model/build_info/test_deduce_locations.py
+++ b/test/unittests/model/build_info/test_deduce_locations.py
@@ -288,3 +288,14 @@ def test_several_libs_and_exact_match(lib_name, libs, conanfile):
     result = cppinfo.deduce_full_cpp_info(conanfile)
     assert result.location == f"{folder}/libdir/{lib_name}.lib"
     assert result.type == "static-library"
+
+
+def test_sources(conanfile):
+    folder = temp_folder()
+    save(os.path.join(folder, "src", "mylib.cpp"), "")
+    cppinfo = CppInfo()
+    cppinfo.sources = ["src/mylib.cpp"]
+    cppinfo.set_relative_base_folder(folder)
+    result = cppinfo.deduce_full_cpp_info(conanfile)
+    assert result.location is None
+    assert result.type == "header-library"
diff --git a/test/unittests/tools/cmake/test_cmake_install.py b/test/unittests/tools/cmake/test_cmake_install.py
index d6bf9fa6c..9b7f51bba 100644
--- a/test/unittests/tools/cmake/test_cmake_install.py
+++ b/test/unittests/tools/cmake/test_cmake_install.py
@@ -1,10 +1,14 @@
+import pytest
+
 from conan.internal.default_settings import default_settings_yml
 from conan.tools.cmake import CMake
 from conan.tools.cmake.presets import write_cmake_presets
 from conan.internal.model.conf import Conf
 from conan.internal.model.settings import Settings
-from conan.test.utils.mocks import ConanFileMock
+from conan.test.utils.mocks import ConanFileMock, RedirectedTestOutput
 from conan.test.utils.test_files import temp_folder
+from conan.test.utils.tools import redirect_output
+
 
 
 def test_run_install_component():
@@ -36,7 +40,10 @@ def test_run_install_component():
     assert "--component foo" in conanfile.command
 
 
-def test_run_install_strip():
+@pytest.mark.parametrize("config, deprecated",
+                         [("tools.cmake:install_strip", True),
+                          ("tools.build:install_strip", False),])
+def test_run_install_strip(config, deprecated):
     """
     Testing that the install/strip rule is called
     Issue related: https://github.com/conan-io/conan/issues/14166
@@ -52,7 +59,7 @@ def test_run_install_strip():
     conanfile = ConanFileMock()
 
     conanfile.conf = Conf()
-    conanfile.conf.define("tools.cmake:install_strip", True)
+    conanfile.conf.define(config, True)
 
     conanfile.folders.generators = "."
     conanfile.folders.set_base_generators(temp_folder())
@@ -61,10 +68,18 @@ def test_run_install_strip():
 
     write_cmake_presets(conanfile, "toolchain", "Unix Makefiles", {})
     cmake = CMake(conanfile)
-    cmake.install()
+    stdout = RedirectedTestOutput()  # Initialize each command
+    stderr = RedirectedTestOutput()
+    with redirect_output(stderr, stdout):
+        cmake.install(stdout=stdout, stderr=stderr)
+
+    if deprecated:
+        assert "WARN: deprecated: The 'tools.cmake:install_strip' configuration is deprecated, use"\
+               " 'tools.build:install_strip' instead" in stderr
+    else:
+        assert "tools.cmake:install_strip" not in stderr
     assert "--strip" in conanfile.command
 
-
 def test_run_install_cli_args():
     """
     Testing that the passing cli_args to install works
diff --git a/test/unittests/tools/gnu/test_triplets.py b/test/unittests/tools/gnu/test_triplets.py
index 626479576..5a8998ea5 100644
--- a/test/unittests/tools/gnu/test_triplets.py
+++ b/test/unittests/tools/gnu/test_triplets.py
@@ -51,6 +51,7 @@ from conan.errors import ConanException
     ["tvOS", "x86_64", None, "x86_64-apple-tvos"],
     ["Emscripten", "asm.js", None, "asmjs-local-emscripten"],
     ["Emscripten", "wasm", None, "wasm32-local-emscripten"],
+    ["Emscripten", "wasm64", None, "wasm64-local-emscripten"],
     ["AIX", "ppc32", None, "rs6000-ibm-aix"],
     ["AIX", "ppc64", None, "powerpc-ibm-aix"],
     ["Neutrino", "armv7", None, "arm-nto-qnx"],
diff --git a/test/unittests/tools/meson/test_meson.py b/test/unittests/tools/meson/test_meson.py
index 8954d2bf3..7b4bc800e 100644
--- a/test/unittests/tools/meson/test_meson.py
+++ b/test/unittests/tools/meson/test_meson.py
@@ -5,6 +5,7 @@ import pytest
 from conan.tools.meson import Meson
 from conan.internal.model.conf import ConfDefinition
 from conan.test.utils.mocks import ConanFileMock, MockSettings
+from conan.test.utils.test_files import temp_folder
 from conan.tools.meson.helpers import get_apple_subsystem, to_cstd_flag, to_cppstd_flag
 
 
@@ -64,3 +65,28 @@ def test_meson_to_cstd_flag(cstd, expected):
 ])
 def test_meson_to_cppstd_flag(compiler, compiler_version, cppstd, expected):
     assert to_cppstd_flag(compiler, compiler_version, cppstd) == expected
+
+
+def test_meson_install_strip():
+    """When the configuration `tools.build:install_strip` is set to True,
+        the Meson install command should include the `--strip` option.
+    """
+    c = ConfDefinition()
+    c.loads("tools.build:install_strip=True")
+
+    settings = MockSettings({"build_type": "Release",
+                             "compiler": "gcc",
+                             "compiler.version": "7",
+                             "os": "Linux",
+                             "arch": "x86_64"})
+    conanfile = ConanFileMock()
+    conanfile.settings = settings
+    conanfile.conf = c.get_conanfile_conf(None)
+    conanfile.folders.generators = "."
+    conanfile.folders.set_base_generators(temp_folder())
+    conanfile.folders.set_base_package(temp_folder())
+
+    meson = Meson(conanfile)
+    meson.install()
+
+    assert '--strip' in str(conanfile.command)
diff --git a/test/unittests/util/detect_test.py b/test/unittests/util/detect_test.py
index 51df4cfe9..84f7cf3e2 100644
--- a/test/unittests/util/detect_test.py
+++ b/test/unittests/util/detect_test.py
@@ -65,6 +65,9 @@ class DetectTest(unittest.TestCase):
 @pytest.mark.parametrize("version_return,expected_version", [
     ["cc.exe (Rev3, Built by MSYS2 project) 14.1.0", "14.1.0"],
     ["g++ (Conan-Build-gcc--binutils-2.42) 14.1.0", "14.1.0"],
+    ["gcc.exe (x86_64-posix-seh-rev0, Built by MinGW-Builds project) 15.1.0", "15.1.0"],
+    ["gcc.exe (x86_64-posix-seh-rev0, Built by MinGW-Builds project) 15.15.0", "15.15.0"],
+    ["gcc (GCC) 4.8.1", "4.8.1"],
     ["clang version 18.1.0rc (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18.1.0"],
     ["cc.exe (Rev3, Built by MSYS2 project) 14.0", "14.0"],
     ["clang version 18 (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)", "18"],
@@ -74,6 +77,8 @@ class DetectTest(unittest.TestCase):
 def test_detect_cc_versionings(detect_runner_mock, version_return, expected_version):
     detect_runner_mock.return_value = 0, version_return
     compiler, installed_version, compiler_exe = _cc_compiler()
+    # Using private _value attribute to compare the str that reaches it, so no space issues arise
+    assert installed_version._value == Version(expected_version)._value
     assert installed_version == Version(expected_version)
 
 @pytest.mark.parametrize("function,version_return,expected_version", [