Skip to content

Commit bdadb2a

Browse files
committed
make kube::util::find-binary not dependent on bazel-out/ structure
Implement an aspect that outputs go_build_mode metadata for go binaries, and use that during binary selection.
1 parent d182ecc commit bdadb2a

File tree

3 files changed

+77
-14
lines changed

3 files changed

+77
-14
lines changed

build/go.bzl

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

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")
1617

1718
# Defines a go_binary rule that enables cgo on platform builds targeting Linux,
1819
# and otherwise builds a pure go binary.
@@ -47,3 +48,64 @@ def go_test_conditional_pure(name, out, tags = [], **kwargs):
4748
name = "name",
4849
actual = out,
4950
)
51+
52+
_GO_BUILD_MODE_TMPL = "{goos}/{goarch}/pure={pure},static={static},msan={msan},race={race}\n"
53+
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,
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+
)

build/root/.bazelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ build --define gotags=selinux
2222
# This flag requires Bazel 0.5.0+
2323
build --sandbox_fake_username
2424

25+
# Output go_build_mode metadata for binaries. This metadata is used for
26+
# executable selection e.g. in CI.
27+
build --aspects //build:go.bzl%go_build_mode_aspect
28+
2529
# Enable go race detection.
2630
build:unit --@io_bazel_rules_go//go/config:race
2731
test:unit --@io_bazel_rules_go//go/config:race

hack/lib/util.sh

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,19 +207,16 @@ kube::util::find-binary-for-platform() {
207207
"${KUBE_ROOT}/_output/dockerized/go/bin/${lookfor}"
208208
);
209209
fi
210-
# Also search for binary in bazel build tree.
211-
# The bazel go rules place some binaries in subtrees like
212-
# "bazel-bin/source/path/linux_amd64_pure_stripped/binaryname", so make sure
213-
# the platform name is matched in the path.
214-
while IFS=$'\n' read -r location; do
215-
locations+=("$location");
216-
done < <(find "${KUBE_ROOT}/bazel-bin/" -type f -executable \
217-
\( -path "*/${platform/\//_}*/${lookfor}" -o -path "*/${lookfor}" \) 2>/dev/null || true)
218-
# search for executables for non-GNU versions of find (eg. BSD)
219-
while IFS=$'\n' read -r location; do
220-
locations+=("$location");
221-
done < <(find "${KUBE_ROOT}/bazel-bin/" -type f -perm -111 \
222-
\( -path "*/${platform/\//_}*/${lookfor}" -o -path "*/${lookfor}" \) 2>/dev/null || true)
210+
211+
# Also search for binary in bazel build tree if bazel-out/ exists.
212+
if [[ -d "${KUBE_ROOT}/bazel-out" ]]; then
213+
while IFS=$'\n' read -r bin_build_mode; do
214+
if grep -q "${platform}" "${bin_build_mode}"; then
215+
# drop the extension to get the real binary path.
216+
locations+=("${bin_build_mode%.*}")
217+
fi
218+
done < <(find "${KUBE_ROOT}/bazel-out/" -name "${lookfor}.go_build_mode")
219+
fi
223220

224221
# List most recently-updated location.
225222
local -r bin=$( (ls -t "${locations[@]}" 2>/dev/null || true) | head -1 )

0 commit comments

Comments
 (0)