1# Copyright 2016 The Bazel Go Rules Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14""" 15Toolchain rules used by go. 16""" 17 18load("//go/private:platforms.bzl", "PLATFORMS") 19load("//go/private:providers.bzl", "GoSDK") 20load("//go/private/actions:archive.bzl", "emit_archive") 21load("//go/private/actions:binary.bzl", "emit_binary") 22load("//go/private/actions:link.bzl", "emit_link") 23load("//go/private/actions:stdlib.bzl", "emit_stdlib") 24load("@bazel_skylib//lib:selects.bzl", "selects") 25 26GO_TOOLCHAIN = "@io_bazel_rules_go//go:toolchain" 27 28def _go_toolchain_impl(ctx): 29 sdk = ctx.attr.sdk[GoSDK] 30 cross_compile = ctx.attr.goos != sdk.goos or ctx.attr.goarch != sdk.goarch 31 return [platform_common.ToolchainInfo( 32 # Public fields 33 name = ctx.label.name, 34 cross_compile = cross_compile, 35 default_goos = ctx.attr.goos, 36 default_goarch = ctx.attr.goarch, 37 actions = struct( 38 archive = emit_archive, 39 binary = emit_binary, 40 link = emit_link, 41 stdlib = emit_stdlib, 42 ), 43 flags = struct( 44 compile = (), 45 link = ctx.attr.link_flags, 46 link_cgo = ctx.attr.cgo_link_flags, 47 ), 48 sdk = sdk, 49 50 # Internal fields -- may be read by emit functions. 51 _builder = ctx.executable.builder, 52 )] 53 54go_toolchain = rule( 55 _go_toolchain_impl, 56 attrs = { 57 # Minimum requirements to specify a toolchain 58 "builder": attr.label( 59 mandatory = True, 60 cfg = "exec", 61 executable = True, 62 doc = "Tool used to execute most Go actions", 63 ), 64 "goos": attr.string( 65 mandatory = True, 66 doc = "Default target OS", 67 ), 68 "goarch": attr.string( 69 mandatory = True, 70 doc = "Default target architecture", 71 ), 72 "sdk": attr.label( 73 mandatory = True, 74 providers = [GoSDK], 75 cfg = "exec", 76 doc = "The SDK this toolchain is based on", 77 ), 78 # Optional extras to a toolchain 79 "link_flags": attr.string_list( 80 doc = "Flags passed to the Go internal linker", 81 ), 82 "cgo_link_flags": attr.string_list( 83 doc = "Flags passed to the external linker (if it is used)", 84 ), 85 }, 86 doc = "Defines a Go toolchain based on an SDK", 87 provides = [platform_common.ToolchainInfo], 88) 89 90def declare_go_toolchains(host_goos, sdk, builder): 91 """Declares go_toolchain targets for each platform.""" 92 for p in PLATFORMS: 93 if p.cgo: 94 # Don't declare separate toolchains for cgo_on / cgo_off. 95 # This is controlled by the cgo_context_data dependency of 96 # go_context_data, which is configured using constraint_values. 97 continue 98 99 link_flags = [] 100 cgo_link_flags = [] 101 if host_goos == "darwin": 102 cgo_link_flags.extend(["-shared", "-Wl,-all_load"]) 103 if host_goos == "linux": 104 cgo_link_flags.append("-Wl,-whole-archive") 105 106 go_toolchain( 107 name = "go_" + p.name + "-impl", 108 goos = p.goos, 109 goarch = p.goarch, 110 sdk = sdk, 111 builder = builder, 112 link_flags = link_flags, 113 cgo_link_flags = cgo_link_flags, 114 tags = ["manual"], 115 visibility = ["//visibility:public"], 116 ) 117 118def declare_bazel_toolchains( 119 *, 120 go_toolchain_repo, 121 host_goarch, 122 host_goos, 123 major, 124 minor, 125 patch, 126 prerelease, 127 sdk_type, 128 prefix = ""): 129 """Declares toolchain targets for each platform.""" 130 131 sdk_version_label = Label("//go/toolchain:sdk_version") 132 133 native.config_setting( 134 name = prefix + "match_all_versions", 135 flag_values = { 136 sdk_version_label: "", 137 }, 138 visibility = ["//visibility:private"], 139 ) 140 141 native.config_setting( 142 name = prefix + "match_major_version", 143 flag_values = { 144 sdk_version_label: major, 145 }, 146 visibility = ["//visibility:private"], 147 ) 148 149 native.config_setting( 150 name = prefix + "match_major_minor_version", 151 flag_values = { 152 sdk_version_label: major + "." + minor, 153 }, 154 visibility = ["//visibility:private"], 155 ) 156 157 native.config_setting( 158 name = prefix + "match_patch_version", 159 flag_values = { 160 sdk_version_label: major + "." + minor + "." + patch, 161 }, 162 visibility = ["//visibility:private"], 163 ) 164 165 # 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. 166 native.config_setting( 167 name = prefix + "match_prerelease_version", 168 flag_values = { 169 sdk_version_label: major + "." + minor + "." + patch + prerelease, 170 }, 171 visibility = ["//visibility:private"], 172 ) 173 174 native.config_setting( 175 name = prefix + "match_sdk_type", 176 flag_values = { 177 sdk_version_label: sdk_type, 178 }, 179 visibility = ["//visibility:private"], 180 ) 181 182 selects.config_setting_group( 183 name = prefix + "sdk_version_setting", 184 match_any = [ 185 ":" + prefix + "match_all_versions", 186 ":" + prefix + "match_major_version", 187 ":" + prefix + "match_major_minor_version", 188 ":" + prefix + "match_patch_version", 189 ":" + prefix + "match_prerelease_version", 190 ":" + prefix + "match_sdk_type", 191 ], 192 visibility = ["//visibility:private"], 193 ) 194 195 for p in PLATFORMS: 196 if p.cgo: 197 # Don't declare separate toolchains for cgo_on / cgo_off. 198 # This is controlled by the cgo_context_data dependency of 199 # go_context_data, which is configured using constraint_values. 200 continue 201 202 cgo_constraints = ( 203 "@io_bazel_rules_go//go/toolchain:cgo_off", 204 "@io_bazel_rules_go//go/toolchain:cgo_on", 205 ) 206 constraints = [c for c in p.constraints if c not in cgo_constraints] 207 208 native.toolchain( 209 # keep in sync with generate_toolchain_names 210 name = prefix + "go_" + p.name, 211 toolchain_type = GO_TOOLCHAIN, 212 exec_compatible_with = [ 213 "@io_bazel_rules_go//go/toolchain:" + host_goos, 214 "@io_bazel_rules_go//go/toolchain:" + host_goarch, 215 ], 216 target_compatible_with = constraints, 217 target_settings = [":" + prefix + "sdk_version_setting"], 218 toolchain = go_toolchain_repo + "//:go_" + p.name + "-impl", 219 ) 220