Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 42 additions & 11 deletions apple/internal/xcframework_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,32 @@ load(
"files",
)

def _has_non_system_swift_modules(*, target):
"""Indicates if the given target references any non-system Swift modules.

This is a reasonable signal to determine if we need to generate framework interfaces, though
correctness should be determined as well via further analysis of the graph of deps. See
b/321089167 for follow up work to that end.

Args:
target: A Target representing a dep for a given split from `deps` on the XCFramework rule.

Returns:
`True` if a non-system module was found from the target's SwiftInfo provider, `False`
otherwise.
"""
if SwiftInfo not in target:
return False

swift_info = target[SwiftInfo]

# Covers both direct and transitive modules, from how the SwiftInfo provider is constructed.
for module in swift_info.transitive_modules.to_list():
if module.swift and not module.is_system:
return True

return False

def _group_link_outputs_by_library_identifier(
*,
actions,
Expand Down Expand Up @@ -188,7 +214,7 @@ def _group_link_outputs_by_library_identifier(
dsym_binaries = {}
linkmaps = {}
split_attr_keys = []
swift_infos = {}
framework_swift_infos = {}
uses_swift = False
for link_output in link_outputs:
split_attr_key = transition_support.xcframework_split_attr_key(
Expand All @@ -200,13 +226,18 @@ def _group_link_outputs_by_library_identifier(
architectures.append(link_output.architecture)
split_attr_keys.append(split_attr_key)

# If there's any Swift dependencies on this framework rule,
# look for providers to see if we need to generate Swift interfaces.
# Determine up front if the given dep references any SwiftUsageInfo, for partial
# processing.
if swift_support.uses_swift(deps[split_attr_key]):
uses_swift = True
for dep in deps[split_attr_key]:
if SwiftInfo in dep:
swift_infos[link_output.architecture] = dep[SwiftInfo]

# If there's any Swift dependencies on this framework rule, look for providers
# referencing non-system Swift modules to see if we need to generate Swift interfaces.
for dep in deps[split_attr_key]:
# TODO(b/321089167): Fail the build if the build graph has an arrangement of Swift
# modules that is not suitable for generating frameworks.
if _has_non_system_swift_modules(target = dep):
framework_swift_infos[link_output.architecture] = dep[SwiftInfo]

# static library linking does not support dsym, and linkmaps yet.
if linking_type == "binary":
Expand All @@ -230,7 +261,7 @@ def _group_link_outputs_by_library_identifier(
linkmaps = linkmaps,
platform = platform,
split_attr_keys = split_attr_keys,
swift_infos = swift_infos,
framework_swift_infos = framework_swift_infos,
uses_swift = uses_swift,
)

Expand Down Expand Up @@ -666,14 +697,14 @@ def _apple_xcframework_impl(ctx):
),
]

if link_output.uses_swift and link_output.swift_infos:
if link_output.framework_swift_infos:
processor_partials.append(
partials.swift_framework_partial(
actions = actions,
bundle_name = bundle_name,
label_name = label.name,
output_discriminator = library_identifier,
swift_infos = link_output.swift_infos,
swift_infos = link_output.framework_swift_infos,
),
)
else:
Expand Down Expand Up @@ -968,7 +999,7 @@ def _apple_static_xcframework_impl(ctx):
))
framework_archive_files.append(depset([binary_artifact]))

if link_output.uses_swift and link_output.swift_infos:
if link_output.framework_swift_infos:
# Generate headers, modulemaps, and swiftmodules
interface_artifacts = partial.call(
partials.swift_framework_partial(
Expand All @@ -978,7 +1009,7 @@ def _apple_static_xcframework_impl(ctx):
framework_modulemap = True,
label_name = label.name,
output_discriminator = library_identifier,
swift_infos = link_output.swift_infos,
swift_infos = link_output.framework_swift_infos,
),
)
else:
Expand Down