rules_go: Bazel 0.26.0 fixed the autoconfigured C++ toolchains and now break cross-compilation of Go

Hello 😃

With the fix for https://github.com/bazelbuild/bazel/issues/8330 we discovered one flaw in our design of Go cross compilation. Currently rules_go depend on C++ toolchain in //go/private:context.bzl (toolchains = ["@bazel_tools//tools/cpp:toolchain_type"]). This dependency exists no matter if we actually have C++ dependencies or not.

The problem is that with https://github.com/bazelbuild/bazel/issues/8330 C++ autoconfigured toolchains properly report their constraints, and now Bazel detects that we don’t actually have a C++ cross-compilation toolchain available. As a result the cross-compilation build of go fails:

ERROR: While resolving toolchains for target @io_bazel_rules_go//:go_context_data: no matching toolchains found for types @bazel_tools//tools/cpp:toolchain_type
ERROR: Analysis of target '//:main' failed; build aborted: no matching toolchains found for types @bazel_tools//tools/cpp:toolchain_type

To reproduce, create a hello world go_binary, and build it with bazel build //:hello_world --platforms=@io_bazel_rules_go//go/toolchain:darwin_amd64 on linux, (or if you’re on mac, use a different platform).

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 52 (42 by maintainers)

Commits related to this issue

Most upvoted comments

Just to recap where we are with this issue:

  • In some configurations, rules_go needs a C/C++ toolchain in order to build cgo code. Even if there is no cgo code, a C linker is needed in some configurations. The Go standard library also has some optional C dependencies.
  • So what rules_go really needs is an optional C/C++ toolchain dependency that’s only provided in some configurations. I’ve attempted to do that by requiring a C/C++ toolchain from @io_bazel_rules_go//:cgo_context_data, which is a dependency of @io_bazel_rules_go//:go_context_data, hidden behind a select expression which only picks it on platforms where cgo is enabled. go_context_data is a common dependency of all Go rules.
  • Bazel seems to analyze cgo_context_data even though it isn’t required. bazel cquery --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 'somepath(@io_bazel_rules_go//tests/core/go_binary:hello, @io_bazel_rules_go//:cgo_context_data)' shows that there’s no path through the configured target graph from an example binary rule to cgo_context_data. It’s possible there’s some dependency sneaking through the toolchains, or there might be a bug in Bazel.

I’ve spent several weeks analyzing this issue, and I’ve basically timeboxed it at this point. It should be fixed eventually but probably won’t be any time soon. I’d recommend folks work around this by installing a C/C++ toolchain or configuring a dummy cc_toolchain.

@hlopko the problem though is that it seems if we put a --platform, then the crosstool_top is ignored (and I guess the transition from android_crosstool_top as well)

@strican I will gracefully bow out of that decision, no idea with we have more toolchain work to accomplish. I opened a separate for the rules_docker issues.

Probably more @hlopko or @jayconrod’s call I think.

I can confirm I have the same issues as @chrislovecnm above when building with the --platforms flag set and the above WORKSPACE rule (8ea79bbd5e6ea09dc611c245d1dc09ef7ab7118a).

bazel run --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 //cmd/acmesolver:image
ERROR: While resolving toolchains for target //cmd/acmesolver:image: no matching toolchains found for types @io_bazel_rules_docker//toolchains/docker:toolchain_type
ERROR: Analysis of target '//cmd/acmesolver:image' failed; build aborted: no matching toolchains found for types @io_bazel_rules_docker//toolchains/docker:toolchain_type
INFO: Elapsed time: 18.499s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (5 packages loaded, 103 targets configured)
FAILED: Build did NOT complete successfully (5 packages loaded, 103 targets configured)

If CGO_ENABLED is how people configure cgo outside of Bazel, then let’s do this!