From 7840fee65b4280177ab05bfa881098afd7d7d04e Mon Sep 17 00:00:00 2001 From: Aaron Sky Date: Tue, 21 Jan 2025 13:55:53 -0500 Subject: [PATCH] Propagate `AppleFrameworkImportInfo` from iOS extensions (#2633) I am attempting to cover for a seemingly specific edge-case. Maybe misguided, but it can be validated with the tests on this PR. Here goes: Given an `ios_extension` that depends on an `apple_dynamic_xcframework_import` (I assume this also affects `apple_dynamic_framework_import` but have not tested it), and given an `ios_application` that bundles this extension but **does not depend on the imported framework**, then the Mach-O load command is added to the extension binary, but the framework is not bundled in `$BUNDLE_ROOT/Frameworks`. This causes the extension to crash at launch. [Slack thread for additional context.](https://bazelbuild.slack.com/archives/CD3QY5C2X/p1737049459227449) Based on my read of the code in `ios_rules.bzl`, this feels like an oversight, given that [this line](https://github.com/bazelbuild/rules_apple/blob/master/apple/internal/ios_rules.bzl#L361) takes `ctx.attr.extensions` and attempts to load `AppleFrameworkImportInfo` providers on [this line](https://github.com/bazelbuild/rules_apple/blob/master/apple/internal/partials/framework_import.bzl#L63-L68), but without this PR that doesn't seem as though it will never happen based on [this line](https://github.com/bazelbuild/rules_apple/blob/master/apple/internal/ios_rules.bzl#L1398-L1415). Happy to discuss if my interpretation is off-base! --- apple/internal/ios_rules.bzl | 18 +++++ .../apple_xcframework_import_tests.bzl | 64 +++++++++++++++++ .../targets_under_test/ios/BUILD | 70 +++++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/apple/internal/ios_rules.bzl b/apple/internal/ios_rules.bzl index 3ca6a1bf15..8bf3584b24 100644 --- a/apple/internal/ios_rules.bzl +++ b/apple/internal/ios_rules.bzl @@ -20,6 +20,7 @@ load("@build_bazel_rules_swift//swift:swift.bzl", "SwiftInfo") load( "//apple:providers.bzl", "AppleBundleInfo", + "AppleFrameworkImportInfo", "ApplePlatformInfo", "IosAppClipBundleInfo", "IosExtensionBundleInfo", @@ -84,6 +85,7 @@ load( ) load( "//apple/internal:providers.bzl", + "merge_apple_framework_import_info", "new_appleexecutablebinaryinfo", "new_appleframeworkbundleinfo", "new_iosappclipbundleinfo", @@ -1212,6 +1214,13 @@ def _ios_extension_impl(ctx): binary_artifact = link_result.binary debug_outputs = linking_support.debug_outputs_by_architecture(link_result.outputs) + targets_with_framework_import_info = ctx.attr.deps + ctx.attr.frameworks + merged_apple_framework_import_info = merge_apple_framework_import_info([ + x[AppleFrameworkImportInfo] + for x in targets_with_framework_import_info + if AppleFrameworkImportInfo in x + ]) + archive_for_embedding = outputs.archive_for_embedding( actions = actions, bundle_extension = bundle_extension, @@ -1410,6 +1419,7 @@ def _ios_extension_impl(ctx): processor_result.output_groups, ) ), + merged_apple_framework_import_info, # TODO(b/228856372): Remove when downstream users are migrated off this provider. link_result.debug_outputs_provider, ] + processor_result.providers @@ -2148,6 +2158,13 @@ def _ios_imessage_extension_impl(ctx): binary_artifact = link_result.binary debug_outputs = linking_support.debug_outputs_by_architecture(link_result.outputs) + targets_with_framework_import_info = ctx.attr.deps + ctx.attr.frameworks + merged_apple_framework_import_info = merge_apple_framework_import_info([ + x[AppleFrameworkImportInfo] + for x in targets_with_framework_import_info + if AppleFrameworkImportInfo in x + ]) + archive_for_embedding = outputs.archive_for_embedding( actions = actions, bundle_extension = bundle_extension, @@ -2317,6 +2334,7 @@ def _ios_imessage_extension_impl(ctx): processor_result.output_groups, ) ), + merged_apple_framework_import_info, # TODO(b/228856372): Remove when downstream users are migrated off this provider. link_result.debug_outputs_provider, ] + processor_result.providers diff --git a/test/starlark_tests/apple_xcframework_import_tests.bzl b/test/starlark_tests/apple_xcframework_import_tests.bzl index 7c8bc3b115..925edf0451 100644 --- a/test/starlark_tests/apple_xcframework_import_tests.bzl +++ b/test/starlark_tests/apple_xcframework_import_tests.bzl @@ -53,6 +53,70 @@ def apple_xcframework_import_test_suite(name): tags = [name], ) + archive_contents_test( + name = "{}_dynamic_xcfw_import_with_ext_ipa_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_ext_with_imported_dynamic_xcfmwk", + contains = [ + "$BUNDLE_ROOT/Frameworks/ios_dynamic_xcframework.framework/ios_dynamic_xcframework", + "$BUNDLE_ROOT/PlugIns/ext_with_imported_dynamic_xcfmwk.appex/ext_with_imported_dynamic_xcfmwk", + ], + not_contains = [ + "$BUNDLE_ROOT/PlugIns/ext_with_imported_dynamic_xcfmwk.appex/Frameworks/ios_dynamic_xcframework.framework/ios_dynamic_xcframework", + ], + tags = [name], + ) + + archive_contents_test( + name = "{}_dynamic_xcfw_import_with_ext_app_bin_rpath_load_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_ext_with_imported_dynamic_xcfmwk", + binary_test_file = "$BUNDLE_ROOT/app_with_ext_with_imported_dynamic_xcfmwk", + macho_load_commands_not_contain = ["name @rpath/ios_dynamic_xcframework.framework/ios_dynamic_xcframework (offset 24)"], + tags = [name], + ) + + archive_contents_test( + name = "{}_dynamic_xcfw_import_with_ext_app_ext_rpath_load_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_ext_with_imported_dynamic_xcfmwk", + binary_test_file = "$BUNDLE_ROOT/PlugIns/ext_with_imported_dynamic_xcfmwk.appex/ext_with_imported_dynamic_xcfmwk", + macho_load_commands_contain = ["name @rpath/ios_dynamic_xcframework.framework/ios_dynamic_xcframework (offset 24)"], + tags = [name], + ) + + archive_contents_test( + name = "{}_dynamic_xcfw_import_with_imessage_ext_ipa_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_imessage_ext_with_imported_dynamic_xcfmwk", + contains = [ + "$BUNDLE_ROOT/Frameworks/ios_dynamic_xcframework.framework/ios_dynamic_xcframework", + "$BUNDLE_ROOT/PlugIns/imessage_ext_imported_dynamic_xcfmwk.appex/imessage_ext_imported_dynamic_xcfmwk", + ], + not_contains = [ + "$BUNDLE_ROOT/PlugIns/imessage_ext_imported_dynamic_xcfmwk.appex/Frameworks/ios_dynamic_xcframework.framework/ios_dynamic_xcframework", + ], + tags = [name], + ) + + archive_contents_test( + name = "{}_dynamic_xcfw_import_with_imessage_ext_app_bin_rpath_load_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_imessage_ext_with_imported_dynamic_xcfmwk", + binary_test_file = "$BUNDLE_ROOT/app_with_imessage_ext_with_imported_dynamic_xcfmwk", + macho_load_commands_not_contain = ["name @rpath/ios_dynamic_xcframework.framework/ios_dynamic_xcframework (offset 24)"], + tags = [name], + ) + + archive_contents_test( + name = "{}_dynamic_xcfw_import_with_imessage_ext_app_ext_rpath_load_test".format(name), + build_type = "simulator", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_with_imessage_ext_with_imported_dynamic_xcfmwk", + binary_test_file = "$BUNDLE_ROOT/PlugIns/imessage_ext_imported_dynamic_xcfmwk.appex/imessage_ext_imported_dynamic_xcfmwk", + macho_load_commands_contain = ["name @rpath/ios_dynamic_xcframework.framework/ios_dynamic_xcframework (offset 24)"], + tags = [name], + ) + apple_verification_test( name = "{}_imported_dynamic_xcfmwk_codesign_test".format(name), build_type = "simulator", diff --git a/test/starlark_tests/targets_under_test/ios/BUILD b/test/starlark_tests/targets_under_test/ios/BUILD index 6d816eef8d..aff534cd81 100644 --- a/test/starlark_tests/targets_under_test/ios/BUILD +++ b/test/starlark_tests/targets_under_test/ios/BUILD @@ -3189,6 +3189,40 @@ ios_imessage_extension( ], ) +ios_application( + name = "app_with_imessage_ext_with_imported_dynamic_xcfmwk", + bundle_id = "com.google.example", + extensions = [":imessage_ext_imported_dynamic_xcfmwk"], + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = common.min_os_ios.baseline, + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = common.fixture_tags, + deps = [ + "//test/starlark_tests/resources:objc_main_lib", + ], +) + +ios_imessage_extension( + name = "imessage_ext_imported_dynamic_xcfmwk", + app_icons = ["//test/testdata/resources:message_ext_app_icon_ios"], + bundle_id = "com.google.example.MessagesExtension", + families = [ + "iphone", + "ipad", + ], + infoplists = ["//test/starlark_tests/resources:MessagesExtensionInfo.plist"], + minimum_os_version = common.min_os_ios.baseline, + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = common.fixture_tags, + deps = ["//test/starlark_tests/resources:swift_lib_importing_imported_dynamic_xcfw"], +) + ios_sticker_pack_extension( name = "sticker_ext", bundle_id = "com.google.example.stickerext", @@ -4509,6 +4543,42 @@ ios_application( ], ) +ios_application( + name = "app_with_ext_with_imported_dynamic_xcfmwk", + bundle_id = "com.google.example", + extensions = [":ext_with_imported_dynamic_xcfmwk"], + families = [ + "iphone", + "ipad", + ], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = common.min_os_ios.baseline, + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = common.fixture_tags, + deps = [ + "//test/starlark_tests/resources:objc_main_lib", + ], +) + +ios_extension( + name = "ext_with_imported_dynamic_xcfmwk", + bundle_id = "com.google.example.ext", + entitlements = "//test/starlark_tests/resources:entitlements.plist", + families = ["iphone"], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = common.min_os_ios.baseline, + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = common.fixture_tags, + deps = [ + "//test/starlark_tests/resources:objc_common_lib", + "//test/starlark_tests/resources:swift_lib_importing_imported_dynamic_xcfw", + ], +) + ios_application( name = "app_with_imported_static_xcfmwk", bundle_id = "com.google.example",