|
12 | 12 | # See the License for the specific language governing permissions and
|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
15 |
| -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_test") |
| 15 | +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_context", "go_test") |
| 16 | +load("@io_bazel_rules_go//go/platform:list.bzl", "GOOS_GOARCH") |
16 | 17 |
|
17 |
| -# Defines several go_binary rules to work around a Bazel issue which makes |
18 |
| -# the pure attribute on go_binary not configurable. |
19 |
| -# The name provided will have cgo enabled if targeting Linux, and will |
20 |
| -# be a pure go binary otherwise. Additionally, if targeting Windows, the |
21 |
| -# output filename will have a .exe suffix. |
22 |
| -def go_binary_conditional_pure(name, tags = None, **kwargs): |
23 |
| - tags = tags or [] |
24 |
| - tags.append("manual") |
| 18 | +# Defines a go_binary rule that enables cgo on platform builds targeting Linux, |
| 19 | +# and otherwise builds a pure go binary. |
| 20 | +def go_binary_conditional_pure(name, tags = [], **kwargs): |
25 | 21 | go_binary(
|
26 |
| - name = "_%s-cgo" % name, |
27 |
| - out = name, |
28 |
| - pure = "off", |
29 |
| - tags = tags, |
30 |
| - **kwargs |
31 |
| - ) |
32 |
| - |
33 |
| - # Define a rule for both Unix and Windows exe suffixes. |
34 |
| - [go_binary( |
35 |
| - name = "_%s-pure" % out, |
36 |
| - out = out, |
37 |
| - pure = "on", |
38 |
| - tags = tags, |
39 |
| - **kwargs |
40 |
| - ) for out in [name, name + ".exe"]] |
41 |
| - |
42 |
| - # The real magic, where we work around the pure attribute not being |
43 |
| - # configurable: select the appropriate go_binary rule above based on the |
44 |
| - # configured platform. |
45 |
| - native.alias( |
46 | 22 | name = name,
|
47 |
| - actual = select({ |
48 |
| - "@io_bazel_rules_go//go/platform:linux": ":_%s-cgo" % name, |
49 |
| - "@io_bazel_rules_go//go/platform:windows": ":_%s.exe-pure" % name, |
50 |
| - "//conditions:default": ":_%s-pure" % name, |
| 23 | + pure = select({ |
| 24 | + "@io_bazel_rules_go//go/platform:linux": "off", |
| 25 | + "//conditions:default": "on", |
51 | 26 | }),
|
| 27 | + tags = ["manual"] + tags, |
| 28 | + **kwargs |
52 | 29 | )
|
53 | 30 |
|
54 |
| -# Defines several go_test rules to work around a Bazel issue which makes |
55 |
| -# the pure attribute on go_test not configurable. |
56 |
| -# This also defines genrules to produce test binaries named ${out} and |
57 |
| -# ${out}.exe, and an alias named ${out}_binary which automatically selects |
58 |
| -# the correct filename suffix (i.e. with a .exe on Windows). |
59 |
| -def go_test_conditional_pure(name, out, tags = None, **kwargs): |
60 |
| - tags = tags or [] |
| 31 | +# Defines a go_test rule that enables cgo on platform builds targeting Linux, |
| 32 | +# and otherwise builds a pure go binary. |
| 33 | +def go_test_conditional_pure(name, out, tags = [], **kwargs): |
61 | 34 | tags.append("manual")
|
62 | 35 |
|
63 | 36 | go_test(
|
64 |
| - name = "_%s-cgo" % name, |
65 |
| - pure = "off", |
66 |
| - testonly = False, |
67 |
| - tags = tags, |
68 |
| - **kwargs |
69 |
| - ) |
70 |
| - |
71 |
| - go_test( |
72 |
| - name = "_%s-pure" % name, |
73 |
| - pure = "on", |
| 37 | + name = out, |
| 38 | + pure = select({ |
| 39 | + "@io_bazel_rules_go//go/platform:linux": "off", |
| 40 | + "//conditions:default": "on", |
| 41 | + }), |
74 | 42 | testonly = False,
|
75 | 43 | tags = tags,
|
76 | 44 | **kwargs
|
77 | 45 | )
|
78 | 46 |
|
79 | 47 | native.alias(
|
80 |
| - name = name, |
81 |
| - actual = select({ |
82 |
| - "@io_bazel_rules_go//go/platform:linux": ":_%s-cgo" % name, |
83 |
| - "//conditions:default": ":_%s-pure" % name, |
84 |
| - }), |
| 48 | + name = "name", |
| 49 | + actual = out, |
85 | 50 | )
|
86 | 51 |
|
87 |
| - [native.genrule( |
88 |
| - name = "gen_%s" % o, |
89 |
| - srcs = [name], |
90 |
| - outs = [o], |
91 |
| - cmd = "cp $< $@;", |
92 |
| - output_to_bindir = True, |
93 |
| - executable = True, |
94 |
| - tags = tags, |
95 |
| - ) for o in [out, out + ".exe"]] |
| 52 | +_GO_BUILD_MODE_TMPL = "{goos}/{goarch}/pure={pure},static={static},msan={msan},race={race}\n" |
96 | 53 |
|
97 |
| - native.alias( |
98 |
| - name = "%s_binary" % out, |
99 |
| - actual = select({ |
100 |
| - "@io_bazel_rules_go//go/platform:windows": ":gen_%s.exe" % out, |
101 |
| - "//conditions:default": ":gen_%s" % out, |
102 |
| - }), |
| 54 | +def _go_build_mode_aspect_impl(target, ctx): |
| 55 | + if (not hasattr(ctx.rule.attr, "_is_executable") or |
| 56 | + not ctx.rule.attr._is_executable or |
| 57 | + ctx.rule.attr.testonly): |
| 58 | + # We only care about exporting platform info for executable targets |
| 59 | + # that aren't testonly (e.g. kubectl and e2e.test). |
| 60 | + return [] |
| 61 | + |
| 62 | + mode = go_context(ctx).mode |
| 63 | + |
| 64 | + out = ctx.actions.declare_file( |
| 65 | + target.files_to_run.executable.basename + ".go_build_mode", |
| 66 | + sibling = target.files_to_run.executable, |
103 | 67 | )
|
| 68 | + ctx.actions.write(out, _GO_BUILD_MODE_TMPL.format( |
| 69 | + goos = mode.goos, |
| 70 | + goarch = mode.goarch, |
| 71 | + pure = str(mode.pure).lower(), |
| 72 | + static = str(mode.static).lower(), |
| 73 | + msan = str(mode.msan).lower(), |
| 74 | + race = str(mode.race).lower(), |
| 75 | + )) |
| 76 | + |
| 77 | + return [OutputGroupInfo(default = depset([out]))] |
| 78 | + |
| 79 | +# This aspect ouputs a *.go_build_mode metadata for go binaries. This metadata |
| 80 | +# is used for executable selection e.g. in CI. |
| 81 | +go_build_mode_aspect = aspect( |
| 82 | + implementation = _go_build_mode_aspect_impl, |
| 83 | + attrs = { |
| 84 | + "goos": attr.string( |
| 85 | + default = "auto", |
| 86 | + values = ["auto"] + {goos: None for goos, _ in GOOS_GOARCH}.keys(), |
| 87 | + ), |
| 88 | + "goarch": attr.string( |
| 89 | + default = "auto", |
| 90 | + values = ["auto"] + {goarch: None for _, goarch in GOOS_GOARCH}.keys(), |
| 91 | + ), |
| 92 | + "pure": attr.string( |
| 93 | + default = "auto", |
| 94 | + values = ["auto", "on", "off"], |
| 95 | + ), |
| 96 | + "static": attr.string( |
| 97 | + default = "auto", |
| 98 | + values = ["auto", "on", "off"], |
| 99 | + ), |
| 100 | + "msan": attr.string( |
| 101 | + default = "auto", |
| 102 | + values = ["auto", "on", "off"], |
| 103 | + ), |
| 104 | + "race": attr.string( |
| 105 | + default = "auto", |
| 106 | + values = ["auto", "on", "off"], |
| 107 | + ), |
| 108 | + "_go_context_data": attr.label(default = "@io_bazel_rules_go//:go_context_data"), |
| 109 | + }, |
| 110 | + toolchains = ["@io_bazel_rules_go//go:toolchain"], |
| 111 | +) |
0 commit comments