290 lines
9.2 KiB
Python
290 lines
9.2 KiB
Python
#-*-coding:utf-8-*-
|
|
|
|
import os
|
|
import shutil
|
|
import zipfile
|
|
import hashlib
|
|
import sys
|
|
import platform
|
|
import requests
|
|
import urllib
|
|
import subprocess
|
|
|
|
#工具类
|
|
class Utils():
|
|
#如果目录不存,则创建。
|
|
@staticmethod
|
|
def mkDir(dirPath):
|
|
if os.path.exists(dirPath) and os.path.isdir(dirPath):
|
|
return
|
|
parent = os.path.dirname(dirPath)
|
|
if not (os.path.exists(parent) and os.path.isdir(parent)):
|
|
Utils.mkDir(parent)
|
|
|
|
os.mkdir(dirPath)
|
|
|
|
#获取某个目录是否含有某个文件, extList获取指定的文件后缀
|
|
@staticmethod
|
|
def getAllDirFiles(dirPath, extList = None):
|
|
ret = []
|
|
for file in os.listdir( dirPath):
|
|
if os.path.isfile(os.path.join(dirPath, file)):
|
|
ret.append(os.path.join(dirPath, file))
|
|
else:
|
|
ret += Utils.getAllDirFiles(os.path.join(dirPath, file))
|
|
|
|
#需要过滤某些文件
|
|
if extList != None:
|
|
extList = [tmp.lower() for tmp in extList]
|
|
ret = [path for path in ret if os.path.splitext(path)[1].lower() in extList]
|
|
return ret
|
|
|
|
#清理掉某个数据
|
|
@staticmethod
|
|
def cleanFile(path):
|
|
if not os.path.exists(path):
|
|
return
|
|
if os.path.isdir(path):
|
|
shutil.rmtree(path)
|
|
elif os.path.isfile(path):
|
|
os.remove(path)
|
|
|
|
#将一个文件夹压缩成zip文件
|
|
@staticmethod
|
|
def makeZipFile(fileName, fromDir):
|
|
fileList = Utils.getAllDirFiles(fromDir)
|
|
with zipfile.ZipFile(fileName , 'w') as zip:
|
|
for file in fileList:
|
|
zip.write(file, os.path.relpath(file, fromDir))
|
|
|
|
@staticmethod
|
|
def extractZipFile(fileName, toDir = "."):
|
|
file_zip = zipfile.ZipFile(fileName, 'r')
|
|
for file in file_zip.namelist():
|
|
file_zip.extract(file, toDir)
|
|
file_zip.close()
|
|
|
|
|
|
@staticmethod
|
|
def sha256_checksum(filename, block_size=65536):
|
|
sha256 = hashlib.sha256()
|
|
with open(filename, 'rb') as f:
|
|
for block in iter(lambda: f.read(block_size), b''):
|
|
sha256.update(block)
|
|
return sha256.hexdigest()
|
|
|
|
#获取python文件所在的路径
|
|
def p():
|
|
frozen = "not"
|
|
if getattr(sys, 'frozen',False):
|
|
frozen = "ever so"
|
|
return os.path.dirname(sys.executable)
|
|
|
|
return os.path.split(os.path.realpath(__file__))[0]
|
|
|
|
#下载进度条回调
|
|
def callbackfunc(blocknum, blocksize, totalsize):
|
|
'''回调函数
|
|
@blocknum: 已经下载的数据块
|
|
@blocksize: 数据块的大小
|
|
@totalsize: 远程文件的大小
|
|
'''
|
|
percent = 100.0 * blocknum * blocksize / totalsize
|
|
if percent > 100:
|
|
percent = 100
|
|
|
|
max_arrow = 50 #进度条的长度
|
|
num_arrow = int(percent * max_arrow/100.0)
|
|
|
|
process_bar = '\r[' + '>' * num_arrow + '#' * (max_arrow - num_arrow) + ']'\
|
|
+ '%.2f%%' % percent #带输出的字符串,'\r'表示不换行回到最左边
|
|
sys.stdout.write(process_bar) #这两句打印字符到终端
|
|
sys.stdout.flush()
|
|
|
|
#andoird sdk 的操作sdk路径
|
|
class AndroidSDK():
|
|
def __init__(self):
|
|
self.ANDROID_SDK = self.getAndroidSDKPath()
|
|
if self.ANDROID_SDK == None:
|
|
self.ANDROID_SDK = self.installAndroidSDK()
|
|
#更新android sdk
|
|
self.updateSDK(['platforms;android-16'])
|
|
|
|
self.cmakeDir = self.getCmakeDir()
|
|
if self.cmakeDir == None:
|
|
self.updateSDK(['cmake;3.6.4111459'])
|
|
self.cmakeDir = self.getCmakeDir()
|
|
|
|
self.NDKPath = self.getNDKPath()
|
|
if self.NDKPath == None:
|
|
self.updateSDK(['ndk-bundle'])
|
|
self.NDKPath = self.getNDKPath()
|
|
|
|
|
|
def installAndroidSDK(self):
|
|
sysstr = platform.system().lower()
|
|
|
|
SHA_256 = {
|
|
"windows":'7e81d69c303e47a4f0e748a6352d85cd0c8fd90a5a95ae4e076b5e5f960d3c7a',
|
|
'darwin':'ecb29358bc0f13d7c2fa0f9290135a5b608e38434aad9bf7067d0252c160853e',
|
|
'linux':'92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9',
|
|
}
|
|
|
|
#是否需要下载包
|
|
needDownload = True
|
|
android_sdk_zip = "android_sdk.zip"
|
|
if os.path.isfile(android_sdk_zip):
|
|
sha256 = Utils.sha256_checksum(android_sdk_zip)
|
|
if sha256.lower() == SHA_256[sysstr]:
|
|
needDownload = False
|
|
|
|
print u"下载Android_sdk"
|
|
#下载包
|
|
if needDownload:
|
|
sdk_download_url = 'https://dl.google.com/android/repository/sdk-tools-%s-4333796.zip'%(sysstr, )
|
|
urllib.urlretrieve(sdk_download_url, android_sdk_zip, callbackfunc)
|
|
|
|
#解压文件
|
|
Utils.extractZipFile(android_sdk_zip, "./android_sdk")
|
|
os.environ['ANDROID_HOME'] = os.path.realpath("android_sdk")
|
|
return os.environ['ANDROID_HOME']
|
|
|
|
def updateSDK(self, package = [ 'platforms;android-16', 'cmake;3.6.4111459', 'ndk-bundle' ]):
|
|
sdkmanager = os.path.join(self.ANDROID_SDK, 'tools/bin/sdkmanager')
|
|
if "windows" == platform.system().lower():
|
|
sdkmanager = sdkmanager + '.bat'
|
|
else:
|
|
cmd = 'chmod +x %s' %(sdkmanager,)
|
|
os.system(cmd)
|
|
|
|
args = ['"%s"' %(key) for key in package]
|
|
|
|
args.insert(0, sdkmanager)
|
|
cmd = 'echo y|' + " ".join(args)
|
|
os.system(cmd)
|
|
|
|
|
|
#获取sdk里的 cmake 信息
|
|
def getCmakeDir(self):
|
|
ndk_cmake_dir = os.path.join(self.ANDROID_SDK, "cmake")
|
|
if not os.path.isdir(ndk_cmake_dir):
|
|
return None
|
|
|
|
cmake_dir_list = os.listdir(ndk_cmake_dir)
|
|
list_len = len(cmake_dir_list)
|
|
if list_len <= 0:
|
|
return None
|
|
|
|
return os.path.join(ndk_cmake_dir, cmake_dir_list[list_len - 1] )
|
|
|
|
|
|
def getNDKPath(self):
|
|
#通过系统变量来寻找
|
|
environ_names = [
|
|
'NDK_ROOT',
|
|
]
|
|
|
|
for name in environ_names:
|
|
#环境变量里不存在
|
|
if name not in os.environ.keys():
|
|
continue
|
|
|
|
android_ndk_path = os.environ[name]
|
|
#验证如果不存在此目录
|
|
if not os.path.isdir(android_ndk_path):
|
|
continue
|
|
|
|
return android_ndk_path
|
|
|
|
ndk_bundle_dir = os.path.join(self.ANDROID_SDK, "ndk-bundle/toolchains")
|
|
if os.path.isdir(ndk_bundle_dir):
|
|
return os.path.join(self.ANDROID_SDK, "ndk-bundle")
|
|
|
|
|
|
# 根据系统变量android sdk的路径
|
|
def getAndroidSDKPath(self):
|
|
environ_names = [
|
|
'ANDROID_HOME',
|
|
'ANDROID_SDK_ROOT'
|
|
]
|
|
|
|
for name in environ_names:
|
|
#环境变量里不存在
|
|
if name not in os.environ.keys():
|
|
continue
|
|
|
|
android_sdk_path = os.environ[name]
|
|
#验证如果不存在此目录
|
|
if not os.path.isdir(android_sdk_path):
|
|
continue
|
|
|
|
return android_sdk_path
|
|
|
|
#没有找到相应的sdk路径
|
|
return None
|
|
|
|
|
|
if '__main__' == __name__:
|
|
android_sdk = AndroidSDK()
|
|
ANDROID_SDK = android_sdk.getAndroidSDKPath()
|
|
ANDROID_NDK =android_sdk.getNDKPath()
|
|
|
|
ANDROID_CMAKE = os.path.join(android_sdk.getCmakeDir(), 'bin/cmake')
|
|
ANDROID_NINJA=os.path.join(android_sdk.getCmakeDir(),'bin/ninja')
|
|
|
|
if "windows" == platform.system().lower():
|
|
ANDROID_CMAKE = ANDROID_CMAKE + '.exe'
|
|
ANDROID_NINJA = ANDROID_NINJA + '.exe'
|
|
|
|
pyPath = p()
|
|
buildDir = os.path.join(pyPath, "build")
|
|
outDir = os.path.join(pyPath, "out")
|
|
|
|
|
|
Utils().cleanFile(outDir)
|
|
Utils().mkDir(outDir)
|
|
|
|
#需要打包的abi
|
|
abiList = [
|
|
'armeabi',
|
|
'armeabi-v7a',
|
|
"arm64-v8a",
|
|
"x86",
|
|
'x86_64',
|
|
'mips',
|
|
'mips64',
|
|
]
|
|
for abi in abiList:
|
|
os.chdir(pyPath)
|
|
Utils().cleanFile(buildDir)
|
|
Utils().mkDir(buildDir)
|
|
os.chdir(buildDir)
|
|
|
|
cmd = '''%s -DANDROID_ABI=%s \
|
|
-DANDROID_PLATFORM=android-16 \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DANDROID_NDK=%s \
|
|
-DCMAKE_CXX_FLAGS=-std=c++11 -frtti -fexceptions \
|
|
-DCMAKE_TOOLCHAIN_FILE=%s/build/cmake/android.toolchain.cmake \
|
|
-DCMAKE_MAKE_PROGRAM=%s -G "Ninja" \
|
|
-DCONSOLE=1 \
|
|
-DSXTWL_WRAPPER_JAVA=1 ..'''%(ANDROID_CMAKE,abi,ANDROID_NDK,ANDROID_NDK,ANDROID_NINJA )
|
|
|
|
os.system(cmd)
|
|
os.system("%s --build ."%(ANDROID_CMAKE, ))
|
|
|
|
outSoPath = os.path.join(outDir, "jniLibs/" + abi)
|
|
Utils().cleanFile(outSoPath)
|
|
Utils().mkDir(outSoPath)
|
|
|
|
outJavaPath = os.path.join(outDir, "java/com/huoyaojing")
|
|
if not os.path.isdir(outJavaPath):
|
|
Utils().mkDir(outJavaPath)
|
|
fileList = Utils.getAllDirFiles(buildDir, [".java"])
|
|
for tmp in fileList:
|
|
basename = os.path.basename(tmp)
|
|
shutil.move(tmp, os.path.join(outJavaPath, basename))
|
|
|
|
|
|
shutil.move(os.path.join(buildDir, "libsxtwl_java.so"),os.path.join(outSoPath, "libsxtwl_java.so"))
|
|
|