Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0339bfe

Browse files
authored
macOS: Clean up create_ios_framework.py (#54543)
Over time, this script and others in sky/tools have accumulated a lot of additional and sometimes duplicate code. This is a first pass cleanup of create_macos_framework.py to extract common utility code to utils.py and refactor for better readability. The iOS analogue of this patch was #54500. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent f16aeed commit 0339bfe

File tree

2 files changed

+70
-111
lines changed

2 files changed

+70
-111
lines changed

sky/tools/create_macos_framework.py

Lines changed: 61 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,13 @@
55
# found in the LICENSE file.
66

77
import argparse
8-
import platform
98
import subprocess
109
import shutil
1110
import sys
1211
import os
1312

1413
from create_xcframework import create_xcframework # pylint: disable=import-error
15-
16-
buildroot_dir = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..', '..', '..'))
17-
18-
ARCH_SUBPATH = 'mac-arm64' if platform.processor() == 'arm' else 'mac-x64'
19-
DSYMUTIL = os.path.join(
20-
os.path.dirname(__file__), '..', '..', 'buildtools', ARCH_SUBPATH, 'clang', 'bin', 'dsymutil'
21-
)
22-
23-
out_dir = os.path.join(buildroot_dir, 'out')
14+
import sky_utils # pylint: disable=import-error
2415

2516

2617
def main():
@@ -33,19 +24,18 @@ def main():
3324
parser.add_argument('--x64-out-dir', type=str, required=True)
3425
parser.add_argument('--strip', action='store_true', default=False)
3526
parser.add_argument('--dsym', action='store_true', default=False)
36-
# TODO(godofredoc): Remove after recipes v2 have landed.
3727
parser.add_argument('--zip', action='store_true', default=False)
3828

3929
args = parser.parse_args()
4030

41-
dst = (args.dst if os.path.isabs(args.dst) else os.path.join(buildroot_dir, args.dst))
31+
dst = args.dst if os.path.isabs(args.dst) else sky_utils.buildroot_relative_path(args.dst)
4232
arm64_out_dir = (
43-
args.arm64_out_dir
44-
if os.path.isabs(args.arm64_out_dir) else os.path.join(buildroot_dir, args.arm64_out_dir)
33+
args.arm64_out_dir if os.path.isabs(args.arm64_out_dir) else
34+
sky_utils.buildroot_relative_path(args.arm64_out_dir)
4535
)
4636
x64_out_dir = (
4737
args.x64_out_dir
48-
if os.path.isabs(args.x64_out_dir) else os.path.join(buildroot_dir, args.x64_out_dir)
38+
if os.path.isabs(args.x64_out_dir) else sky_utils.buildroot_relative_path(args.x64_out_dir)
4939
)
5040

5141
fat_framework_bundle = os.path.join(dst, 'FlutterMacOS.framework')
@@ -71,21 +61,15 @@ def main():
7161
print('Cannot find macOS x64 dylib at %s' % x64_dylib)
7262
return 1
7363

74-
if not os.path.isfile(DSYMUTIL):
75-
print('Cannot find dsymutil at %s' % DSYMUTIL)
76-
return 1
77-
78-
shutil.rmtree(fat_framework_bundle, True)
79-
shutil.copytree(arm64_framework, fat_framework_bundle, symlinks=True)
64+
sky_utils.copy_tree(arm64_framework, fat_framework_bundle, symlinks=True)
8065

8166
regenerate_symlinks(fat_framework_bundle)
8267

8368
fat_framework_binary = os.path.join(fat_framework_bundle, 'Versions', 'A', 'FlutterMacOS')
8469

8570
# Create the arm64/x64 fat framework.
86-
subprocess.check_call([
87-
'lipo', arm64_dylib, x64_dylib, '-create', '-output', fat_framework_binary
88-
])
71+
sky_utils.lipo([arm64_dylib, x64_dylib], fat_framework_binary)
72+
8973
# Make the framework readable and executable: u=rwx,go=rx.
9074
subprocess.check_call(['chmod', '755', fat_framework_bundle])
9175

@@ -107,7 +91,8 @@ def main():
10791
xcframeworks = [fat_framework_bundle]
10892
create_xcframework(location=dst, name='FlutterMacOS', frameworks=xcframeworks)
10993

110-
zip_framework(dst, args)
94+
if args.zip:
95+
zip_framework(dst)
11196

11297
return 0
11398

@@ -143,108 +128,78 @@ def regenerate_symlinks(fat_framework_bundle):
143128
)
144129

145130

146-
def embed_codesign_configuration(config_path, content):
147-
with open(config_path, 'w') as file:
148-
file.write(content)
149-
150-
151131
def process_framework(dst, args, fat_framework_bundle, fat_framework_binary):
152132
if args.dsym:
153133
dsym_out = os.path.splitext(fat_framework_bundle)[0] + '.dSYM'
154-
subprocess.check_call([DSYMUTIL, '-o', dsym_out, fat_framework_binary])
134+
sky_utils.extract_dsym(fat_framework_binary, dsym_out)
155135
if args.zip:
156136
dsym_dst = os.path.join(dst, 'FlutterMacOS.dSYM')
157-
subprocess.check_call(['zip', '-r', '-y', 'FlutterMacOS.dSYM.zip', '.'], cwd=dsym_dst)
137+
sky_utils.create_zip(dsym_dst, 'FlutterMacOS.dSYM.zip', ['.'], symlinks=True)
158138
# Double zip to make it consistent with legacy artifacts.
159139
# TODO(fujino): remove this once https://github.com/flutter/flutter/issues/125067 is resolved
160-
subprocess.check_call([
161-
'zip',
162-
'-y',
163-
'FlutterMacOS.dSYM_.zip',
164-
'FlutterMacOS.dSYM.zip',
165-
],
166-
cwd=dsym_dst)
167-
# Use doubled zipped file.
140+
sky_utils.create_zip(dsym_dst, 'FlutterMacOS.dSYM_.zip', ['FlutterMacOS.dSYM.zip'])
141+
142+
# Overwrite the FlutterMacOS.dSYM.zip with the double-zipped archive.
168143
dsym_final_src_path = os.path.join(dsym_dst, 'FlutterMacOS.dSYM_.zip')
169144
dsym_final_dst_path = os.path.join(dst, 'FlutterMacOS.dSYM.zip')
170145
shutil.move(dsym_final_src_path, dsym_final_dst_path)
171146

172147
if args.strip:
173-
# copy unstripped
174148
unstripped_out = os.path.join(dst, 'FlutterMacOS.unstripped')
175-
shutil.copyfile(fat_framework_binary, unstripped_out)
176-
177-
subprocess.check_call(['strip', '-x', '-S', fat_framework_binary])
149+
sky_utils.strip_binary(fat_framework_binary, unstripped_out)
150+
151+
152+
def zip_framework(dst):
153+
framework_dst = os.path.join(dst, 'FlutterMacOS.framework')
154+
sky_utils.write_codesign_config(os.path.join(framework_dst, 'entitlements.txt'), [])
155+
sky_utils.write_codesign_config(
156+
os.path.join(framework_dst, 'without_entitlements.txt'),
157+
[
158+
# TODO(cbracken): Remove the zip file from the path when outer zip is removed.
159+
'FlutterMacOS.framework.zip/Versions/A/FlutterMacOS'
160+
]
161+
)
162+
sky_utils.create_zip(framework_dst, 'FlutterMacOS.framework.zip', ['.'], symlinks=True)
163+
164+
# Double zip to make it consistent with legacy artifacts.
165+
# TODO(fujino): remove this once https://github.com/flutter/flutter/issues/125067 is resolved
166+
sky_utils.create_zip(
167+
framework_dst,
168+
'FlutterMacOS.framework_.zip',
169+
[
170+
'FlutterMacOS.framework.zip',
171+
# TODO(cbracken): Move these files to inner zip before removing the outer zip.
172+
'entitlements.txt',
173+
'without_entitlements.txt',
174+
],
175+
symlinks=True
176+
)
178177

178+
# Overwrite the FlutterMacOS.framework.zip with the double-zipped archive.
179+
final_src_path = os.path.join(framework_dst, 'FlutterMacOS.framework_.zip')
180+
final_dst_path = os.path.join(dst, 'FlutterMacOS.framework.zip')
181+
shutil.move(final_src_path, final_dst_path)
179182

180-
def zip_framework(dst, args):
181-
# Zip FlutterMacOS.framework.
182-
if args.zip:
183-
filepath_with_entitlements = ''
184-
185-
framework_dst = os.path.join(dst, 'FlutterMacOS.framework')
186-
# TODO(xilaizhang): Remove the zip file from the path when outer zip is removed.
187-
filepath_without_entitlements = 'FlutterMacOS.framework.zip/Versions/A/FlutterMacOS'
188-
189-
embed_codesign_configuration(
190-
os.path.join(framework_dst, 'entitlements.txt'), filepath_with_entitlements
191-
)
192-
193-
embed_codesign_configuration(
194-
os.path.join(framework_dst, 'without_entitlements.txt'), filepath_without_entitlements
195-
)
196-
subprocess.check_call([
197-
'zip',
198-
'-r',
199-
'-y',
200-
'FlutterMacOS.framework.zip',
201-
'.',
202-
],
203-
cwd=framework_dst)
204-
# Double zip to make it consistent with legacy artifacts.
205-
# TODO(fujino): remove this once https://github.com/flutter/flutter/issues/125067 is resolved
206-
subprocess.check_call(
207-
[
208-
'zip',
209-
'-y',
210-
'FlutterMacOS.framework_.zip',
211-
'FlutterMacOS.framework.zip',
212-
# TODO(xilaizhang): Move these files to inner zip before removing the outer zip.
213-
'entitlements.txt',
214-
'without_entitlements.txt',
215-
],
216-
cwd=framework_dst
217-
)
218-
# Use doubled zipped file.
219-
final_src_path = os.path.join(framework_dst, 'FlutterMacOS.framework_.zip')
220-
final_dst_path = os.path.join(dst, 'FlutterMacOS.framework.zip')
221-
shutil.move(final_src_path, final_dst_path)
222-
223-
zip_xcframework_archive(dst)
183+
zip_xcframework_archive(dst)
224184

225185

226186
def zip_xcframework_archive(dst):
227-
filepath_with_entitlements = ''
228-
filepath_without_entitlements = (
229-
'FlutterMacOS.xcframework/macos-arm64_x86_64/'
230-
'FlutterMacOS.framework/Versions/A/FlutterMacOS'
231-
)
232-
embed_codesign_configuration(os.path.join(dst, 'entitlements.txt'), filepath_with_entitlements)
187+
sky_utils.write_codesign_config(os.path.join(dst, 'entitlements.txt'), [])
233188

234-
embed_codesign_configuration(
235-
os.path.join(dst, 'without_entitlements.txt'), filepath_without_entitlements
189+
sky_utils.write_codesign_config(
190+
os.path.join(dst, 'without_entitlements.txt'), [
191+
'FlutterMacOS.xcframework/macos-arm64_x86_64/'
192+
'FlutterMacOS.framework/Versions/A/FlutterMacOS'
193+
]
236194
)
237195

238-
subprocess.check_call([
239-
'zip',
240-
'-r',
241-
'-y',
242-
'framework.zip',
243-
'FlutterMacOS.xcframework',
244-
'entitlements.txt',
245-
'without_entitlements.txt',
246-
],
247-
cwd=dst)
196+
sky_utils.create_zip(
197+
dst, 'framework.zip', [
198+
'FlutterMacOS.xcframework',
199+
'entitlements.txt',
200+
'without_entitlements.txt',
201+
]
202+
)
248203

249204

250205
if __name__ == '__main__':

sky/tools/sky_utils.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,20 @@ def copy_binary(source_path, destination_path):
3737
shutil.copy2(source_path, destination_path)
3838

3939

40-
def copy_tree(source_path, destination_path):
40+
def copy_tree(source_path, destination_path, symlinks=False):
4141
"""Performs a recursive copy of a directory.
4242
If the destination path is present, it is deleted first."""
4343
assert_directory(source_path, 'directory to copy')
4444
shutil.rmtree(destination_path, True)
45-
shutil.copytree(source_path, destination_path)
45+
shutil.copytree(source_path, destination_path, symlinks=symlinks)
4646

4747

48-
def create_zip(cwd, zip_filename, paths):
48+
def create_zip(cwd, zip_filename, paths, symlinks=False):
4949
"""Creates a zip archive in cwd, containing a set of cwd-relative files."""
50-
subprocess.check_call(['zip', '-r', zip_filename] + paths, cwd=cwd)
50+
options = ['-r']
51+
if symlinks:
52+
options.append('-y')
53+
subprocess.check_call(['zip'] + options + [zip_filename] + paths, cwd=cwd)
5154

5255

5356
def _dsymutil_path():
@@ -86,4 +89,5 @@ def strip_binary(binary_path, unstripped_copy_path):
8689
def write_codesign_config(output_path, paths):
8790
"""Writes an Apple codesign configuration file containing the specified paths."""
8891
with open(output_path, mode='w', encoding='utf-8') as file:
89-
file.write('\n'.join(paths) + '\n')
92+
if paths:
93+
file.write('\n'.join(paths) + '\n')

0 commit comments

Comments
 (0)