Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
create_embedder_framework.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2#
3# Copyright 2013 The Flutter Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7import argparse
8import platform
9import subprocess
10import shutil
11import sys
12import os
13
14buildroot_dir = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..', '..', '..'))
15
16ARCH_SUBPATH = 'mac-arm64' if platform.processor() == 'arm' else 'mac-x64'
17DSYMUTIL = os.path.join(
18 os.path.dirname(__file__), '..', '..', 'buildtools', ARCH_SUBPATH, 'clang', 'bin', 'dsymutil'
19)
20
21out_dir = os.path.join(buildroot_dir, 'out')
22
23
24def main():
25 parser = argparse.ArgumentParser(description='Creates FlutterEmbedder.framework for macOS')
26
27 parser.add_argument('--dst', type=str, required=True)
28 parser.add_argument('--arm64-out-dir', type=str, required=True)
29 parser.add_argument('--x64-out-dir', type=str, required=True)
30 parser.add_argument('--strip', action='store_true', default=False)
31 parser.add_argument('--dsym', action='store_true', default=False)
32 # TODO(godofredoc): Remove after recipes v2 have landed.
33 parser.add_argument('--zip', action='store_true', default=False)
34
35 args = parser.parse_args()
36
37 dst = (args.dst if os.path.isabs(args.dst) else os.path.join(buildroot_dir, args.dst))
38 arm64_out_dir = (
39 args.arm64_out_dir
40 if os.path.isabs(args.arm64_out_dir) else os.path.join(buildroot_dir, args.arm64_out_dir)
41 )
42 x64_out_dir = (
43 args.x64_out_dir
44 if os.path.isabs(args.x64_out_dir) else os.path.join(buildroot_dir, args.x64_out_dir)
45 )
46
47 fat_framework = os.path.join(dst, 'FlutterEmbedder.framework')
48 arm64_framework = os.path.join(arm64_out_dir, 'FlutterEmbedder.framework')
49 x64_framework = os.path.join(x64_out_dir, 'FlutterEmbedder.framework')
50
51 arm64_dylib = os.path.join(arm64_framework, 'FlutterEmbedder')
52 x64_dylib = os.path.join(x64_framework, 'FlutterEmbedder')
53
54 if not os.path.isdir(arm64_framework):
55 print('Cannot find macOS arm64 Framework at %s' % arm64_framework)
56 return 1
57
58 if not os.path.isdir(x64_framework):
59 print('Cannot find macOS x64 Framework at %s' % x64_framework)
60 return 1
61
62 if not os.path.isfile(arm64_dylib):
63 print('Cannot find macOS arm64 dylib at %s' % arm64_dylib)
64 return 1
65
66 if not os.path.isfile(x64_dylib):
67 print('Cannot find macOS x64 dylib at %s' % x64_dylib)
68 return 1
69
70 if not os.path.isfile(DSYMUTIL):
71 print('Cannot find dsymutil at %s' % DSYMUTIL)
72 return 1
73
74 shutil.rmtree(fat_framework, True)
75 shutil.copytree(arm64_framework, fat_framework, symlinks=True)
76 regenerate_symlinks(fat_framework)
77
78 fat_framework_binary = os.path.join(fat_framework, 'Versions', 'A', 'FlutterEmbedder')
79
80 # Create the arm64/x64 fat framework.
81 subprocess.check_call([
82 'lipo', arm64_dylib, x64_dylib, '-create', '-output', fat_framework_binary
83 ])
84 process_framework(dst, args, fat_framework, fat_framework_binary)
85
86 return 0
87
88
89def regenerate_symlinks(fat_framework):
90 """Regenerates the symlinks structure.
91
92 Recipes V2 upload artifacts in CAS before integration and CAS follows symlinks.
93 This logic regenerates the symlinks in the expected structure.
94 """
95 if os.path.islink(os.path.join(fat_framework, 'FlutterEmbedder')):
96 return
97 os.remove(os.path.join(fat_framework, 'FlutterEmbedder'))
98 shutil.rmtree(os.path.join(fat_framework, 'Headers'), True)
99 shutil.rmtree(os.path.join(fat_framework, 'Modules'), True)
100 shutil.rmtree(os.path.join(fat_framework, 'Resources'), True)
101 current_version_path = os.path.join(fat_framework, 'Versions', 'Current')
102 shutil.rmtree(current_version_path, True)
103 os.symlink('A', current_version_path)
104 os.symlink(
105 os.path.join('Versions', 'Current', 'FlutterEmbedder'),
106 os.path.join(fat_framework, 'FlutterEmbedder')
107 )
108 os.symlink(os.path.join('Versions', 'Current', 'Headers'), os.path.join(fat_framework, 'Headers'))
109 os.symlink(os.path.join('Versions', 'Current', 'Modules'), os.path.join(fat_framework, 'Modules'))
110 os.symlink(
111 os.path.join('Versions', 'Current', 'Resources'), os.path.join(fat_framework, 'Resources')
112 )
113
114
115def process_framework(dst, args, fat_framework, fat_framework_binary):
116 if args.dsym:
117 dsym_out = os.path.splitext(fat_framework)[0] + '.dSYM'
118 subprocess.check_call([DSYMUTIL, '-o', dsym_out, fat_framework_binary])
119 if args.zip:
120 dsym_dst = os.path.join(dst, 'FlutterEmbedder.dSYM')
121 subprocess.check_call(['zip', '-r', '-y', 'FlutterEmbedder.dSYM.zip', '.'], cwd=dsym_dst)
122 dsym_final_src_path = os.path.join(dsym_dst, 'FlutterEmbedder.dSYM.zip')
123 dsym_final_dst_path = os.path.join(dst, 'FlutterEmbedder.dSYM.zip')
124 shutil.move(dsym_final_src_path, dsym_final_dst_path)
125
126 if args.strip:
127 # copy unstripped
128 unstripped_out = os.path.join(dst, 'FlutterEmbedder.unstripped')
129 shutil.copyfile(fat_framework_binary, unstripped_out)
130 subprocess.check_call(['strip', '-x', '-S', fat_framework_binary])
131
132 # Zip FlutterEmbedder.framework.
133 if args.zip:
134 framework_dst = os.path.join(dst, 'FlutterEmbedder.framework')
135 subprocess.check_call([
136 'zip',
137 '-r',
138 '-y',
139 'FlutterEmbedder.framework.zip',
140 '.',
141 ],
142 cwd=framework_dst)
143 final_src_path = os.path.join(framework_dst, 'FlutterEmbedder.framework.zip')
144 final_dst_path = os.path.join(dst, 'FlutterEmbedder.framework.zip')
145 shutil.move(final_src_path, final_dst_path)
146
147
148if __name__ == '__main__':
149 sys.exit(main())
void print(void *str)
Definition bridge.cpp:126
process_framework(dst, args, fat_framework, fat_framework_binary)
Definition main.py:1