-
-
Notifications
You must be signed in to change notification settings - Fork 665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatic mobile platforms detection (transition from cpu and crosstool_top) #2443
Comments
On the other hand, one could get away with |
Here is a quick draft. Basically, if diff --git a/go/private/rules/transition.bzl b/go/private/rules/transition.bzl
index 9c3b3583..39294519 100644
--- a/go/private/rules/transition.bzl
+++ b/go/private/rules/transition.bzl
@@ -100,6 +100,36 @@ def go_transition_rule(**kwargs):
kwargs["cfg"] = go_transition
return rule(**kwargs)
+_ANDROID_CPUS_TO_TOOLCHAIN = {
+ "arm64-v8a": "android_arm64",
+ "armeabi-v7a": "android_arm",
+ "x86": "android_386",
+ "x86_64": "android_amd64",
+}
+
+_IOS_CPUS_TO_TOOLCHAIN = {
+ "ios_arm64": "ios_arm64",
+ "ios_armv7": "ios_arm",
+ "ios_i386": "ios_386",
+ "ios_x86_64": "ios_amd64",
+}
+
+def android_toolchain(crosstool_top, cpu):
+ return \
+ (str(crosstool_top) == "//external:android/crosstool" or \
+ crosstool_top.workspace_name == "androidndk") and \
+ _ANDROID_CPUS_TO_TOOLCHAIN.get(cpu)
+
+def ios_toolchain(crosstool_top, cpu):
+ return _IOS_CPUS_TO_TOOLCHAIN.get(cpu)
+
+def detect_mobile_platforms(settings):
+ crosstool_top = settings.pop("//command_line_option:crosstool_top")
+ cpu = settings.pop("//command_line_option:cpu")
+ toolchain = android_toolchain(crosstool_top, cpu) or ios_toolchain(crosstool_top, cpu)
+ if toolchain:
+ settings["//command_line_option:platforms"] = "@io_bazel_rules_go//go/toolchain:%s_cgo" % toolchain
+
def _go_transition_impl(settings, attr):
settings = dict(settings)
goos = getattr(attr, "goos", "auto")
@@ -118,6 +148,8 @@ def _go_transition_impl(settings, attr):
fail('pure is "off" but cgo is not supported on {} {}'.format(goos, goarch))
platform = "@io_bazel_rules_go//go/toolchain:{}_{}{}".format(goos, goarch, "_cgo" if cgo else "")
settings["//command_line_option:platforms"] = platform
+ else:
+ detect_mobile_platform(settings)
if pure != "auto":
pure_label = _filter_transition_label("@io_bazel_rules_go//go/config:pure")
settings[pure_label] = pure == "on"
@@ -138,6 +170,8 @@ def _go_transition_impl(settings, attr):
go_transition = transition(
implementation = _go_transition_impl,
inputs = [_filter_transition_label(label) for label in [
+ "//command_line_option:cpu",
+ "//command_line_option:crosstool_top",
"//command_line_option:platforms",
"@io_bazel_rules_go//go/config:static",
"@io_bazel_rules_go//go/config:msan", |
When combined with #2445, adding a
Which is really cool IMHO. |
Sounds like it could work, but I don't understand how Android / iOS targets are built well enough to implement or maintain it. I'd be very nervous about adding something like this. Just to confirm my understanding, this would let you build an Are there tracking issues for when Android / iOS would support I wonder if, instead, it would make more sense to have a separate rule that does this transition while depending on a regular
This would be less magical, but I imagine it would be a lot more straightforward for you to maintain, and probably useful in other situations as well. |
I don't think having another target is the way to go. When #2445 is implemented, depending on It seems the generic issue is transiting the platform based on inbound I figure iOS and Android rules are so widely used that it makes sense to have special cases for them, such as what exists in Impacted platforms would be macOS, iOS, TvOS, WatchOS and Android. |
The maintainability is a good point, however. I can work on something more generic in the transition to separate inbound values from actual mobile stuff. Something like I expect maintainability to be low. |
A quick V2 to get the mood. This is the sort of organisation i'd like to have, separated in diff --git a/go/platform/crosstool.bzl b/go/platform/crosstool.bzl
new file mode 100644
index 00000000..6839476c
--- /dev/null
+++ b/go/platform/crosstool.bzl
@@ -0,0 +1,32 @@
+def _match_apple(crosstool_top, cpu):
+ platform = {
+ "darwin_x86_64": "darwin_amd64",
+ "ios_arm64": "ios_arm64",
+ "ios_armv7": "ios_arm",
+ "ios_i386": "ios_386",
+ "ios_x86_64": "ios_amd64",
+ }.get(cpu)
+ if platform:
+ return "%s_cgo" % platform
+
+def _match_android(crosstool_top, cpu):
+ if str(crosstool_top) == "//external:android/crosstool" or \
+ crosstool_top.workspace_name == "androidndk":
+ platform_cpu = {
+ "arm64-v8a": "arm64",
+ "armeabi-v7a": "arm",
+ "x86": "386",
+ "x86_64": "amd64",
+ }.get(cpu)
+ if platform_cpu:
+ return "android_%s_cgo" % platform_cpu
+
+def platform_from_crosstool(crosstool_top, cpu):
+ matchers = [
+ _match_apple,
+ _match_android,
+ ]
+ for matcher in matchers:
+ platform = matcher(crosstool, cpu)
+ if platform:
+ return "@io_bazel_rules_go//go/toolchain:%s" % platform
diff --git a/go/private/rules/transition.bzl b/go/private/rules/transition.bzl
index 9c3b3583..ed0584e5 100644
--- a/go/private/rules/transition.bzl
+++ b/go/private/rules/transition.bzl
@@ -25,6 +25,10 @@ load(
"@io_bazel_rules_go_name_hack//:def.bzl",
"IS_RULES_GO",
)
+load(
+ "@io_bazel_rules_go//go/platform:crosstool.bzl",
+ "platform_from_crosstool",
+)
def _filter_transition_label(label):
"""Transforms transition labels for the current workspace.
@@ -106,6 +110,8 @@ def _go_transition_impl(settings, attr):
goarch = getattr(attr, "goarch", "auto")
pure = getattr(attr, "pure", "auto")
_check_ternary("pure", pure)
+ crosstool_top = settings.pop("//command_line_option:crosstool_top")
+ cpu = settings.pop("//command_line_option:cpu")
if goos != "auto" or goarch != "auto":
if goos == "auto":
fail("goos must be set if goarch is set")
@@ -118,6 +124,10 @@ def _go_transition_impl(settings, attr):
fail('pure is "off" but cgo is not supported on {} {}'.format(goos, goarch))
platform = "@io_bazel_rules_go//go/toolchain:{}_{}{}".format(goos, goarch, "_cgo" if cgo else "")
settings["//command_line_option:platforms"] = platform
+ else:
+ platform = platform_from_crosstool(crosstool_top, cpu)
+ if platform:
+ settings["//command_line_option:platforms"] = platform
if pure != "auto":
pure_label = _filter_transition_label("@io_bazel_rules_go//go/config:pure")
settings[pure_label] = pure == "on"
|
Also, unfortunately this doesn't work: def _go_mobile_binary_impl(ctx):
return [ctx.attr.dep[p] for p in [DefaultInfo, CcInfo, GoArchive, GoSource, GoLibrary]] bazel will complain that the executable in |
As of Bazel 3.0, Android and iOS rules do not set constraints (android toolchain can be selected via a constraint, however).
I propose to add an automatic transition step for those, so that the use is seamless. The code is pretty simple and straightforward.
Perhaps could even be added to #2433.
I know ideally those rules shoud set constraints and
rules_go
would follow along, but from what I'd wager, it's really not there yet, so I think it could be a cool stopgap solution.The text was updated successfully, but these errors were encountered: