| # 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("@bazel_skylib//lib:selects.bzl", "selects") |
| load("//go/private:common.bzl", "GO_TOOLCHAIN") |
| 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") |
| |
| 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", |
| ) |