Skip to content

Commit 85e1e12

Browse files
committed
Sync xcframework_rules with upstream
1 parent ee75682 commit 85e1e12

3 files changed

Lines changed: 1143 additions & 799 deletions

File tree

apple/internal/swift_support.bzl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,80 @@
1414

1515
"""Support functions for working with Swift."""
1616

17+
load("@build_bazel_rules_swift//swift:providers.bzl", "SwiftInfo")
1718
load(
1819
"//apple/internal/aspects:swift_usage_aspect.bzl",
1920
"SwiftUsageInfo",
2021
)
2122

23+
visibility([
24+
"//apple/...",
25+
"//test/...",
26+
])
27+
28+
def _has_only_one_non_system_swift_module(*, target):
29+
"""Indicates if the given target references any non-system Swift modules.
30+
31+
Args:
32+
target: A Target representing a dep for a given split from `deps` on the XCFramework rule.
33+
34+
Returns:
35+
`True` if a non-system module was found from the target's SwiftInfo provider, `False`
36+
otherwise.
37+
"""
38+
if SwiftInfo not in target:
39+
return False
40+
41+
module_names = []
42+
43+
# Covers both direct and transitive modules, from how the SwiftInfo provider is constructed.
44+
for module in target[SwiftInfo].transitive_modules.to_list():
45+
if module.swift and not module.is_system:
46+
module_names.append(module.name)
47+
48+
# If there is more than one non-system Swift module in the transitive modules, then there is an
49+
# invalid Swift module dependency present within deps.
50+
if len(module_names) > 1:
51+
fail("""
52+
Error: Found more than one Swift module dependency in this XCFramework's deps: \
53+
{module_names}
54+
55+
Check that you are only referencing ONE Swift module, such as from a a swift_library rule, and \
56+
that there are no additional Swift modules referenced outside of its private_deps, such as from an \
57+
additional swift_library dependency.
58+
""".format(module_names = ", ".join(module_names)))
59+
60+
return bool(module_names)
61+
62+
def _target_supporting_swift_xcframework_interfaces(targets):
63+
"""Returns a target with SwiftInfo capable of supporting Swift XCFramework interfaces.
64+
65+
If there are issues with the dependencies found, they will be raised as failures during the
66+
build's analysis phase.
67+
68+
Args:
69+
targets: A List of Targets representing `deps` for a given split on the XCFramework rule.
70+
71+
Returns:
72+
A target referencing a `SwiftInfo` provider if a module capable of supporting Swift
73+
XCFramework interfaces was found, `None` if not.
74+
"""
75+
76+
direct_swift_module = None
77+
78+
for target in targets:
79+
if _has_only_one_non_system_swift_module(target = target):
80+
# Check that there's only one direct Swift module in an XCFramework rule's deps.
81+
if not direct_swift_module:
82+
direct_swift_module = target
83+
else:
84+
fail("""
85+
Error: Found more than one non-system Swift module in the deps of this XCFramework rule. Check \
86+
that you are not directly referencing more than one swift_library rule in the deps of the rule.
87+
""")
88+
89+
return direct_swift_module
90+
2291
def _uses_swift(targets):
2392
"""Returns True if any of the given targets uses Swift.
2493
@@ -40,5 +109,6 @@ def _uses_swift(targets):
40109

41110
# Define the loadable module that lists the exported symbols in this file.
42111
swift_support = struct(
112+
target_supporting_swift_xcframework_interfaces = _target_supporting_swift_xcframework_interfaces,
43113
uses_swift = _uses_swift,
44114
)

apple/internal/transition_support.bzl

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ _IOS_ARCH_TO_64_BIT_WATCHOS = {
7272
"arm64": "arm64_32",
7373
}
7474

75+
# Set the default architecture for all platforms as 64-bit Intel.
76+
# TODO(b/246375874): Consider changing the default when a build is invoked from an Apple Silicon
77+
# Mac. The --host_cpu command line option is not guaranteed to reflect the actual host device that
78+
# dispatched the invocation.
79+
_DEFAULT_ARCH = "x86_64"
80+
7581
def _platform_specific_cpu_setting_name(platform_type):
7682
"""Returns the name of a platform-specific CPU setting.
7783
@@ -433,7 +439,8 @@ def _command_line_options_for_xcframework_platform(
433439
for target_environment in target_environments:
434440
if not platform_attr.get(target_environment):
435441
continue
436-
for arch in platform_attr[target_environment]:
442+
sorted_target_archs = sorted(platform_attr[target_environment])
443+
for arch in sorted_target_archs:
437444
resolved_environment_arch = _resolved_environment_arch_for_arch(
438445
arch = arch,
439446
environment = target_environment,
@@ -727,12 +734,30 @@ _apple_platform_split_transition = transition(
727734
outputs = _apple_rule_base_transition_outputs,
728735
)
729736

730-
def _xcframework_transition_impl(settings, attr):
737+
def _xcframework_base_transition_impl(settings, _):
738+
"""Rule transition for XCFramework rules producing SDK-adjacent artifacts."""
739+
740+
# For safety, lean on darwin_{default arch} with no incoming minimum_os_version to avoid
741+
# incoming settings meant for other platforms overriding the settings for the xcframework rule's
742+
# underlying actions, and allow for toolchain resolution in the future.
743+
return _command_line_options(
744+
environment_arch = _DEFAULT_ARCH,
745+
minimum_os_version = None,
746+
platform_type = "macos",
747+
settings = settings,
748+
)
749+
750+
_xcframework_base_transition = transition(
751+
implementation = _xcframework_base_transition_impl,
752+
inputs = _apple_rule_common_transition_inputs,
753+
outputs = _apple_rule_base_transition_outputs,
754+
)
755+
756+
def _xcframework_split_transition_impl(settings, attr):
731757
"""Starlark 1:2+ transition for generation of multiple frameworks for the current target."""
732758
output_dictionary = {}
733759

734-
# TODO(b/288582842): Update for visionOS when we're ready to support it in XCFramework rules.
735-
for platform_type in ["ios", "tvos", "visionos", "watchos", "macos"]:
760+
for platform_type in ["ios", "tvos", "watchos", "visionos", "macos"]:
736761
platform_attr = getattr(attr, platform_type, None)
737762
if not platform_attr:
738763
continue
@@ -751,7 +776,7 @@ def _xcframework_transition_impl(settings, attr):
751776
platform_attr = platform_attr,
752777
platform_type = platform_type,
753778
settings = settings,
754-
target_environments = target_environments,
779+
target_environments = sorted(target_environments),
755780
)
756781
output_dictionary = dicts.add(command_line_options, output_dictionary)
757782

@@ -761,8 +786,8 @@ def _xcframework_transition_impl(settings, attr):
761786

762787
return output_dictionary
763788

764-
_xcframework_transition = transition(
765-
implementation = _xcframework_transition_impl,
789+
_xcframework_split_transition = transition(
790+
implementation = _xcframework_split_transition_impl,
766791
inputs = _apple_rule_common_transition_inputs,
767792
outputs = _apple_rule_base_transition_outputs,
768793
)
@@ -775,5 +800,6 @@ transition_support = struct(
775800
apple_rule_transition = _apple_rule_base_transition,
776801
apple_universal_binary_rule_transition = _apple_universal_binary_rule_transition,
777802
xcframework_split_attr_key = _xcframework_split_attr_key,
778-
xcframework_transition = _xcframework_transition,
803+
xcframework_base_transition = _xcframework_base_transition,
804+
xcframework_split_transition = _xcframework_split_transition,
779805
)

0 commit comments

Comments
 (0)