Skip to content

Commit afc22f3

Browse files
author
Bin Zhang
authored
Merge pull request #409 from natural-law/gradle-support
Improve the command cocos compile to fit the new implementation of AndroidStudio project.
2 parents 6339981 + d6b54c2 commit afc22f3

File tree

3 files changed

+149
-58
lines changed

3 files changed

+149
-58
lines changed

bin/strings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@
183183
"COMPILE_ERROR_WRONG_VS_VER_FMT" : "VS %d is not supported.",
184184
"COMPILE_ERROR_LOW_VS_VER" : "Version of VS is too low.",
185185
"COMPILE_ERROR_MSDBUILD_NOT_FOUND" : "MSBuild is not found.",
186+
"COMPILE_ERROR_UNKNOWN_ENGINE_VERSION" : "Unknown engine version!",
186187
"COMPILE_INFO_FIND_VS_PATH_FMT" : "Find VS path : %s",
187188
"COMPILE_INFO_DEVENV_NOT_FOUND" : "Not found devenv. Try to use msbuild instead.",
188189
"COMPILE_INFO_FIND_MSBUILD_FMT" : "Found msbuild path: %s",
@@ -526,6 +527,7 @@
526527
"COMPILE_ERROR_WRONG_VS_VER_FMT" : "不支持 VS %d。",
527528
"COMPILE_ERROR_LOW_VS_VER" : "VS 版本过低。",
528529
"COMPILE_ERROR_MSDBUILD_NOT_FOUND" : "未找到 MSBuild 工具。",
530+
"COMPILE_ERROR_UNKNOWN_ENGINE_VERSION" : "無法識別引擎版本!",
529531
"COMPILE_INFO_FIND_VS_PATH_FMT" : "找到 VS 安装路径:%s",
530532
"COMPILE_INFO_DEVENV_NOT_FOUND" : "未找到 devenv。尝试使用 msbuild 来代替。",
531533
"COMPILE_INFO_FIND_MSBUILD_FMT" : "找到 msbuild 安装路径:%s",
@@ -868,6 +870,7 @@
868870
"COMPILE_ERROR_WRONG_VS_VER_FMT" : "不支持 VS %d。",
869871
"COMPILE_ERROR_LOW_VS_VER" : "VS 版本過低。",
870872
"COMPILE_ERROR_MSDBUILD_NOT_FOUND" : "未找到 MSBuild 工具。",
873+
"COMPILE_ERROR_UNKNOWN_ENGINE_VERSION" : "无法识别引擎版本!",
871874
"COMPILE_INFO_FIND_VS_PATH_FMT" : "找到 VS 安裝路徑:%s",
872875
"COMPILE_INFO_DEVENV_NOT_FOUND" : "未找到 devenv。嘗試使用 msbuild 來代替。",
873876
"COMPILE_INFO_FIND_MSBUILD_FMT" : "找到 msbuild 安裝路徑:%s",

plugins/plugin_compile/build_android.py

Lines changed: 100 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,24 @@ class AndroidBuilder(object):
3737
GRADLE_KEY_STORE_PASS = "RELEASE_STORE_PASSWORD"
3838
GRADLE_KEY_ALIAS_PASS = "RELEASE_KEY_PASSWORD"
3939

40-
def __init__(self, verbose, app_android_root, no_res, proj_obj, use_studio=False):
40+
GRADLE_PROP_TARGET_VERSION = 'PROP_TARGET_SDK_VERSION'
41+
GRADLE_PROP_NDK_MODE = 'PROP_NDK_MODE'
42+
GRADLE_PROP_APP_ABI = 'PROP_APP_ABI'
43+
GRADLE_PROP_COMPILE_SCRIPT = 'PROP_COMPILE_SCRIPT'
44+
GRADLE_PROP_LUA_ENCRYPT = 'PROP_LUA_ENCRYPT'
45+
GRADLE_PROP_LUA_ENCRYPT_KEY = 'PROP_LUA_ENCRYPT_KEY'
46+
GRADLE_PROP_LUA_ENCRYPT_SIGN = 'PROP_LUA_ENCRYPT_SIGN'
47+
48+
def __init__(self, verbose, app_android_root, no_res, proj_obj, ndk_mode, app_abi, use_studio=False, gradle_support_ndk=False):
4149
self._verbose = verbose
4250

4351
self.app_android_root = app_android_root
4452
self._no_res = no_res
4553
self._project = proj_obj
4654
self.use_studio = use_studio
55+
self.gradle_support_ndk = gradle_support_ndk
56+
self.app_abi = app_abi
57+
self.ndk_mode = ndk_mode
4758

4859
# check environment variable
4960
if self.use_studio:
@@ -60,6 +71,21 @@ def _run_cmd(self, command, cwd=None):
6071
cocos.CMDRunner.run_cmd(command, self._verbose, cwd=cwd)
6172

6273
def _parse_cfg(self):
74+
# get the properties for sign release apk
75+
if self.use_studio:
76+
self.key_store_str = AndroidBuilder.GRADLE_KEY_STORE
77+
self.key_alias_str = AndroidBuilder.GRADLE_KEY_ALIAS
78+
self.key_store_pass_str = AndroidBuilder.GRADLE_KEY_STORE_PASS
79+
self.key_alias_pass_str = AndroidBuilder.GRADLE_KEY_ALIAS_PASS
80+
else:
81+
self.key_store_str = AndroidBuilder.ANT_KEY_STORE
82+
self.key_alias_str = AndroidBuilder.ANT_KEY_ALIAS
83+
self.key_store_pass_str = AndroidBuilder.ANT_KEY_STORE_PASS
84+
self.key_alias_pass_str = AndroidBuilder.ANT_KEY_ALIAS_PASS
85+
86+
if self.gradle_support_ndk:
87+
return
88+
6389
self.cfg_path = os.path.join(self.app_android_root, BUILD_CFIG_FILE)
6490
try:
6591
f = open(self.cfg_path)
@@ -79,18 +105,6 @@ def _parse_cfg(self):
79105

80106
self.ndk_module_paths = cfg['ndk_module_path']
81107

82-
# get the properties for sign release apk
83-
if self.use_studio:
84-
self.key_store_str = AndroidBuilder.GRADLE_KEY_STORE
85-
self.key_alias_str = AndroidBuilder.GRADLE_KEY_ALIAS
86-
self.key_store_pass_str = AndroidBuilder.GRADLE_KEY_STORE_PASS
87-
self.key_alias_pass_str = AndroidBuilder.GRADLE_KEY_ALIAS_PASS
88-
else:
89-
self.key_store_str = AndroidBuilder.ANT_KEY_STORE
90-
self.key_alias_str = AndroidBuilder.ANT_KEY_ALIAS
91-
self.key_store_pass_str = AndroidBuilder.ANT_KEY_STORE_PASS
92-
self.key_alias_pass_str = AndroidBuilder.ANT_KEY_ALIAS_PASS
93-
94108
move_cfg = {}
95109
self.key_store = None
96110
if cfg.has_key(AndroidBuilder.CFG_KEY_STORE):
@@ -169,6 +183,18 @@ def remove_c_libs(self, libs_dir):
169183
os.remove(lib_file)
170184

171185
def update_project(self, android_platform):
186+
if self.gradle_support_ndk:
187+
# If gradle supports ndk build, should write local.properties manually
188+
local_porps_path = os.path.join(self.app_android_root, 'local.properties')
189+
lines = [
190+
'sdk.dir=%s\n' % self.sdk_root,
191+
'ndk.dir=%s\n' % cocos.check_environment_variable('NDK_ROOT')
192+
]
193+
f = open(local_porps_path, 'w')
194+
f.writelines(lines)
195+
f.close()
196+
return
197+
172198
if self.use_studio:
173199
manifest_path = os.path.join(self.app_android_root, 'app')
174200
else:
@@ -356,7 +382,7 @@ def ant_build_apk(self, build_mode, custom_step_args):
356382
self._project.invoke_custom_step_script(cocos_project.Project.CUSTOM_STEP_POST_ANT_BUILD,
357383
target_platform, args_ant_copy)
358384

359-
def gradle_build_apk(self, build_mode):
385+
def gradle_build_apk(self, build_mode, android_platform, compile_obj):
360386
# check the compileSdkVersion & buildToolsVersion
361387
check_file = os.path.join(self.app_android_root, 'app', 'build.gradle')
362388
f = open(check_file)
@@ -404,6 +430,32 @@ def gradle_build_apk(self, build_mode):
404430

405431
mode_str = 'Debug' if build_mode == 'debug' else 'Release'
406432
cmd = '"%s" --parallel --info assemble%s' % (gradle_path, mode_str)
433+
434+
if self.gradle_support_ndk:
435+
add_props = {
436+
AndroidBuilder.GRADLE_PROP_NDK_MODE: self.ndk_mode
437+
}
438+
if android_platform:
439+
add_props[AndroidBuilder.GRADLE_PROP_TARGET_VERSION] = android_platform
440+
441+
if self.app_abi:
442+
add_props[AndroidBuilder.GRADLE_PROP_APP_ABI] = ':'.join(self.app_abi.split(' '))
443+
444+
if self._project._is_script_project():
445+
if compile_obj._compile_script:
446+
add_props[AndroidBuilder.GRADLE_PROP_COMPILE_SCRIPT] = 1
447+
else:
448+
add_props[AndroidBuilder.GRADLE_PROP_COMPILE_SCRIPT] = 0
449+
450+
if self._project._is_lua_project():
451+
if compile_obj._lua_encrypt:
452+
add_props[AndroidBuilder.GRADLE_PROP_LUA_ENCRYPT] = 1
453+
add_props[AndroidBuilder.GRADLE_PROP_LUA_ENCRYPT_KEY] = compile_obj._lua_encrypt_key
454+
add_props[AndroidBuilder.GRADLE_PROP_LUA_ENCRYPT_SIGN] = compile_obj._lua_encrypt_sign
455+
456+
for key in add_props.keys():
457+
cmd += ' -P%s=%s' % (key, add_props[key])
458+
407459
self._run_cmd(cmd, cwd=self.app_android_root)
408460

409461
class LuaBuildType:
@@ -461,7 +513,7 @@ def _get_build_type(self, param_of_appabi):
461513

462514
return self.LuaBuildType.UNKNOWN
463515

464-
def do_build_apk(self, build_mode, no_apk, output_dir, custom_step_args, compile_obj):
516+
def do_build_apk(self, build_mode, no_apk, output_dir, custom_step_args, android_platform, compile_obj):
465517
if self.use_studio:
466518
assets_dir = os.path.join(self.app_android_root, "app", "assets")
467519
project_name = None
@@ -489,45 +541,44 @@ def do_build_apk(self, build_mode, no_apk, output_dir, custom_step_args, compile
489541
project_name = self._xml_attr(self.app_android_root, 'build.xml', 'project', 'name')
490542
gen_apk_folder = os.path.join(self.app_android_root, 'bin')
491543

492-
# copy resources
493-
self._copy_resources(custom_step_args, assets_dir)
544+
# gradle supports copy assets & compile scripts from engine 3.15
545+
if not self.gradle_support_ndk:
546+
# copy resources
547+
self._copy_resources(custom_step_args, assets_dir)
548+
549+
# check the project config & compile the script files
550+
if self._project._is_lua_project():
551+
src_dir = os.path.join(assets_dir, 'src')
552+
build_type = self._get_build_type(compile_obj.app_abi)
494553

495-
# check the project config & compile the script files
496-
if self._project._is_lua_project():
497-
print "generate byte code ............"
498-
src_dir = os.path.join(assets_dir, 'src')
499-
build_type = self._get_build_type(compile_obj.app_abi)
554+
# only build 64bit
555+
if build_type == self.LuaBuildType.ONLY_BUILD_64BIT:
556+
dst_dir = os.path.join(assets_dir, 'src/64bit')
557+
is_compiled = compile_obj.compile_lua_scripts(src_dir, dst_dir, True)
558+
if is_compiled:
559+
# remove unneeded lua files
560+
compile_obj._remove_file_with_ext(src_dir, '.lua')
561+
shutil.rmtree(os.path.join(src_dir, 'cocos'))
562+
563+
# only build 32bit
564+
if build_type == self.LuaBuildType.ONLY_BUILD_32BIT:
565+
# build 32-bit bytecode
566+
compile_obj.compile_lua_scripts(src_dir, src_dir, False)
500567

501-
# only build 64bit
502-
if build_type == self.LuaBuildType.ONLY_BUILD_64BIT:
503-
if build_mode == 'release':
568+
# build 32bit and 64bit
569+
if build_type == self.LuaBuildType.BUILD_32BIT_AND_64BIT:
570+
# build 64-bit bytecode
504571
dst_dir = os.path.join(assets_dir, 'src/64bit')
505572
compile_obj.compile_lua_scripts(src_dir, dst_dir, True)
506-
# remove unneeded lua files
507-
compile_obj._remove_file_with_ext(src_dir, '.lua')
508-
shutil.rmtree(os.path.join(src_dir, 'cocos'))
509-
else:
573+
# build 32-bit bytecode
574+
compile_obj.compile_lua_scripts(src_dir, src_dir, False)
575+
576+
if build_type == self.LuaBuildType.UNKNOWN:
577+
# haven't set APP_ABI in parameter and Application.mk, default build 32bit
510578
compile_obj.compile_lua_scripts(src_dir, src_dir, False)
511579

512-
# only build 32bit
513-
if build_type == self.LuaBuildType.ONLY_BUILD_32BIT:
514-
# build 32-bit bytecode
515-
compile_obj.compile_lua_scripts(src_dir, src_dir, False)
516-
517-
# build 32bit and 64bit
518-
if build_type == self.LuaBuildType.BUILD_32BIT_AND_64BIT:
519-
# build 64-bit bytecode
520-
dst_dir = os.path.join(assets_dir, 'src/64bit')
521-
compile_obj.compile_lua_scripts(src_dir, dst_dir, True)
522-
# build 32-bit bytecode
523-
compile_obj.compile_lua_scripts(src_dir, src_dir, False)
524-
525-
if build_type == self.LuaBuildType.UNKNOWN:
526-
# haven't set APP_ABI in parameter and Application.mk, default build 32bit
527-
compile_obj.compile_lua_scripts(src_dir, src_dir, False)
528-
529-
if self._project._is_js_project():
530-
compile_obj.compile_js_scripts(assets_dir, assets_dir)
580+
if self._project._is_js_project():
581+
compile_obj.compile_js_scripts(assets_dir, assets_dir)
531582

532583
if not no_apk:
533584
# gather the sign info if necessary
@@ -536,7 +587,7 @@ def do_build_apk(self, build_mode, no_apk, output_dir, custom_step_args, compile
536587

537588
# build apk
538589
if self.use_studio:
539-
self.gradle_build_apk(build_mode)
590+
self.gradle_build_apk(build_mode, android_platform, compile_obj)
540591
else:
541592
self.ant_build_apk(build_mode, custom_step_args)
542593

plugins/plugin_compile/project_compile.py

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -378,19 +378,18 @@ def _remove_file_with_ext(self, work_dir, ext):
378378

379379
def compile_lua_scripts(self, src_dir, dst_dir, build_64):
380380
if not self._project._is_lua_project():
381-
return
381+
return False
382382

383383
if not self._compile_script and not self._lua_encrypt:
384-
return
384+
return False
385385

386386
cocos_cmd_path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "cocos")
387387
rm_ext = ".lua"
388388
compile_cmd = "\"%s\" luacompile -s \"%s\" -d \"%s\"" % (cocos_cmd_path, src_dir, dst_dir)
389389

390390
if not self._compile_script:
391391
compile_cmd = "%s --disable-compile" % compile_cmd
392-
393-
if build_64:
392+
elif build_64:
394393
compile_cmd = "%s --bytecode-64bit" % compile_cmd
395394

396395
if self._lua_encrypt:
@@ -409,12 +408,14 @@ def compile_lua_scripts(self, src_dir, dst_dir, build_64):
409408
# remove the source scripts
410409
self._remove_file_with_ext(dst_dir, rm_ext)
411410

411+
return True
412+
412413
def compile_js_scripts(self, src_dir, dst_dir):
413414
if not self._project._is_js_project():
414-
return
415+
return False
415416

416417
if not self._compile_script:
417-
return
418+
return False
418419

419420
cocos_cmd_path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "cocos")
420421
rm_ext = ".js"
@@ -425,6 +426,7 @@ def compile_js_scripts(self, src_dir, dst_dir):
425426

426427
# remove the source scripts
427428
self._remove_file_with_ext(dst_dir, rm_ext)
429+
return True
428430

429431
def add_warning_at_end(self, warning_str):
430432
if warning_str is None or len(warning_str) == 0:
@@ -439,6 +441,26 @@ def is_valid_path(self, p):
439441

440442
return ret
441443

444+
def get_engine_version_num(self):
445+
# 1. get engine version from .cocos_project.json
446+
engine_ver_str = self._project.get_proj_config(cocos_project.Project.KEY_ENGINE_VERSION)
447+
448+
# 2. engine version is not found. find from source file
449+
if engine_ver_str is None:
450+
engine_dir = self.get_engine_dir()
451+
if engine_dir is not None:
452+
engine_ver_str = utils.get_engine_version(engine_dir)
453+
454+
if engine_ver_str is None:
455+
return None
456+
457+
version_pattern = r'.*([\d]+)\.([\d]+)'
458+
match = re.match(version_pattern, engine_ver_str)
459+
if match:
460+
return ((int)(match.group(1)), (int)(match.group(2)))
461+
else:
462+
return None
463+
442464
def build_android(self):
443465
if not self._platforms.is_android_active():
444466
return
@@ -475,9 +497,24 @@ def build_android(self):
475497
ide_name = 'Eclipse'
476498
cocos.Logging.info(MultiLanguage.get_string('COMPILE_INFO_ANDROID_PROJPATH_FMT', (ide_name, project_android_dir)))
477499

500+
# Check whether the gradle of the project is support ndk or not
501+
gradle_support_ndk = False
502+
if using_studio:
503+
# Get the engine version of the project
504+
engine_version_num = self.get_engine_version_num()
505+
if engine_version_num is None:
506+
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_UNKNOWN_ENGINE_VERSION'))
507+
508+
# Gradle supports NDK build from engine 3.15
509+
main_ver = engine_version_num[0]
510+
minor_ver = engine_version_num[1]
511+
if main_ver > 3 or (main_ver == 3 and minor_ver >= 15):
512+
gradle_support_ndk = True
513+
478514
from build_android import AndroidBuilder
479515
builder = AndroidBuilder(self._verbose, project_android_dir,
480-
self._no_res, self._project, using_studio)
516+
self._no_res, self._project, self._ndk_mode,
517+
self.app_abi, using_studio, gradle_support_ndk)
481518

482519
args_ndk_copy = self._custom_step_args.copy()
483520
target_platform = self._platforms.get_current_platform()
@@ -486,7 +523,7 @@ def build_android(self):
486523
builder.update_project(self._ap)
487524

488525
if not self._project._is_script_project() or self._project._is_native_support():
489-
if self._ndk_mode != "none":
526+
if self._ndk_mode != "none" and not gradle_support_ndk:
490527
# build native code
491528
cocos.Logging.info(MultiLanguage.get_string('COMPILE_INFO_BUILD_NATIVE'))
492529
ndk_build_param = [
@@ -541,7 +578,7 @@ def build_android(self):
541578
# build apk
542579
if not self._no_apk:
543580
cocos.Logging.info(MultiLanguage.get_string('COMPILE_INFO_BUILD_APK'))
544-
self.apk_path = builder.do_build_apk(build_mode, self._no_apk, output_dir, self._custom_step_args, self)
581+
self.apk_path = builder.do_build_apk(build_mode, self._no_apk, output_dir, self._custom_step_args, self._ap, self)
545582
self.android_package, self.android_activity = builder.get_apk_info()
546583

547584
cocos.Logging.info(MultiLanguage.get_string('COMPILE_INFO_BUILD_SUCCEED'))

0 commit comments

Comments
 (0)