Skip to content

Commit

Permalink
Have Xcode 15+ builds support the newer App Intents metadata processo…
Browse files Browse the repository at this point in the history
…r logic.

PiperOrigin-RevId: 589151949
  • Loading branch information
nglevin authored and swiple-rules-gardener committed Dec 8, 2023
1 parent 4d951fb commit 41d5bb7
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
1 change: 1 addition & 0 deletions apple/internal/aspects/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ bzl_library(
deps = [
"//apple/internal:cc_info_support",
"//apple/internal/providers:app_intents_info",
"@build_bazel_apple_support//lib:apple_support",
],
)

Expand Down
12 changes: 12 additions & 0 deletions apple/internal/aspects/app_intents_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

"""Implementation of the aspect that propagates AppIntentsInfo providers."""

load(
"@build_bazel_apple_support//lib:apple_support.bzl",
"apple_support",
)
load("@build_bazel_rules_apple//apple/internal:cc_info_support.bzl", "cc_info_support")
load(
"@build_bazel_rules_apple//apple/internal/providers:app_intents_info.bzl",
Expand All @@ -34,13 +38,21 @@ def _app_intents_aspect_impl(target, ctx):
"Found the following SDK frameworks: %s" % sdk_frameworks.to_list(),
)

swiftconstvalues_files = []
xcode_version_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig]
if xcode_version_config.xcode_version() >= apple_common.dotted_version("15.0"):
swiftconstvalues_files = target[OutputGroupInfo]["const_values"].to_list()

return [
AppIntentsInfo(
swift_source_files = ctx.rule.files.srcs,
swiftconstvalues_files = swiftconstvalues_files,
),
]

app_intents_aspect = aspect(
implementation = _app_intents_aspect_impl,
# The only attrs required for this aspect are for the `xcode_version` >= 15.0 check above.
attrs = apple_support.action_required_attrs(),
doc = "Collects Swift source files from swift_library targets required by AppIntents tooling.",
)
19 changes: 15 additions & 4 deletions apple/internal/partials/app_intents_metadata_bundle.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,25 @@ def _app_intents_metadata_bundle_partial_impl(
label.name + "_app_intents_stub_binary",
)

# Mirroring Xcode 15+ behavior, the metadata tool only looks at the first split for a given arch
# rather than every possible set of source files and inputs. Oddly, this only applies to the
# swift source files and the swiftconstvalues files; the triples and other files do cover all
# available archs.
first_cc_toolchain_key = cc_toolchains.keys()[0]

metadata_bundle = generate_app_intents_metadata_bundle(
actions = actions,
apple_fragment = platform_prerequisites.apple_fragment,
bundle_binary = fat_stub_binary,
constvalues_files = [
swiftconstvalues_file
for dep in deps[first_cc_toolchain_key]
for swiftconstvalues_file in dep[AppIntentsInfo].swiftconstvalues_files
],
label = label,
source_files = [
swift_source_file
for split_deps in deps.values()
for dep in split_deps
for dep in deps[first_cc_toolchain_key]
for swift_source_file in dep[AppIntentsInfo].swift_source_files
],
target_triples = [
Expand Down Expand Up @@ -138,9 +148,10 @@ def app_intents_metadata_bundle_partial(
Args:
actions: The actions provider from ctx.actions.
cc_toolchains: Dictionary of CcToolchainInfo providers for current target splits.
cc_toolchains: Dictionary of CcToolchainInfo and ApplePlatformInfo providers under a split
transition to relay target platform information.
ctx: The Starlark context for a rule target being built.
deps: List of dependencies implementing the AppIntents protocol.
deps: Dictionary of targets under a split transition implementing the AppIntents protocol.
disabled_features: List of features to be disabled for C++ link actions.
features: List of features to be enabled for C++ link actions.
label: Label of the target being built.
Expand Down
9 changes: 7 additions & 2 deletions apple/internal/providers/app_intents_info.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
visibility("//apple/internal/...")

AppIntentsInfo = provider(
doc = "Private provider to propagate `.swift` source files required by AppIntents processing.",
fields = ["swift_source_files"],
doc = "Private provider to propagate source files required by AppIntents processing.",
fields = {
"swift_source_files": """
A List with the swift source Files to handle via app intents processing.""",
"swiftconstvalues_files": """
A List with the swiftconstvalues Files to handle via app intents processing for Xcode 15+.""",
},
)
12 changes: 8 additions & 4 deletions apple/internal/resource_actions/app_intents.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def generate_app_intents_metadata_bundle(
actions,
apple_fragment,
bundle_binary,
constvalues_files,
source_files,
label,
target_triples,
Expand All @@ -34,6 +35,8 @@ def generate_app_intents_metadata_bundle(
actions: The actions provider from `ctx.actions`.
apple_fragment: An Apple fragment (ctx.fragments.apple).
bundle_binary: File referencing an application/extension/framework binary.
constvalues_files: List of swiftconstvalues files generated from Swift source files
implementing the AppIntents protocol.
source_files: List of Swift source files implementing the AppIntents protocol.
label: Label for the current target (`ctx.label`).
target_triples: List of Apple target triples from `CcToolchainInfo` providers.
Expand All @@ -56,22 +59,23 @@ def generate_app_intents_metadata_bundle(
args.add("--module-name", label.name)
args.add("--output", output.dirname)
args.add_all("--source-files", source_files)
transitive_inputs = [depset(source_files)]
args.add("--sdk-root", apple_support.path_placeholders.sdkroot())
args.add_all(target_triples, before_each = "--target-triple")
args.add("--toolchain-dir", "{xcode_path}/Toolchains/XcodeDefault.xctoolchain".format(
xcode_path = apple_support.path_placeholders.xcode(),
))
if xcode_version_config.xcode_version() >= apple_common.dotted_version("15.0"):
# TODO(b/295227222): Generate app intents metadata with --compile-time-extraction using
# .swiftconstvals instead of --legacy-extraction at the earliest convenience.
args.add("--legacy-extraction")
args.add_all("--swift-const-vals", constvalues_files)
transitive_inputs.append(depset(constvalues_files))
args.add("--compile-time-extraction")

apple_support.run(
actions = actions,
apple_fragment = apple_fragment,
arguments = [args],
executable = "/usr/bin/xcrun",
inputs = depset([bundle_binary], transitive = [depset(source_files)]),
inputs = depset([bundle_binary], transitive = transitive_inputs),
outputs = [output],
mnemonic = "AppIntentsMetadataProcessor",
xcode_config = xcode_version_config,
Expand Down
15 changes: 15 additions & 0 deletions test/starlark_tests/ios_application_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,21 @@ def ios_application_test_suite(name):
tags = [name],
)

# Test app with App Intents generates and bundles Metadata.appintents bundle for fat binaries.
archive_contents_test(
name = "{}_fat_build_contains_app_intents_metadata_bundle_test".format(name),
build_type = "simulator",
cpus = {
"ios_multi_cpus": ["x86_64", "sim_arm64"],
},
target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_app_intents",
contains = [
"$BUNDLE_ROOT/Metadata.appintents/extract.actionsdata",
"$BUNDLE_ROOT/Metadata.appintents/version.json",
],
tags = [name],
)

# Test Metadata.appintents bundle contents for simulator and device.
archive_contents_test(
name = "{}_metadata_appintents_bundle_contents_for_simulator_test".format(name),
Expand Down

1 comment on commit 41d5bb7

@keith
Copy link
Member

@keith keith commented on 41d5bb7 Feb 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.