diff options
Diffstat (limited to 'go/private/go_toolchain.bzl')
-rw-r--r-- | go/private/go_toolchain.bzl | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/go/private/go_toolchain.bzl b/go/private/go_toolchain.bzl new file mode 100644 index 00000000..2dc3bf4f --- /dev/null +++ b/go/private/go_toolchain.bzl @@ -0,0 +1,219 @@ +# Copyright 2016 The Bazel Go Rules Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Toolchain rules used by go. +""" + +load("//go/private:platforms.bzl", "PLATFORMS") +load("//go/private:providers.bzl", "GoSDK") +load("//go/private/actions:archive.bzl", "emit_archive") +load("//go/private/actions:binary.bzl", "emit_binary") +load("//go/private/actions:link.bzl", "emit_link") +load("//go/private/actions:stdlib.bzl", "emit_stdlib") +load("@bazel_skylib//lib:selects.bzl", "selects") + +GO_TOOLCHAIN = "@io_bazel_rules_go//go:toolchain" + +def _go_toolchain_impl(ctx): + sdk = ctx.attr.sdk[GoSDK] + cross_compile = ctx.attr.goos != sdk.goos or ctx.attr.goarch != sdk.goarch + return [platform_common.ToolchainInfo( + # Public fields + name = ctx.label.name, + cross_compile = cross_compile, + default_goos = ctx.attr.goos, + default_goarch = ctx.attr.goarch, + actions = struct( + archive = emit_archive, + binary = emit_binary, + link = emit_link, + stdlib = emit_stdlib, + ), + flags = struct( + compile = (), + link = ctx.attr.link_flags, + link_cgo = ctx.attr.cgo_link_flags, + ), + sdk = sdk, + + # Internal fields -- may be read by emit functions. + _builder = ctx.executable.builder, + )] + +go_toolchain = rule( + _go_toolchain_impl, + attrs = { + # Minimum requirements to specify a toolchain + "builder": attr.label( + mandatory = True, + cfg = "exec", + executable = True, + doc = "Tool used to execute most Go actions", + ), + "goos": attr.string( + mandatory = True, + doc = "Default target OS", + ), + "goarch": attr.string( + mandatory = True, + doc = "Default target architecture", + ), + "sdk": attr.label( + mandatory = True, + providers = [GoSDK], + cfg = "exec", + doc = "The SDK this toolchain is based on", + ), + # Optional extras to a toolchain + "link_flags": attr.string_list( + doc = "Flags passed to the Go internal linker", + ), + "cgo_link_flags": attr.string_list( + doc = "Flags passed to the external linker (if it is used)", + ), + }, + doc = "Defines a Go toolchain based on an SDK", + provides = [platform_common.ToolchainInfo], +) + +def declare_go_toolchains(host_goos, sdk, builder): + """Declares go_toolchain targets for each platform.""" + for p in PLATFORMS: + if p.cgo: + # Don't declare separate toolchains for cgo_on / cgo_off. + # This is controlled by the cgo_context_data dependency of + # go_context_data, which is configured using constraint_values. + continue + + link_flags = [] + cgo_link_flags = [] + if host_goos == "darwin": + cgo_link_flags.extend(["-shared", "-Wl,-all_load"]) + if host_goos == "linux": + cgo_link_flags.append("-Wl,-whole-archive") + + go_toolchain( + name = "go_" + p.name + "-impl", + goos = p.goos, + goarch = p.goarch, + sdk = sdk, + builder = builder, + link_flags = link_flags, + cgo_link_flags = cgo_link_flags, + tags = ["manual"], + visibility = ["//visibility:public"], + ) + +def declare_bazel_toolchains( + *, + go_toolchain_repo, + host_goarch, + host_goos, + major, + minor, + patch, + prerelease, + sdk_type, + prefix = ""): + """Declares toolchain targets for each platform.""" + + sdk_version_label = Label("//go/toolchain:sdk_version") + + native.config_setting( + name = prefix + "match_all_versions", + flag_values = { + sdk_version_label: "", + }, + visibility = ["//visibility:private"], + ) + + native.config_setting( + name = prefix + "match_major_version", + flag_values = { + sdk_version_label: major, + }, + visibility = ["//visibility:private"], + ) + + native.config_setting( + name = prefix + "match_major_minor_version", + flag_values = { + sdk_version_label: major + "." + minor, + }, + visibility = ["//visibility:private"], + ) + + native.config_setting( + name = prefix + "match_patch_version", + flag_values = { + sdk_version_label: major + "." + minor + "." + patch, + }, + visibility = ["//visibility:private"], + ) + + # If prerelease version is "", this will be the same as ":match_patch_version", but that's fine since we use match_any in config_setting_group. + native.config_setting( + name = prefix + "match_prerelease_version", + flag_values = { + sdk_version_label: major + "." + minor + "." + patch + prerelease, + }, + visibility = ["//visibility:private"], + ) + + native.config_setting( + name = prefix + "match_sdk_type", + flag_values = { + sdk_version_label: sdk_type, + }, + visibility = ["//visibility:private"], + ) + + selects.config_setting_group( + name = prefix + "sdk_version_setting", + match_any = [ + ":" + prefix + "match_all_versions", + ":" + prefix + "match_major_version", + ":" + prefix + "match_major_minor_version", + ":" + prefix + "match_patch_version", + ":" + prefix + "match_prerelease_version", + ":" + prefix + "match_sdk_type", + ], + visibility = ["//visibility:private"], + ) + + for p in PLATFORMS: + if p.cgo: + # Don't declare separate toolchains for cgo_on / cgo_off. + # This is controlled by the cgo_context_data dependency of + # go_context_data, which is configured using constraint_values. + continue + + cgo_constraints = ( + "@io_bazel_rules_go//go/toolchain:cgo_off", + "@io_bazel_rules_go//go/toolchain:cgo_on", + ) + constraints = [c for c in p.constraints if c not in cgo_constraints] + + native.toolchain( + # keep in sync with generate_toolchain_names + name = prefix + "go_" + p.name, + toolchain_type = GO_TOOLCHAIN, + exec_compatible_with = [ + "@io_bazel_rules_go//go/toolchain:" + host_goos, + "@io_bazel_rules_go//go/toolchain:" + host_goarch, + ], + target_compatible_with = constraints, + target_settings = [":" + prefix + "sdk_version_setting"], + toolchain = go_toolchain_repo + "//:go_" + p.name + "-impl", + ) |