From dcc5457b82ec9472a276f142dea286d57340b8d4 Mon Sep 17 00:00:00 2001 From: Yves-Stan Le Cornec Date: Mon, 24 Apr 2023 13:30:13 +0200 Subject: [PATCH] go_sdk extension: create `go_host_compatible_sdk` repository See issue 1469 on https://github.com/bazelbuild/bazel-gazelle --- go/private/extensions.bzl | 30 +++++++++++++++++++++++++++++- go/private/sdk.bzl | 8 ++++---- tests/bcr/MODULE.bazel | 3 +++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/go/private/extensions.bzl b/go/private/extensions.bzl index dd1166ec3b..263de8364f 100644 --- a/go/private/extensions.bzl +++ b/go/private/extensions.bzl @@ -1,6 +1,24 @@ -load("//go/private:sdk.bzl", "go_download_sdk_rule", "go_host_sdk_rule", "go_multiple_toolchains") +load("//go/private:sdk.bzl", "detect_host_platform", "go_download_sdk_rule", "go_host_sdk_rule", "go_multiple_toolchains") load("//go/private:repositories.bzl", "go_rules_dependencies") +def host_compatible_toolchain_impl(ctx): + ctx.file("BUILD.bazel", content = "") + host_compatible_sdk = ctx.attr.toolchains[0] + ctx.file("defs.bzl", content = """ +host_compatible_sdk = Label("{}") +""".format(host_compatible_sdk)) + +host_compatible_toolchain = repository_rule( + implementation = host_compatible_toolchain_impl, + attrs = { + "toolchains": attr.string_list( + doc = "A non empty list of host compatible toolchains", + mandatory = True, + ), + }, + doc = "An external repository to expose the first host compatible toolchain", +) + _download_tag = tag_class( attrs = { "name": attr.string(), @@ -33,6 +51,11 @@ def _go_sdk_impl(ctx): else: multi_version_module[module.name] = False + # We build a list of the host compatible toolchains declared by the download and host tags. + # The order follows bazel's iteration over modules (the toolchains declared by the root module are at the beginning of the list). + # This list will contain at least `go_default_sdk` which is declared by the `rules_go` module itself. + host_compatible_toolchains = [] + host_detected_goos, host_detected_goarch = detect_host_platform(ctx) toolchains = [] for module in ctx.modules: for index, download_tag in enumerate(module.tags.download): @@ -66,6 +89,9 @@ def _go_sdk_impl(ctx): version = download_tag.version, ) + if (not download_tag.goos or download_tag.goos == host_detected_goos) and (not download_tag.goarch or download_tag.goarch == host_detected_goarch): + host_compatible_toolchains.append("@{}//:ROOT".format(name)) + toolchains.append(struct( goos = download_tag.goos, goarch = download_tag.goarch, @@ -99,7 +125,9 @@ def _go_sdk_impl(ctx): sdk_type = "host", sdk_version = host_tag.version, )) + host_compatible_toolchains.append("@{}//:ROOT".format(name)) + host_compatible_toolchain(name = "go_host_compatible_sdk", toolchains = host_compatible_toolchains) if len(toolchains) > _MAX_NUM_TOOLCHAINS: fail("more than {} go_sdk tags are not supported".format(_MAX_NUM_TOOLCHAINS)) diff --git a/go/private/sdk.bzl b/go/private/sdk.bzl index 5a3ef4228c..8a9bc642d6 100644 --- a/go/private/sdk.bzl +++ b/go/private/sdk.bzl @@ -59,7 +59,7 @@ def go_host_sdk(name, register_toolchains = True, **kwargs): def _go_download_sdk_impl(ctx): if not ctx.attr.goos and not ctx.attr.goarch: - goos, goarch = _detect_host_platform(ctx) + goos, goarch = detect_host_platform(ctx) else: if not ctx.attr.goos: fail("goarch set but goos not set") @@ -173,7 +173,7 @@ def _to_constant_name(s): def go_toolchains_single_definition(ctx, *, prefix, goos, goarch, sdk_repo, sdk_type, sdk_version): if not goos and not goarch: - goos, goarch = _detect_host_platform(ctx) + goos, goarch = detect_host_platform(ctx) else: if not goos: fail("goarch set but goos not set") @@ -354,7 +354,7 @@ def _go_wrap_sdk_impl(ctx): if ctx.attr.root_file: root_file = ctx.attr.root_file else: - goos, goarch = _detect_host_platform(ctx) + goos, goarch = detect_host_platform(ctx) platform = goos + "_" + goarch if platform not in ctx.attr.root_files: fail("unsupported platform {}".format(platform)) @@ -466,7 +466,7 @@ def _sdk_build_file(ctx, platform, version, experiments): content = _define_version_constants(version), ) -def _detect_host_platform(ctx): +def detect_host_platform(ctx): goos = ctx.os.name if goos == "mac os x": goos = "darwin" diff --git a/tests/bcr/MODULE.bazel b/tests/bcr/MODULE.bazel index 151f522e63..28bd341110 100644 --- a/tests/bcr/MODULE.bazel +++ b/tests/bcr/MODULE.bazel @@ -30,6 +30,9 @@ go_sdk.host(version = "3.0.0") # Bring the default SDK into scope to verify that it exists. use_repo(go_sdk, "go_default_sdk") +# Bring the selected host compatible SDK into scope to verify that it exists. +use_repo(go_sdk, "go_host_compatible_sdk") + go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps.module( path = "google.golang.org/grpc",