-
-
Notifications
You must be signed in to change notification settings - Fork 682
/
Copy pathmode.bzl
232 lines (208 loc) · 7.38 KB
/
mode.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# Copyright 2017 The Bazel 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.
# Modes are documented in go/modes.rst#compilation-modes
LINKMODE_NORMAL = "normal"
LINKMODE_SHARED = "shared"
LINKMODE_PIE = "pie"
LINKMODE_PLUGIN = "plugin"
LINKMODE_C_SHARED = "c-shared"
LINKMODE_C_ARCHIVE = "c-archive"
LINKMODES = [LINKMODE_NORMAL, LINKMODE_PLUGIN, LINKMODE_C_SHARED, LINKMODE_C_ARCHIVE, LINKMODE_PIE]
def mode_string(mode):
result = [mode.goos, mode.goarch]
if mode.static:
result.append("static")
if mode.race:
result.append("race")
if mode.msan:
result.append("msan")
if mode.pure:
result.append("pure")
if mode.debug:
result.append("debug")
if mode.strip:
result.append("stripped")
if not result or not mode.link == LINKMODE_NORMAL:
result.append(mode.link)
return "_".join(result)
def _ternary(*values):
for v in values:
if v == None:
continue
if type(v) == "bool":
return v
if type(v) != "string":
fail("Invalid value type {}".format(type(v)))
v = v.lower()
if v == "on":
return True
if v == "off":
return False
if v == "auto":
continue
fail("Invalid value {}".format(v))
fail("_ternary failed to produce a final result from {}".format(values))
def get_mode(ctx, go_toolchain, cgo_context_info, go_config_info):
static = _ternary(go_config_info.static if go_config_info else "off")
pure = _ternary(
"on" if not cgo_context_info else "auto",
go_config_info.pure if go_config_info else "off",
)
race = _ternary(go_config_info.race if go_config_info else "off")
msan = _ternary(go_config_info.msan if go_config_info else "off")
strip = go_config_info.strip if go_config_info else False
stamp = go_config_info.stamp if go_config_info else False
debug = go_config_info.debug if go_config_info else False
linkmode = go_config_info.linkmode if go_config_info else LINKMODE_NORMAL
goos = go_toolchain.default_goos
goarch = go_toolchain.default_goarch
# TODO(jayconrod): check for more invalid and contradictory settings.
if pure and race:
fail("race instrumentation can't be enabled when cgo is disabled. Check that pure is not set to \"off\" and a C/C++ toolchain is configured.")
if pure and msan:
fail("msan instrumentation can't be enabled when cgo is disabled. Check that pure is not set to \"off\" and a C/C++ toolchain is configured.")
tags = list(go_config_info.tags) if go_config_info else []
if "gotags" in ctx.var:
tags.extend(ctx.var["gotags"].split(","))
if cgo_context_info:
tags.extend(cgo_context_info.tags)
if race:
tags.append("race")
if msan:
tags.append("msan")
return struct(
static = static,
race = race,
msan = msan,
pure = pure,
link = linkmode,
strip = strip,
stamp = stamp,
debug = debug,
goos = goos,
goarch = goarch,
tags = tags,
)
def installsuffix(mode):
s = mode.goos + "_" + mode.goarch
if mode.race:
s += "_race"
elif mode.msan:
s += "_msan"
return s
def mode_tags_equivalent(l, r):
"""Returns whether two modes are equivalent for Go build tags. For example,
goos and goarch must match, but static doesn't matter."""
return (l.goos == r.goos and
l.goarch == r.goarch and
l.race == r.race and
l.msan == r.msan)
# Ported from https://github.com/golang/go/blob/master/src/cmd/go/internal/work/init.go#L76
_LINK_C_ARCHIVE_PLATFORMS = {
"darwin/arm": None,
"darwin/arm64": None,
}
_LINK_C_ARCHIVE_GOOS = {
"dragonfly": None,
"freebsd": None,
"linux": None,
"netbsd": None,
"openbsd": None,
"solaris": None,
}
_LINK_C_SHARED_PLATFORMS = {
"linux/amd64": None,
"linux/arm": None,
"linux/arm64": None,
"linux/386": None,
"linux/ppc64le": None,
"linux/s390x": None,
"android/amd64": None,
"android/arm": None,
"android/arm64": None,
"android/386": None,
}
_LINK_PLUGIN_PLATFORMS = {
"linux/amd64": None,
"linux/arm": None,
"linux/arm64": None,
"linux/386": None,
"linux/s390x": None,
"linux/ppc64le": None,
"android/amd64": None,
"android/arm": None,
"android/arm64": None,
"android/386": None,
"darwin/amd64": None,
}
_LINK_PIE_PLATFORMS = {
"linux/amd64": None,
"linux/arm": None,
"linux/arm64": None,
"linux/386": None,
"linux/s390x": None,
"linux/ppc64le": None,
"android/amd64": None,
"android/arm": None,
"android/arm64": None,
"android/386": None,
"freebsd/amd64": None,
}
def link_mode_args(mode):
# based on buildModeInit in cmd/go/internal/work/init.go
platform = mode.goos + "/" + mode.goarch
args = []
if mode.link == LINKMODE_C_ARCHIVE:
if (platform in _LINK_C_ARCHIVE_PLATFORMS or
mode.goos in _LINK_C_ARCHIVE_GOOS and platform != "linux/ppc64"):
args.append("-shared")
elif mode.link == LINKMODE_C_SHARED:
if platform in _LINK_C_SHARED_PLATFORMS:
args.append("-shared")
elif mode.link == LINKMODE_PLUGIN:
if platform in _LINK_PLUGIN_PLATFORMS:
args.append("-dynlink")
elif mode.link == LINKMODE_PIE:
if platform in _LINK_PIE_PLATFORMS:
args.append("-shared")
return args
def extldflags_from_cc_toolchain(go):
if not go.cgo_tools:
return []
elif go.mode.link in (LINKMODE_SHARED, LINKMODE_PLUGIN, LINKMODE_C_SHARED):
return go.cgo_tools.ld_dynamic_lib_options
else:
# NOTE: in c-archive mode, -extldflags are ignored by the linker.
# However, we still need to set them for cgo, which links a binary
# in each package. We use the executable options for this.
return go.cgo_tools.ld_executable_options
def extld_from_cc_toolchain(go):
if not go.cgo_tools:
return []
elif go.mode.link in (LINKMODE_SHARED, LINKMODE_PLUGIN, LINKMODE_C_SHARED, LINKMODE_PIE):
return ["-extld", go.cgo_tools.ld_dynamic_lib_path]
elif go.mode.link == LINKMODE_C_ARCHIVE:
if go.mode.goos == "darwin":
# TODO(jayconrod): on macOS, set -extar. At this time, wrapped_ar is
# a bash script without a shebang line, so we can't execute it. We
# use /usr/bin/ar (the default) instead.
return []
else:
return ["-extar", go.cgo_tools.ld_static_lib_path]
else:
# NOTE: In c-archive mode, we should probably set -extar. However,
# on macOS, Bazel returns wrapped_ar, which is not executable.
# /usr/bin/ar (the default) should be visible though, and we have a
# hack in link.go to strip out non-reproducible stuff.
return ["-extld", go.cgo_tools.ld_executable_path]