Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ikavalio authored Dec 12, 2023
2 parents acc2297 + d4667fe commit ddb7741
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 8 deletions.
5 changes: 3 additions & 2 deletions docs/go/core/bzlmod.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ To register a particular version of the Go SDK, use the `go_sdk` module extensio
```starlark
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

# Download an SDK for the host OS & architecture.
# Download an SDK for the host OS & architecture as well as common remote execution platforms.
go_sdk.download(version = "1.20.3")

# Alternately, download an SDK for a fixed OS/architecture, e.g. for remote execution.
# Alternately, download an SDK for a fixed OS/architecture.
go_sdk.download(
version = "1.20.3",
goarch = "amd64",
Expand All @@ -45,6 +45,7 @@ go_sdk.host()
```

You can register multiple Go SDKs and select which one to use on a per-target basis using [`go_cross_binary`](rules.md#go_cross_binary).
As long as you specify the `version` of an SDK, it will be downloaded lazily, that is, only when it is actually needed during a particular build.
The usual rules of [toolchain resolution](https://bazel.build/extending/toolchains#toolchain-resolution) apply, with SDKs registered in the root module taking precedence over those registered in dependencies.

### Using a Go SDK
Expand Down
60 changes: 54 additions & 6 deletions go/private/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ _host_tag = tag_class(
},
)

# A list of (goos, goarch) pairs that are commonly used for remote executors in cross-platform
# builds (where host != exec platform). By default, we register toolchains for all of these
# platforms in addition to the host platform.
_COMMON_EXEC_PLATFORMS = [
("darwin", "amd64"),
("darwin", "arm64"),
("linux", "amd64"),
("linux", "arm64"),
("windows", "amd64"),
("windows", "arm64"),
]

# This limit can be increased essentially arbitrarily, but doing so will cause a rebuild of all
# targets using any of these toolchains due to the changed repository name.
_MAX_NUM_TOOLCHAINS = 9999
Expand Down Expand Up @@ -96,10 +108,9 @@ def _go_sdk_impl(ctx):

# SDKs with an explicit name are at risk of colliding with those from other modules.
# This is acceptable if brought in by the root module as the user is responsible for any
# conflicts that arise. rules_go itself provides "go_default_sdk", which is used by
# Gazelle to bootstrap itself.
# TODO(https://github.com/bazelbuild/bazel-gazelle/issues/1469): Investigate whether
# Gazelle can use the first user-defined SDK instead to prevent unnecessary downloads.
# conflicts that arise. rules_go itself provides "go_default_sdk".
# TODO: Now that Gazelle relies on the go_host_compatible_sdk_label repo, remove the
# special case for "go_default_sdk". Users should migrate to @rules_go//go.
if (not module.is_root and not module.name == "rules_go") and download_tag.name:
fail("go_sdk.download: name must not be specified in non-root module " + module.name)

Expand Down Expand Up @@ -133,6 +144,42 @@ def _go_sdk_impl(ctx):
sdk_version = download_tag.version,
))

# Additionally register SDKs for all common execution platforms, but only if the user
# specified a version to prevent eager fetches.
if download_tag.version and not download_tag.goos and not download_tag.goarch:
for goos, goarch in _COMMON_EXEC_PLATFORMS:
if goos == host_detected_goos and goarch == host_detected_goarch:
# We already added the host-compatible toolchain above.
continue

if download_tag.sdks and not "{}_{}".format(goos, goarch) in download_tag.sdks:
# The user supplied custom download links, but not for this tuple.
continue

default_name = _default_go_sdk_name(
module = module,
multi_version = multi_version_module[module.name],
tag_type = "download",
index = index,
suffix = "_{}_{}".format(goos, goarch),
)
go_download_sdk_rule(
name = default_name,
goos = download_tag.goos,
goarch = download_tag.goarch,
sdks = download_tag.sdks,
urls = download_tag.urls,
version = download_tag.version,
)

toolchains.append(struct(
goos = goos,
goarch = goarch,
sdk_repo = default_name,
sdk_type = "remote",
sdk_version = download_tag.version,
))

for index, host_tag in enumerate(module.tags.host):
# Dependencies can rely on rules_go providing a default remote SDK. They can also
# configure a specific version of the SDK to use. However, they should not add a
Expand Down Expand Up @@ -183,15 +230,16 @@ def _go_sdk_impl(ctx):
sdk_versions = [toolchain.sdk_version for toolchain in toolchains],
)

def _default_go_sdk_name(*, module, multi_version, tag_type, index):
def _default_go_sdk_name(*, module, multi_version, tag_type, index, suffix = ""):
# Keep the version out of the repository name if possible to prevent unnecessary rebuilds when
# it changes.
return "{name}_{version}_{tag_type}_{index}".format(
return "{name}_{version}_{tag_type}_{index}{suffix}".format(
# "main_" is not a valid module name and thus can't collide.
name = module.name or "main_",
version = module.version if multi_version else "",
tag_type = tag_type,
index = index,
suffix = suffix,
)

def _toolchain_prefix(index, name):
Expand Down

0 comments on commit ddb7741

Please sign in to comment.