Skip to content

Commit

Permalink
Add initial visionOS support (#2014)
Browse files Browse the repository at this point in the history
  • Loading branch information
keith committed Sep 7, 2023
1 parent 5896714 commit 22d5dd8
Show file tree
Hide file tree
Showing 61 changed files with 3,631 additions and 28 deletions.
2 changes: 2 additions & 0 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ x_defaults:
- --test_tag_filters=-skipci
common_last_green: &common_last_green
bazel: last_green
build_flags:
- --config=visionos
test_flags:
- --test_tag_filters=-skipci

Expand Down
2 changes: 2 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ build --enable_platform_specific_config
build:macos --apple_crosstool_top=@local_config_apple_cc//:toolchain
build:macos --crosstool_top=@local_config_apple_cc//:toolchain
build:macos --host_crosstool_top=@local_config_apple_cc//:toolchain

build:visionos --platform_mappings=platform_mappings_visionos
19 changes: 19 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")

licenses(["notice"])

exports_files(["LICENSE"])
Expand Down Expand Up @@ -26,3 +28,20 @@ filegroup(
"//:__subpackages__",
],
)

config_setting(
name = "supports_visionos_setting",
flag_values = {
":supports_visionos": "True",
},
visibility = [
"//examples:__subpackages__",
"//test:__subpackages__",
],
)

bool_flag(
name = "supports_visionos",
build_setting_default = False,
visibility = ["//visibility:private"],
)
19 changes: 19 additions & 0 deletions apple/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ bzl_library(
name = "apple_binary",
srcs = ["apple_binary.bzl"],
deps = [
"//apple/internal:apple_toolchains",
"//apple/internal:linking_support",
"//apple/internal:rule_attrs",
"//apple/internal:rule_factory",
Expand All @@ -59,6 +60,7 @@ bzl_library(
srcs = ["apple_static_library.bzl"],
deps = [
":providers",
"//apple/internal:apple_toolchains",
"//apple/internal:linking_support",
"//apple/internal:providers",
"//apple/internal:rule_attrs",
Expand Down Expand Up @@ -204,6 +206,23 @@ bzl_library(
],
)

bzl_library(
name = "visionos",
srcs = ["visionos.bzl"],
deps = [
"//apple/internal:visionos_rules",
"//apple/internal/testing:apple_test_assembler",
"//apple/internal/testing:build_test_rules",
"//apple/internal/testing:visionos_rules",
],
)

bzl_library(
name = "visionos.doc",
srcs = ["visionos.doc.bzl"],
deps = ["visionos"],
)

bzl_library(
name = "watchos",
srcs = ["watchos.bzl"],
Expand Down
10 changes: 10 additions & 0 deletions apple/apple_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ def _linker_flag_for_sdk_dylib(dylib):
return "-l{}".format(dylib)

def _apple_binary_impl(ctx):
# Fail early if using the not yet fully supported visionOS platform type outside of testing.
if ctx.attr.platform_type == "visionos":
xcode_version_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]
if xcode_version_config.xcode_version() < apple_common.dotted_version("15.0"):
fail("""
visionOS binaries require a visionOS SDK provided by Xcode 15 or later.
Resolved Xcode is version {xcode_version}.
""".format(xcode_version = str(xcode_version_config.xcode_version())))

binary_type = ctx.attr.binary_type
bundle_loader = ctx.attr.bundle_loader

Expand Down
19 changes: 15 additions & 4 deletions apple/apple_static_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@

"""apple_static_library Starlark implementation"""

load(
"@build_bazel_rules_apple//apple/internal:transition_support.bzl",
"transition_support",
)
load(
"@build_bazel_rules_apple//apple/internal:linking_support.bzl",
"linking_support",
Expand All @@ -34,12 +30,26 @@ load(
"@build_bazel_rules_apple//apple/internal:rule_factory.bzl",
"rule_factory",
)
load(
"@build_bazel_rules_apple//apple/internal:transition_support.bzl",
"transition_support",
)
load(
"@build_bazel_rules_apple//apple:providers.bzl",
"ApplePlatformInfo",
)

def _apple_static_library_impl(ctx):
# Fail early if using the not yet fully supported visionOS platform type outside of testing.
if ctx.attr.platform_type == "visionos":
xcode_version_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]
if xcode_version_config.xcode_version() < apple_common.dotted_version("15.0"):
fail("""
visionOS static libraries require a visionOS SDK provided by Xcode 15 or later.
Resolved Xcode is version {xcode_version}.
""".format(xcode_version = str(xcode_version_config.xcode_version())))

# Most validation of the platform type and minimum version OS currently happens in
# `transition_support.apple_platform_split_transition`, either implicitly through native
# `dotted_version` or explicitly through `fail` on an unrecognized platform type value.
Expand Down Expand Up @@ -161,6 +171,7 @@ binaries/libraries will be created combining all architectures specified by
* `ios`: architectures gathered from `--ios_multi_cpus`.
* `macos`: architectures gathered from `--macos_cpus`.
* `tvos`: architectures gathered from `--tvos_cpus`.
* `visionos`: architectures gathered from `--visionos_cpus`.
* `watchos`: architectures gathered from `--watchos_cpus`.
""",
),
Expand Down
6 changes: 6 additions & 0 deletions apple/cc_toolchain_forwarder.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def _target_os_from_rule_ctx(ctx):
ios_constraint = ctx.attr._ios_constraint[platform_common.ConstraintValueInfo]
macos_constraint = ctx.attr._macos_constraint[platform_common.ConstraintValueInfo]
tvos_constraint = ctx.attr._tvos_constraint[platform_common.ConstraintValueInfo]
visionos_constraint = ctx.attr._visionos_constraint[platform_common.ConstraintValueInfo]
watchos_constraint = ctx.attr._watchos_constraint[platform_common.ConstraintValueInfo]

if ctx.target_platform_has_constraint(ios_constraint):
Expand All @@ -33,6 +34,8 @@ def _target_os_from_rule_ctx(ctx):
return str(apple_common.platform_type.macos)
elif ctx.target_platform_has_constraint(tvos_constraint):
return str(apple_common.platform_type.tvos)
elif ctx.target_platform_has_constraint(visionos_constraint):
return str(getattr(apple_common.platform_type, "visionos", None))
elif ctx.target_platform_has_constraint(watchos_constraint):
return str(apple_common.platform_type.watchos)
fail("ERROR: A valid Apple platform constraint could not be found from the resolved toolchain.")
Expand Down Expand Up @@ -92,6 +95,9 @@ cc_toolchain_forwarder = rule(
"_tvos_constraint": attr.label(
default = Label("@platforms//os:tvos"),
),
"_visionos_constraint": attr.label(
default = Label("@platforms//os:visionos"),
),
"_watchos_constraint": attr.label(
default = Label("@platforms//os:watchos"),
),
Expand Down
43 changes: 43 additions & 0 deletions apple/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ bzl_library(
"//apple:__subpackages__",
],
deps = [
"//apple/build_settings",
"@bazel_skylib//lib:dicts",
],
)
Expand Down Expand Up @@ -670,6 +671,39 @@ bzl_library(
],
)

bzl_library(
name = "visionos_rules",
srcs = ["visionos_rules.bzl"],
visibility = [
"//apple:__subpackages__",
],
deps = [
":apple_product_type",
":apple_toolchains",
":bundling_support",
":entitlements_support",
":features_support",
":linking_support",
":outputs",
":partials",
":platform_support",
":processor",
":providers",
":resources",
":rule_attrs",
":rule_factory",
":rule_support",
":stub_support",
":swift_support",
"//apple:providers",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/utils:clang_rt_dylibs",
"@bazel_skylib//lib:sets",
"@bazel_tools//tools/cpp:toolchain_utils.bzl",
],
)

bzl_library(
name = "watchos_rules",
srcs = ["watchos_rules.bzl"],
Expand Down Expand Up @@ -811,6 +845,15 @@ environment_plist(
visibility = ["//visibility:public"],
)

environment_plist(
name = "environment_plist_visionos",
platform_type = "visionos",
# Used by the rule implementations, so it needs to be public; but
# should be considered an implementation detail of the rules and
# not used by other things.
visibility = ["//visibility:public"],
)

environment_plist(
name = "environment_plist_watchos",
platform_type = "watchos",
Expand Down
2 changes: 1 addition & 1 deletion apple/internal/apple_framework_import.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ When linking a binary, all libraries named in that binary's transitive dependenc
"sdk_frameworks": attr.string_list(
doc = """
Names of SDK frameworks to link with (e.g. `AddressBook`, `QuartzCore`). `UIKit` and `Foundation`
are always included when building for the iOS, tvOS and watchOS platforms. For macOS, only
are always included when building for the iOS, tvOS, visionOS, and watchOS platforms. For macOS, only
`Foundation` is always included. When linking a top level binary, all SDK frameworks listed in that
binary's transitive dependency graph are linked.
""",
Expand Down
2 changes: 1 addition & 1 deletion apple/internal/apple_universal_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ The `lipo` tool is used to combine built binaries of multiple architectures.
An optional list of target CPUs for which the universal binary should be built.
If this attribute is present, the value of the platform-specific CPU flag
(`--ios_multi_cpus`, `--macos_cpus`, `--tvos_cpus`, or `--watchos_cpus`) will be
(`--ios_multi_cpus`, `--macos_cpus`, `--tvos_cpus`, `--visionos_cpus`, or `--watchos_cpus`) will be
ignored and the binary will be built for all of the specified architectures
instead.
Expand Down
2 changes: 1 addition & 1 deletion apple/internal/apple_xcframework_import.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ When linking a binary, all libraries named in that binary's transitive dependenc
"sdk_frameworks": attr.string_list(
doc = """
Names of SDK frameworks to link with (e.g. `AddressBook`, `QuartzCore`). `UIKit` and `Foundation`
are always included when building for the iOS, tvOS and watchOS platforms. For macOS, only
are always included when building for the iOS, tvOS, visionOS and watchOS platforms. For macOS, only
`Foundation` is always included. When linking a top level binary, all SDK frameworks listed in that
binary's transitive dependency graph are linked.
""",
Expand Down
6 changes: 6 additions & 0 deletions apple/internal/partials/app_assets_validation.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ def _app_assets_validation_partial_impl(
app_icons,
"brandassets",
)
elif platform_prerequisites.platform_type == getattr(apple_common.platform_type, "visionos", None):
bundling_support.ensure_single_xcassets_type(
"app_icons",
app_icons,
"solidimagestack",
)
else:
bundling_support.ensure_single_xcassets_type(
"app_icons",
Expand Down
1 change: 1 addition & 0 deletions apple/internal/partials/swift_dylibs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ _MIN_OS_PLATFORM_SWIFT_PRESENCE = {
"ios": apple_common.dotted_version("15.0"),
"macos": apple_common.dotted_version("12.0"),
"tvos": apple_common.dotted_version("15.0"),
"visionos": apple_common.dotted_version("1.0"),
"watchos": apple_common.dotted_version("8.0"),
}

Expand Down
1 change: 1 addition & 0 deletions apple/internal/platform_support.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ _DEVICE_FAMILY_VALUES = {
"ipad": 2,
"tv": 3,
"watch": 4,
"reality": 7,
# We want _ui_device_family_plist_value to find None for the valid "mac"
# family since macOS doesn't use the UIDeviceFamily Info.plist key, but we
# still want to catch invalid families with a KeyError.
Expand Down
2 changes: 1 addition & 1 deletion apple/internal/processor.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Location types can be:
- watch: Files are to be placed inside the Watch section of the bundle. Only applicable for iOS
apps.
For iOS, tvOS and watchOS, binary, content and resources all refer to the same
For iOS, tvOS, visionOS, and watchOS, binary, content and resources all refer to the same
location. Only in macOS these paths differ.
All the files given will be symlinked into their expected location in the
Expand Down
66 changes: 66 additions & 0 deletions apple/internal/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,72 @@ is a tvOS .xctest bundle should use this provider to describe that requirement.
init = _make_banned_init(provider_name = "TvosXcTestBundleInfo"),
)

VisionosApplicationBundleInfo, new_visionosapplicationbundleinfo = provider(
doc = """
Denotes that a target is a visionOS application.
This provider does not contain any fields of its own at this time but is used as
a "marker" to indicate that a target is specifically a visionOS application
bundle (and not some other Apple bundle). Rule authors who wish to require that a
dependency is a visionOS application should use this provider to describe that
requirement.
""",
fields = {},
init = _make_banned_init(provider_name = "VisionosApplicationBundleInfo"),
)

VisionosExtensionBundleInfo, new_visionosextensionbundleinfo = provider(
doc = """
Denotes that a target is an visionOS application extension.
This provider does not contain any fields of its own at this time but is used as
a "marker" to indicate that a target is specifically an iOS application
extension bundle (and not some other Apple bundle). Rule authors who wish to
require that a dependency is an iOS application extension should use this
provider to describe that requirement.
""",
fields = {},
init = _make_banned_init(provider_name = "VisionosExtensionBundleInfo"),
)

VisionosFrameworkBundleInfo, new_visionosframeworkbundleinfo = provider(
doc = """
Denotes that a target is visionOS dynamic framework.
This provider does not contain any fields of its own at this time but is used as
a "marker" to indicate that a target is specifically a visionOS dynamic framework
bundle (and not some other Apple bundle). Rule authors who wish to require that
a dependency is a visionOS dynamic framework should use this provider to describe
that requirement.
""",
fields = {},
init = _make_banned_init(provider_name = "VisionosFrameworkBundleInfo"),
)

VisionosStaticFrameworkBundleInfo, new_visionosstaticframeworkbundleinfo = provider(
doc = """
Denotes that a target is an visionOS static framework.
This provider does not contain any fields of its own at this time but is used as
a "marker" to indicate that a target is specifically a visionOS static framework
bundle (and not some other Apple bundle). Rule authors who wish to require that
a dependency is a visionOS static framework should use this provider to describe
that requirement.
""",
fields = {},
init = _make_banned_init(provider_name = "VisionosStaticFrameworkBundleInfo"),
)

VisionosXcTestBundleInfo, new_visionosxctestbundleinfo = provider(
doc = """
Denotes a target that is a visionOS .xctest bundle.
This provider does not contain any fields of its own at this time but is used as
a "marker" to indicate that a target is specifically a visionOS .xctest bundle (and
not some other Apple bundle). Rule authors who wish to require that a dependency
is a visionOS .xctest bundle should use this provider to describe that requirement.
""",
fields = {},
init = _make_banned_init(provider_name = "VisionosXcTestBundleInfo"),
)

WatchosApplicationBundleInfo, new_watchosapplicationbundleinfo = provider(
doc = """
Denotes that a target is a watchOS application.
Expand Down
3 changes: 3 additions & 0 deletions apple/internal/resource_actions/actool.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ def _actool_args_for_special_file_types(
elif platform_prerequisites.platform_type == apple_common.platform_type.tvos:
appicon_extension = "brandassets"
icon_files = [f for f in asset_files if ".brandassets/" in f.path]
elif platform_prerequisites.platform_type == getattr(apple_common.platform_type, "visionos", None):
appicon_extension = "solidimagestack"
icon_files = [f for f in asset_files if ".solidimagestack/" in f.path]
else:
appicon_extension = "appiconset"
icon_files = [f for f in asset_files if ".appiconset/" in f.path]
Expand Down
1 change: 1 addition & 0 deletions apple/internal/rule_attrs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,7 @@ rule_attrs = struct(
ios = ["iphone", "ipad"],
macos = ["mac"],
tvos = ["tv"],
visionos = ["reality"],
watchos = ["watch"],
),
test_bundle_infoplist = _test_bundle_infoplist,
Expand Down

0 comments on commit 22d5dd8

Please sign in to comment.