From 64d84bfb1547c1dd83ba018577d56a981c2304b1 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 24 Sep 2026 20:59:54 -0400 Subject: [PATCH] Upgrade rules_go and adapt Go build rules The rules_go archive override still selects 0.57 despite declaring 0.59, and retains implicit symbols removed by Bazel 9. Upgrade to 0.63 from the Bazel Central Registry while retaining the required local patches. This also satisfies the rules_go dependency of hermetic-llvm [1]. Align Gazelle and platforms with rules_go and refresh their license records. Bazel 8.5 exposes module-extension facts through a Facts object. The 0.57 SDK extension treats it as a dictionary and fails before target analysis. This upgrade includes the upstream API adaptation [2]. Use the public Go context fields and rule factory [3]. The factory owns the C++ toolchain declarations needed by custom cgo rules, avoiding a load of private rules_go definitions. Nogo's aspect only analyzes Go sources; request its SDK and target mode without a C++ context, retaining race and sanitizer settings [4]. Select cgo-capable target platforms for race and plugin builds while the pure flag still disables ordinary cgo. Rebase the cgo and export patches while preserving registration of otherwise unreferenced C objects and both test compilation archives. Remove the obsolete SDK patch: go_sdk.from_file already supports the upstream patches and patch_strip API. Newer rules_go versions install cmd/internal/cov and cmd/internal/bio archives for coverage [5]. Skip cmd archives when enumerating the standard library because nogo already excludes their sources from analysis. [1]: https://github.com/hermeticbuild/hermetic-llvm/blob/v0.8.23/MODULE.bazel [2]: https://github.com/bazel-contrib/rules_go/commit/30a6f8da4 [3]: https://github.com/bazel-contrib/rules_go/commit/cb2845953 [4]: https://github.com/bazel-contrib/rules_go/commit/903722985 [5]: https://github.com/bazel-contrib/rules_go/commit/56929daa4 Assisted-by: Codex --- .bazelrc | 4 ++-- MODULE.bazel | 14 ++++++------- tools/bazeldefs/go.bzl | 19 ++++++++++-------- tools/licensecheck/dependencies.yaml | 24 +++++++++++----------- tools/nogo/check/build.go | 6 ++++++ tools/rules_cgo.patch | 10 +++++----- tools/rules_go_export.patch | 10 ++++++---- tools/rules_go_sdk.patch | 30 ---------------------------- 8 files changed, 48 insertions(+), 69 deletions(-) delete mode 100644 tools/rules_go_sdk.patch diff --git a/.bazelrc b/.bazelrc index c5dff0de11a..19e9e2a5d89 100644 --- a/.bazelrc +++ b/.bazelrc @@ -43,12 +43,12 @@ build --build_tag_filters=-nogo # Set flags for x86_64. build:x86_64 --crosstool_top=@crosstool//:toolchains build:x86_64 --cpu=k8 -build:x86_64 --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 +build:x86_64 --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64_cgo # Set flags for aarch64. build:aarch64 --crosstool_top=@crosstool//:toolchains build:aarch64 --cpu=aarch64 -build:aarch64 --platforms=@io_bazel_rules_go//go/toolchain:linux_arm64 +build:aarch64 --platforms=@io_bazel_rules_go//go/toolchain:linux_arm64_cgo # Use prebuilt protoc to speed up builds. common --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc diff --git a/MODULE.bazel b/MODULE.bazel index 49d2ad96bae..145d4d9ba01 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -3,8 +3,8 @@ module( version = "0.0.1", ) -bazel_dep(name = "rules_go", version = "0.59.0", repo_name = "io_bazel_rules_go") -bazel_dep(name = "gazelle", version = "0.47.0", repo_name = "bazel_gazelle") +bazel_dep(name = "rules_go", version = "0.63.0", repo_name = "io_bazel_rules_go") +bazel_dep(name = "gazelle", version = "0.51.3", repo_name = "bazel_gazelle") bazel_dep(name = "rules_license", version = "1.0.0") bazel_dep(name = "bazel_skylib", version = "1.9.2") bazel_dep(name = "rules_pkg", version = "1.0.1") @@ -12,7 +12,7 @@ bazel_dep(name = "rules_cc", version = "0.2.17") bazel_dep(name = "rules_shell", version = "0.8.0") bazel_dep(name = "grpc", version = "1.76.0", repo_name = "com_github_grpc_grpc") bazel_dep(name = "protobuf", version = "33.4", repo_name = "com_google_protobuf") -bazel_dep(name = "platforms", version = "1.0.0") +bazel_dep(name = "platforms", version = "1.1.0") bazel_dep(name = "abseil-cpp", version = "20250814.1", repo_name = "com_google_absl") bazel_dep(name = "googletest", version = "1.17.0", repo_name = "com_google_googletest") bazel_dep(name = "google_benchmark", version = "1.8.4", repo_name = "com_google_benchmark") @@ -23,17 +23,15 @@ bazel_dep(name = "protoc-gen-validate", version = "1.3.0") bazel_dep(name = "xds", version = "0.0.0-20251210-ee656c7") bazel_dep(name = "cel-spec", version = "0.25.1") -archive_override( +single_version_override( module_name = "rules_go", - integrity = "sha256-pynI7SRHyQ/hQAd2iQecoKz7dYDsQWN/MS1lDOnZPZY=", - patch_args = ["-p1"], + patch_strip = 1, patches = [ "//tools:rules_go_symbols.patch", - "//tools:rules_go_sdk.patch", "//tools:rules_cgo.patch", "//tools:rules_go_export.patch", ], - url = "https://github.com/bazel-contrib/rules_go/releases/download/v0.57.0/rules_go-v0.57.0.zip", + version = "0.63.0", ) archive_override( diff --git a/tools/bazeldefs/go.bzl b/tools/bazeldefs/go.bzl index 0be97741ddc..c3c94c649e9 100644 --- a/tools/bazeldefs/go.bzl +++ b/tools/bazeldefs/go.bzl @@ -3,7 +3,7 @@ load("@bazel_gazelle//:def.bzl", _gazelle = "gazelle") load("@bazel_skylib//lib:paths.bzl", "paths") load("@bazel_skylib//lib:shell.bzl", "shell") -load("@io_bazel_rules_go//go:def.bzl", "GoArchive", "GoLibrary", _go_binary = "go_binary", _go_context = "go_context", _go_library = "go_library", _go_path = "go_path", _go_reset_target = "go_reset_target", _go_test = "go_test") +load("@io_bazel_rules_go//go:def.bzl", "GoArchive", "GoLibrary", _go_binary = "go_binary", _go_context = "go_context", _go_library = "go_library", _go_path = "go_path", _go_reset_target = "go_reset_target", _go_rule = "go_rule", _go_test = "go_test") load("@io_bazel_rules_go//proto:def.bzl", _go_grpc_library = "go_grpc_library", _go_proto_library = "go_proto_library") load("//tools/bazeldefs:defs.bzl", "select_arch", "select_system") @@ -165,7 +165,7 @@ def go_rule(rule, implementation, **kwargs): """Wraps a rule definition with Go attributes. Args: - rule: rule function (typically rule or aspect). + rule: rule or aspect function. implementation: implementation function. **kwargs: other arguments to pass to rule. @@ -176,8 +176,11 @@ def go_rule(rule, implementation, **kwargs): "_go_context_data": attr.label(default = "@io_bazel_rules_go//:go_context_data"), "_stdlib": attr.label(default = "@io_bazel_rules_go//:stdlib"), }) - kwargs.setdefault("toolchains", []).append("@io_bazel_rules_go//go:toolchain") - return rule(implementation, **kwargs) + if rule == aspect: + # Nogo analyzes Go sources without invoking the C/C++ toolchain. + kwargs.setdefault("toolchains", []).append("@io_bazel_rules_go//go:toolchain") + return aspect(implementation, **kwargs) + return _go_rule(implementation, **kwargs) def go_embed_libraries(target): if hasattr(target.attr, "embed"): @@ -200,7 +203,7 @@ def go_context(ctx, goos = None, goarch = None, attr = None): # We don't change anything for the standard library analysis. All Go files # are available in all instances. Note that this includes the standard # library sources, which are analyzed by nogo. - go_ctx = _go_context(ctx, attr = attr) + go_ctx = _go_context(ctx, attr = attr, maybe_needs_cc_toolchain = False) nogo_args = [] if go_ctx.mode.race: @@ -215,13 +218,13 @@ def go_context(ctx, goos = None, goarch = None, attr = None): return struct( env = dict(go_ctx.env, CGO_ENABLED = "0"), - go = go_ctx.go, + go = go_ctx.sdk.go, goarch = goarch or go_ctx.sdk.goarch, goos = goos or go_ctx.sdk.goos, - gotags = go_ctx.tags, + gotags = go_ctx.mode.tags, lang_version = "go" + go_ctx.sdk.version, # go_ctx.sdk.version excludes the go prefix. nogo_args = nogo_args, - runfiles = depset([go_ctx.go] + go_ctx.sdk.srcs.to_list() + go_ctx.sdk.tools.to_list() + go_ctx.stdlib.libs.to_list()), + runfiles = depset([go_ctx.sdk.go] + go_ctx.sdk.srcs.to_list() + go_ctx.sdk.tools.to_list() + go_ctx.stdlib.libs.to_list()), stdlib_srcs = go_ctx.sdk.srcs, stdlib_mod = stdlib_mod, ) diff --git a/tools/licensecheck/dependencies.yaml b/tools/licensecheck/dependencies.yaml index adb2c1917d8..24d0276b248 100644 --- a/tools/licensecheck/dependencies.yaml +++ b/tools/licensecheck/dependencies.yaml @@ -89,10 +89,10 @@ sha256: 2c8a2520ef58c3d2a6e9e0392ec2cea37adb17db4e00c903d48415fd809397f8 license: Apache-2.0 - dependency: gazelle - version: https://github.com/bazel-contrib/bazel-gazelle/releases/download/v0.47.0/bazel-gazelle-v0.47.0.tar.gz - retrieved: "2026-08-27" - commit: b13c1573c378bb3dd9b9de1397db89d0392f8e72 - sha256: 675114d8b433d0a9f54d81171833be96ebc4113115664b791e6f204d58e93446 + version: https://github.com/bazel-contrib/bazel-gazelle/releases/download/v0.51.3/bazel-gazelle-v0.51.3.tar.gz + retrieved: "2026-09-25" + commit: b66b19ce4b0ecebd3ae416e6b55a0d22a49fef34 + sha256: 49d9eba309b0b695824ff417d734242824ad9ab5edb56063b9d3400df1a61a56 license: Apache-2.0 - dependency: github.com/BurntSushi/toml version: v1.4.1-0.20240526193622-a339e1f7089c @@ -1020,10 +1020,10 @@ sha256: a22461d13119ac5c78f205d3df1db13403e58ce1bb1794edc9313677313f4a9d license: MIT - dependency: platforms - version: https://github.com/bazelbuild/platforms/releases/download/1.0.0/platforms-1.0.0.tar.gz - retrieved: "2026-08-27" - commit: ab99943ab6bed53cff461a3afa99fc79d31e4351 - sha256: 3384eb1c30762704fbe38e440204e114154086c8fc8a8c2e3e28441028c019a8 + version: https://github.com/bazelbuild/platforms/releases/download/1.1.0/platforms-1.1.0.tar.gz + retrieved: "2026-09-25" + commit: 2d4b4996f0bf52376704c49264164e166213159e + sha256: dbad4a23abcca6171e47b79edc53bd6a41067a3b75f9e8b104656b459ff25046 license: Apache-2.0 - dependency: protobuf version: https://github.com/protocolbuffers/protobuf/releases/download/v33.4/protobuf-33.4.bazel.tar.gz @@ -1044,10 +1044,10 @@ sha256: 283fa1cdaaf172337898749cf4b9b1ef5ea269da59540954e51fba0e7b8f277a license: Apache-2.0 - dependency: rules_go - version: https://github.com/bazel-contrib/rules_go/releases/download/v0.57.0/rules_go-v0.57.0.zip - retrieved: "2026-08-27" - commit: 64d9225db70d2e9014217fd8e0340ba4407066fb - sha256: a729c8ed2447c90fe140077689079ca0acfb7580ec41637f312d650ce9d93d96 + version: https://github.com/bazel-contrib/rules_go/releases/download/v0.63.0/rules_go-v0.63.0.zip + retrieved: "2026-09-29" + commit: 9792f1c079a7602347e0fd966542b6d6b35a6c64 + sha256: c3e253237109ab2e2a8d3cb075688b98a6e6fce43d849849648e8e3a84f20d6f license: Apache-2.0 - dependency: rules_license version: https://github.com/bazelbuild/rules_license/releases/download/1.0.0/rules_license-1.0.0.tar.gz diff --git a/tools/nogo/check/build.go b/tools/nogo/check/build.go index 7b08dce4fbe..baf8c2ceeb3 100644 --- a/tools/nogo/check/build.go +++ b/tools/nogo/check/build.go @@ -85,6 +85,12 @@ func FilterStdPackages(srcPkgs map[string][]string) (map[string][]string, error) return err } if d.IsDir() { + // rules_go includes cmd/internal/{cov,bio} archives for coverage: + // https://github.com/bazel-contrib/rules_go/commit/56929daa4 + // SplitStdPackages excludes cmd sources, so skip those archives. + if path == "cmd" { + return fs.SkipDir + } return nil } diff --git a/tools/rules_cgo.patch b/tools/rules_cgo.patch index 0f4f2d26e25..7db193058e3 100644 --- a/tools/rules_cgo.patch +++ b/tools/rules_cgo.patch @@ -1,8 +1,8 @@ diff --git a/go/private/rules/cgo.bzl b/go/private/rules/cgo.bzl -index b8fc93a6..3fec27e4 100644 +index 541b2fec..dc12ed51 100644 --- a/go/private/rules/cgo.bzl +++ b/go/private/rules/cgo.bzl -@@ -144,7 +144,12 @@ def cgo_configure(go, srcs, cdeps, cppopts, copts, cxxopts, clinkopts): +@@ -157,7 +157,12 @@ def cgo_configure(go, srcs, cdeps, cppopts, copts, cxxopts, clinkopts): # libclntsh.dylib.12.1, users have to create a unversioned symbolic link, # so it can be treated as a simple shared library too. continue @@ -12,6 +12,6 @@ index b8fc93a6..3fec27e4 100644 lib_opts.append(lib.path) + # Disable whole-archive for other libraries. + lib_opts.append("-Wl,--no-whole-archive") - clinkopts.extend(cc_link_flags) - - elif hasattr(d, "objc"): + if lib.basename.endswith(".a"): + # Match cgo2's heuristic: static cdeps may need the C++ runtime. + needs_cxx_runtime = True diff --git a/tools/rules_go_export.patch b/tools/rules_go_export.patch index 6955cfc380f..5456e2942fe 100644 --- a/tools/rules_go_export.patch +++ b/tools/rules_go_export.patch @@ -58,15 +58,17 @@ index 68a1d3b9..53c38cb2 100644 + ), ] - go_tool_library = rule( + go_tool_library = go_rule( diff --git a/go/private/rules/test.bzl b/go/private/rules/test.bzl index dcb4eb63..660505b4 100644 --- a/go/private/rules/test.bzl +++ b/go/private/rules/test.bzl -@@ -215,6 +215,8 @@ def _go_test_impl(ctx): - ), +@@ -220,8 +220,10 @@ def _go_test_impl(ctx): OutputGroupInfo( - compilation_outputs = [internal_archive.data.file], + compilation_outputs = [ + internal_archive.data.file, + external_archive.data.file, + ], + export_files = internal_archive.export_files, + libs = internal_archive.libs, nogo_fix = nogo_diagnosticss, diff --git a/tools/rules_go_sdk.patch b/tools/rules_go_sdk.patch deleted file mode 100644 index 2e43f5db481..00000000000 --- a/tools/rules_go_sdk.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/go/private/sdk.bzl b/go/private/sdk.bzl -index 156bb255..619c5395 100644 ---- a/go/private/sdk.bzl -+++ b/go/private/sdk.bzl -@@ -129,6 +129,8 @@ def _go_download_sdk_impl(ctx): - "sdks": ctx.attr.sdks, - "urls": ctx.attr.urls, - "version": version, -+ "patch": ctx.attr.patch, -+ "patch_strip": ctx.attr.patch_strip, - "strip_prefix": ctx.attr.strip_prefix, - } - return None -@@ -144,6 +146,7 @@ go_download_sdk_rule = repository_rule( - ), - "urls": attr.string_list(default = ["https://dl.google.com/go/{}"]), - "version": attr.string(), -+ "patch": attr.label(default = None), - "strip_prefix": attr.string(default = "go"), - "patches": attr.label_list( - doc = "A list of patches to apply to the SDK after downloading it", -@@ -432,6 +435,8 @@ def _remote_sdk(ctx, urls, strip_prefix, sha256): - sha256 = sha256, - auth = auth, - ) -+ if ctx.attr.patch: -+ ctx.patch(ctx.attr.patch, strip = ctx.attr.patch_strip) - - def _local_sdk(ctx, path): - for entry in ctx.path(path).readdir():