Closed steeve closed 5 years ago
Actually, I'm not sure how we can tell bazel how to use multiple toolchains
Adding --toolchain_resolution_debug
shows the problem:
INFO: ToolchainResolution: Considering toolchain @local_config_cc//:cc-compiler-ios_arm64...
INFO: ToolchainResolution: Toolchain constraint @bazel_tools//platforms:os has value @bazel_tools//platforms:ios, which does not match value @bazel_tools//platforms:osx from the target platform @bazel_tools//platforms:target_platform
INFO: ToolchainResolution: Toolchain constraint @bazel_tools//platforms:cpu has value @bazel_tools//platforms:arm, which does not match value @bazel_tools//platforms:x86_64 from the target platform @bazel_tools//platforms:target_platform
INFO: ToolchainResolution: Rejected toolchain @local_config_cc//:cc-compiler-tvos_arm64, because of target platform mismatch
As you said, the problem seems to be that the platform
rule @io_bazel_rules_go//go/toolchain:darwin_amd64
depends on constraint_value
@bazel_tools//platforms:osx
, not @bazel_tools//platforms:ios
.
darwin
is ambiguous: as far as Go is concerned darwin/amd64
is macOS and darwin/arm64
is iOS. We should define our darwin/amd64
toolchain to be compatible with @bazel_tools//platforms:ios
. You'll probably need to define a custom platform
, but the toolchain should be resolved automatically.
Go considers android
to be a separate operating system, so I don't think we'll have the same ambiguity there.
@steeve Could you try applying the patch below? I apparently don't have a C/C++ toolchain installed for iOS, so I'm not able to test this. It's probably not complete, but it's a start.
diff --git a/go/private/go_toolchain.bzl b/go/private/go_toolchain.bzl
index 9e98fde8ba..cccfec456f 100644
--- a/go/private/go_toolchain.bzl
+++ b/go/private/go_toolchain.bzl
@@ -100,10 +100,16 @@ def go_toolchain(name, target, sdk, host = None, constraints = [], **kwargs):
if not host:
host = target
goos, _, goarch = target.partition("_")
- target_constraints = constraints + [
- "@io_bazel_rules_go//go/toolchain:" + goos,
- "@io_bazel_rules_go//go/toolchain:" + goarch,
- ]
+ if goos == "darwin" and goarch == "arm64":
+ target_constraints = [
+ "@bazel_tools//platforms:ios",
+ "@bazel_tools//platforms:aarch64",
+ ]
+ else:
+ target_constraints = constraints + [
+ "@io_bazel_rules_go//go/toolchain:" + goos,
+ "@io_bazel_rules_go//go/toolchain:" + goarch,
+ ]
host_goos, _, host_goarch = host.partition("_")
exec_constraints = [
"@io_bazel_rules_go//go/toolchain:" + host_goos,
diff --git a/go/toolchain/toolchains.bzl b/go/toolchain/toolchains.bzl
index 4094bc733e..70033792b1 100644
--- a/go/toolchain/toolchains.bzl
+++ b/go/toolchain/toolchains.bzl
@@ -45,10 +45,19 @@ def declare_constraints():
constraint_setting = "@bazel_tools//platforms:cpu",
)
for goos, goarch in GOOS_GOARCH:
- native.platform(
- name = goos + "_" + goarch,
- constraint_values = [
- ":" + goos,
- ":" + goarch,
- ],
- )
+ if goos == "darwin" and goarch == "arm64":
+ native.platform(
+ name = "darwin_arm64",
+ constraint_values = [
+ "@bazel_tools//platforms:aarch64",
+ "@bazel_tools//platforms:ios",
+ ],
+ )
+ else:
+ native.platform(
+ name = goos + "_" + goarch,
+ constraint_values = [
+ ":" + goos,
+ ":" + goarch,
+ ],
+ )
darwin
is ambiguous: as far as Go is concerneddarwin/amd64
is macOS anddarwin/arm64
is iOS.
That's even more twisted than that: darwin_386
and darwin_amd64
can also mean iOS (iPhoneSimulator). We differentiate based on the cpu after (in https://github.com/bazelbuild/rules_go/blob/master/go/platform/apple.bzl). Perhaps defining an ios
virtual GOOS would do the trick ?
Also, bazel defines both archs as being arm
(perhaps that's a bug though):
"ios_armv7": ["@bazel_tools//platforms:ios", "@bazel_tools//platforms:arm"],
"ios_arm64": ["@bazel_tools//platforms:ios", "@bazel_tools//platforms:arm"],
That would mean darwin_386
and darwin_arm64
would define the same constraint values, so I'm not sure how the Go toolchain would properly resolve?
Thank you for the diff! I'll try that and so how I can go from that approach.
That's even more twisted than that: darwin_386 and darwin_amd64 can also mean iOS (iPhoneSimulator). We differentiate based on the cpu after (in https://github.com/bazelbuild/rules_go/blob/master/go/platform/apple.bzl). Perhaps defining an ios virtual GOOS would do the trick ?
I think it would be fine to define platform
and toolchain
that depend on the ios
constraint_value
but set GOOS=darwin
for the purpose of Go compile and linking. I'd much prefer that to the special case in the patch above, I mostly meant that to be diagnostic.
Also, bazel defines both archs as being arm (perhaps that's a bug though):
Seems like a bug. Maybe that's why I couldn't get it to work yesterday? Can you reproduce that just with objc_library
or cc_library
? If so, please report in bazelbuild/bazel.
Seems like a bug.
I've opened https://github.com/bazelbuild/bazel/issues/8520 just in case
I'm not sure what you want me to reproduce though?
I think it would be fine to define platform and toolchain that depend on the ios constraint_value but set GOOS=darwin for the purpose of Go compile and linking. I'd much prefer that to the special case in the patch above, I mostly meant that to be diagnostic.
I agree that's the way to go. Actually I find it rather nicer than how Go itself does it to be honest.
So far I have this
diff --git a/go/platform/list.bzl b/go/platform/list.bzl
index ec6ec797..a0dad29e 100644
--- a/go/platform/list.bzl
+++ b/go/platform/list.bzl
@@ -13,8 +13,9 @@
# limitations under the License.
GOOS = {
- "android": None,
+ "android": "@bazel_tools//platforms:android",
"darwin": "@bazel_tools//platforms:osx",
+ "ios": "@bazel_tools//platforms:ios",
"dragonfly": None,
"freebsd": "@bazel_tools//platforms:freebsd",
"linux": "@bazel_tools//platforms:linux",
@@ -52,6 +53,10 @@ GOOS_GOARCH = (
("darwin", "amd64"),
("darwin", "arm"),
("darwin", "arm64"),
+ ("ios", "386"),
+ ("ios", "amd64"),
+ ("ios", "arm"),
+ ("ios", "arm64"),
("dragonfly", "amd64"),
("freebsd", "386"),
("freebsd", "amd64"),
Where would you like to see the ios -> darwin
substitution happen ?
I was thinking in _go_toolchain_impl
but it can be deeper perhaps ?
So this works, save for the aarch64
bug:
diff --git a/go/platform/list.bzl b/go/platform/list.bzl
index ec6ec797..a0dad29e 100644
--- a/go/platform/list.bzl
+++ b/go/platform/list.bzl
@@ -13,8 +13,9 @@
# limitations under the License.
GOOS = {
- "android": None,
+ "android": "@bazel_tools//platforms:android",
"darwin": "@bazel_tools//platforms:osx",
+ "ios": "@bazel_tools//platforms:ios",
"dragonfly": None,
"freebsd": "@bazel_tools//platforms:freebsd",
"linux": "@bazel_tools//platforms:linux",
@@ -52,6 +53,10 @@ GOOS_GOARCH = (
("darwin", "amd64"),
("darwin", "arm"),
("darwin", "arm64"),
+ ("ios", "386"),
+ ("ios", "amd64"),
+ ("ios", "arm"),
+ ("ios", "arm64"),
("dragonfly", "amd64"),
("freebsd", "386"),
("freebsd", "amd64"),
diff --git a/go/private/go_toolchain.bzl b/go/private/go_toolchain.bzl
index 9e98fde8..ee4e7933 100644
--- a/go/private/go_toolchain.bzl
+++ b/go/private/go_toolchain.bzl
@@ -31,12 +31,15 @@ load("@io_bazel_rules_go//go/private:actions/stdlib.bzl", "emit_stdlib")
def _go_toolchain_impl(ctx):
sdk = ctx.attr.sdk[GoSDK]
- cross_compile = ctx.attr.goos != sdk.goos or ctx.attr.goarch != sdk.goarch
+ goos = ctx.attr.goos
+ if goos == "ios":
+ goos = "darwin"
+ cross_compile = goos != sdk.goos or ctx.attr.goarch != sdk.goarch
return [platform_common.ToolchainInfo(
# Public fields
name = ctx.label.name,
cross_compile = cross_compile,
- default_goos = ctx.attr.goos,
+ default_goos = goos,
default_goarch = ctx.attr.goarch,
actions = struct(
archive = emit_archive,
I tried to push the luck into having the ios
-> darwin
substitution happen only on go.env
, but it would fail in weird ways, probably because of installsuffix
Also, ios_arm64
and android_arm64
are broken because of https://github.com/bazelbuild/bazel/issues/8520. I've opened https://github.com/bazelbuild/bazel/pull/8522 to fix that.
I've started to work on a fix for this. Currently, we have a GOOS_GOARCH table of valid platforms, and everything is generated from that. I'm working on expanding this to be a wider table with struct elements. The GOOS and GOARCH may be independent from the constraint_values.
I'd rather not introduce ios as anything other than a prefix for a few platform and toolchain targets. It's not a real GOOS value. I haven't figured out how "@io_bazel_rules_go//go/platform:darwin" is going to work yet in select. Need to experiment more.
By the way, I've tested 0.26.1-rc1
and constraining on @bazel_tools//platforms:ios
and @bazel_tools//platforms:arm
/aarch64
works. Save for the select()
issue of course.
As I said in the PR: A gazelle change may be required as now this select doesn't work:
deps = select({
"@io_bazel_rules_go//go/platform:darwin": [
"//vendor/golang.org/x/sys/unix:go_default_library",
],
Perhaps it should be:
deps = select({
"@io_bazel_rules_go//go/platform:darwin": [
"//vendor/golang.org/x/sys/unix:go_default_library",
],
"@io_bazel_rules_go//go/platform:ios": [
"//vendor/golang.org/x/sys/unix:go_default_library",
],
What version of rules_go are you using?
What version of gazelle are you using?
What version of Bazel are you using?
Does this issue reproduce with the latest releases of all the above?
Yes.
What operating system and processor architecture are you using?
The problem
Bazel 0.26 ships with new platform enabled toolchains, which are defined like this:
Rules go uses the following constraints:
Now the problem is that it then becomes impossible to build for iOS since the toolchain requires
@bazel_tools//platforms:ios
and@bazel_tools//platforms:arm
but compiling fordarwin_arm64
requires/enforces@bazel_tools//platforms:osx
and@bazel_tools//platforms:aarch64
.I'm not sure what to do here since we can't apply both
osx
andios
constraints on the sameconstaint_setting
.