Skip to content

Commit

Permalink
Add new setting //go/toolchain:sdk_name to allow the selection of a s…
Browse files Browse the repository at this point in the history
…pecific Go toolchain (#4242)

**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

This commit adds a new setting
--@io_bazel_rules_go//go/toolchain:sdk_name which can be used to select
a registered Go toolchain via the name provided in go_download_sdk,
go_wrap_sdk, etc.

This fixes the problem of selecting a toolchain where the same Go
version is used, but different experiements are enabled or patches
applied.

**Which issues(s) does this PR fix?**

Fixes #4240

**Other notes for review**

Works also as a workaround for #3582
  • Loading branch information
bluec0re authored Jan 31, 2025
1 parent 7f6a9bf commit 9bc9acc
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 4 deletions.
36 changes: 35 additions & 1 deletion go/private/go_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def declare_bazel_toolchains(
minor,
patch,
prerelease,
sdk_name,
sdk_type,
prefix = ""):
"""Declares toolchain targets for each platform."""
Expand Down Expand Up @@ -200,6 +201,36 @@ def declare_bazel_toolchains(
visibility = ["//visibility:private"],
)

# use Label constructor to resolve the label relative to the package this bzl file
# is located, instead of the context of the caller of declare_bazel_toolchains.
# See https://bazel.build/rules/lib/builtins/Label#Label for details.
sdk_name_label = Label("//go/toolchain:sdk_name")

native.config_setting(
name = prefix + "match_sdk_name",
flag_values = {
sdk_name_label: sdk_name,
},
visibility = ["//visibility:private"],
)

native.config_setting(
name = prefix + "match_all_sdks",
flag_values = {
sdk_name_label: "",
},
visibility = ["//visibility:private"],
)

selects.config_setting_group(
name = prefix + "sdk_name_setting",
match_any = [
":" + prefix + "match_all_sdks",
":" + prefix + "match_sdk_name",
],
visibility = ["//visibility:private"],
)

for p in PLATFORMS:
if p.cgo:
# Don't declare separate toolchains for cgo_on / cgo_off.
Expand All @@ -222,6 +253,9 @@ def declare_bazel_toolchains(
"@io_bazel_rules_go//go/toolchain:" + host_goarch,
],
target_compatible_with = constraints,
target_settings = [":" + prefix + "sdk_version_setting"],
target_settings = [
":" + prefix + "sdk_name_setting",
":" + prefix + "sdk_version_setting",
],
toolchain = go_toolchain_repo + "//:go_" + p.name + "-impl",
)
1 change: 1 addition & 0 deletions go/private/sdk.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def go_toolchains_single_definition(ctx, *, prefix, goos, goarch, sdk_repo, sdk_
minor = {identifier_prefix}MINOR_VERSION,
patch = {identifier_prefix}PATCH_VERSION,
prerelease = {identifier_prefix}PRERELEASE_SUFFIX,
sdk_name = "{sdk_repo}",
sdk_type = "{sdk_type}",
)
""".format(
Expand Down
5 changes: 5 additions & 0 deletions go/toolchain/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ string_flag(
build_setting_default = "",
)

string_flag(
name = "sdk_name",
build_setting_default = "",
)

filegroup(
name = "all_rules",
srcs = glob(["*.bzl"]),
Expand Down
34 changes: 34 additions & 0 deletions go/toolchains.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,40 @@ The SDK version can omit the patch, or include a prerelease part, eg. ``"1"``,
When ``go_host_sdk`` is used, ``"version"`` can be set to ``host`` to refer to the host Go SDK.
It can also be set ``remote`` to match any non-host version.

If you would like to use a specific Go SDK target, pass the flag ``--@io_bazel_rules_go//go/toolchain:sdk_name="name"``.
This can be useful if there are several `go_download_sdk`_ / `go_host_sdk`_ / `go_local_sdk`_ / `go_wrap_sdk`_
with the same Go SDK version, but have different experiments enabled or patches applied:

.. code:: bzl
# WORKSPACE
go_download_sdk(
name = "go_sdk",
version = "1.23.5",
)
# select with bazel build --@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_with_rangefunc
go_download_sdk(
name = "go_sdk_with_rangefunc",
version = "1.23.5",
experiments = ["rangefunc"],
)
# MODULE.bazel
go_sdk.download(
name = "go_sdk",
version = "1.23.5",
)
# select with bazel build --@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_with_rangefunc
go_sdk.download(
name = "go_sdk_with_rangefunc",
version = "1.23.5",
experiments = ["rangefunc"],
)
The toolchain
~~~~~~~~~~~~~

Expand Down
37 changes: 34 additions & 3 deletions tests/core/go_download_sdk/go_download_sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,44 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk")
go_download_sdk(
name = "go_sdk",
goarch = "amd64",
goos = "windows",
version = "1.20.4",
goarch = "amd64",
goos = "windows",
version = "1.20.4",
)
`,
fetchOnly: "@go_sdk//:BUILD.bazel",
},
{
desc: "multiple_sdks_by_name",
rule: `
load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk", "go_host_sdk")
go_download_sdk(
name = "go_sdk",
version = "1.23.5",
)
go_download_sdk(
name = "go_sdk_1_17",
version = "1.17",
)
go_download_sdk(
name = "go_sdk_1_17_1",
version = "1.17.1",
)
go_download_sdk(
name = "go_sdk_with_experiments",
version = "1.23.5",
experiments = ["rangefunc"],
)
`,
optToWantVersion: map[string]string{
"": "go1.23.5 X:nocoverageredesign",
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_1_17_1": "go1.17.1",
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_1_17": "go1.17",
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk": "go1.23.5 X:nocoverageredesign",
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_with_experiments": "go1.23.5 X:nocoverageredesign,rangefunc",
},
},
} {
t.Run(test.desc, func(t *testing.T) {
origWorkspaceData, err := ioutil.ReadFile("WORKSPACE")
Expand Down
2 changes: 2 additions & 0 deletions tests/core/starlark/sdk_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ _123_PREFIX_PRERELEASE_SUFFIX = "rc1"
minor = _123_PREFIX_MINOR_VERSION,
patch = _123_PREFIX_PATCH_VERSION,
prerelease = _123_PREFIX_PRERELEASE_SUFFIX,
sdk_name = "sdk_repo",
sdk_type = "download",
)
""",
Expand Down Expand Up @@ -69,6 +70,7 @@ def _go_toolchains_single_definition_without_version_test(ctx):
minor = _123_PREFIX_MINOR_VERSION,
patch = _123_PREFIX_PATCH_VERSION,
prerelease = _123_PREFIX_PRERELEASE_SUFFIX,
sdk_name = "sdk_repo",
sdk_type = "download",
)
""",
Expand Down

0 comments on commit 9bc9acc

Please sign in to comment.