Created
September 21, 2023 08:12
-
-
Save 0x1306a94/7720b9b70e5666e63366c2a908d20e23 to your computer and use it in GitHub Desktop.
mars build xcframework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import sys | |
import glob | |
from mars_utils import * | |
SCRIPT_PATH = os.path.split(os.path.realpath(__file__))[0] | |
BUILD_OUT_PATH = 'cmake_build/iOS' | |
INSTALL_PATH = BUILD_OUT_PATH + '/iOS.out' | |
IOS_BUILD_SIMULATOR_CMD = 'cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=SIMULATOR64 -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1 && make -j8 && make install' | |
IOS_BUILD_SIMULATOR_ARM64_CMD = 'cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=SIMULATORARM64 -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1 && make -j8 && make install' | |
IOS_BUILD_OS_CMD = 'cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=OS64 -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1 && make -j8 && make install' | |
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' | |
OPEN_SSL_ARCHS = ['x86_64', 'arm64'] | |
def build_ios(tag=''): | |
gen_mars_revision_file('comm', tag) | |
clean(BUILD_OUT_PATH) | |
os.chdir(BUILD_OUT_PATH) | |
ret = os.system(IOS_BUILD_OS_CMD) | |
os.chdir(SCRIPT_PATH) | |
if ret != 0: | |
print('!!!!!!!!!!!build os fail!!!!!!!!!!!!!!!') | |
return False | |
libtool_os_dst_lib = INSTALL_PATH + '/os' | |
libtool_src_lib = glob.glob(INSTALL_PATH + '/*.a') | |
libtool_src_lib.append(BUILD_OUT_PATH + '/zstd/libzstd.a') | |
if not libtool_libs(libtool_src_lib, libtool_os_dst_lib): | |
return False | |
clean(BUILD_OUT_PATH) | |
os.chdir(BUILD_OUT_PATH) | |
ret = os.system(IOS_BUILD_SIMULATOR_CMD) | |
os.chdir(SCRIPT_PATH) | |
if ret != 0: | |
print('!!!!!!!!!!!build simulator fail!!!!!!!!!!!!!!!') | |
return False | |
libtool_simulator_dst_lib = INSTALL_PATH + '/simulator' | |
if not libtool_libs(libtool_src_lib, libtool_simulator_dst_lib): | |
return False | |
lipo_src_libs = [] | |
lipo_src_libs.append(libtool_os_dst_lib) | |
lipo_src_libs.append(libtool_simulator_dst_lib) | |
ssl_lib = INSTALL_PATH + '/ssl' | |
if not lipo_thin_libs('openssl/openssl_lib_iOS/libssl.a', ssl_lib, OPEN_SSL_ARCHS): | |
return False | |
crypto_lib = INSTALL_PATH + '/crypto' | |
if not lipo_thin_libs('openssl/openssl_lib_iOS/libcrypto.a', crypto_lib, OPEN_SSL_ARCHS): | |
return False | |
lipo_src_libs.append(ssl_lib) | |
lipo_src_libs.append(crypto_lib) | |
lipo_dst_lib = INSTALL_PATH + '/mars' | |
if not libtool_libs(lipo_src_libs, lipo_dst_lib): | |
return False | |
dst_framework_path = INSTALL_PATH + '/mars.framework' | |
make_static_framework(lipo_dst_lib, dst_framework_path, COMM_COPY_HEADER_FILES, '../') | |
print('==================Output========================') | |
print(dst_framework_path) | |
return True | |
def build_ios_xlog(tag=''): | |
gen_mars_revision_file('comm', tag) | |
clean(BUILD_OUT_PATH) | |
os.chdir(BUILD_OUT_PATH) | |
ret = os.system(IOS_BUILD_OS_CMD) | |
os.chdir(SCRIPT_PATH) | |
if ret != 0: | |
print('!!!!!!!!!!!build os fail!!!!!!!!!!!!!!!') | |
return False | |
libtool_os_dst_lib = INSTALL_PATH + '/mars' | |
libtool_src_libs = [INSTALL_PATH + '/libcomm.a', | |
INSTALL_PATH + '/libmars-boost.a', | |
INSTALL_PATH + '/libxlog.a', | |
BUILD_OUT_PATH + '/zstd/libzstd.a'] | |
if not libtool_libs(libtool_src_libs, libtool_os_dst_lib): | |
return False | |
dst_os_framework_path = INSTALL_PATH + '/iphoneos/mars.framework' | |
make_static_framework(libtool_os_dst_lib, dst_os_framework_path, XLOG_COPY_HEADER_FILES, '../') | |
clean(BUILD_OUT_PATH) | |
os.chdir(BUILD_OUT_PATH) | |
ret = os.system(IOS_BUILD_SIMULATOR_CMD) | |
os.chdir(SCRIPT_PATH) | |
if ret != 0: | |
print('!!!!!!!!!!!build simulator fail!!!!!!!!!!!!!!!') | |
return False | |
libtool_simulator_dst_lib = INSTALL_PATH + '/mars_sim_x86_64' | |
if not libtool_libs(libtool_src_libs, libtool_simulator_dst_lib): | |
return False | |
clean(BUILD_OUT_PATH) | |
os.chdir(BUILD_OUT_PATH) | |
ret = os.system(IOS_BUILD_SIMULATOR_ARM64_CMD) | |
os.chdir(SCRIPT_PATH) | |
if ret != 0: | |
print('!!!!!!!!!!!build simulator fail!!!!!!!!!!!!!!!') | |
return False | |
libtool_simulator_arm64_dst_lib = INSTALL_PATH + '/mars_sim_arm64' | |
if not libtool_libs(libtool_src_libs, libtool_simulator_arm64_dst_lib): | |
return False | |
sim_all_libs = [ | |
libtool_simulator_dst_lib, | |
libtool_simulator_arm64_dst_lib, | |
] | |
libtool_simulator_merge_dst_lib = INSTALL_PATH + '/mars' | |
if not lipo_libs(sim_all_libs, libtool_simulator_merge_dst_lib): | |
return False | |
dst_sim_framework_path = INSTALL_PATH + '/iphonesimulator/mars.framework' | |
make_static_framework(libtool_simulator_merge_dst_lib, dst_sim_framework_path, XLOG_COPY_HEADER_FILES, '../') | |
print('==================Output framework========================') | |
print(dst_os_framework_path) | |
print(dst_sim_framework_path) | |
dst_xcframework = INSTALL_PATH + '/mars.xcframework' | |
make_static_xcframework([dst_os_framework_path,dst_sim_framework_path], dst_xcframework) | |
print('==================Output xcframework========================') | |
print(dst_xcframework) | |
def gen_ios_project(): | |
gen_mars_revision_file('comm') | |
clean(BUILD_OUT_PATH) | |
os.chdir(BUILD_OUT_PATH) | |
ret = os.system(GEN_IOS_OS_PROJ) | |
os.chdir(SCRIPT_PATH) | |
if ret != 0: | |
print('!!!!!!!!!!!gen fail!!!!!!!!!!!!!!!') | |
return False | |
print('==================Output========================') | |
print('project file: %s/%s' %(SCRIPT_PATH, BUILD_OUT_PATH)) | |
return True | |
def main(): | |
while True: | |
if len(sys.argv) >= 2: | |
build_ios(sys.argv[1]) | |
break | |
else: | |
num = input('Enter menu:\n1. Clean && build mars.\n2. Clean && build xlog.\n3. Gen iOS mars Project.\n4. Exit\n') | |
if num == '1': | |
build_ios() | |
break | |
if num == '2': | |
build_ios_xlog() | |
break | |
elif num == '3': | |
gen_ios_project() | |
break | |
elif num == '4': | |
break | |
else: | |
build_ios() | |
break | |
if __name__ == '__main__': | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import shutil | |
import time | |
import subprocess | |
COMM_COPY_HEADER_FILES = { | |
"mars/comm/verinfo.h": "comm", | |
"mars/comm/autobuffer.h": "comm", | |
"mars/comm/http.h": "comm", | |
"mars/comm/time_utils.h": "comm", | |
"mars/comm/strutil.h": "comm", | |
"mars/comm/string_cast.h": "comm", | |
"mars/comm/comm_data.h": "comm", | |
"mars/comm/projdef.h": "comm", | |
"mars/comm/platform_comm.h": "comm", | |
"mars/comm/socket/local_ipstack.h": "comm", | |
"mars/comm/socket/nat64_prefix_util.h": "comm", | |
"mars/comm/has_member.h" : "comm", | |
"mars/comm/objc/scope_autoreleasepool.h": "comm", | |
"mars/comm/objc/ThreadOperationQueue.h": "comm", | |
"mars/stn/stn.h": "stn", | |
"mars/stn/stn_logic.h": "stn", | |
"mars/stn/proto/stnproto_logic.h": "stn", | |
"mars/baseevent/base_logic.h": "baseevent", | |
"mars/comm/xlogger/preprocessor.h": "xlog", | |
"mars/comm/xlogger/xloggerbase.h": "xlog", | |
"mars/comm/xlogger/xlogger.h": "xlog", | |
"mars/log/appender.h": "xlog", | |
"mars/log/xlogger_interface.h": "xlog", | |
"mars/app/app.h": "app", | |
"mars/app/app_logic.h": "app", | |
"mars/sdt/sdt.h": "sdt", | |
"mars/sdt/sdt_logic.h": "sdt", | |
"mars/sdt/constants.h": "sdt", | |
"mars/sdt/netchecker_profile.h": "sdt", | |
"mars/stn/proto/longlink_packer.h": "stn/proto", | |
} | |
WIN_COPY_EXT_FILES = { | |
"mars/comm/platform_comm.h": "comm", | |
"mars/comm/windows/projdef.h": "comm/windows", | |
"mars/comm/windows/sys/cdefs.h": "comm/windows/sys", | |
"mars/comm/windows/sys/time.h": "comm/windows/sys", | |
"mars/comm/platform_comm.h": "comm", | |
} | |
XLOG_COPY_HEADER_FILES = { | |
"mars/comm/verinfo.h": "comm", | |
"mars/comm/autobuffer.h": "comm", | |
"mars/comm/http.h": "comm", | |
"mars/comm/time_utils.h": "comm", | |
"mars/comm/strutil.h": "comm", | |
"mars/comm/string_cast.h": "comm", | |
"mars/comm/comm_data.h": "comm", | |
"mars/comm/projdef.h": "comm", | |
"mars/comm/socket/local_ipstack.h": "comm", | |
"mars/comm/socket/nat64_prefix_util.h": "comm", | |
"mars/comm/has_member.h" : "comm", | |
"mars/comm/objc/scope_autoreleasepool.h": "comm", | |
"mars/comm/objc/ThreadOperationQueue.h": "comm", | |
"mars/comm/xlogger/preprocessor.h": "xlog", | |
"mars/comm/xlogger/xloggerbase.h": "xlog", | |
"mars/comm/xlogger/xlogger.h": "xlog", | |
"mars/log/appender.h": "xlog", | |
"mars/log/xlogger_interface.h": "xlog", | |
} | |
class bcolors: | |
HEADER = '\033[95m' | |
OKBLUE = '\033[94m' | |
OKGREEN = '\033[92m' | |
WARNING = '\033[93m' | |
FAIL = '\033[91m' | |
ENDC = '\033[0m' | |
BOLD = '\033[1m' | |
UNDERLINE = '\033[4m' | |
def libtool_libs(src_libs, dst_lib): | |
src_lib_str = '' | |
for l in src_libs: | |
src_lib_str = '%s %s'%(src_lib_str, l) | |
print(src_lib_str) | |
ret = os.system('libtool -static -no_warning_for_no_symbols -o %s %s' %(dst_lib, src_lib_str)) | |
if ret != 0: | |
print('!!!!!!!!!!!libtool %s fail!!!!!!!!!!!!!!!' %(dst_lib)) | |
return False | |
return True | |
def lipo_libs(src_libs, dst_lib): | |
src_lib_str = u'' | |
for l in src_libs: | |
src_lib_str = '%s %s'%(src_lib_str, l) | |
cmd = 'lipo -create %s -output %s' %(src_lib_str, dst_lib) | |
ret = os.system(cmd) | |
if ret != 0: | |
print('!!!!!!!!!!!lipo_libs %s fail, cmd:%s!!!!!!!!!!!!!!!' %(dst_lib, cmd)) | |
return False | |
return True | |
def lipo_thin_libs(src_lib, dst_lib, archs): | |
tmp_results = [] | |
for arch in archs: | |
if len(archs) == 1: | |
tmp_result = dst_lib | |
else: | |
tmp_result = dst_lib + '.' + arch | |
cmd = 'lipo %s -thin %s -output %s' %(src_lib, arch, tmp_result) | |
ret = os.system(cmd) | |
if ret != 0: | |
print('!!!!!!!!!!!lipo_thin_libs %s fail, cmd:%s!!!!!!!!!!!!!!!' %(tmp_result, cmd)) | |
return False | |
tmp_results.append(tmp_result) | |
if len(archs) == 1: | |
return True | |
else: | |
return lipo_libs(tmp_results, dst_lib) | |
GENERATE_DSYM_FILE_CMD = 'dsymutil %s -o %s' | |
def gen_dwarf_with_dsym(src_dylib, dst_dsym): | |
os.system(GENERATE_DSYM_FILE_CMD %(src_dylib, dst_dsym)) | |
def remove_cmake_files(path): | |
cmake_files = path + '/CMakeFiles' | |
if os.path.exists(cmake_files): | |
shutil.rmtree(cmake_files) | |
make_files = path + '/Makefile' | |
if os.path.isfile(make_files): | |
os.remove(make_files) | |
cmake_cache = path + '/CMakeCache.txt' | |
if os.path.isfile(cmake_cache): | |
os.remove(cmake_cache) | |
for f in glob.glob(path + '/*.a'): | |
os.remove(f) | |
for f in glob.glob(path + '/*.so'): | |
os.remove(f) | |
def clean_except(path, except_list): | |
for fpath, dirs, fs in os.walk(path): | |
in_except = False | |
for exc in except_list: | |
if exc in fpath: | |
in_except = True | |
break | |
if not in_except: | |
remove_cmake_files(fpath) | |
if not os.path.exists(path): | |
os.makedirs(path) | |
def clean(path, incremental=False): | |
if not incremental: | |
for fpath, dirs, fs in os.walk(path): | |
remove_cmake_files(fpath) | |
if not os.path.exists(path): | |
os.makedirs(path) | |
def clean_windows(path, incremental): | |
if not os.path.exists(path): | |
os.makedirs(path) | |
return | |
if incremental: | |
return; | |
try: | |
if os.path.exists(path): | |
shutil.rmtree(path) | |
if not os.path.exists(path): | |
os.makedirs(path) | |
except Exception: | |
pass | |
def copy_windows_pdb(cmake_out, sub_folder, config, dst_folder): | |
for sf in sub_folder: | |
# src_file = "%s/%s/" %(cmake_out, sf) | |
# dirs = glob.glob(src_file + "*.dir") | |
# if len(dirs) != 1: | |
# print("Warning: %s path error." %src_file) | |
# continue | |
src_file = "%s/%s/%s" %(cmake_out, sf, config) | |
pdbs = glob.glob(src_file + "/*.pdb") | |
if len(pdbs) != 1: | |
print("Warning: %s path error." %src_file) | |
continue | |
pdb = pdbs[0] | |
if os.path.isfile(pdb): | |
shutil.copy(pdb, dst_folder) | |
else: | |
print("%s not exists" %pdb) | |
def copy_file(src, dst): | |
if not os.path.isfile(src): | |
print('Warning: %s not exist cwd %s' %(src, os.getcwd())) | |
return; | |
if dst.rfind("/") != -1 and not os.path.exists(dst[:dst.rfind("/")]): | |
os.makedirs(dst[:dst.rfind("/")]) | |
shutil.copy(src, dst) | |
def copy_file_mapping(header_file_mappings, header_files_src_base, header_files_dst_end): | |
for (src, dst) in header_file_mappings.items(): | |
copy_file(header_files_src_base + src, header_files_dst_end + "/" + dst + '/' + src[src.rfind("/"):]) | |
def make_static_framework(src_lib, dst_framework, header_file_mappings, header_files_src_base='./'): | |
if os.path.exists(dst_framework): | |
shutil.rmtree(dst_framework) | |
os.makedirs(dst_framework) | |
shutil.copy(src_lib, dst_framework) | |
framework_path = dst_framework + '/Headers' | |
for (src, dst) in header_file_mappings.items(): | |
copy_file(header_files_src_base + src, framework_path + "/" + dst + '/' + src[src.rfind("/"):]) | |
return True | |
def make_static_xcframework(src_frameworks, dst_xcframework): | |
if os.path.exists(dst_xcframework): | |
shutil.rmtree(dst_xcframework) | |
cmd = 'xcodebuild -create-xcframework' | |
for f in src_frameworks: | |
cmd = '%s -framework %s' % (cmd, f) | |
cmd = '%s -output %s' % (cmd, dst_xcframework) | |
print('==================create xcframework========================') | |
print(cmd) | |
os.system(cmd) | |
def check_ndk_env(): | |
try: | |
ndk_path = os.environ['NDK_ROOT'] | |
except KeyError as identifier: | |
print("Error: ndk does not exist or you do not set it into NDK_ROOT.") | |
return False | |
if ndk_path is not None and ndk_path.strip(): | |
print("ndk path:%s"%ndk_path) | |
if not ndk_path: | |
print("Error: ndk does not exist or you do not set it into NDK_ROOT.") | |
return False | |
if not os.path.isfile(os.path.join(ndk_path, "source.properties")): | |
print("Error: source.properties does not exist, make sure ndk's version==r16b") | |
return False | |
ndk_revision = None | |
f = open(os.path.join(ndk_path, "source.properties")) | |
line = f.readline() | |
while line: | |
if line.startswith("Pkg.Revision") and len(line.split("=")) == 2: | |
ndk_revision = line.split("=")[1].strip() | |
line = f.readline() | |
f.close() | |
if not ndk_revision or len(ndk_revision) < 4: | |
print("Error: parse source.properties fail") | |
return False | |
if ndk_revision[:4] >= "16.1": | |
return True | |
print("Error: make sure ndk's version >= r16b") | |
return False | |
html_css = ''' | |
<style type="text/css"> | |
.description table { | |
margin: 10px 0 15px 0; | |
border-collapse: collapse; | |
font-family: Helvetica, "Hiragino Sans GB", Arial, sans-serif; | |
font-size: 11px; | |
line-height: 16px; | |
color: #737373; | |
background-color: white; | |
margin: 10px 12px 10px 12px; | |
} | |
.description td,th { border: 1px solid #ddd; padding: 3px 10px; } | |
.description th { padding: 5px 10px; } | |
.description a { color: #0069d6; } | |
.description a:hover { color: #0050a3; text-decoration: none; } | |
.description h5 { font-size: 14px; } | |
</style> | |
''' | |
html_table_template = ''' | |
<div class="description"> | |
<h5>{title}</h5> | |
<table> | |
<thead> | |
<tr> | |
<th align="left">KEY</th> | |
<th align="left">VALUE</th> | |
</tr> | |
</thead> | |
{table_rows} | |
</table> | |
</div> | |
''' | |
html_row_template = ''' | |
<tr> | |
<td align="left">{key}</td> | |
<td align="left">{value}</td> | |
</tr> | |
''' | |
def parse_as_git(path): | |
curdir = os.getcwd() | |
os.chdir(path) | |
revision = os.popen('git rev-parse --short HEAD').read().strip() | |
path = os.popen('git rev-parse --abbrev-ref HEAD').read().strip() | |
url = '' | |
os.chdir(curdir) | |
return revision, path, url | |
def gen_mars_revision_file(version_file_path, tag=''): | |
revision, path, url = parse_as_git(version_file_path) | |
build_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) | |
contents = ''' | |
#ifndef Mars_verinfo_h | |
#define Mars_verinfo_h | |
#define MARS_REVISION "%s" | |
#define MARS_PATH "%s" | |
#define MARS_URL "%s" | |
#define MARS_BUILD_TIME "%s" | |
#define MARS_TAG "%s" | |
#endif | |
''' % (revision, path, url, build_time, tag) | |
with open('%s/verinfo.h' % version_file_path, 'wb') as f: | |
f.write(contents.encode()) | |
f.flush() | |
version_data = { | |
'PublicComponent': { | |
'Branch': path, | |
'Revision': revision, | |
'BuildTag': tag, | |
'BuildTime': build_time | |
} | |
} | |
output = '[[==BUILD_DESCRIPTION==]]Revision: %s %s' % ( | |
version_data['PublicComponent']['Revision'], | |
' ' * 18) | |
html = html_css | |
data_type = 'PublicComponent' | |
html_rows = '' | |
for key in sorted(version_data[data_type].keys()): | |
html_rows += html_row_template.format(key=key, value=version_data[data_type][key]) | |
html += html_table_template.format(title=data_type, table_rows=html_rows) | |
output += html | |
print (''.join(output.splitlines())) | |
def check_vs_env(): | |
vs_tool_dir = os.getenv("VS140COMNTOOLS") | |
if not vs_tool_dir: | |
print("You must install visual studio 2015 for build.") | |
return False | |
print('vs.dir: ' + vs_tool_dir) | |
envbat = vs_tool_dir + "../../vc/vcvarsall.bat" | |
print('vsvar.dir: ' + envbat) | |
p = subprocess.Popen(envbat) | |
p.wait() | |
return True | |
def merge_win_static_libs(src_libs, dst_lib): | |
vs_tool_dir = os.getenv("VS140COMNTOOLS") | |
lib_cmd = vs_tool_dir + '/../../VC/bin/lib.exe' | |
print('lib cmd:' + lib_cmd) | |
src_libs.insert(0, '/OUT:' + dst_lib) | |
src_libs.insert(0, lib_cmd) | |
p = subprocess.Popen(src_libs) | |
p.wait() | |
if p.returncode != 0: | |
print('!!!!!!!!!!!lib.exe %s fail!!!!!!!!!!!!!!!' %(dst_lib)) | |
return False | |
return True | |
import glob | |
if __name__ == '__main__': | |
lipo_thin_libs(u'/Users/garry/Documents/gitcode/mmnet/mars/openssl/openssl_lib_iOS/libcrypto.a', u'/Users/garry/Documents/gitcode/mmnet/mars/openssl/openssl_lib_iOS/libcrypto_test.a', ['x86_64', 'arm64']) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment