From 8b52276b66f20f49d921f0be0358078bfc40a076 Mon Sep 17 00:00:00 2001 From: Nick Jefferies Date: Fri, 9 Jan 2026 13:22:55 -0500 Subject: [PATCH] SERVER-116369: Implement platform-conditional Bazel Python toolchain registration to fix Windows builds for python 3.13 (#46028) GitOrigin-RevId: eabc4e5b00cb0415df261c86f94f4f3533a46875 --- bazel/bzlmod.bzl | 4 +- bazel/toolchains/python/python_toolchain.bzl | 73 +++++++++++++++++--- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/bazel/bzlmod.bzl b/bazel/bzlmod.bzl index 59161538e85..151c4e20d68 100644 --- a/bazel/bzlmod.bzl +++ b/bazel/bzlmod.bzl @@ -10,8 +10,8 @@ bazel_features_deps = module_extension( implementation = _bazel_features_deps_impl, ) -def _setup_mongo_python_toolchains_impl(_ctx): - _setup_mongo_python_toolchains() +def _setup_mongo_python_toolchains_impl(ctx): + _setup_mongo_python_toolchains(ctx) setup_mongo_python_toolchains = module_extension( implementation = _setup_mongo_python_toolchains_impl, diff --git a/bazel/toolchains/python/python_toolchain.bzl b/bazel/toolchains/python/python_toolchain.bzl index 6f5342e4673..201ddc9bb45 100644 --- a/bazel/toolchains/python/python_toolchain.bzl +++ b/bazel/toolchains/python/python_toolchain.bzl @@ -63,6 +63,53 @@ def _py_download(ctx): else: arch = ctx.os.arch + # Platform-conditional download: only download if this toolchain matches the host OS + # This prevents downloading all 7 platform toolchains (saves ~630MB per build) + host_os_name = ctx.os.name.lower() + is_host_windows = "win" in host_os_name + is_host_macos = "mac" in host_os_name or "darwin" in host_os_name + is_host_linux = not is_host_windows and not is_host_macos + + is_toolchain_windows = os == "windows" + is_toolchain_macos = os == "macos" + is_toolchain_linux = os == "linux" + + # Check if OS matches + os_matches = ( + (is_host_windows and is_toolchain_windows) or + (is_host_macos and is_toolchain_macos) or + (is_host_linux and is_toolchain_linux) + ) + + # If OS doesn't match, create a minimal stub BUILD file and skip download + if not os_matches: + os_constraint = OS_TO_PLATFORM_MAP[os] + arch_constraint = ARCH_TO_PLATFORM_MAP[arch] + constraints = [os_constraint, arch_constraint] + constraints_str = ",\n ".join(['"%s"' % c for c in constraints]) + + ctx.file("BUILD.bazel", """ +# Stub toolchain - platform doesn't match host, not downloaded +load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair") + +py_runtime_pair( + name = "runtime_pair", + py2_runtime = None, + py3_runtime = None, +) + +toolchain( + name = "python_toolchain", + toolchain_type = "@bazel_tools//tools/python:toolchain_type", + toolchain = ":runtime_pair", + exec_compatible_with = [ + {constraints} + ], + visibility = ["//visibility:public"], +) +""".format(constraints = constraints_str)) + return None + if ctx.attr.urls: urls = ctx.attr.urls sha = ctx.attr.sha256 @@ -191,15 +238,24 @@ py_download = repository_rule( }, ) -def setup_mongo_python_toolchains(): - # This will autoselect a toolchain that matches the host environment - # this toolchain is intended be used only for local repository exectutions, - # and will not be registered as a bazel toolchain by omitting from the return - # value below. - py_download( - name = "py_host", - ) +def setup_mongo_python_toolchains(ctx): + """Setup Python toolchains for all platforms. + Creates py_download repos for all platforms. The py_download repository rule + detects if the toolchain OS matches the host OS and only downloads if there's + a match. Non-matching platforms get stub BUILD files without downloading. + + This ensures MODULE.bazel.lock is platform-agnostic since all platforms see the + same repository definitions. + + Args: + ctx: Module extension context (unused, required by signature). + """ + + # Always create py_host for local repository operations + py_download(name = "py_host") + + # Create all platform toolchains - downloads are conditional inside py_download py_download( name = "py_linux_arm64", arch = "aarch64", @@ -257,6 +313,7 @@ def setup_mongo_python_toolchains(): urls = [URLS_MAP["macos_x86_64"]["url"]], ) + # Return value is not used since toolchains are registered in MODULE.bazel return ( "@py_linux_arm64//:python_toolchain", "@py_linux_x86_64//:python_toolchain",