Skip to content

Commit 8e2c66f

Browse files
committed
feat: build ios with xcframework
1 parent c559159 commit 8e2c66f

File tree

1 file changed

+90
-79
lines changed

1 file changed

+90
-79
lines changed

mars/build_ios.py

Lines changed: 90 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import os
33
import sys
44
import glob
5+
import re
6+
import shutil
57

68
from mars_utils import *
79

@@ -11,115 +13,124 @@
1113
BUILD_OUT_PATH = 'cmake_build/iOS'
1214
INSTALL_PATH = BUILD_OUT_PATH + '/iOS.out'
1315

14-
IOS_BUILD_SIMULATOR_CMD = 'cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=SIMULATOR -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1 && make -j8 && make install'
15-
IOS_BUILD_OS_CMD = 'cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=OS -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1 && make -j8 && make install'
16-
1716
GEN_IOS_OS_PROJ = 'cmake ../.. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=OS -DIOS_ARCH="arm64" -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1'
18-
OPEN_SSL_ARCHS = ['x86_64', 'arm64']
19-
2017

21-
def build_ios(tag=''):
22-
gen_mars_revision_file('comm', tag)
23-
18+
def generate_lib(platform, deps = None, filter = None):
2419
clean(BUILD_OUT_PATH)
2520
os.chdir(BUILD_OUT_PATH)
26-
27-
ret = os.system(IOS_BUILD_OS_CMD)
21+
22+
command = 'cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=%s -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1 && make -j8 && make install' % platform
23+
ret = os.system(command)
2824
os.chdir(SCRIPT_PATH)
2925
if ret != 0:
30-
print('!!!!!!!!!!!build os fail!!!!!!!!!!!!!!!')
31-
return False
26+
print('!!!!!!!!!!!build %s fail!!!!!!!!!!!!!!!' % platform)
27+
return None
28+
29+
libs = glob.glob(INSTALL_PATH + '/*.a')
30+
libs.append(BUILD_OUT_PATH + '/zstd/libzstd.a')
31+
if filter:
32+
pattern = re.compile(filter)
33+
libs = [lib for lib in libs if pattern.search(lib)]
34+
if deps:
35+
libs.extend(deps)
36+
dest_lib = '%s/mars-%s' % (INSTALL_PATH, platform)
37+
if not libtool_libs(libs, dest_lib):
38+
return None
39+
return dest_lib
40+
41+
def make_mars_framework(src_libs, platform, header_files):
42+
lib = INSTALL_PATH + '/mars'
43+
if not libtool_libs(src_libs, lib):
44+
return None
45+
46+
path = '%s/%s/mars.framework' % (INSTALL_PATH, platform)
47+
if os.path.exists(path):
48+
shutil.rmtree(path)
49+
os.makedirs(path)
50+
make_static_framework(lib, path, header_files, '../')
51+
return path
52+
53+
def make_mars_xcframework(frameworks):
54+
path = INSTALL_PATH + '/mars.xcframework'
55+
option = ' '.join(['-framework %s' % framework for framework in frameworks])
56+
command = 'xcodebuild -create-xcframework %s -output %s' % (option, path)
57+
ret = os.system(command)
58+
if ret != 0:
59+
print('!!!!!!!!!!!make xcframework fail!!!!!!!!!!!!!!!')
60+
return None
61+
return path
62+
63+
def extract_arch(lib, arch):
64+
dst_lib = lib.replace('.a', '-%s.a' % arch)
65+
command = 'lipo %s -extract %s -o %s' % (lib, arch, dst_lib)
66+
ret = os.system(command)
67+
if ret != 0:
68+
print('!!!!!!!!!!!extract %s fail!!!!!!!!!!!!!!!' % arch)
69+
return None
70+
return dst_lib
3271

33-
libtool_os_dst_lib = INSTALL_PATH + '/os'
34-
libtool_src_lib = glob.glob(INSTALL_PATH + '/*.a')
35-
libtool_src_lib.append(BUILD_OUT_PATH + '/zstd/libzstd.a')
72+
def build_ios(tag=''):
73+
gen_mars_revision_file('comm', tag)
3674

37-
if not libtool_libs(libtool_src_lib, libtool_os_dst_lib):
38-
return False
75+
deps = ['openssl/openssl_lib_iOS/libssl.a', 'openssl/openssl_lib_iOS/libcrypto.a']
3976

40-
clean(BUILD_OUT_PATH)
41-
os.chdir(BUILD_OUT_PATH)
42-
ret = os.system(IOS_BUILD_SIMULATOR_CMD)
43-
os.chdir(SCRIPT_PATH)
44-
if ret != 0:
45-
print('!!!!!!!!!!!build simulator fail!!!!!!!!!!!!!!!')
77+
os_deps = [extract_arch(dep, 'arm64') for dep in deps]
78+
os_lib = generate_lib('OS64', deps=os_deps)
79+
for dep in os_deps:
80+
os.remove(dep)
81+
if not os_lib:
4682
return False
47-
48-
libtool_simulator_dst_lib = INSTALL_PATH + '/simulator'
49-
if not libtool_libs(libtool_src_lib, libtool_simulator_dst_lib):
83+
os_framework = make_mars_framework([os_lib], 'OS', COMM_COPY_HEADER_FILES)
84+
if not os_framework:
5085
return False
5186

52-
lipo_src_libs = []
53-
lipo_src_libs.append(libtool_os_dst_lib)
54-
lipo_src_libs.append(libtool_simulator_dst_lib)
55-
ssl_lib = INSTALL_PATH + '/ssl'
56-
if not lipo_thin_libs('openssl/openssl_lib_iOS/libssl.a', ssl_lib, OPEN_SSL_ARCHS):
87+
simulator_deps = [extract_arch(dep, 'x86_64') for dep in deps]
88+
simulator_lib = generate_lib('SIMULATOR64', deps=simulator_deps)
89+
for dep in simulator_deps:
90+
os.remove(dep)
91+
if not simulator_lib:
5792
return False
58-
59-
crypto_lib = INSTALL_PATH + '/crypto'
60-
if not lipo_thin_libs('openssl/openssl_lib_iOS/libcrypto.a', crypto_lib, OPEN_SSL_ARCHS):
93+
simulator_framework = make_mars_framework([simulator_lib], 'SIMULATOR', COMM_COPY_HEADER_FILES)
94+
if not simulator_framework:
6195
return False
6296

63-
lipo_src_libs.append(ssl_lib)
64-
lipo_src_libs.append(crypto_lib)
65-
66-
lipo_dst_lib = INSTALL_PATH + '/mars'
67-
68-
if not libtool_libs(lipo_src_libs, lipo_dst_lib):
97+
xcframework_path = make_mars_xcframework([os_framework, simulator_framework])
98+
if not xcframework_path:
6999
return False
70100

71-
dst_framework_path = INSTALL_PATH + '/mars.framework'
72-
make_static_framework(lipo_dst_lib, dst_framework_path, COMM_COPY_HEADER_FILES, '../')
73-
74101
print('==================Output========================')
75-
print(dst_framework_path)
102+
print(xcframework_path)
76103
return True
77104

78105
def build_ios_xlog(tag=''):
79106
gen_mars_revision_file('comm', tag)
80-
81-
clean(BUILD_OUT_PATH)
82-
os.chdir(BUILD_OUT_PATH)
83-
84-
ret = os.system(IOS_BUILD_OS_CMD)
85-
os.chdir(SCRIPT_PATH)
86-
if ret != 0:
87-
print('!!!!!!!!!!!build os fail!!!!!!!!!!!!!!!')
88-
return False
89107

90-
libtool_os_dst_lib = INSTALL_PATH + '/os'
91-
libtool_src_libs = [INSTALL_PATH + '/libcomm.a',
92-
INSTALL_PATH + '/libmars-boost.a',
93-
INSTALL_PATH + '/libxlog.a',
94-
BUILD_OUT_PATH + '/zstd/libzstd.a']
95-
if not libtool_libs(libtool_src_libs, libtool_os_dst_lib):
96-
return False
108+
filter = '(libcomm.a|libmars-boost.a|libxlog.a|libzstd.a)'
97109

98-
clean(BUILD_OUT_PATH)
99-
os.chdir(BUILD_OUT_PATH)
100-
ret = os.system(IOS_BUILD_SIMULATOR_CMD)
101-
os.chdir(SCRIPT_PATH)
102-
if ret != 0:
103-
print('!!!!!!!!!!!build simulator fail!!!!!!!!!!!!!!!')
110+
os_lib = generate_lib('OS64', filter=filter)
111+
if not os_lib:
104112
return False
105-
106-
libtool_simulator_dst_lib = INSTALL_PATH + '/simulator'
107-
if not libtool_libs(libtool_src_libs, libtool_simulator_dst_lib):
113+
os_framework = make_mars_framework([os_lib], 'OS', XLOG_COPY_HEADER_FILES)
114+
if not os_framework:
108115
return False
109116

110-
lipo_src_libs = []
111-
lipo_src_libs.append(libtool_os_dst_lib)
112-
lipo_src_libs.append(libtool_simulator_dst_lib)
113-
lipo_dst_lib = INSTALL_PATH + '/mars'
114-
115-
if not lipo_libs(lipo_src_libs, lipo_dst_lib):
117+
simulator64_lib = generate_lib('SIMULATOR64', filter=filter)
118+
if not simulator64_lib:
119+
return False
120+
simulatorarm64_lib = generate_lib('SIMULATORARM64', filter=filter)
121+
if not simulatorarm64_lib:
122+
return False
123+
simulator_framework = make_mars_framework([simulator64_lib, simulatorarm64_lib], 'SIMULATOR', XLOG_COPY_HEADER_FILES)
124+
if not simulator_framework:
116125
return False
117126

118-
dst_framework_path = INSTALL_PATH + '/mars.framework'
119-
make_static_framework(lipo_dst_lib, dst_framework_path, XLOG_COPY_HEADER_FILES, '../')
127+
xcframework_path = make_mars_xcframework([os_framework, simulator_framework])
128+
if not xcframework_path:
129+
return False
120130

121131
print('==================Output========================')
122-
print(dst_framework_path)
132+
print(xcframework_path)
133+
return True
123134

124135

125136

@@ -137,7 +148,7 @@ def gen_ios_project():
137148

138149
print('==================Output========================')
139150
print('project file: %s/%s' %(SCRIPT_PATH, BUILD_OUT_PATH))
140-
151+
141152
return True
142153

143154
def main():

0 commit comments

Comments
 (0)