Split toolchains from cc_toolchains in cc_configure

This change modifies which part of cc_configure is executed unconditionally and which only on demand.

The root of the problem was the call `register_toolchains(@local_config_cc//:all)`. Because this was appended to the WORKSPACE file, each Bazel project executed the repository (and therefore tried to detect C++ toolchain and its capabilities) even when the C++ toolchain was not needed for the build.

This change split `@local_config_cc` into 2 repositories:

1. `@local_config_cc_toolchains` which contains only `toolchain` targets, and doesn't require C++ toolchain to be detected.
2. `@local_config_cc` which contains `cc_toolchain` targets, which do require C++ toolchain to be detected.

The point is that toolchain resolution has all the information needed to select the appropriate toolchain without autoconfiguration, therefore C++ toolchain will only be autoconfigured only after we already know it will be selected.

This cl is backwards incompatible for projects that relied on `@local_config_cc` containing `toolchain` targets. But because https://github.com/bazelbuild/bazel/issues/7260 is not yet flipped, there are not that many users of toolchains with C++ who manually instantiate `cc_autoconf` rule.

Fixes https://github.com/bazelbuild/bazel/issues/7751.
Progress towards https://github.com/bazelbuild/bazel/issues/7260.

RELNOTES: Repository containing autoconfigured C++ toolchain `@local_config_cc` has been split in 2 - see `local_config_cc_toolchains`.

Closes #8459.

PiperOrigin-RevId: 250131245
diff --git a/src/test/shell/integration/discard_graph_edges_test.sh b/src/test/shell/integration/discard_graph_edges_test.sh
index 1895eee..892d2e4 100755
--- a/src/test/shell/integration/discard_graph_edges_test.sh
+++ b/src/test/shell/integration/discard_graph_edges_test.sh
@@ -271,7 +271,7 @@
   package_count="$(extract_histogram_count "$histo_file" \
       'devtools\.build\.lib\..*\.Package$')"
   # A few packages aren't cleared.
-  [[ "$package_count" -le 15 ]] \
+  [[ "$package_count" -le 16 ]] \
       || fail "package count $package_count too high"
   glob_count="$(extract_histogram_count "$histo_file" "GlobValue$")"
   [[ "$glob_count" -le 1 ]] \
diff --git a/tools/cpp/BUILD.toolchains.tpl b/tools/cpp/BUILD.toolchains.tpl
new file mode 100644
index 0000000..024d8bf
--- /dev/null
+++ b/tools/cpp/BUILD.toolchains.tpl
@@ -0,0 +1,20 @@
+load("@local_config_platform//:constraints.bzl", "HOST_CONSTRAINTS")
+toolchain(
+    name = "cc-toolchain-%{name}",
+    exec_compatible_with = HOST_CONSTRAINTS,
+    target_compatible_with = HOST_CONSTRAINTS,
+    toolchain = "@local_config_cc//:cc-compiler-%{name}",
+    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
+)
+
+toolchain(
+    name = "cc-toolchain-armeabi-v7a",
+    exec_compatible_with = HOST_CONSTRAINTS,
+    target_compatible_with = [
+        "@bazel_tools//platforms:arm",
+        "@bazel_tools//platforms:android",
+    ],
+    toolchain = "@local_config_cc//:cc-compiler-armabi-v7a",
+    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
+)
+
diff --git a/tools/cpp/BUILD.tpl b/tools/cpp/BUILD.tpl
index 23a4bc5..a919524 100644
--- a/tools/cpp/BUILD.tpl
+++ b/tools/cpp/BUILD.tpl
@@ -18,7 +18,6 @@
 
 load(":cc_toolchain_config.bzl", "cc_toolchain_config")
 load(":armeabi_cc_toolchain_config.bzl", "armeabi_cc_toolchain_config")
-load("@local_config_platform//:constraints.bzl", "HOST_CONSTRAINTS")
 
 licenses(["notice"])  # Apache 2.0
 
@@ -93,14 +92,6 @@
     supports_start_end_lib = %{supports_start_end_lib},
 )
 
-toolchain(
-    name = "cc-toolchain-%{name}",
-    exec_compatible_with = HOST_CONSTRAINTS,
-    target_compatible_with = HOST_CONSTRAINTS,
-    toolchain = ":cc-compiler-%{name}",
-    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
-)
-
 # Android tooling requires a default toolchain for the armeabi-v7a cpu.
 cc_toolchain(
     name = "cc-compiler-armeabi-v7a",
@@ -118,14 +109,3 @@
 )
 
 armeabi_cc_toolchain_config(name = "stub_armeabi-v7a")
-
-toolchain(
-    name = "cc-toolchain-armeabi-v7a",
-    exec_compatible_with = HOST_CONSTRAINTS,
-    target_compatible_with = [
-        "@bazel_tools//platforms:arm",
-        "@bazel_tools//platforms:android",
-    ],
-    toolchain = ":cc-compiler-armabi-v7a",
-    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
-)
diff --git a/tools/cpp/cc_configure.bzl b/tools/cpp/cc_configure.bzl
index 2ecfc9f..37f5c68 100644
--- a/tools/cpp/cc_configure.bzl
+++ b/tools/cpp/cc_configure.bzl
@@ -22,7 +22,47 @@
     "resolve_labels",
 )
 
+def cc_autoconf_toolchains_impl(repository_ctx):
+    """Generate BUILD file with 'toolchain' targets for the local host C++ toolchain.
+
+    Args:
+      repository_ctx: repository context
+    """
+    paths = resolve_labels(repository_ctx, [
+        "@bazel_tools//tools/cpp:BUILD.toolchains.tpl",
+        "@bazel_tools//tools/osx/crosstool:BUILD.toolchains",
+        "@bazel_tools//tools/osx/crosstool:osx_archs.bzl",
+    ])
+    env = repository_ctx.os.environ
+    cpu_value = get_cpu_value(repository_ctx)
+    if "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" in env and env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] == "1":
+        repository_ctx.file("BUILD", "# C++ toolchain autoconfiguration was disabled by BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN env variable.")
+    elif (cpu_value == "darwin" and
+          ("BAZEL_USE_CPP_ONLY_TOOLCHAIN" not in env or env["BAZEL_USE_CPP_ONLY_TOOLCHAIN"] != "1")):
+        repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:BUILD.toolchains"], "BUILD")
+        repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:osx_archs.bzl"], "osx_archs.bzl")
+    else:
+        repository_ctx.template(
+            "BUILD",
+            paths["@bazel_tools//tools/cpp:BUILD.toolchains.tpl"],
+            {"%{name}": cpu_value},
+        )
+
+cc_autoconf_toolchains = repository_rule(
+    environ = [
+        "BAZEL_USE_CPP_ONLY_TOOLCHAIN",
+        "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
+    ],
+    implementation = cc_autoconf_toolchains_impl,
+)
+
 def cc_autoconf_impl(repository_ctx, overriden_tools = dict()):
+    """Generate BUILD file with 'cc_toolchain' targets for the local host C++ toolchain.
+
+    Args:
+       repository_ctx: repository context
+       overriden_tools: dict of tool paths to use instead of autoconfigured tools
+    """
     paths = resolve_labels(repository_ctx, [
         "@bazel_tools//tools/cpp:BUILD.static.freebsd",
         "@bazel_tools//tools/cpp:cc_toolchain_config.bzl",
@@ -89,9 +129,10 @@
 
 def cc_configure():
     """A C++ configuration rules that generate the crosstool file."""
+    cc_autoconf_toolchains(name = "local_config_cc_toolchains")
     cc_autoconf(name = "local_config_cc")
     native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain")
     native.register_toolchains(
         # Use register_toolchain's target pattern expansion to register all toolchains in the package.
-        "@local_config_cc//:all",
+        "@local_config_cc_toolchains//:all",
     )
diff --git a/tools/cpp/osx_cc_configure.bzl b/tools/cpp/osx_cc_configure.bzl
index b4b2e22..0498881 100644
--- a/tools/cpp/osx_cc_configure.bzl
+++ b/tools/cpp/osx_cc_configure.bzl
@@ -58,7 +58,6 @@
         "@bazel_tools//tools/objc:xcrunwrapper.sh",
         "@bazel_tools//tools/osx/crosstool:BUILD.tpl",
         "@bazel_tools//tools/osx/crosstool:cc_toolchain_config.bzl.tpl",
-        "@bazel_tools//tools/osx/crosstool:osx_archs.bzl",
         "@bazel_tools//tools/osx/crosstool:wrapped_ar.tpl",
         "@bazel_tools//tools/osx/crosstool:wrapped_clang.cc",
         "@bazel_tools//tools/osx:xcode_locator.m",
@@ -99,11 +98,6 @@
             paths["@bazel_tools//tools/osx/crosstool:BUILD.tpl"],
             "BUILD",
         )
-        repository_ctx.symlink(
-            paths["@bazel_tools//tools/osx/crosstool:osx_archs.bzl"],
-            "osx_archs.bzl",
-        )
-
         wrapped_clang_src_path = str(repository_ctx.path(
             paths["@bazel_tools//tools/osx/crosstool:wrapped_clang.cc"],
         ))
diff --git a/tools/osx/crosstool/BUILD.toolchains b/tools/osx/crosstool/BUILD.toolchains
new file mode 100644
index 0000000..178ab86
--- /dev/null
+++ b/tools/osx/crosstool/BUILD.toolchains
@@ -0,0 +1,18 @@
+package(default_visibility = ["//visibility:public"])
+
+load(":osx_archs.bzl", "OSX_TOOLS_ARCHS", "OSX_TOOLS_CONSTRAINTS")
+
+[
+    toolchain(
+        name = "cc-toolchain-" + arch,
+        exec_compatible_with = [
+            # These only execute on macOS.
+            "@bazel_tools//platforms:osx",
+            "@bazel_tools//platforms:x86_64",
+        ],
+        target_compatible_with = OSX_TOOLS_CONSTRAINTS[arch],
+        toolchain = "@local_config_cc//:cc-compiler-" + arch,
+        toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
+    )
+    for arch in OSX_TOOLS_ARCHS
+]
diff --git a/tools/osx/crosstool/BUILD.tpl b/tools/osx/crosstool/BUILD.tpl
index 2ef62b9..4ec81fe 100644
--- a/tools/osx/crosstool/BUILD.tpl
+++ b/tools/osx/crosstool/BUILD.tpl
@@ -1,8 +1,15 @@
 package(default_visibility = ["//visibility:public"])
 
-load(":osx_archs.bzl", "OSX_TOOLS_ARCHS", "OSX_TOOLS_CONSTRAINTS")
+load("@local_config_cc_toolchains//:osx_archs.bzl", "OSX_TOOLS_ARCHS")
 load(":cc_toolchain_config.bzl", "cc_toolchain_config")
 
+# Reexporting osx_arch.bzl for backwards compatibility
+# Originally this file was present in @local_config_cc, but with the split in
+# https://github.com/bazelbuild/bazel/pull/8459 we had to move the file to
+# @local_config_cc_toolchains. This alias is there to keep the code backwards
+# compatible (and serves no other purpose).
+alias(name = "osx_archs.bzl", actual = "@local_config_cc_toolchains//:osx_archs.bzl")
+
 CC_TOOLCHAINS = [(
     cpu + "|compiler",
     ":cc-compiler-" + cpu,
@@ -81,18 +88,3 @@
     )
     for arch in OSX_TOOLS_ARCHS
 ]
-
-[
-    toolchain(
-        name = "cc-toolchain-" + arch,
-        exec_compatible_with = [
-            # These only execute on macOS.
-            "@bazel_tools//platforms:osx",
-            "@bazel_tools//platforms:x86_64",
-        ],
-        target_compatible_with = OSX_TOOLS_CONSTRAINTS[arch],
-        toolchain = ":cc-compiler-" + arch,
-        toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
-    )
-    for arch in OSX_TOOLS_ARCHS
-]