From 41d5bb71ed2aade26dfa6e894e05b2b681ea523e Mon Sep 17 00:00:00 2001 From: Nicholas Levin Date: Fri, 8 Dec 2023 09:17:39 -0800 Subject: [PATCH] Have Xcode 15+ builds support the newer App Intents metadata processor logic. PiperOrigin-RevId: 589151949 --- apple/internal/aspects/BUILD | 1 + apple/internal/aspects/app_intents_aspect.bzl | 12 ++++++++++++ .../partials/app_intents_metadata_bundle.bzl | 19 +++++++++++++++---- apple/internal/providers/app_intents_info.bzl | 9 +++++++-- .../internal/resource_actions/app_intents.bzl | 12 ++++++++---- test/starlark_tests/ios_application_tests.bzl | 15 +++++++++++++++ 6 files changed, 58 insertions(+), 10 deletions(-) diff --git a/apple/internal/aspects/BUILD b/apple/internal/aspects/BUILD index af58332c38..01d849eaa8 100644 --- a/apple/internal/aspects/BUILD +++ b/apple/internal/aspects/BUILD @@ -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", ], ) diff --git a/apple/internal/aspects/app_intents_aspect.bzl b/apple/internal/aspects/app_intents_aspect.bzl index fc18323f14..06f19beddd 100644 --- a/apple/internal/aspects/app_intents_aspect.bzl +++ b/apple/internal/aspects/app_intents_aspect.bzl @@ -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", @@ -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.", ) diff --git a/apple/internal/partials/app_intents_metadata_bundle.bzl b/apple/internal/partials/app_intents_metadata_bundle.bzl index 6e10b8534f..c3217fd652 100644 --- a/apple/internal/partials/app_intents_metadata_bundle.bzl +++ b/apple/internal/partials/app_intents_metadata_bundle.bzl @@ -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 = [ @@ -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. diff --git a/apple/internal/providers/app_intents_info.bzl b/apple/internal/providers/app_intents_info.bzl index 76a33446b1..967718d4b5 100644 --- a/apple/internal/providers/app_intents_info.bzl +++ b/apple/internal/providers/app_intents_info.bzl @@ -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+.""", + }, ) diff --git a/apple/internal/resource_actions/app_intents.bzl b/apple/internal/resource_actions/app_intents.bzl index c080a5749a..f24515e379 100644 --- a/apple/internal/resource_actions/app_intents.bzl +++ b/apple/internal/resource_actions/app_intents.bzl @@ -24,6 +24,7 @@ def generate_app_intents_metadata_bundle( actions, apple_fragment, bundle_binary, + constvalues_files, source_files, label, target_triples, @@ -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. @@ -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, diff --git a/test/starlark_tests/ios_application_tests.bzl b/test/starlark_tests/ios_application_tests.bzl index 3fe3a585a0..6d6ca3decd 100644 --- a/test/starlark_tests/ios_application_tests.bzl +++ b/test/starlark_tests/ios_application_tests.bzl @@ -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),