From 882ac4a92129e1d8a958fa2487aca3d976d67e82 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Wed, 21 Aug 2024 13:12:54 -0700 Subject: [PATCH 1/3] macOS: Bundle dSYM packages in FlutterMacOS.xcframework As of Xcode 16, App Store validation requires dSYMs for frameworks in app archives. Bundling dSYMs also significantly simplifies stack trace symbolification, so we should be doing this regardless. This adds both framework and simulator framework dSYMs to the FlutterMacOS.xcframework bundle. Issue: https://github.com/flutter/flutter/issues/153879 --- sky/tools/create_macos_framework.py | 74 ++++++++++++++++++----------- sky/tools/sky_utils.py | 8 +--- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/sky/tools/create_macos_framework.py b/sky/tools/create_macos_framework.py index 359fb8d86fcf8..78bfdb6af4fcb 100755 --- a/sky/tools/create_macos_framework.py +++ b/sky/tools/create_macos_framework.py @@ -64,15 +64,16 @@ def main(): # Create XCFramework from the arm64 and x64 fat framework. xcframeworks = [fat_framework] - create_xcframework(location=dst, name='FlutterMacOS', frameworks=xcframeworks) + dsyms = [fat_framework + '.dSYM'] if args.dsym else None + create_xcframework(location=dst, name='FlutterMacOS', frameworks=xcframeworks, dsyms=dsyms) if args.zip: - zip_framework(dst) + zip_framework(dst, args) return 0 -def zip_framework(dst): +def zip_framework(dst, args): framework_dst = os.path.join(dst, 'FlutterMacOS.framework') sky_utils.write_codesign_config(os.path.join(framework_dst, 'entitlements.txt'), []) sky_utils.write_codesign_config( @@ -102,40 +103,57 @@ def zip_framework(dst): final_dst_path = os.path.join(dst, 'FlutterMacOS.framework.zip') shutil.move(final_src_path, final_dst_path) - zip_xcframework_archive(dst) + zip_xcframework_archive(dst, args) + + # Generate Flutter.dSYM.zip for manual symbolification. + # + # Historically, the framework dSYM was named Flutter.dSYM, so in order to + # remain backward-compatible with existing instructions in docs/Crashes.md + # and existing tooling such as dart-lang/dart_ci, we rename back to that name + # + # TODO(cbracken): remove these archives and the upload steps once we bundle + # dSYMs in app archives. https://github.com/flutter/flutter/issues/153879 + framework_dsym = framework_dst + '.dSYM' + if os.path.exists(framework_dsym): + renamed_dsym = framework_dsym.replace('FlutterMacOS.framework.dSYM', 'FlutterMacOS.dSYM') + os.rename(framework_dsym, renamed_dsym) - dsym_dst = os.path.join(dst, 'FlutterMacOS.dSYM') - if os.path.exists(dsym_dst): # Create a zip of just the contents of the dSYM, then create a zip of that zip. # TODO(cbracken): remove this once https://github.com/flutter/flutter/issues/125067 is resolved - sky_utils.create_zip(dsym_dst, 'FlutterMacOS.dSYM.zip', ['.']) - sky_utils.create_zip(dsym_dst, 'FlutterMacOS.dSYM_.zip', ['FlutterMacOS.dSYM.zip']) + sky_utils.create_zip(renamed_dsym, 'FlutterMacOS.dSYM.zip', ['.']) + sky_utils.create_zip(renamed_dsym, 'FlutterMacOS.dSYM_.zip', ['FlutterMacOS.dSYM.zip']) # Move the double-zipped FlutterMacOS.dSYM.zip to dst. - dsym_final_src_path = os.path.join(dsym_dst, 'FlutterMacOS.dSYM_.zip') + dsym_final_src_path = os.path.join(renamed_dsym, 'FlutterMacOS.dSYM_.zip') dsym_final_dst_path = os.path.join(dst, 'FlutterMacOS.dSYM.zip') shutil.move(dsym_final_src_path, dsym_final_dst_path) -def zip_xcframework_archive(dst): - sky_utils.write_codesign_config(os.path.join(dst, 'entitlements.txt'), []) - - sky_utils.write_codesign_config( - os.path.join(dst, 'without_entitlements.txt'), [ - 'FlutterMacOS.xcframework/macos-arm64_x86_64/' - 'FlutterMacOS.framework/Versions/A/FlutterMacOS' - ] - ) - - sky_utils.create_zip( - dst, - 'framework.zip', - [ - 'FlutterMacOS.xcframework', - 'entitlements.txt', - 'without_entitlements.txt', - ], - ) +def zip_xcframework_archive(dst, args): + # pylint: disable=line-too-long + with_entitlements = [] + with_entitlements_file = os.path.join(dst, 'entitlements.txt') + sky_utils.write_codesign_config(with_entitlements_file, with_entitlements) + + without_entitlements = [ + 'FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS', + ] + if args.dsym: + without_entitlements.extend([ + 'FlutterMacOS.xcframework/macos-arm64_x86_64/dSYMs/FlutterMacOS.framework.dSYM/Contents/Resources/DWARF/FlutterMacOS', + ]) + + without_entitlements_file = os.path.join(dst, 'without_entitlements.txt') + sky_utils.write_codesign_config(without_entitlements_file, without_entitlements) + # pylint: enable=line-too-long + + zip_contents = [ + 'FlutterMacOS.xcframework', + 'entitlements.txt', + 'without_entitlements.txt', + ] + sky_utils.assert_valid_codesign_config(dst, zip_contents, with_entitlements, without_entitlements) + sky_utils.create_zip(dst, 'framework.zip', zip_contents) if __name__ == '__main__': diff --git a/sky/tools/sky_utils.py b/sky/tools/sky_utils.py index 1fcb14732595a..a00131d9b255b 100644 --- a/sky/tools/sky_utils.py +++ b/sky/tools/sky_utils.py @@ -84,7 +84,7 @@ def _contains_duplicates(strings): def _is_macho_binary(filename): """Returns True if the specified path is file and a Mach-O binary.""" - if not os.path.isfile(filename): + if os.path.islink(filename) or not os.path.isfile(filename): return False with open(filename, 'rb') as file: @@ -128,11 +128,7 @@ def create_fat_macos_framework(args, dst, fat_framework, arm64_framework, x64_fr get_mac_framework_dylib_path(x64_framework)], framework_dylib) _set_framework_permissions(fat_framework) - # Compute dsym output path, if enabled. - framework_dsym = None - if args.dsym: - framework_dsym = os.path.join(dst, get_framework_name(fat_framework) + '.dSYM') - + framework_dsym = fat_framework + '.dSYM' if args.dsym else None _process_macos_framework(args, dst, framework_dylib, framework_dsym) From 9f714f9cf47c90a7897b867f7f8a4a241e73fade Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Wed, 21 Aug 2024 20:58:14 -0700 Subject: [PATCH 2/3] Add/Update comments --- sky/tools/create_ios_framework.py | 6 ++++++ sky/tools/create_macos_framework.py | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sky/tools/create_ios_framework.py b/sky/tools/create_ios_framework.py index 91f398731a9ed..98e7d2ce9ab15 100644 --- a/sky/tools/create_ios_framework.py +++ b/sky/tools/create_ios_framework.py @@ -164,6 +164,12 @@ def create_framework( # pylint: disable=too-many-arguments def zip_archive(dst, args): # pylint: disable=line-too-long + + # When updating with_entitlements and without_entitlements, + # `binariesWithoutEntitlements` and `signedXcframeworks` should be updated in + # the framework's `verifyCodeSignedTestRunner`. + # + # See: https://github.com/flutter/flutter/blob/62382c7b83a16b3f48dc06c19a47f6b8667005a5/dev/bots/suite_runners/run_verify_binaries_codesigned_tests.dart#L82-L130 with_entitlements = ['gen_snapshot_arm64'] with_entitlements_file = os.path.join(dst, 'entitlements.txt') sky_utils.write_codesign_config(with_entitlements_file, with_entitlements) diff --git a/sky/tools/create_macos_framework.py b/sky/tools/create_macos_framework.py index 78bfdb6af4fcb..f7395f20911b9 100755 --- a/sky/tools/create_macos_framework.py +++ b/sky/tools/create_macos_framework.py @@ -74,6 +74,11 @@ def main(): def zip_framework(dst, args): + # When updating with_entitlements and without_entitlements, + # `binariesWithoutEntitlements` and `signedXcframeworks` should be updated in + # the framework's `verifyCodeSignedTestRunner`. + # + # See: https://github.com/flutter/flutter/blob/62382c7b83a16b3f48dc06c19a47f6b8667005a5/dev/bots/suite_runners/run_verify_binaries_codesigned_tests.dart#L82-L130 framework_dst = os.path.join(dst, 'FlutterMacOS.framework') sky_utils.write_codesign_config(os.path.join(framework_dst, 'entitlements.txt'), []) sky_utils.write_codesign_config( @@ -107,8 +112,8 @@ def zip_framework(dst, args): # Generate Flutter.dSYM.zip for manual symbolification. # - # Historically, the framework dSYM was named Flutter.dSYM, so in order to - # remain backward-compatible with existing instructions in docs/Crashes.md + # Historically, the framework dSYM was named FlutterMacOS.dSYM, so in order + # to remain backward-compatible with existing instructions in docs/Crashes.md # and existing tooling such as dart-lang/dart_ci, we rename back to that name # # TODO(cbracken): remove these archives and the upload steps once we bundle @@ -131,6 +136,12 @@ def zip_framework(dst, args): def zip_xcframework_archive(dst, args): # pylint: disable=line-too-long + + # When updating with_entitlements and without_entitlements, + # `binariesWithoutEntitlements` and `signedXcframeworks` should be updated in + # the framework's `verifyCodeSignedTestRunner`. + # + # See: https://github.com/flutter/flutter/blob/62382c7b83a16b3f48dc06c19a47f6b8667005a5/dev/bots/suite_runners/run_verify_binaries_codesigned_tests.dart#L82-L130 with_entitlements = [] with_entitlements_file = os.path.join(dst, 'entitlements.txt') sky_utils.write_codesign_config(with_entitlements_file, with_entitlements) From e8d994f5a5ab43e36870d919d62f22089870d072 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Thu, 22 Aug 2024 00:02:00 -0700 Subject: [PATCH 3/3] pylint --- sky/tools/create_macos_framework.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sky/tools/create_macos_framework.py b/sky/tools/create_macos_framework.py index f7395f20911b9..4649d8bae7d13 100755 --- a/sky/tools/create_macos_framework.py +++ b/sky/tools/create_macos_framework.py @@ -74,6 +74,7 @@ def main(): def zip_framework(dst, args): + # pylint: disable=line-too-long # When updating with_entitlements and without_entitlements, # `binariesWithoutEntitlements` and `signedXcframeworks` should be updated in # the framework's `verifyCodeSignedTestRunner`. @@ -89,6 +90,7 @@ def zip_framework(dst, args): ] ) sky_utils.create_zip(framework_dst, 'FlutterMacOS.framework.zip', ['.']) + # pylint: enable=line-too-long # Double zip to make it consistent with legacy artifacts. # TODO(fujino): remove this once https://github.com/flutter/flutter/issues/125067 is resolved