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