Repository: conan-io/conan

Issue:
[question] Compatibility with bazel 7.0
Hi! I have a question regarding the compatibility of `conan` with `bazel`. I tried to make my first steps following [this guide](https://docs.conan.io/2/examples/tools/google/bazeltoolchain/build_simple_bazel_project.html#examples-tools-bazel-toolchain-build-simple-bazel-project), which works fine for `bazel 6.2.0`, but fails for me using `bazel 7.0.0` at the build step with the following error message:
```
❯ bazel --bazelrc=./conan/conan_bzl.rc build --config=conan-config //main:demo
Extracting Bazel installation...
Starting local Bazel server and connecting to it...
WARNING: --enable_bzlmod is set, but no MODULE.bazel file was found at the workspace root. Bazel will create an empty MODULE.bazel file. Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel. For more details, please refer to https://github.com/bazelbuild/bazel/issues/18958.
ERROR: /tmp/examples2/examples/tools/google/bazeltoolchain/string_formatter/WORKSPACE:2:24: //external:fmt: invalid label '/tmp/examples2/examples/tools/google/bazeltoolchain/string_formatter/conan/fmt/BUILD.bazel' in attribute 'build_file' in 'new_local_repository' rule: invalid target name '/tmp/examples2/examples/tools/google/bazeltoolchain/string_formatter/conan/fmt/BUILD.bazel': target names may not start with '/'
WARNING: Target pattern parsing failed.
ERROR: Skipping '//main:demo': error loading package 'main': Encountered error while reading extension file 'cc/defs.bzl': no such package '@@rules_cc//cc': error loading package 'external': Could not load //external package
ERROR: error loading package 'main': Encountered error while reading extension file 'cc/defs.bzl': no such package '@@rules_cc//cc': error loading package 'external': Could not load //external package
INFO: Elapsed time: 4.572s
INFO: 0 processes.
ERROR: Build did NOT complete successfully
```

Getting rid of the warning by passing `--noenable_bzlmod` does not solve the errors and I have now two questions:

* Is is possible (or planned) to support the `bzlmod` mode of `bazel` within the generated files? As it is the new default it looks worthwhile to me.
* How to get rid of the error? Are some adaptions within the generated files necessary? Or do you think it is also in the long-term favorable to have some special configuration for `bazel` (which I don't know, yet...)?

For both it would be great, depending on your preferred solution, to update the linked guide above.

Thanks in advance!

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide
[feature] Add Bazel 7.x support
### What is your suggestion?

Conan is not working with Bazel 7.x for now. Figure out the needed changes to make it work with Bazel 6.x, and 7.x.

### Have you read the CONTRIBUTING guide?

- [ ] I've read the CONTRIBUTING guide


Discussion:
Hi @marlamb 

Thanks for your question.
Yes, it is true that the current integration is designed for Bazel 6, and does not support yet Bazel 7.
I think we will want to support it at some point, but I am assigning @franramirez688 for feedback, estimation of what would need to be done, etc.
Hi @marlamb 

Thanks for the question. I am so glad to see you involved in testing the BazelDeps generator 👏 

I just tried the Bazel hello-world example (https://bazel.build/start/cpp), and it's not working for Bazel v7.0.0 yet. IMO, I think it's worth waiting for those Bazel examples to be updated to see the changes we should make in the `conan new` templates before trying anything else.

Anyway, do you have any other Hello-World example working with Bazel 7.0.0?
Hi @franramirez688 

Unfortunately I don't have further examples. I am completely new to `bazel` and therefore just out of ignorance chose the newest version to start with. I am totally fine with waiting a little until it becomes clearer how the new version should be handled. Until then I will learn it with version 6. I am looking forward to your future developments and will try out version 7 as soon as I see that `conan` supports it as well :smiley: .





Patch:
diff --git a/conan/api/subapi/new.py b/conan/api/subapi/new.py
index 573ce75d49d..a0cde2d20c6 100644
--- a/conan/api/subapi/new.py
+++ b/conan/api/subapi/new.py
@@ -26,6 +26,8 @@ def get_builtin_template(template_name):
         from conan.internal.api.new.msbuild_exe import msbuild_exe_files
         from conan.internal.api.new.bazel_lib import bazel_lib_files
         from conan.internal.api.new.bazel_exe import bazel_exe_files
+        from conan.internal.api.new.bazel_7_lib import bazel_lib_files_7
+        from conan.internal.api.new.bazel_7_exe import bazel_exe_files_7
         from conan.internal.api.new.autotools_lib import autotools_lib_files
         from conan.internal.api.new.autoools_exe import autotools_exe_files
         from conan.internal.api.new.local_recipes_index import local_recipes_index_files
@@ -36,8 +38,11 @@ def get_builtin_template(template_name):
                          "meson_exe": meson_exe_files,
                          "msbuild_lib": msbuild_lib_files,
                          "msbuild_exe": msbuild_exe_files,
+                         # TODO: Rename xxx_7 to xxx when dropped Bazel 6.x compatibility
                          "bazel_lib": bazel_lib_files,
                          "bazel_exe": bazel_exe_files,
+                         "bazel_7_lib": bazel_lib_files_7,
+                         "bazel_7_exe": bazel_exe_files_7,
                          "autotools_lib": autotools_lib_files,
                          "autotools_exe": autotools_exe_files,
                          "alias": alias_file,
diff --git a/conan/internal/api/new/bazel_7_exe.py b/conan/internal/api/new/bazel_7_exe.py
new file mode 100644
index 00000000000..570482a1d65
--- /dev/null
+++ b/conan/internal/api/new/bazel_7_exe.py
@@ -0,0 +1,70 @@
+from conan.internal.api.new.cmake_lib import source_cpp, source_h, test_main
+
+
+conanfile_exe = """
+import os
+from conan import ConanFile
+from conan.tools.google import Bazel, bazel_layout
+from conan.tools.files import copy
+
+
+class {{package_name}}Recipe(ConanFile):
+    name = "{{name}}"
+    version = "{{version}}"
+    package_type = "application"
+
+    # Binary configuration
+    settings = "os", "compiler", "build_type", "arch"
+
+    # Sources are located in the same place as this recipe, copy them to the recipe
+    exports_sources = "main/*", "MODULE.bazel"
+
+    generators = "BazelToolchain"
+
+    def layout(self):
+        bazel_layout(self)
+
+    def build(self):
+        bazel = Bazel(self)
+        bazel.build(target="//main:{{name}}")
+
+    def package(self):
+        dest_bin = os.path.join(self.package_folder, "bin")
+        build = os.path.join(self.build_folder, "bazel-bin", "main")
+        copy(self, "{{name}}", build, dest_bin, keep_path=False)
+        copy(self, "{{name}}.exe", build, dest_bin, keep_path=False)
+        """
+
+test_conanfile_exe_v2 = """from conan import ConanFile
+from conan.tools.build import can_run
+
+
+class {{package_name}}Test(ConanFile):
+    settings = "os", "compiler", "build_type", "arch"
+
+    def requirements(self):
+        self.requires(self.tested_reference_str)
+
+    def test(self):
+        if can_run(self):
+            self.run("{{name}}", env="conanrun")
+"""
+
+_bazel_build_exe = """\
+cc_binary(
+    name = "{{name}}",
+    srcs = ["main.cpp", "{{name}}.cpp", "{{name}}.h"]
+)
+"""
+
+_bazel_workspace = " "  # Important not empty, so template doesn't discard it
+
+
+bazel_exe_files_7 = {"conanfile.py": conanfile_exe,
+                     "main/{{name}}.cpp": source_cpp,
+                     "main/{{name}}.h": source_h,
+                     "main/main.cpp": test_main,
+                     "main/BUILD": _bazel_build_exe,
+                     "MODULE.bazel": _bazel_workspace,
+                     "test_package/conanfile.py": test_conanfile_exe_v2
+                   }
diff --git a/conan/internal/api/new/bazel_7_lib.py b/conan/internal/api/new/bazel_7_lib.py
new file mode 100644
index 00000000000..024a0f23e8c
--- /dev/null
+++ b/conan/internal/api/new/bazel_7_lib.py
@@ -0,0 +1,142 @@
+from conan.internal.api.new.cmake_lib import source_cpp, source_h, test_main
+
+conanfile_sources_v2 = """
+import os
+from conan import ConanFile
+from conan.tools.google import Bazel, bazel_layout
+from conan.tools.files import copy
+
+class {{package_name}}Recipe(ConanFile):
+    name = "{{name}}"
+    version = "{{version}}"
+    package_type = "library"
+
+    # Binary configuration
+    settings = "os", "compiler", "build_type", "arch"
+    options = {"shared": [True, False], "fPIC": [True, False]}
+    default_options = {"shared": False, "fPIC": True}
+
+    # Sources are located in the same place as this recipe, copy them to the recipe
+    exports_sources = "main/*", "MODULE.bazel"
+    generators = "BazelToolchain"
+
+    def config_options(self):
+        if self.settings.os == "Windows":
+            self.options.rm_safe("fPIC")
+
+    def configure(self):
+        if self.options.shared:
+            self.options.rm_safe("fPIC")
+
+    def layout(self):
+        bazel_layout(self)
+
+    def build(self):
+        bazel = Bazel(self)
+        # On Linux platforms, Bazel creates both shared and static libraries by default, and
+        # it is getting naming conflicts if we use the cc_shared_library rule
+        if self.options.shared and self.settings.os != "Linux":
+            # We need to add '--experimental_cc_shared_library' because the project uses
+            # cc_shared_library to create shared libraries
+            bazel.build(args=["--experimental_cc_shared_library"], target="//main:{{name}}_shared")
+        else:
+            bazel.build(target="//main:{{name}}")
+
+    def package(self):
+        dest_lib = os.path.join(self.package_folder, "lib")
+        dest_bin = os.path.join(self.package_folder, "bin")
+        build = os.path.join(self.build_folder, "bazel-bin", "main")
+        copy(self, "*.so", build, dest_lib, keep_path=False)
+        copy(self, "*.dll", build, dest_bin, keep_path=False)
+        copy(self, "*.dylib", build, dest_lib, keep_path=False)
+        copy(self, "*.a", build, dest_lib, keep_path=False)
+        copy(self, "*.lib", build, dest_lib, keep_path=False)
+        copy(self, "{{name}}.h", os.path.join(self.source_folder, "main"),
+             os.path.join(self.package_folder, "include"), keep_path=False)
+
+    def package_info(self):
+        if self.options.shared and self.settings.os != "Linux":
+            self.cpp_info.libs = ["{{name}}_shared"]
+        else:
+            self.cpp_info.libs = ["{{name}}"]
+"""
+
+
+test_conanfile_v2 = """import os
+from conan import ConanFile
+from conan.tools.google import Bazel, bazel_layout
+from conan.tools.build import can_run
+
+
+class {{package_name}}TestConan(ConanFile):
+    settings = "os", "compiler", "build_type", "arch"
+    generators = "BazelToolchain", "BazelDeps"
+
+    def requirements(self):
+        self.requires(self.tested_reference_str)
+
+    def build(self):
+        bazel = Bazel(self)
+        bazel.build(target="//main:example")
+
+    def layout(self):
+        bazel_layout(self)
+
+    def test(self):
+        if can_run(self):
+            cmd = os.path.join(self.cpp.build.bindir, "main", "example")
+            self.run(cmd, env="conanrun")
+"""
+
+
+_bazel_build_test = """\
+cc_binary(
+    name = "example",
+    srcs = ["example.cpp"],
+    deps = [
+        "@{{name}}//:{{name}}",
+    ],
+)
+"""
+
+_bazel_build = """\
+cc_library(
+    name = "{{name}}",
+    srcs = ["{{name}}.cpp"],
+    hdrs = ["{{name}}.h"],
+)
+"""
+
+_bazel_build_shared = """
+cc_shared_library(
+    name = "{{name}}_shared",
+    shared_lib_name = "lib{{name}}_shared.%s",
+    deps = [":{{name}}"],
+)
+"""
+
+_bazel_workspace = " "  # Important not empty, so template doesn't discard it
+_test_bazel_module_bazel = """\
+load_conan_dependencies = use_extension("//conan:conan_deps_module_extension.bzl", "conan_extension")
+use_repo(load_conan_dependencies, "{{name}}")
+"""
+
+
+def _get_bazel_build():
+    import platform
+    os_ = platform.system()
+    ret = _bazel_build
+    if os_ != "Linux":
+        ret += _bazel_build_shared % ("dylib" if os_ == "Darwin" else "dll")
+    return ret
+
+
+bazel_lib_files_7 = {"conanfile.py": conanfile_sources_v2,
+                     "main/{{name}}.cpp": source_cpp,
+                     "main/{{name}}.h": source_h,
+                     "main/BUILD": _get_bazel_build(),
+                     "MODULE.bazel": _bazel_workspace,
+                     "test_package/conanfile.py": test_conanfile_v2,
+                     "test_package/main/example.cpp": test_main,
+                     "test_package/main/BUILD": _bazel_build_test,
+                     "test_package/MODULE.bazel": _test_bazel_module_bazel}
diff --git a/conan/internal/api/new/bazel_exe.py b/conan/internal/api/new/bazel_exe.py
index e8e733110a4..a68271d8556 100644
--- a/conan/internal/api/new/bazel_exe.py
+++ b/conan/internal/api/new/bazel_exe.py
@@ -18,13 +18,16 @@ class {{package_name}}Recipe(ConanFile):
 
     # Sources are located in the same place as this recipe, copy them to the recipe
     exports_sources = "main/*", "WORKSPACE"
-
     generators = "BazelToolchain"
 
     def layout(self):
         bazel_layout(self)
 
     def build(self):
+        from conan.api.output import ConanOutput
+        ConanOutput().warning("This is the template for Bazel 6.x version, "
+                              "but it will be overridden by the 'bazel_7_exe' template "
+                              "(Bazel >= 7.1 compatible).", warn_tag="deprecated")
         bazel = Bazel(self)
         bazel.build(target="//main:{{name}}")
 
@@ -51,8 +54,6 @@ def test(self):
 """
 
 _bazel_build_exe = """\
-load("@rules_cc//cc:defs.bzl", "cc_binary")
-
 cc_binary(
     name = "{{name}}",
     srcs = ["main.cpp", "{{name}}.cpp", "{{name}}.h"]
diff --git a/conan/internal/api/new/bazel_lib.py b/conan/internal/api/new/bazel_lib.py
index 222dba65918..28328b20d97 100644
--- a/conan/internal/api/new/bazel_lib.py
+++ b/conan/internal/api/new/bazel_lib.py
@@ -32,6 +32,10 @@ def layout(self):
         bazel_layout(self)
 
     def build(self):
+        from conan.api.output import ConanOutput
+        ConanOutput().warning("This is the template for Bazel 6.x version, "
+                              "but it will be overridden by the 'bazel_7_lib' template "
+                              "(Bazel >= 7.1 compatible).", warn_tag="deprecated")
         bazel = Bazel(self)
         # On Linux platforms, Bazel creates both shared and static libraries by default, and
         # it is getting naming conflicts if we use the cc_shared_library rule
@@ -90,8 +94,6 @@ def test(self):
 
 
 _bazel_build_test = """\
-load("@rules_cc//cc:defs.bzl", "cc_binary")
-
 cc_binary(
     name = "example",
     srcs = ["example.cpp"],
@@ -102,8 +104,6 @@ def test(self):
 """
 
 _bazel_build = """\
-load("@rules_cc//cc:defs.bzl", "cc_library")
-
 cc_library(
     name = "{{name}}",
     srcs = ["{{name}}.cpp"],
diff --git a/conan/tools/google/bazel.py b/conan/tools/google/bazel.py
index baa5a5e8eb5..e0a8cbb4d9d 100644
--- a/conan/tools/google/bazel.py
+++ b/conan/tools/google/bazel.py
@@ -53,6 +53,8 @@ def build(self, args=None, target="//...", clean=True):
         # See more info in https://bazel.build/run/bazelrc
         bazelrc_paths.extend(self._conanfile.conf.get("tools.google.bazel:bazelrc_path", default=[],
                                                       check_type=list))
+        # Note: In case of error like this: ... https://bcr.bazel.build/: PKIX path building failed
+        # Check this comment: https://github.com/bazelbuild/bazel/issues/3915#issuecomment-1120894057
         command = "bazel"
         for rc in bazelrc_paths:
             rc = rc.replace("\\", "/")
diff --git a/conan/tools/google/bazeldeps.py b/conan/tools/google/bazeldeps.py
index b2d64f985c5..4cb213e8878 100644
--- a/conan/tools/google/bazeldeps.py
+++ b/conan/tools/google/bazeldeps.py
@@ -205,16 +205,22 @@ def _relativize_path(path, pattern):
 
 class _BazelDependenciesBZLGenerator:
     """
-    Bazel needs to know all the dependencies for its current project. So, the only way
+    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.
     """
 
-    filename = "dependencies.bzl"
-    template = textwrap.dedent("""\
+    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")
@@ -229,19 +235,95 @@ def load_conan_dependencies():
             )
         {% 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):
-        template = Template(self.template, trim_blocks=True, lstrip_blocks=True,
-                            undefined=StrictUndefined)
-        content = template.render(dependencies=self._dependencies)
-        # Saving the BUILD (empty) and dependencies.bzl files
-        save(self.filename, content)
-        save("BUILD.bazel", "# This is an empty BUILD file to be able to load the "
-                            "dependencies.bzl one.")
+        # 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 _BazelBUILDGenerator:
@@ -336,8 +418,6 @@ class _BazelBUILDGenerator:
     )
     {% endif %}
     {% endmacro %}
-    load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library")
-
     # Components precompiled libs
     {% for component in components %}
     {{ cc_import_macro(component["libs"]) }}
@@ -557,14 +637,28 @@ def __init__(self, conanfile):
 
     def generate(self):
         """
-        Generates all the targets <DEP>/BUILD.bazel files and the dependencies.bzl one in the
-        build folder. It's important to highlight that the dependencies.bzl file should be loaded
-        by your WORKSPACE Bazel file:
+        Generates all the targets <DEP>/BUILD.bazel files, a dependencies.bzl (for bazel<7), a
+        conan_deps_repo_rules.bzl and a conan_deps_module_extension.bzl file (for bazel>=7.1) one in the
+        build folder.
+
+        In case of bazel < 7, it's important to highlight that the ``dependencies.bzl`` file should
+        be loaded by your WORKSPACE Bazel file:
 
         .. code-block:: python
 
             load("@//[BUILD_FOLDER]:dependencies.bzl", "load_conan_dependencies")
             load_conan_dependencies()
+
+        In case of bazel >= 7.1, the ``conan_deps_module_extension.bzl`` file should be loaded by your
+        Module.bazel file, e.g. like this:
+
+        .. code-block:: python
+
+            load_conan_dependencies = use_extension(
+                "//build:conan_deps_module_extension.bzl",
+                "conan_extension"
+            )
+            use_repo(load_conan_dependencies, "dep-1", "dep-2", ...)
         """
         check_duplicated_generator(self, self._conanfile)
         requirements = _get_requirements(self._conanfile, self.build_context_activated)


Test patch:
diff --git a/test/functional/toolchains/google/test_bazel.py b/test/functional/toolchains/google/test_bazel.py
index 6ce6414eac2..f9ce5e02608 100644
--- a/test/functional/toolchains/google/test_bazel.py
+++ b/test/functional/toolchains/google/test_bazel.py
@@ -32,8 +32,8 @@ def base_profile():
 
 
 @pytest.mark.parametrize("build_type", ["Debug", "Release", "RelWithDebInfo", "MinSizeRel"])
-@pytest.mark.tool("bazel")
-def test_basic_exe(bazelrc, build_type, base_profile):
+@pytest.mark.tool("bazel", "6.3.2")
+def test_basic_exe_6x(bazelrc, build_type, base_profile):
     client = TestClient(path_with_spaces=False)
     client.run("new bazel_exe -d name=myapp -d version=1.0")
     # The build:<config> define several configurations that can be activated by passing
@@ -49,9 +49,27 @@ def test_basic_exe(bazelrc, build_type, base_profile):
         assert "myapp/1.0: Hello World Debug!" in client.out
 
 
+@pytest.mark.parametrize("build_type", ["Debug", "Release", "RelWithDebInfo", "MinSizeRel"])
+@pytest.mark.tool("bazel", "7.1.2")
+def test_basic_exe(bazelrc, build_type, base_profile):
+    client = TestClient(path_with_spaces=False)
+    client.run("new bazel_7_exe -d name=myapp -d version=1.0")
+    # The build:<config> define several configurations that can be activated by passing
+    # the bazel config with tools.google.bazel:configs
+    client.save({"mybazelrc": bazelrc})
+    profile = base_profile.format(build_type=build_type,
+                                  curdir=client.current_folder.replace("\\", "/"))
+    client.save({"my_profile": profile})
+    client.run("create . --profile=./my_profile")
+    if build_type != "Debug":
+        assert "myapp/1.0: Hello World Release!" in client.out
+    else:
+        assert "myapp/1.0: Hello World Debug!" in client.out
+
+
 @pytest.mark.parametrize("shared", [False, True])
-@pytest.mark.tool("bazel")
-def test_transitive_libs_consuming(shared):
+@pytest.mark.tool("bazel", "6.3.2")
+def test_transitive_libs_consuming_6x(shared):
     """
     Testing the next dependencies structure for shared/static libs
 
@@ -107,8 +125,6 @@ def test_transitive_libs_consuming(shared):
         load_conan_dependencies()
         """)
         bazel_build_linux = textwrap.dedent("""\
-        load("@rules_cc//cc:defs.bzl", "cc_library")
-
         cc_library(
             name = "mysecondlib",
             srcs = ["mysecondlib.cpp"],
@@ -117,8 +133,6 @@ def test_transitive_libs_consuming(shared):
         )
         """)
         bazel_build = textwrap.dedent("""\
-        load("@rules_cc//cc:defs.bzl", "cc_library")
-
         cc_library(
             name = "mysecondlib",
             srcs = ["mysecondlib.cpp"],
@@ -177,3 +191,129 @@ def test_transitive_libs_consuming(shared):
         client.run(f"create . -o '*:shared={shared}'")
         assert "mysecondlib() First define MY_VALUE and other define 2" in client.out
         assert "myfirstlib/1.2.11: Hello World Release!"
+
+
+@pytest.mark.parametrize("shared", [False, True])
+@pytest.mark.tool("bazel", "7.1.2")
+def test_transitive_libs_consuming(shared):
+    """
+    Testing the next dependencies structure for shared/static libs
+
+    /.
+    |- myfirstlib/
+         |- conanfile.py
+         |- MODULE.bazel
+         |- main/
+            |- BUILD
+            |- myfirstlib.cpp
+            |- myfirstlib.h
+    |- mysecondlib/  (requires myfirstlib)
+         |- conanfile.py
+         |- MODULE.bazel
+         |- main/
+            |- BUILD
+            |- mysecondlib.cpp
+            |- mysecondlib.h
+         |- test_package/
+            |- MODULE.bazel
+            |- conanfile.py
+            |- main
+                |- example.cpp
+                |- BUILD
+    """
+    client = TestClient(path_with_spaces=False)
+    # A regular library made with Bazel
+    with client.chdir("myfirstlib"):
+        client.run("new bazel_7_lib -d name=myfirstlib -d version=1.2.11")
+        conanfile = client.load("conanfile.py")
+        conanfile += """
+        self.cpp_info.defines.append("MY_DEFINE=\\"MY_VALUE\\"")
+        self.cpp_info.defines.append("MY_OTHER_DEFINE=2")
+        if self.settings.os != "Windows":
+            self.cpp_info.system_libs.append("m")
+        else:
+            self.cpp_info.system_libs.append("ws2_32")
+        """
+        client.save({"conanfile.py": conanfile})
+        client.run(f"create . -o '*:shared={shared}' -tf ''")  # skipping tests
+
+    with client.chdir("mysecondlib"):
+        # We prepare a consumer with Bazel (library mysecondlib using myfirstlib)
+        # and a test_package with an example executable
+        os_ = platform.system()
+        client.run("new bazel_7_lib -d name=mysecondlib -d version=1.0")
+        conanfile = client.load("conanfile.py")
+        conanfile = conanfile.replace('generators = "BazelToolchain"',
+                                      'generators = "BazelToolchain", "BazelDeps"\n'
+                                      '    requires = "myfirstlib/1.2.11"')
+        workspace = textwrap.dedent("""
+        load_conan_dependencies = use_extension("//conan:conan_deps_module_extension.bzl", "conan_extension")
+        use_repo(load_conan_dependencies, "myfirstlib")
+        """)
+        bazel_build_linux = textwrap.dedent("""\
+        cc_library(
+            name = "mysecondlib",
+            srcs = ["mysecondlib.cpp"],
+            hdrs = ["mysecondlib.h"],
+            deps = [ "@myfirstlib//:myfirstlib" ]
+        )
+        """)
+        bazel_build = textwrap.dedent("""\
+        cc_library(
+            name = "mysecondlib",
+            srcs = ["mysecondlib.cpp"],
+            hdrs = ["mysecondlib.h"],
+            deps = [ "@myfirstlib//:myfirstlib" ]
+        )
+
+        cc_shared_library(
+            name = "mysecondlib_shared",
+            shared_lib_name = "libmysecondlib_shared.{}",
+            deps = [":mysecondlib"],
+        )
+        """.format("dylib" if os_ == "Darwin" else "dll"))
+        mysecondlib_cpp = textwrap.dedent("""
+        #include <iostream>
+        #include "mysecondlib.h"
+        #include "myfirstlib.h"
+        #include <cmath>
+
+        void mysecondlib(){
+            std::cout << "mysecondlib() First define " << MY_DEFINE << " and other define " << MY_OTHER_DEFINE << std::endl;
+            myfirstlib();
+            // This comes from the systemlibs declared in the myfirstlib
+            sqrt(25);
+        }
+        void mysecondlib_print_vector(const std::vector<std::string> &strings) {
+            for(std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); ++it) {
+                std::cout << "mysecondlib/1.0 " << *it << std::endl;
+            }
+        }
+        """)
+        mysecondlib_cpp_win = textwrap.dedent("""
+        #include <iostream>
+        #include "mysecondlib.h"
+        #include "myfirstlib.h"
+        #include <WinSock2.h>
+
+        void mysecondlib(){
+            SOCKET foo; // From the system library
+            std::cout << "mysecondlib() First define " << MY_DEFINE << " and other define " << MY_OTHER_DEFINE << std::endl;
+            myfirstlib();
+        }
+        void mysecondlib_print_vector(const std::vector<std::string> &strings) {
+            for(std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); ++it) {
+                std::cout << "mysecondlib/1.0 " << *it << std::endl;
+            }
+        }
+        """)
+        # Overwriting files
+        client.save({"conanfile.py": conanfile,
+                     "MODULE.bazel": workspace,
+                     "main/BUILD": bazel_build_linux if os_ == "Linux" else bazel_build,
+                     "main/mysecondlib.cpp": mysecondlib_cpp if os_ != "Windows" else mysecondlib_cpp_win,
+                     })
+
+        client.run(f"create . -o '*:shared={shared}'")
+        assert "mysecondlib() First define MY_VALUE and other define 2" in client.out
+        assert "myfirstlib/1.2.11: Hello World Release!"
diff --git a/test/functional/toolchains/google/test_bazeltoolchain_cross_compilation.py b/test/functional/toolchains/google/test_bazeltoolchain_cross_compilation.py
index 197887d506b..1768210ef21 100644
--- a/test/functional/toolchains/google/test_bazeltoolchain_cross_compilation.py
+++ b/test/functional/toolchains/google/test_bazeltoolchain_cross_compilation.py
@@ -9,7 +9,7 @@
 
 
 @pytest.mark.skipif(platform.system() != "Darwin", reason="Only for Darwin")
-@pytest.mark.tool("bazel")
+@pytest.mark.tool("bazel", "6.3.2")  # not working for Bazel 7.x
 def test_bazel_simple_cross_compilation():
     profile = textwrap.dedent("""
     [settings]
@@ -53,7 +53,6 @@ def build(self):
             bazel.build()
     """)
     BUILD = textwrap.dedent("""
-    load("@rules_cc//cc:defs.bzl", "cc_library")
     cc_library(
         name = "myapp",
         srcs = ["myapp.cpp"],
diff --git a/test/integration/toolchains/google/test_bazeldeps.py b/test/integration/toolchains/google/test_bazeldeps.py
index 2eb9c971f8f..d4b99059ad3 100644
--- a/test/integration/toolchains/google/test_bazeldeps.py
+++ b/test/integration/toolchains/google/test_bazeldeps.py
@@ -1,4 +1,5 @@
 import os
+import pathlib
 import textwrap
 
 from conan.test.assets.genconanfile import GenConanfile
@@ -53,8 +54,6 @@ def layout(self):
     assert "conanfile.py: Generator 'BazelToolchain' calling 'generate()'" in c.out
     build_file = c.load("consumer/conandeps/dep/BUILD.bazel")
     expected = textwrap.dedent("""\
-    load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library")
-
     # Components precompiled libs
     # Root package precompiled libs
 
@@ -150,8 +149,6 @@ def package_info(self):
     c.run("install --requires=dep/0.1 -g BazelDeps --build=missing")
     build_file = c.load("dep/BUILD.bazel")
     expected = textwrap.dedent("""\
-    load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library")
-
     # Components precompiled libs
     # Root package precompiled libs
     cc_import(
@@ -617,6 +614,7 @@ def package_info(self):
     recipes_folder = client.current_folder.replace("\\", "/")
     with client.chdir("pkg"):
         client.run("install . -g BazelDeps")
+        # TODO: Remove when dropped Bazel 6.x compatibility
         content = client.load("dependencies.bzl")
         assert textwrap.dedent(f"""\
         def load_conan_dependencies():
@@ -625,7 +623,17 @@ def load_conan_dependencies():
                 path="{recipes_folder}/dep",
                 build_file="{recipes_folder}/pkg/dep/BUILD.bazel",
             )""") in content
+        # Bazel 7.x
+        content = client.load("conan_deps_module_extension.bzl")
+        assert textwrap.dedent(f"""\
+        def _load_dependenies_impl(mctx):
+            conan_dependency_repo(
+                name = "dep",
+                package_path = "{recipes_folder}/dep",
+                build_file_path = "{recipes_folder}/pkg/dep/BUILD.bazel",
+            )""") in content
         content = client.load("dep/BUILD.bazel")
+        assert pathlib.Path(client.current_folder, "conan_deps_repo_rules.bzl").exists()
         assert textwrap.dedent("""\
         cc_import(
             name = "mylib_precompiled",
@@ -756,10 +764,16 @@ def generate(self):
             ":component3",
         ],
     )""") in client.load("build-other-repo/BUILD.bazel")
+    # TODO: Remove when dropped Bazel 6.x compatibility
     # Let's check if the names used in the dependencies.bzl are correct
     content = client.load("dependencies.bzl")
     assert 'name="build-other-repo"' in content  # build context + bazel_repository_name prop
     assert 'name="build-tool"' in content  # build context + package reference name
+    # Bazel 7.x
+    # Let's check if the names used in the conan_deps_repo_rules.bzl are correct
+    content = client.load("conan_deps_module_extension.bzl")
+    assert 'name = "build-other-repo"' in content  # build context + bazel_repository_name prop
+    assert 'name = "build-tool"' in content  # build context + package reference name
 
 
 def test_tool_requires_not_created_if_no_activated():