Skip to content

Commit 9bc9acc

Browse files
authored
Add new setting //go/toolchain:sdk_name to allow the selection of a specific 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
1 parent 7f6a9bf commit 9bc9acc

File tree

6 files changed

+111
-4
lines changed

6 files changed

+111
-4
lines changed

go/private/go_toolchain.bzl

+35-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ def declare_bazel_toolchains(
123123
minor,
124124
patch,
125125
prerelease,
126+
sdk_name,
126127
sdk_type,
127128
prefix = ""):
128129
"""Declares toolchain targets for each platform."""
@@ -200,6 +201,36 @@ def declare_bazel_toolchains(
200201
visibility = ["//visibility:private"],
201202
)
202203

204+
# use Label constructor to resolve the label relative to the package this bzl file
205+
# is located, instead of the context of the caller of declare_bazel_toolchains.
206+
# See https://bazel.build/rules/lib/builtins/Label#Label for details.
207+
sdk_name_label = Label("//go/toolchain:sdk_name")
208+
209+
native.config_setting(
210+
name = prefix + "match_sdk_name",
211+
flag_values = {
212+
sdk_name_label: sdk_name,
213+
},
214+
visibility = ["//visibility:private"],
215+
)
216+
217+
native.config_setting(
218+
name = prefix + "match_all_sdks",
219+
flag_values = {
220+
sdk_name_label: "",
221+
},
222+
visibility = ["//visibility:private"],
223+
)
224+
225+
selects.config_setting_group(
226+
name = prefix + "sdk_name_setting",
227+
match_any = [
228+
":" + prefix + "match_all_sdks",
229+
":" + prefix + "match_sdk_name",
230+
],
231+
visibility = ["//visibility:private"],
232+
)
233+
203234
for p in PLATFORMS:
204235
if p.cgo:
205236
# Don't declare separate toolchains for cgo_on / cgo_off.
@@ -222,6 +253,9 @@ def declare_bazel_toolchains(
222253
"@io_bazel_rules_go//go/toolchain:" + host_goarch,
223254
],
224255
target_compatible_with = constraints,
225-
target_settings = [":" + prefix + "sdk_version_setting"],
256+
target_settings = [
257+
":" + prefix + "sdk_name_setting",
258+
":" + prefix + "sdk_version_setting",
259+
],
226260
toolchain = go_toolchain_repo + "//:go_" + p.name + "-impl",
227261
)

go/private/sdk.bzl

+1
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ def go_toolchains_single_definition(ctx, *, prefix, goos, goarch, sdk_repo, sdk_
227227
minor = {identifier_prefix}MINOR_VERSION,
228228
patch = {identifier_prefix}PATCH_VERSION,
229229
prerelease = {identifier_prefix}PRERELEASE_SUFFIX,
230+
sdk_name = "{sdk_repo}",
230231
sdk_type = "{sdk_type}",
231232
)
232233
""".format(

go/toolchain/BUILD.bazel

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ string_flag(
1414
build_setting_default = "",
1515
)
1616

17+
string_flag(
18+
name = "sdk_name",
19+
build_setting_default = "",
20+
)
21+
1722
filegroup(
1823
name = "all_rules",
1924
srcs = glob(["*.bzl"]),

go/toolchains.rst

+34
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,40 @@ The SDK version can omit the patch, or include a prerelease part, eg. ``"1"``,
7979
When ``go_host_sdk`` is used, ``"version"`` can be set to ``host`` to refer to the host Go SDK.
8080
It can also be set ``remote`` to match any non-host version.
8181

82+
If you would like to use a specific Go SDK target, pass the flag ``--@io_bazel_rules_go//go/toolchain:sdk_name="name"``.
83+
This can be useful if there are several `go_download_sdk`_ / `go_host_sdk`_ / `go_local_sdk`_ / `go_wrap_sdk`_
84+
with the same Go SDK version, but have different experiments enabled or patches applied:
85+
86+
.. code:: bzl
87+
88+
# WORKSPACE
89+
90+
go_download_sdk(
91+
name = "go_sdk",
92+
version = "1.23.5",
93+
)
94+
95+
# select with bazel build --@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_with_rangefunc
96+
go_download_sdk(
97+
name = "go_sdk_with_rangefunc",
98+
version = "1.23.5",
99+
experiments = ["rangefunc"],
100+
)
101+
102+
# MODULE.bazel
103+
104+
go_sdk.download(
105+
name = "go_sdk",
106+
version = "1.23.5",
107+
)
108+
109+
# select with bazel build --@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_with_rangefunc
110+
go_sdk.download(
111+
name = "go_sdk_with_rangefunc",
112+
version = "1.23.5",
113+
experiments = ["rangefunc"],
114+
)
115+
82116
The toolchain
83117
~~~~~~~~~~~~~
84118

tests/core/go_download_sdk/go_download_sdk_test.go

+34-3
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,44 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk")
142142
143143
go_download_sdk(
144144
name = "go_sdk",
145-
goarch = "amd64",
146-
goos = "windows",
147-
version = "1.20.4",
145+
goarch = "amd64",
146+
goos = "windows",
147+
version = "1.20.4",
148148
)
149149
`,
150150
fetchOnly: "@go_sdk//:BUILD.bazel",
151151
},
152+
{
153+
desc: "multiple_sdks_by_name",
154+
rule: `
155+
load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk", "go_host_sdk")
156+
157+
go_download_sdk(
158+
name = "go_sdk",
159+
version = "1.23.5",
160+
)
161+
go_download_sdk(
162+
name = "go_sdk_1_17",
163+
version = "1.17",
164+
)
165+
go_download_sdk(
166+
name = "go_sdk_1_17_1",
167+
version = "1.17.1",
168+
)
169+
go_download_sdk(
170+
name = "go_sdk_with_experiments",
171+
version = "1.23.5",
172+
experiments = ["rangefunc"],
173+
)
174+
`,
175+
optToWantVersion: map[string]string{
176+
"": "go1.23.5 X:nocoverageredesign",
177+
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_1_17_1": "go1.17.1",
178+
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_1_17": "go1.17",
179+
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk": "go1.23.5 X:nocoverageredesign",
180+
"--@io_bazel_rules_go//go/toolchain:sdk_name=go_sdk_with_experiments": "go1.23.5 X:nocoverageredesign,rangefunc",
181+
},
182+
},
152183
} {
153184
t.Run(test.desc, func(t *testing.T) {
154185
origWorkspaceData, err := ioutil.ReadFile("WORKSPACE")

tests/core/starlark/sdk_tests.bzl

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ _123_PREFIX_PRERELEASE_SUFFIX = "rc1"
3030
minor = _123_PREFIX_MINOR_VERSION,
3131
patch = _123_PREFIX_PATCH_VERSION,
3232
prerelease = _123_PREFIX_PRERELEASE_SUFFIX,
33+
sdk_name = "sdk_repo",
3334
sdk_type = "download",
3435
)
3536
""",
@@ -69,6 +70,7 @@ def _go_toolchains_single_definition_without_version_test(ctx):
6970
minor = _123_PREFIX_MINOR_VERSION,
7071
patch = _123_PREFIX_PATCH_VERSION,
7172
prerelease = _123_PREFIX_PRERELEASE_SUFFIX,
73+
sdk_name = "sdk_repo",
7274
sdk_type = "download",
7375
)
7476
""",

0 commit comments

Comments
 (0)