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

Commit 7682457

Browse files
authored
macOS: Extract framework creation to sky_utils (#54586)
This refactors `create_mac_framework.py` to extract framework creation to `sky_utils.py`. The only other changes are minor variable renaming and extraction of functions to make the code more readable/easier to work with. The resulting zip archives have been verified to be identical before and after. This is refactoring to support embedding dSYM debug information in a follow-up patch. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 8bcc17a commit 7682457

File tree

2 files changed

+66
-66
lines changed

2 files changed

+66
-66
lines changed

sky/tools/create_macos_framework.py

Lines changed: 10 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
# found in the LICENSE file.
66

77
import argparse
8-
import subprocess
98
import shutil
109
import sys
1110
import os
@@ -38,57 +37,32 @@ def main():
3837
if os.path.isabs(args.x64_out_dir) else sky_utils.buildroot_relative_path(args.x64_out_dir)
3938
)
4039

41-
fat_framework_bundle = os.path.join(dst, 'FlutterMacOS.framework')
4240
arm64_framework = os.path.join(arm64_out_dir, 'FlutterMacOS.framework')
43-
x64_framework = os.path.join(x64_out_dir, 'FlutterMacOS.framework')
44-
45-
arm64_dylib = os.path.join(arm64_framework, 'FlutterMacOS')
46-
x64_dylib = os.path.join(x64_framework, 'FlutterMacOS')
47-
4841
if not os.path.isdir(arm64_framework):
4942
print('Cannot find macOS arm64 Framework at %s' % arm64_framework)
5043
return 1
5144

45+
x64_framework = os.path.join(x64_out_dir, 'FlutterMacOS.framework')
5246
if not os.path.isdir(x64_framework):
5347
print('Cannot find macOS x64 Framework at %s' % x64_framework)
5448
return 1
5549

50+
arm64_dylib = os.path.join(arm64_framework, 'FlutterMacOS')
5651
if not os.path.isfile(arm64_dylib):
5752
print('Cannot find macOS arm64 dylib at %s' % arm64_dylib)
5853
return 1
5954

55+
x64_dylib = os.path.join(x64_framework, 'FlutterMacOS')
6056
if not os.path.isfile(x64_dylib):
6157
print('Cannot find macOS x64 dylib at %s' % x64_dylib)
6258
return 1
6359

64-
sky_utils.copy_tree(arm64_framework, fat_framework_bundle, symlinks=True)
65-
66-
regenerate_symlinks(fat_framework_bundle)
67-
68-
fat_framework_binary = os.path.join(fat_framework_bundle, 'Versions', 'A', 'FlutterMacOS')
69-
70-
# Create the arm64/x64 fat framework.
71-
sky_utils.lipo([arm64_dylib, x64_dylib], fat_framework_binary)
72-
73-
# Make the framework readable and executable: u=rwx,go=rx.
74-
subprocess.check_call(['chmod', '755', fat_framework_bundle])
75-
76-
# Add group and other readability to all files.
77-
versions_path = os.path.join(fat_framework_bundle, 'Versions')
78-
subprocess.check_call(['chmod', '-R', 'og+r', versions_path])
79-
# Find all the files below the target dir with owner execute permission
80-
find_subprocess = subprocess.Popen(['find', versions_path, '-perm', '-100', '-print0'],
81-
stdout=subprocess.PIPE)
82-
# Add execute permission for other and group for all files that had it for owner.
83-
xargs_subprocess = subprocess.Popen(['xargs', '-0', 'chmod', 'og+x'],
84-
stdin=find_subprocess.stdout)
85-
find_subprocess.wait()
86-
xargs_subprocess.wait()
87-
88-
process_framework(dst, args, fat_framework_bundle, fat_framework_binary)
60+
fat_framework = os.path.join(dst, 'FlutterMacOS.framework')
61+
sky_utils.create_fat_macos_framework(fat_framework, arm64_framework, x64_framework)
62+
process_framework(dst, args, fat_framework)
8963

9064
# Create XCFramework from the arm64 and x64 fat framework.
91-
xcframeworks = [fat_framework_bundle]
65+
xcframeworks = [fat_framework]
9266
create_xcframework(location=dst, name='FlutterMacOS', frameworks=xcframeworks)
9367

9468
if args.zip:
@@ -97,40 +71,10 @@ def main():
9771
return 0
9872

9973

100-
def regenerate_symlinks(fat_framework_bundle):
101-
"""Regenerates the symlinks structure.
102-
103-
Recipes V2 upload artifacts in CAS before integration and CAS follows symlinks.
104-
This logic regenerates the symlinks in the expected structure.
105-
"""
106-
if os.path.islink(os.path.join(fat_framework_bundle, 'FlutterMacOS')):
107-
return
108-
os.remove(os.path.join(fat_framework_bundle, 'FlutterMacOS'))
109-
shutil.rmtree(os.path.join(fat_framework_bundle, 'Headers'), True)
110-
shutil.rmtree(os.path.join(fat_framework_bundle, 'Modules'), True)
111-
shutil.rmtree(os.path.join(fat_framework_bundle, 'Resources'), True)
112-
current_version_path = os.path.join(fat_framework_bundle, 'Versions', 'Current')
113-
shutil.rmtree(current_version_path, True)
114-
os.symlink('A', current_version_path)
115-
os.symlink(
116-
os.path.join('Versions', 'Current', 'FlutterMacOS'),
117-
os.path.join(fat_framework_bundle, 'FlutterMacOS')
118-
)
119-
os.symlink(
120-
os.path.join('Versions', 'Current', 'Headers'), os.path.join(fat_framework_bundle, 'Headers')
121-
)
122-
os.symlink(
123-
os.path.join('Versions', 'Current', 'Modules'), os.path.join(fat_framework_bundle, 'Modules')
124-
)
125-
os.symlink(
126-
os.path.join('Versions', 'Current', 'Resources'),
127-
os.path.join(fat_framework_bundle, 'Resources')
128-
)
129-
130-
131-
def process_framework(dst, args, fat_framework_bundle, fat_framework_binary):
74+
def process_framework(dst, args, fat_framework):
75+
fat_framework_binary = os.path.join(fat_framework, 'Versions', 'A', 'FlutterMacOS')
13276
if args.dsym:
133-
dsym_out = os.path.splitext(fat_framework_bundle)[0] + '.dSYM'
77+
dsym_out = os.path.splitext(fat_framework)[0] + '.dSYM'
13478
sky_utils.extract_dsym(fat_framework_binary, dsym_out)
13579
if args.zip:
13680
dsym_dst = os.path.join(dst, 'FlutterMacOS.dSYM')

sky/tools/sky_utils.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,62 @@ def copy_tree(source_path, destination_path, symlinks=False):
118118
shutil.copytree(source_path, destination_path, symlinks=symlinks)
119119

120120

121+
def create_fat_macos_framework(fat_framework, arm64_framework, x64_framework):
122+
copy_tree(arm64_framework, fat_framework, symlinks=True)
123+
_regenerate_symlinks(fat_framework)
124+
125+
fat_framework_binary = os.path.join(fat_framework, 'Versions', 'A', 'FlutterMacOS')
126+
127+
# Create the arm64/x64 fat framework.
128+
arm64_dylib = os.path.join(arm64_framework, 'FlutterMacOS')
129+
x64_dylib = os.path.join(x64_framework, 'FlutterMacOS')
130+
lipo([arm64_dylib, x64_dylib], fat_framework_binary)
131+
_set_framework_permissions(fat_framework)
132+
133+
134+
def _regenerate_symlinks(framework_dir):
135+
"""Regenerates the symlinks structure.
136+
137+
Recipes V2 upload artifacts in CAS before integration and CAS follows symlinks.
138+
This logic regenerates the symlinks in the expected structure.
139+
"""
140+
if os.path.islink(os.path.join(framework_dir, 'FlutterMacOS')):
141+
return
142+
os.remove(os.path.join(framework_dir, 'FlutterMacOS'))
143+
shutil.rmtree(os.path.join(framework_dir, 'Headers'), True)
144+
shutil.rmtree(os.path.join(framework_dir, 'Modules'), True)
145+
shutil.rmtree(os.path.join(framework_dir, 'Resources'), True)
146+
current_version_path = os.path.join(framework_dir, 'Versions', 'Current')
147+
shutil.rmtree(current_version_path, True)
148+
os.symlink('A', current_version_path)
149+
os.symlink(
150+
os.path.join('Versions', 'Current', 'FlutterMacOS'),
151+
os.path.join(framework_dir, 'FlutterMacOS')
152+
)
153+
os.symlink(os.path.join('Versions', 'Current', 'Headers'), os.path.join(framework_dir, 'Headers'))
154+
os.symlink(os.path.join('Versions', 'Current', 'Modules'), os.path.join(framework_dir, 'Modules'))
155+
os.symlink(
156+
os.path.join('Versions', 'Current', 'Resources'), os.path.join(framework_dir, 'Resources')
157+
)
158+
159+
160+
def _set_framework_permissions(framework_dir):
161+
# Make the framework readable and executable: u=rwx,go=rx.
162+
subprocess.check_call(['chmod', '755', framework_dir])
163+
164+
# Add group and other readability to all files.
165+
versions_path = os.path.join(framework_dir, 'Versions')
166+
subprocess.check_call(['chmod', '-R', 'og+r', versions_path])
167+
# Find all the files below the target dir with owner execute permission
168+
find_subprocess = subprocess.Popen(['find', versions_path, '-perm', '-100', '-print0'],
169+
stdout=subprocess.PIPE)
170+
# Add execute permission for other and group for all files that had it for owner.
171+
xargs_subprocess = subprocess.Popen(['xargs', '-0', 'chmod', 'og+x'],
172+
stdin=find_subprocess.stdout)
173+
find_subprocess.wait()
174+
xargs_subprocess.wait()
175+
176+
121177
def create_zip(cwd, zip_filename, paths):
122178
"""Creates a zip archive in cwd, containing a set of cwd-relative files.
123179

0 commit comments

Comments
 (0)