Android.mk文件,位置在android工程/jni目录下,是android工程中的makefile文件,这里我们简称它为mk文件。
1.2 自动刷新mk文件
这一节介绍mk文件的自动生成过程,所谓刷新mk文件,其实只是刷新变动的那部分mk文件内容,主要是宏设置,cpp文件删减,头文件删减这三部分。这里不介绍android.mk文件结构和相关知识,仅仅介绍如何刷mk文件变动的那部分内容。
首先,我们先来看下一个完整的mk文件,看不懂的可以直接往下翻:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS += -DNAME_MYGAME=1 LOCAL_MODULE := game_shared LOCAL_MODULE_FILENAME := libcocos2dcpp LOCAL_SRC_FILES := hellocpp/main.cpp libiconv.a ../../Classes/AppDelegate.cpp ../../Classes/Common/JavaHelper.cpp ../../Classes/GameOverScene.cpp ../../Classes/HelloWorldScene.cpp ../../Classes/LoginBackScene.cpp ../../Classes/PayBackScene.cpp ../../Classes/SDKManager/NS_SDKFactory.cpp ../../Classes/SDKManager/NS_SDKManager.cpp ../../Classes/SDKManager/NS_SDKPlatformAndroid.cpp ../../Classes/SettingScene.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../../Classes$(LOCAL_PATH)/../../Classes/SDKManager LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static include $(BUILD_SHARED_LIBRARY) $(call import-module,CocosDenshion/android) $(call import-module,extensions) $(call import-module,cocos2dx)
我将这个mk文件分为四个部分,我们先来看第一个部分:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS += -DNAME_MYGAME=1 LOCAL_MODULE := game_shared LOCAL_MODULE_FILENAME := libcocos2dcpp
这一部分代码大部分都是固定代码,除了用红色标注的那一行,用来设置宏相关的功能,每个游戏平台或者每个平台的不同子包都可以使用宏来加以区分。这个在前一节我们已经介绍过了,再来看下build_xx.sh文件,
############################################## ##平台数据,需要更改 ############################################## PLATFORMHONE_CHILD=() SDKDIR="game_xx" BUILDDIR="build_android" LIBRARYDIR="nosdk_xx" TOOLSDIR="tools" PlatformTarget="libcocos2dcpp" # PlatformName="PLATFORM_XX" PlatformGameName=( "NAME_MYGAME" ) ...
PlatformGameName变量里定义的NAME_MYGAME就是一个宏,当同一个游戏有多个子包时,可以用来区分不同游戏登录背景和游戏名称等,PLATFORM_XX也是一个宏,用来区分不同平台,
不过目前已经废弃了,所有平台相关的宏都会放在PLATFORMHONE_CHILD变量中。
mk文件的第二部,是cpp文件,mk刷新主要是便是cpp文件的刷新,当然还需要排除一些在其它平台(比如ios)使用的cpp文件。
LOCAL_SRC_FILES := hellocpp/main.cpp libiconv.a ../../Classes/AppDelegate.cpp ../../Classes/Common/JavaHelper.cpp ../../Classes/GameOverScene.cpp ../../Classes/HelloWorldScene.cpp ../../Classes/LoginBackScene.cpp ../../Classes/PayBackScene.cpp ../../Classes/SDKManager/NS_SDKFactory.cpp ../../Classes/SDKManager/NS_SDKManager.cpp ../../Classes/SDKManager/NS_SDKPlatformAndroid.cpp ../../Classes/SettingScene.cpp \
mk文件的第三部分,是包含头文件的路径集合,设置过IDE编译环境的同学应该对这个很熟悉。
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../../Classes$(LOCAL_PATH)/../../Classes/SDKManager
mk文件的第四部分,是固定部分,不会变化,当然除非你更换了cocos2d-x版本。
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static include $(BUILD_SHARED_LIBRARY) $(call import-module,CocosDenshion/android) $(call import-module,extensions) $(call import-module,cocos2dx)
下面我们将介绍刷新mk文件的脚本build_android/tools/platform_refresh.sh脚本,我们先复习下与mk刷新有关的脚本文件,主要有下面4个:
- tools: //保存通用的功能脚本
- file_list.sh //遍历文件夹,输出文件列表
- normal_define.sh //刷新mk所需的mk变量
- platform_define.sh //刷新mk所需的mk变量
- platform_refresh.sh //刷新mk的脚本
我们先来看下normal_define.sh脚本,normal_define.sh定义了头文件集合和排除文件集合(刚刚mk文件的第三部分和少量第二部分相关内容),normalcppfile是一个怪异的变量,一般情况不会使用到它。这里GameDir变量的定义其实有些多余的,不过也没啥大的问题。
############################################# ##一般数据,一般来说不需要更改 ############################################## #cpp 目录 GameDir=( "../Classes" ) #固定的cpp文件,比如一个文件夹100个cpp文件中只有10个需要,可以写死在这里 NormalCppfile=( ) #头文件目录 NormalIncludefile=( "\$(LOCAL_PATH)/../../Classes\\" "\$(LOCAL_PATH)/../../Classes/SDKManager" ) #不需要的文件(在GameDir中) NormalExcludefile=( "../Classes/SDKManager/NS_SDKPlatform.cpp" )
接下来我们看下platform_define.sh文件,这个脚本主要是处理mk文件第四部分的固定内容,这个‘/‘需要注意下
#注意: ‘/‘ 是转义字符需要转义的主要有$, PlatformOtherDefine=( "LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static" "include \$(BUILD_SHARED_LIBRARY)" "\$(call import-module,CocosDenshion/android) \\" "\$(call import-module,extensions) \\" "\$(call import-module,cocos2dx)" )
然后再来看下file_list.sh脚本,file_list.sh顾名思义就是遍历Class目录,输出可用的cpp文件列表(排除在外的文件不输出),主要是输出第三部分的内容,红色的代码将会判断文件是否在排除列表中,如果在排除列表,则不会输出。
#遍历文件夹 输出cpp文件名 for file in $1/* do if [ -d $file ]; then echo $file source file_list.sh $file $2 elif [ -f $file ]; then echo $file if [ ${file##*.} == "cpp" ] || [ ${file##*.} == "c" ]; then canDo="false" for data in ${NormalExcludefile[@]} do if [ $data == $file ]; then canDo="true" fi done if [ $canDo == "false" ]; then echo "../$file \\" >> "$2" fi fi fi done
最后,让我们看下platform_refresh.sh脚本文件,我使用颜色将这个脚本分成了6个部分,
PlatformDir="./jni" Name="Android.mk" if [ -f "$Name" ]; then rm -r "$Name" fi source platform_define.sh source normal_define.sh echo "LOCAL_PATH := \$(call my-dir)" > "$Name" echo "" >> "$Name" echo "include \$(CLEAR_VARS)" >> "$Name" echo "" >> "$Name" for data in ${PLATFORMHONE_CHILD[@]} do echo "LOCAL_CFLAGS += -D${data}=1" >> "$Name" done echo "LOCAL_MODULE := game_shared" >> "$Name" echo "" >> "$Name" echo "LOCAL_MODULE_FILENAME := $PlatformTarget" >> "$Name" echo "" >> "$Name" echo "" >> "$Name" echo "LOCAL_SRC_FILES := hellocpp/main.cpp \\" >> "$Name" echo "libiconv.a \\" >> "$Name" #Game中的cpp文件 for data in ${PlatformCppfile[@]} do echo ${data} >> "$Name" done #其它文件夹文件 for data in ${NormalCppfile[@]} do echo ${data} >> "$Name" done for data in ${GameDir[@]} do source file_list.sh $data $Name done echo "" >> "$Name" echo "LOCAL_C_INCLUDES := \$(LOCAL_PATH) \\" >> "$Name" for data in ${PlatformIncludefile[@]} do echo ${data} >> "$Name" done for data in ${NormalIncludefile[@]} do echo ${data} >> "$Name" done IFS=";" for data in ${PlatformOtherDefine[@]} do echo ${data} >> "$Name" done mv "$Name" "${PlatformDir}/Android.mk"
- 新建一个临时文件,并刷新之前定义变量的脚本,获取到变量内容;
- 处理mk文件的第一部分的内容,所有宏都在变量PLATFORMHONE_CHILD中;
- 处理mk文件的第二部分的内容,刷新cpp文件,这里我们可以看到file_list脚本的使用;
- 处理mk文件的第三部分的内容,刷洗头文件集合;
- 处理mk文件的第四部分的内容,输出固定内容;
- 将临时文件拷贝到jni目录下,替换Android.mk源文件。
这一节就到此为止了,下一节我们将介绍自动编译及拷贝资源的脚本,这部分的脚本都是cocos2d-x自带的,因此只会简单介绍下。
PS:项目中android这边的demo已经基本成型了,有兴趣可以看看(项目地址可以看前言)。