2013-10-30 14:19:07 +08:00
#!/usr/bin/python
# android-build.py
2014-03-14 12:52:24 +08:00
# Build android
2013-10-30 14:19:07 +08:00
import sys
import os , os . path
2013-10-30 18:27:56 +08:00
import shutil
2013-10-30 14:19:07 +08:00
from optparse import OptionParser
2014-06-30 03:25:49 +08:00
CPP_SAMPLES = [ ' cpp-empty-test ' , ' cpp-tests ' , ' game-controller-test ' ]
2014-07-09 18:05:02 +08:00
LUA_SAMPLES = [ ' lua-empty-test ' , ' lua-tests ' , ' lua-game-controller-test ' ]
2014-03-10 11:54:26 +08:00
ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES
2014-11-27 13:56:15 +08:00
class BUILD_CONSTANT :
SDK_ROOT = None
COCOS_ROOT = None
NDK_BUILD_COMMAND = None
def initBuildConstant ( ndk_build_param , build_mode ) :
2013-10-30 14:19:07 +08:00
''' Checking the environment NDK_ROOT, which will be used for building
'''
try :
2014-11-27 13:56:15 +08:00
ndk_root = os . environ [ ' NDK_ROOT ' ]
ndk_build_path = os . path . join ( ndk_root , " ndk-build " )
2013-10-30 14:19:07 +08:00
except Exception :
print " NDK_ROOT not defined. Please define NDK_ROOT in your environment "
sys . exit ( 1 )
2014-11-27 13:56:15 +08:00
toolchainVersion = ' 4.8 '
try :
versionFile = open ( os . path . join ( ndk_root , " RELEASE.TXT " ) )
firstLine = versionFile . readline ( )
if firstLine :
ndkVersion = firstLine [ firstLine . index ( ' r ' ) : firstLine . index ( ' ' ) ]
ndkVersionValue = int ( filter ( str . isdigit , ndkVersion ) )
if ndkVersionValue < 10 or cmp ( ndkVersion , ' r10c ' ) < 0 :
print ''' Please use NDK r10c above.
2014-11-27 16:10:52 +08:00
If you do not , your application may crash or freeze on Android L ( 5.0 ) when use BMFont and HttpClient .
2014-11-27 13:56:15 +08:00
For More information :
https : / / github . com / cocos2d / cocos2d - x / issues / 9114
https : / / github . com / cocos2d / cocos2d - x / issues / 9138 \n '''
else :
toolchainVersion = ' 4.9 '
versionFile . close ( )
except Exception :
print " Can not be determined your NDK version "
2014-11-27 16:10:52 +08:00
if toolchainVersion == ' 4.8 ' :
print ' NDK_TOOLCHAIN_VERSION is 4.8,your application may crash on Androud when use c++ 11 regular \n '
2014-11-27 13:56:15 +08:00
current_dir = os . path . dirname ( os . path . realpath ( __file__ ) )
cocos_root = os . path . join ( current_dir , " .. " )
BUILD_CONSTANT . COCOS_ROOT = cocos_root
# windows should use ";" to seperate module paths
platform = sys . platform
if platform == ' win32 ' :
ndk_module_path = ' NDK_MODULE_PATH= %s ; %s /external; %s /cocos ' % ( cocos_root , cocos_root , cocos_root )
else :
ndk_module_path = ' NDK_MODULE_PATH= %s : %s /external: %s /cocos ' % ( cocos_root , cocos_root , cocos_root )
''' The build process can be accelerated by running multiple concurrent job processes using the -j-option.
'''
try :
import multiprocessing
num_of_cpu = multiprocessing . cpu_count ( )
except Exception :
print " Can ' t know cpuinfo, use default 1 cpu "
num_of_cpu = 1
if ndk_build_param == None :
BUILD_CONSTANT . NDK_BUILD_COMMAND = ' %s -j %d NDK_DEBUG= %d %s NDK_TOOLCHAIN_VERSION= %s ' % ( ndk_build_path , num_of_cpu , build_mode == ' debug ' , ndk_module_path , toolchainVersion )
else :
BUILD_CONSTANT . NDK_BUILD_COMMAND = ' %s -j %d NDK_DEBUG= %d %s %s NDK_TOOLCHAIN_VERSION= %s ' % ( ndk_build_path , num_of_cpu , build_mode == ' debug ' , ndk_build_param , ndk_module_path , toolchainVersion )
2013-11-26 11:58:01 +08:00
def check_environment_variables_sdk ( ) :
''' Checking the environment ANDROID_SDK_ROOT, which will be used for building
'''
try :
2014-11-27 16:10:52 +08:00
BUILD_CONSTANT . SDK_ROOT = os . environ [ ' ANDROID_SDK_ROOT ' ]
2013-11-26 11:58:01 +08:00
except Exception :
print " ANDROID_SDK_ROOT not defined. Please define ANDROID_SDK_ROOT in your environment "
sys . exit ( 1 )
2014-03-10 11:54:26 +08:00
def caculate_built_samples ( args ) :
''' Compute the sampels to be built
' cpp ' for short of all cpp tests
2014-03-14 12:52:24 +08:00
' lua ' for short of all lua tests
2014-03-10 11:54:26 +08:00
'''
if ' all ' in args :
return ALL_SAMPLES
targets = [ ]
if ' cpp ' in args :
targets + = CPP_SAMPLES
args . remove ( ' cpp ' )
if ' lua ' in args :
targets + = LUA_SAMPLES
args . remove ( ' lua ' )
targets + = args
# remove duplicate elements, for example
# python android-build.py cpp hellocpp
targets = set ( targets )
return list ( targets )
2014-11-27 13:56:15 +08:00
def do_build ( app_android_root , android_platform , build_mode ) :
command = ' %s -C %s ' % ( BUILD_CONSTANT . NDK_BUILD_COMMAND , app_android_root )
2014-01-20 10:37:01 +08:00
print command
2013-11-09 21:05:17 +08:00
if os . system ( command ) != 0 :
2013-11-26 11:58:01 +08:00
raise Exception ( " Build dynamic library for project [ " + app_android_root + " ] fails! " )
elif android_platform is not None :
2014-11-27 13:56:15 +08:00
sdk_tool_path = os . path . join ( BUILD_CONSTANT . SDK_ROOT , " tools/android " )
cocoslib_path = os . path . join ( BUILD_CONSTANT . COCOS_ROOT , " cocos/platform/android/java " )
2014-03-14 12:52:24 +08:00
command = ' %s update lib-project -t %s -p %s ' % ( sdk_tool_path , android_platform , cocoslib_path )
if os . system ( command ) != 0 :
raise Exception ( " update cocos lib-project [ " + cocoslib_path + " ] fails! " )
command = ' %s update project -t %s -p %s -s ' % ( sdk_tool_path , android_platform , app_android_root )
if os . system ( command ) != 0 :
raise Exception ( " update project [ " + app_android_root + " ] fails! " )
buildfile_path = os . path . join ( app_android_root , " build.xml " )
2014-11-27 13:56:15 +08:00
command = ' ant clean %s -f %s -Dsdk.dir= %s ' % ( build_mode , buildfile_path , BUILD_CONSTANT . SDK_ROOT )
2014-03-14 12:52:24 +08:00
os . system ( command )
2013-10-30 14:19:07 +08:00
2013-10-30 18:27:56 +08:00
def copy_files ( src , dst ) :
for item in os . listdir ( src ) :
path = os . path . join ( src , item )
# Android can not package the file that ends with ".gz"
if not item . startswith ( ' . ' ) and not item . endswith ( ' .gz ' ) and os . path . isfile ( path ) :
shutil . copy ( path , dst )
if os . path . isdir ( path ) :
new_dst = os . path . join ( dst , item )
os . mkdir ( new_dst )
copy_files ( path , new_dst )
2014-08-08 15:22:12 +08:00
def copy_file ( src_file , dst ) :
if not src_file . startswith ( ' . ' ) and not src_file . endswith ( ' .gz ' ) and os . path . isfile ( src_file ) :
shutil . copy ( src_file , dst )
2013-10-30 18:27:56 +08:00
def copy_resources ( target , app_android_root ) :
# remove app_android_root/assets if it exists
assets_dir = os . path . join ( app_android_root , " assets " )
if os . path . isdir ( assets_dir ) :
shutil . rmtree ( assets_dir )
os . mkdir ( assets_dir )
2014-03-11 16:10:02 +08:00
# copy resources(cpp samples)
if target in CPP_SAMPLES :
resources_dir = os . path . join ( app_android_root , " ../Resources " )
if os . path . isdir ( resources_dir ) :
copy_files ( resources_dir , assets_dir )
2013-10-30 18:27:56 +08:00
2014-03-10 11:54:26 +08:00
# lua samples should copy lua script
if target in LUA_SAMPLES :
2014-03-11 16:10:02 +08:00
resources_dir = os . path . join ( app_android_root , " ../../res " )
2014-04-01 20:06:43 +08:00
assets_res_dir = os . path . join ( assets_dir , " res " )
2014-03-11 17:34:08 +08:00
os . mkdir ( assets_res_dir )
2014-04-01 20:06:43 +08:00
if target != " lua-tests " :
copy_files ( resources_dir , assets_res_dir )
src_dir = os . path . join ( app_android_root , " ../../src " )
assets_src_dir = os . path . join ( assets_dir , " src " )
2014-03-11 17:34:08 +08:00
os . mkdir ( assets_src_dir )
2014-04-01 20:06:43 +08:00
copy_files ( src_dir , assets_src_dir )
2014-03-14 12:52:24 +08:00
2014-10-14 21:34:55 +08:00
common_script_dir = os . path . join ( app_android_root , " ../../../../cocos/scripting/lua-bindings/script/ " )
cocos_src_dir = os . path . join ( assets_src_dir , " cocos " )
if os . path . exists ( cocos_src_dir ) :
shutil . rmtree ( cocos_src_dir )
os . mkdir ( cocos_src_dir )
copy_files ( common_script_dir , cocos_src_dir )
2014-03-10 11:54:26 +08:00
2014-04-01 20:06:43 +08:00
luasocket_script_dir = os . path . join ( app_android_root , " ../../../../external/lua/luasocket " )
for root , dirs , files in os . walk ( luasocket_script_dir ) :
2014-03-29 14:58:23 +08:00
for f in files :
if os . path . splitext ( f ) [ 1 ] == ' .lua ' :
2014-04-01 20:06:43 +08:00
fall = os . path . join ( root , f )
2014-04-01 18:09:49 +08:00
shutil . copy ( fall , assets_dir )
2014-03-29 14:58:23 +08:00
2014-03-11 16:10:02 +08:00
# lua-tests shared resources with cpp-tests
if target == " lua-tests " :
2014-04-01 20:06:43 +08:00
resources_cocosbuilder_res_dir = os . path . join ( resources_dir , " cocosbuilderRes " )
assets_cocosbuilder_res_dir = os . path . join ( assets_res_dir , " cocosbuilderRes " )
os . mkdir ( assets_cocosbuilder_res_dir )
copy_files ( resources_cocosbuilder_res_dir , assets_cocosbuilder_res_dir )
2014-03-10 16:04:46 +08:00
resources_dir = os . path . join ( app_android_root , " ../../../cpp-tests/Resources " )
2014-03-11 17:34:08 +08:00
copy_files ( resources_dir , assets_res_dir )
2014-07-09 18:05:02 +08:00
if target == " lua-game-controller-test " :
print ( " coming generator game controller " )
resources_dir = os . path . join ( app_android_root , " ../../../game-controller-test/Resources " )
copy_files ( resources_dir , assets_res_dir )
2014-03-10 11:54:26 +08:00
2013-11-26 11:58:01 +08:00
def build_samples ( target , ndk_build_param , android_platform , build_mode ) :
2013-10-30 14:19:07 +08:00
2014-11-27 13:56:15 +08:00
if build_mode is None :
build_mode = ' debug '
elif build_mode != ' release ' :
build_mode = ' debug '
initBuildConstant ( ndk_build_param , build_mode )
2014-03-10 11:54:26 +08:00
build_targets = caculate_built_samples ( target )
2014-11-27 13:56:15 +08:00
2013-11-26 11:58:01 +08:00
if android_platform is not None :
2014-11-27 13:56:15 +08:00
check_environment_variables_sdk ( )
2014-03-14 12:52:24 +08:00
if android_platform . isdigit ( ) :
android_platform = ' android- ' + android_platform
else :
print ' please use vaild android platform '
exit ( 1 )
2014-03-10 11:54:26 +08:00
app_android_root = ' '
2014-03-11 16:10:02 +08:00
target_proj_path_map = {
" cpp-empty-test " : " tests/cpp-empty-test/proj.android " ,
2014-06-30 03:25:49 +08:00
" game-controller-test " : " tests/game-controller-test/proj.android " ,
2014-03-11 16:10:02 +08:00
" cpp-tests " : " tests/cpp-tests/proj.android " ,
" lua-empty-test " : " tests/lua-empty-test/project/proj.android " ,
2014-07-09 18:05:02 +08:00
" lua-tests " : " tests/lua-tests/project/proj.android " ,
" lua-game-controller-test " : " tests/lua-game-controller-test/project/proj.android "
2014-03-11 16:10:02 +08:00
}
2014-03-10 11:54:26 +08:00
for target in build_targets :
2014-03-11 16:10:02 +08:00
if target in target_proj_path_map :
2014-11-27 13:56:15 +08:00
app_android_root = os . path . join ( BUILD_CONSTANT . COCOS_ROOT , target_proj_path_map [ target ] )
2014-03-10 11:54:26 +08:00
else :
print ' unknown target: %s ' % target
continue
2013-10-30 14:19:07 +08:00
2014-03-14 12:52:24 +08:00
copy_resources ( target , app_android_root )
2014-11-27 13:56:15 +08:00
do_build ( app_android_root , android_platform , build_mode )
2013-10-30 14:19:07 +08:00
# -------------- main --------------
if __name__ == ' __main__ ' :
#parse the params
2014-01-26 16:09:28 +08:00
usage = """
2014-02-01 06:09:28 +08:00
This script is mainy used for building tests built - in with cocos2d - x .
2014-03-14 12:52:24 +08:00
Usage : % prog [ options ] [ cpp - empty - test | cpp - tests | lua - empty - test | lua - tests | cpp | lua | all ]
2014-01-26 16:09:28 +08:00
2014-03-11 16:10:02 +08:00
If you are new to cocos2d - x , I recommend you start with cpp - empty - test , lua - empty - test .
2014-01-26 16:09:28 +08:00
You can combine these targets like this :
2014-03-11 16:10:02 +08:00
python android - build . py - p 10 cpp - empty - test lua - empty - test
2014-01-26 16:09:28 +08:00
2014-02-01 06:09:28 +08:00
Note : You should install ant to generate apk while building the andriod tests . But it is optional . You can generate apk with eclipse .
2014-01-26 16:09:28 +08:00
"""
2013-12-22 17:48:35 +08:00
parser = OptionParser ( usage = usage )
2014-03-14 12:52:24 +08:00
parser . add_option ( " -n " , " --ndk " , dest = " ndk_build_param " ,
2014-01-26 16:09:28 +08:00
help = ' Parameter for ndk-build ' )
2014-03-14 12:52:24 +08:00
parser . add_option ( " -p " , " --platform " , dest = " android_platform " ,
2014-01-26 16:09:28 +08:00
help = ' Parameter for android-update. Without the parameter,the script just build dynamic library for the projects. Valid android-platform are:[10|11|12|13|14|15|16|17|18|19] ' )
2014-03-14 12:52:24 +08:00
parser . add_option ( " -b " , " --build " , dest = " build_mode " ,
2014-01-26 16:09:28 +08:00
help = ' The build mode for java project,debug[default] or release. Get more information,please refer to http://developer.android.com/tools/building/building-cmdline.html ' )
2013-10-30 14:19:07 +08:00
( opts , args ) = parser . parse_args ( )
2014-11-27 13:56:15 +08:00
print " We will use cocos console to build tests built-in with cocos2d-x and remove this script next version. \n "
2014-03-10 11:54:26 +08:00
if len ( args ) == 0 :
2013-12-22 17:48:35 +08:00
parser . print_help ( )
2014-03-14 12:52:24 +08:00
sys . exit ( 1 )
2013-10-30 14:19:07 +08:00
else :
2013-11-09 21:05:17 +08:00
try :
2013-11-26 11:58:01 +08:00
build_samples ( args , opts . ndk_build_param , opts . android_platform , opts . build_mode )
2013-11-09 21:05:17 +08:00
except Exception as e :
print e
sys . exit ( 1 )