flutter打包流程接入jenkins
2022-05-05 本文已影响0人
你飞跃俊杰
iOS命令
python3 ci-build.py build --platform ios --version 1.0.0-SNAPSHOT --output_dir /Users/lvfeijun/Desktop/hqjy/fluttermodule/output_dir --macro_arg local_build
ci-build.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import argparse
import subprocess
def parse_args():
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('action', choices=['build', 'release'], default='build')
parser.add_argument('--platform', choices=['ios', 'android', 'windows'])
parser.add_argument('--version')
parser.add_argument('--output_dir')
parser.add_argument('--macro_arg')
return parser.parse_args()
def fetch_submodule(is_develop):
cmd = 'git submodule update --init'
if is_develop:
cmd += ' --remote'
subprocess.call(cmd.split(' '))
def main():
print((sys.version_info))
cfg = parse_args()
fetch_submodule(cfg.action == 'build')
from ci_build import ios, android, windows, sync_version
sync_version.generate_version_header(version=cfg.version)
locals()[cfg.platform].run(cfg)
if __name__ == '__main__':
main()
ios.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import glob
import shutil
from . import utils
BUILD_OUT_PATH = 'build/iOS'
POD_PROJECT_PATH = os.path.join(utils.root_path(), '.ios')
DEPENDENCY_PATH = os.path.join(utils.root_path(), 'depends')
FRAMEWORK_PATH = os.path.join(utils.root_path(), 'ios_frameworks')
GEN_IOS_OS_PROJ = 'cmake ../.. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../../ci_build/cmake/ios.toolchain.cmake -DIOS_PLATFORM=OS -DIOS_ARCH="armv7;arm64" -DENABLE_ARC=0 -DENABLE_BITCODE=0 -DENABLE_VISIBILITY=1'
def install_path(project_name):
return '{}/{}'.format(BUILD_OUT_PATH, project_name)
def run_make(is_simulator):
platform = 'SIMULATOR' if is_simulator else 'OS'
archs = '"x86_64"' if is_simulator else '"armv7;arm64"'
project_path = utils.root_path()
build_path = os.path.join(project_path, BUILD_OUT_PATH)
params = {
'CMAKE_INSTALL_PREFIX': build_path,
'CMAKE_BUILD_TYPE': 'Release',
'CMAKE_TOOLCHAIN_FILE': os.path.join(project_path, 'ci_build/cmake/ios.toolchain.cmake'),
'IOS_DEPLOYMENT_TARGET': '9.0',
'IOS_PLATFORM': platform,
'IOS_ARCH': archs,
'ENABLE_ARC': '1',
'ENABLE_BITCODE': '0',
'ENABLE_VISIBLITY': '1'
}
cmd = ' '.join(['-D{}={}'.format(k, v) for (k, v) in params.items()])
cmd = 'cmake {} {} && make -j8 && make install'.format(project_path, cmd)
print(cmd)
utils.clean(build_path)
os.chdir(build_path)
ret = os.system(cmd)
os.chdir(project_path)
return ret == 0
def build(project_name):
ret = run_make(False)
if not ret:
print('!!!!!!!!!!!build os fail!!!!!!!!!!!!!!!')
return False
lib_path = install_path(project_name) + '/libs'
libtool_os_dst_lib = lib_path + '/os'
if not utils.libtool_libs(glob.glob(lib_path + '/*.a'), libtool_os_dst_lib):
return False
ret = run_make(True)
if not ret:
print('!!!!!!!!!!!build simulator fail!!!!!!!!!!!!!!!')
return False
libtool_simulator_dst_lib = lib_path + '/simulator'
if not utils.libtool_libs(glob.glob(lib_path + '/*.a'), 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)
lipo_dst_lib = lib_path + '/lib{}.a'.format(project_name)
if not utils.lipo_libs(lipo_src_libs, lipo_dst_lib):
return False
if os.path.isfile(libtool_os_dst_lib):
os.remove(libtool_os_dst_lib)
if os.path.isfile(libtool_simulator_dst_lib):
os.remove(libtool_simulator_dst_lib)
print('==================Output========================')
print(lipo_dst_lib)
return True
#不需要依赖列表,需要flutter打包
def dependencies_info_mapper():
# info_mapper_path = os.path.join(POD_PROJECT_PATH, 'info_mapper.json')
return True #utils.load_json(info_mapper_path)
def flutter_build_debug():
print('flutter_build_debug')
os.chdir(utils.root_path())
return os.system('flutter build ios --debug --no-codesign')
def flutter_build_release():
print('flutter_build_release')
os.chdir(utils.root_path())
return os.system('flutter build ios --release --no-codesign')
def flutter_build_sh():
print('flutter_build_sh')
os.chdir(utils.root_path())
os.system('ls')
return os.system('sh ci-build.sh');
def dependency_info(name, version, infos, is_daily_build):
info = infos.get(name, {
'name': name,
'version': version
}).copy()
if version and not is_daily_build:
info['version'] = info['versions'].get(version, version)
return info
# 不需要pod
# def pod_content(dependencies_info, project_name, is_daily_build):
# dependencies = []
# #便利依赖列表
# # info_mapper = dependencies_info_mapper()
# # for n, v in dependencies_info.items():
# # info = dependency_info(n, v, info_mapper, is_daily_build)
# # print('name : {}, version : {}'.format(info['name'], info['version']))
# # dependencies.append("pod '{}', '~> {}'".format(info['name'], info['version']))
# return '''
# source 'https://github.com/CocoaPods/Specs.git'
# source 'https://git.duowan.com/ci_team/Specs.git'
# target '{project_name}' do
# platform :ios, '9.0'
# {dependencies}
# end
# '''.format(project_name=project_name, dependencies='\n '.join(dependencies))
def generate_pod_dependencies(project_info, output_dir, is_daily_build):
dependencies_info = project_info['dependencies']
project_name = project_info['name']
# print('Runner')
downloader_project = 'Runner'
#写入 Podfile
podfile_path = os.path.join(POD_PROJECT_PATH, 'Podfile')
# utils.write_content(pod_content(dependencies_info, downloader_project, is_daily_build), podfile_path)
# print('Runner')
#用来写framework
# podfile_path = os.path.join(output_dir, 'Podfile')
# utils.write_content(pod_content(dependencies_info, project_name, is_daily_build), podfile_path)
def find_headers_path(dependency_name):
public_headers = os.path.join(POD_PROJECT_PATH, 'Pods/Headers/Public/{}'.format(dependency_name))
if os.path.isdir(public_headers):
return public_headers
proj_path = os.path.join(POD_PROJECT_PATH, 'Pods/{}'.format(dependency_name))
include_path = os.path.join(proj_path, 'include')
if os.path.isdir(include_path):
return include_path
include_paths = glob.glob('{}/libs/*.framework/Headers'.format(proj_path))
if len(include_paths) > 0:
return include_paths[0]
def download_dependencies(project_info, output_dir, is_daily_build, force_update=False):
dependencies_info = project_info['dependencies']
# generate_pod_dependencies(project_info, output_dir, is_daily_build)
print('POD_PROJECT_PATH')
# print(os.chdir(POD_PROJECT_PATH))
os.system('ls')
print('POD_PROJECT')
# ret = 0
# if force_update:
# ret = os.system('pod install --repo-update')
# else:
# ret = os.system('pod install')
flutter_build_debug()
print('flutter_build_debug success')
# flutter_build_sh()
# os.chdir(utils.root_path())
# if ret != 0:
# print('!!!!!!!!!!!download dependencies fail!!!!!!!!!!!!!!!')
# return False
# info_mapper = dependencies_info_mapper()
# if os.path.exists(DEPENDENCY_PATH):
# shutil.rmtree(DEPENDENCY_PATH)
# os.mkdir(DEPENDENCY_PATH)
# for n in dependencies_info:
# info = dependency_info(n, '', info_mapper, is_daily_build)
# origin_path = find_headers_path(info['name'])
# if not origin_path:
# continue
# target_path = os.path.join(DEPENDENCY_PATH, n)
# os.mkdir(target_path)
# target_path = os.path.join(target_path, 'include')
#遍历依赖库
# header_dir = info.get('header_dir', '')
# if len(header_dir) > 0:
# os.mkdir(target_path)
# target_path = os.path.join(target_path, header_dir)
# os.symlink(origin_path, target_path)
return True
# 生产plist
def generate_plist(output_dir, project_name, version):
content = '''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>{version}</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
'''.format(version=version)
plist_path = '{}/{}-Info.plist'.format(output_dir, project_name)
utils.write_content(content, plist_path)
def generate_zip(output_dir, project_name):
product_dir = os.path.join(output_dir, project_name)
shutil.make_archive(product_dir, 'zip', FRAMEWORK_PATH)
# shutil.move(install_path(project_name), product_dir)
def pack(cfg, project_name, version):
generate_plist(cfg.output_dir, project_name, version)
generate_zip(cfg.output_dir, project_name)
def build_version(cfg, project):
if cfg.action != 'build' or 'version' not in project:
return cfg.version
version = project['version']
if not version.endswith('-dev'):
version += '-dev'
return version
def run(cfg):
print('--------ios---------')
project = utils.project_info()
# print(project)
# print(cfg)
flutter_build_sh()
if not os.path.exists(cfg.output_dir):
os.makedirs(cfg.output_dir)
project_name = project['name']
pack(cfg, project_name, build_version(cfg, project))
# shutil.copy(FRAMEWORK_PATH,cfg.output_dir)
# os.system('ls ' + cfg.output_dir)
# force_update_deps = ('UpdatePod' in cfg.macro_arg)
# is_daily_build = (cfg.action == 'build')
# if download_dependencies(project, cfg.output_dir, is_daily_build, force_update_deps or not is_daily_build) and build(project_name):
# pack(cfg, project_name, build_version(cfg, project))
# os.system('ls ' + cfg.output_dir)
# print('build success')
# exit(0)
# exit(1)
ci-build.sh
if [ -z $out ]; then
out='ios_frameworks'
fi
echo "准备输出所有文件到目录: $out"
echo "清除所有已编译文件"
find . -d -name build | xargs rm -rf
flutter clean
rm -rf $out
rm -rf build
flutter packages get
addFlag(){
cat .ios/Podfile > tmp1.txt
echo "use_frameworks!" >> tmp2.txt
cat tmp1.txt >> tmp2.txt
cat tmp2.txt > .ios/Podfile
rm tmp1.txt tmp2.txt
}
# echo "检查 .ios/Podfile文件状态"
# a=$(cat .ios/Podfile)
# if [[ $a == use* ]]; then
# echo '已经添加use_frameworks, 不再添加'
# else
# echo '未添加use_frameworks,准备添加'
# addFlag
# echo "添加use_frameworks 完成"
# fi
echo "编译flutter"
flutter build ios --debug --no-codesign
#release下放开下一行注释,注释掉上一行代码
#flutter build ios --release --no-codesign
echo "编译flutter完成"
mkdir $out
cp -r build/ios/Debug-iphoneos/*.framework $out
#release下放开下一行注释,注释掉上一行代码
#cp -r build/ios/Release-iphoneos/*/*.framework $out
# cp -r .ios/Flutter/App.framework $out
# cp -r .ios/Flutter/engine/Flutter.framework $out
echo "复制framework库到临时文件夹: $out"
libpath='../'
rm -rf "$libpath/ios_frameworks"
mkdir $libpath
cp -r $out $libpath
echo "复制库文件到: $libpath"
utils.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import shutil
import glob
import json
import subprocess
def root_path():
return os.path.abspath(os.path.join(__file__, '../..'))
def project_info():
project_file = os.path.join(root_path(), 'project.json')
return load_json(project_file)
def load_json(path):
with open(path) as json_file:
return json.load(json_file)
def write_content(content, file_path):
with open(file_path, 'wb') as f:
f.write(content.encode('utf-8'))
f.flush()
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 -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 = ''
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)
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(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 get_git_revision_hash(project_path=None, is_short=False):
cmds = ['git']
if project_path:
cmds.extend(['-C', project_path])
cmds.append('rev-parse')
if is_short:
cmds.append('--short')
cmds.append('HEAD')
return subprocess.check_output(cmds).decode('utf-8').strip()
python3 ci-build.py build --platform android --version 1.0.0-SNAPSHOT --output_dir /Users/lvfeijun/Desktop/hqjy/fluttermodule/and_aar --macro_arg local_build
android.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import glob
import shutil
import json
import zipfile
import platform
import xml.etree.cElementTree as ET
if sys.version > '3':
import urllib.request as urllib2
else:
import urllib2
from . import utils,sync_version
try:
NDK_ROOT = os.environ['ANDROID_NDK_HOME']
ANDROID_HOME = os.environ['ANDROID_HOME']
except KeyError as identifier:
NDK_ROOT = ''
ANDROID_HOME = ''
#python ci-build.py build --platform android --version 1.0.0-SNAPSHOT --output_dir /Users/hqwx/new_sdk/build --macro_arg local_build
CMAKE_PATH = ANDROID_HOME + '/cmake/3.6.4111459/bin/cmake'
BUILD_OUT_PATH = 'build/Android'
ANDROID_BUILD_CMD = '%s %s -DCMAKE_INSTALL_PREFIX=%s -DANDROID_ABI="%s" -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=%s/build/cmake/android.toolchain.cmake -DANDROID_TOOLCHAIN=clang -DANDROID_NDK=%s -DANDROID_PLATFORM=android-14 -DANDROID_STL="c++_shared" && %s --build . --config Release -- -j8 && make install'
DEPENDENCY_PATH = os.path.join(utils.root_path(), 'and_aar')
def system_architecture_is64():
return platform.machine().endswith('64')
#NDK strip
ANDROID_STRIP_FILE = {
'armeabi': NDK_ROOT + '/toolchains/arm-linux-androideabi-4.9/prebuilt/%s/bin/arm-linux-androideabi-strip',
'armeabi-v7a': NDK_ROOT + '/toolchains/arm-linux-androideabi-4.9/prebuilt/%s/bin/arm-linux-androideabi-strip',
'x86': NDK_ROOT + '/toolchains/x86-4.9/prebuilt/%s/bin/i686-linux-android-strip',
'arm64-v8a': NDK_ROOT + '/toolchains/aarch64-linux-android-4.9/prebuilt/%s/bin/aarch64-linux-android-strip',
'x86_64': NDK_ROOT + '/toolchains/x86_64-4.9/prebuilt/%s/bin/x86_64-linux-android-strip',
}
ANDROID_STL_FILE = {
'armeabi': NDK_ROOT + '/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++_shared.so',
'armeabi-v7a': NDK_ROOT + '/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so',
'x86': NDK_ROOT + '/sources/cxx-stl/llvm-libc++/libs/x86/libc++_shared.so',
'arm64-v8a': NDK_ROOT + '/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so',
'x86_64': NDK_ROOT + '/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so',
}
def get_android_strip_cmd(arch):
system_str = platform.system().lower()
if (system_architecture_is64()):
system_str = system_str + '-x86_64'
else:
pass
strip_cmd = ANDROID_STRIP_FILE[arch] %(system_str)
print('Android strip cmd:%s' %(strip_cmd))
return strip_cmd
def project_info():
project_file = os.path.join(utils.root_path(), 'android/project.json')
return load_json(project_file)
def load_json(path):
with open(path) as json_file:
return json.load(json_file)
def get_download_url(group, artifact, version, abi, file_name):
url = 'http://repo.duowan.com:8181/nexus/content/groups/public'
url = url+'/'+group+'/'+artifact+'/'+version
url = url + '/' + file_name
return url
def dependencies_info_mapper():
info_mapper_path = os.path.join(utils.root_path(), 'ci_build/android_ver_mapper.json')
return utils.load_json(info_mapper_path)
def download_dependencies_abi(project_info,arch):
info_mapper = dependencies_info_mapper()
name_mapper = project_info['name_mapper']
for info in project_info['dependencies']:
group = info['group']
artifact = info['artifact']
version = info['version']
if info_mapper.get(artifact) is not None:
mapper_ver = info_mapper[artifact]["versions"][version]
if mapper_ver is not None:
version = mapper_ver
abi = arch
file_type = info['type']
is_snapshot = version.endswith("-SNAPSHOT")
if is_snapshot :
file_name = "maven-metadata.xml"
else :
file_name = artifact + '-' + version + '-' + abi + '.' + file_type
url = get_download_url(group,artifact,version,abi,file_name)
print('====== download url =='+url+"======")
name = name_mapper.get(artifact)
if name is not None:
artifact = name
target_dir = os.path.join(DEPENDENCY_PATH,artifact+"/"+abi)
if not os.path.exists(target_dir):
os.makedirs(target_dir)
######自定义文件夹
folder = info.get('folder')
if folder is not None:
target_dir = os.path.join(target_dir,folder)
if not os.path.exists(target_dir):
os.mkdir(target_dir)
if file_type == 'so' or file_type == "a":
file_name = 'lib'+artifact+"."+file_type
target_path = os.path.join(target_dir,file_name)
download(url,target_path)
if is_snapshot :
tree = ET.parse(os.path.join(target_dir,"maven-metadata.xml"))
root = tree.getroot()
for versioning in root.findall("versioning"):
for snapshot in versioning.findall("snapshot") :
timestamp = snapshot.find("timestamp").text
buildNumber = snapshot.find("buildNumber").text
file_name = artifact + '-' + version.replace("-SNAPSHOT","") + '-' + timestamp + "-" + buildNumber + "-" + abi + '.' + file_type
url = get_download_url(group,artifact,version,abi,file_name)
target_path = os.path.join(target_dir,file_name)
print('====== download url =='+url+"======")
download(url,target_path)
if file_type == 'har':
unzipfile(target_path,target_dir)
os.remove(target_path)
return True
def download_dependencies(project_info,archs):
for arch in archs:
if not download_dependencies_abi(project_info,arch):
return False
return True
def download(url, dst):
ret = None
try:
ret = urllib2.urlopen(url,timeout=30)
except urllib2.HTTPError as e:
print('====download HTTPError=====')
if ret is not None:
data = ret.read()
with open(dst, 'wb') as w:
w.write(data)
print('download success [%s]'%url)
def unzipfile(file_path, dest_dir):
if not os.path.exists(dest_dir):
os.mkdir(dest_dir)
zf = zipfile.ZipFile(file_path)
# try:
zf.extractall(path=dest_dir)
# except RuntimeError as e:
# print(e)
zf.close()
def build_android_abi(local_build,project,arch):
utils.clean(BUILD_OUT_PATH)
os.chdir(BUILD_OUT_PATH)
project_path = utils.root_path()
build_path = os.path.join(project_path, BUILD_OUT_PATH+"/"+arch)
build_cmd = ANDROID_BUILD_CMD %(CMAKE_PATH,project_path,build_path,arch, NDK_ROOT, NDK_ROOT,CMAKE_PATH)
print(("build cmd:" + build_cmd))
ret = os.system(build_cmd)
if ret != 0:
print('==================build fail========================')
return False
#ndk srtip prebuilt 生成正式可用 so
# lib_path = arch+"/"+project['name'] + '/libs'
out_lib_path = os.path.join(build_path, project['name'] + '/libs')
strip_cmd = get_android_strip_cmd(arch)
for f in glob.glob('%s/*.so' %(out_lib_path)):
os.system('%s %s' %(strip_cmd, f))
android_path = os.path.join(project_path,'android')
print("android_path:" + android_path+",out_lib_path:"+out_lib_path)
if project['copy_lib'] == 1:
copy_file(out_lib_path,android_path,arch)
elif project['copy_lib'] == 2:
shutil.copy(ANDROID_STL_FILE[arch], out_lib_path)
copy_file2(out_lib_path,android_path,arch)
if local_build:
project_name = project['name']
if project_name == 'hqwxbase':
update_dependencies(build_path,'hqwxsignalling',project_name,arch)
update_dependencies(build_path,'hqwxclassing',project_name,arch)
update_dependencies(build_path,'hqwxclassroom',project_name,arch)
update_dependencies(build_path,'hqwxwhiteboard',project_name,arch)
elif project_name == 'hqwxsignalling':
update_dependencies(build_path,'hqwxclassroom',project_name,arch)
update_dependencies(build_path,'hqwxclassing',project_name,arch)
elif project_name == 'hqwxclassroom':
update_dependencies(build_path,'hqwxclassing',project_name,arch)
update_dependencies(build_path,'hqwxwhiteboard',project_name,arch)
update_dependencies(build_path,'hqwxinteractive',project_name,arch)
elif project_name == 'hqwxinteractive':
update_dependencies(build_path,'hqwxclassing',project_name,arch)
elif project_name == 'hqwxmetrics':
update_dependencies(build_path,'hqwxclassing',project_name,arch)
update_dependencies(build_path,'hqwxsignalling',project_name,arch)
update_dependencies(build_path,'hqwxclassroom',project_name,arch)
update_dependencies(build_path,'hqwxwhiteboard',project_name,arch)
update_dependencies(build_path,'hqwxinteractive',project_name,arch)
return True
def build_android(local_build,project,archs):
for arch in archs:
if not build_android_abi(local_build, project,arch):
return False
if local_build:
return True
project_path = utils.root_path()
android_path = os.path.join(project_path,'android')
os.chdir(os.path.join(android_path,'gradle_build'))
#bash gradlew clean assembleRelease bash gradlew clean publish
ret = os.system('bash gradlew clean publish')
if ret:
print('==================publish fail========================'+android_path)
return False
print('==================publish success========================'+android_path)
return True
#本地构建 更新到引用的库
def update_dependencies(build_path,module_name,project_name,arch):
build_path = build_path+"/"+project_name
depend_path = os.path.dirname(utils.root_path())+'/'+module_name+'/depends/'+project_name+"/"+arch
if os.path.exists(depend_path):
del_file(depend_path)
shutil.rmtree(depend_path,True)
os.makedirs(depend_path)
shutil.copytree(build_path+"/include",depend_path+"/include")
shutil.copytree(build_path+"/libs",depend_path+"/libs")
print("===== update "+module_name+" dependencies ===="+build_path)
def del_file(path):
for i in os.listdir(path):
path_file = os.path.join(path,i)
if os.path.isfile(path_file):
os.remove(path_file)
else:
del_file(path_file)
def copy_file(out_lib_path,android_path,arch):
target_path = os.path.join(android_path,"libs/"+arch)
if os.path.exists(target_path):
shutil.rmtree(target_path)
os.makedirs(target_path)
flist = os.listdir(out_lib_path)
for file_name in flist:
shutil.copyfile(os.path.join(out_lib_path,file_name),os.path.join(target_path,file_name))
print('========coy_file========'+target_path)
return target_path
def copy_file2(out_lib_path,android_path,arch):
target_path = copy_file(out_lib_path,android_path,arch)
shutil.copyfile(utils.root_path()+"/depends/hqwxsignalling/"+arch+"/libs/libhqwxsignalling.so",os.path.join(target_path,'libhqwxsignalling.so'))
shutil.copyfile(utils.root_path()+"/depends/hqwxbase/"+arch+"/libs/libhqwxbase.so",os.path.join(target_path,'libhqwxbase.so'))
#shutil.copyfile(utils.root_path()+"/depends/hqwxclassroom/libs/libhqwxclassroom.so",os.path.join(target_path,'libhqwxclassroom.so'))
#shutil.copyfile(utils.root_path()+"/depends/hqwxinteractive/libs/libhqwxinteractive.so",os.path.join(target_path,'libhqwxinteractive.so'))
print('========coy_file2========')
def version_header_content(project_info, file_name):
_name = project_info.get('name')
_version_name = _name.upper()
_version = project_info.get('version', '1.0.0-dev')
_version = dependencies_info_mapper().get(_name).get('versions').get(_version)
_build_num = os.environ.get('BUILD_NUMBER', 1)
_commit_id = utils.get_git_revision_hash(project_path=utils.root_path(), is_short=True)
return '''#ifndef {file_name}_h
#define {file_name}_h
#define {version_name}_VERSION "{version}"
#define {version_name}_BUILD_NUM {build_num}
#define {version_name}_COMMIT_ID "{commit_id}"
#endif /* {file_name}_h */
'''.format(file_name=file_name, version_name=_version_name, version=_version, build_num=_build_num, commit_id=_commit_id)
def flutter_build_sh():
print('ci-build-and')
os.chdir(utils.root_path())
os.system('ls')
return os.system('sh ci-build-and.sh');
def flutter_build_aar():
print('flutter_build_aar')
os.chdir(utils.root_path())
return os.system('flutter build aar')
def flutter_build_apk():
print('flutter_build_apk')
os.chdir(utils.root_path())
return os.system('flutter build apk')
def generate_zip(output_dir, project_name):
product_dir = os.path.join(output_dir, project_name)
shutil.make_archive(product_dir, 'zip', DEPENDENCY_PATH)
def run(cfg):
print('--------android---------')
print(cfg)
project = utils.project_info()
if not os.path.exists(cfg.output_dir):
os.makedirs(cfg.output_dir)
flutter_build_sh()
project_name = project['name']
print(project_name)
generate_zip(cfg.output_dir, project_name)
# local_bool = cfg.macro_arg == "local_build"
# project = project_info()
# file_name = '{}_version'.format(project.get('name'))
# content = version_header_content(project, file_name)
# file_path = os.path.join(utils.root_path(), 'src/{}.h'.format(file_name))
# utils.write_content(content, file_path)
# archs = set(["arm64-v8a","armeabi-v7a"])
# if local_bool :
# if os.path.exists(DEPENDENCY_PATH):
# build_android(local_bool,project,archs)
# else:
# project = project_info()
# print(project)
# os.mkdir(DEPENDENCY_PATH)
# if download_dependencies(project,archs) and build_android(local_bool,project,archs):
# print('==================output========================')
# exit(0)
# exit(1)
# else:
# if os.path.exists(DEPENDENCY_PATH):
# shutil.rmtree(DEPENDENCY_PATH)
# os.mkdir(DEPENDENCY_PATH)
# print(project)
# if download_dependencies(project,archs) and build_android(local_bool,project,archs):
# print('==================output========================')
# exit(0)
# exit(1)
ci-build-and.sh
if [ -z $out ]; then
out='and_aar'
fi
echo "准备输出所有文件到目录: $out"
echo "清除所有已编译文件"
find . -d -name build | xargs rm -rf
flutter clean
rm -rf $out
rm -rf build
flutter packages get
addFlag(){
cat .ios/Podfile > tmp1.txt
echo "and_aar!" >> tmp2.txt
cat tmp1.txt >> tmp2.txt
cat tmp2.txt > .android/gradlew
rm tmp1.txt tmp2.txt
}
# echo "检查 .ios/Podfile文件状态"
# a=$(cat .ios/Podfile)
# if [[ $a == use* ]]; then
# echo '已经添加use_frameworks, 不再添加'
# else
# echo '未添加use_frameworks,准备添加'
# addFlag
# echo "添加use_frameworks 完成"
# fi
echo "编译flutter"
flutter build aar
# flutter build apk
echo "编译flutter完成"
mkdir $out
cp -r build/host/outputs/* $out
#release下放开下一行注释,注释掉上一行代码
#cp -r build/ios/Release-iphoneos/*/*.framework $out
# cp -r .ios/Flutter/App.framework $out
# cp -r .ios/Flutter/engine/Flutter.framework $out
echo "复制aar库到临时文件夹: $out"
libpath='../'
rm -rf "$libpath/and_aar"
mkdir $libpath
cp -r $out $libpath
echo "复制库文件到: $libpath"