先说明一下本人的技术与岗位背景吧,方便大家理解,要吐槽的请当看笑话一下样,跳过!

本人自2013年3月进入某得的,那个时候我只有一年左右的cocos2d-x的开发经验,说多不多,说少不少!在进入某得之前,我一个好朋友老是对我说,某得现在有一套很好的技术,想让我去学习一下某得的技术(朋友之前也是某得的员工,但在我进去之前就已经离开了!)传说中的opencore(我不想吐槽这技术的)。
     现在回归主题,在项目将要完成的时候,我接到一个我尚未接触过的工作。那就是写一个build包工具!!从接到工作开始,我一直想直接用aapt之类的来解决这个build问题,因为那个时候项目已经有13个android渠道了,如果还是用传统的eclipse来build包的话,那就坑大发了!在天朝下,android的平台听说有近百个,要死了!
     gradle:一个屌炸天的工具出现了,这货居然是好几年前就出现了,看来专心搞一样东西,同样会让人视野更小了!具体什么是gradle, 我就不说了。自己百度去!怎么弄环境,想信不用我教,自己去看官方文档!
     因为我们的项目是便用cocos2dx开发,所以我们使用的都是同一个.so,而java代码却只有那么几个文件,而且我们每个渠道在项目一开始就已经被其它人定死了,每一个渠道都要使用一个新的工程!结果就导致我们项目如下这样子的结构!
screenshot.png
 
看到这样子的结构是不是有点蛋碎的赶脚 ?反正我是看得很不爽!
     既然工程已经生成了,那如果要我一个一个工程去写.gradle文件,那不是要写死我?所以,我做了以下的决定!!!
打开eclipse!
把所有的target和其相依赖的工程全部都导入到eclipse里!
 
export;
 
在eclipse里,里面就有一个gradle,爽吧,但别高兴太早了,后面会坑你的!一路next,一直到出现下面这个界面
 
在这里,我们需要选中你所有相关的项目,这样子你的target里才会包括所有的项目哦!
 
框内说的是,gradle已经存在,是否要覆盖?然后next到完成!
到些时,所有的工程都一次性导完了。
     重头戏开始了!!
我们cd到整个工程的根目录(这个根目录,就是刚刚用eclipse导出gradle的目录),比如的我就在client,执行一下以下命令
gradle clean
这个时候,你会download一些gradle相关的东西,并且对gradle进行一些初始化!
如果网络和你的gradle环境没有问题的话,那么你clean应该是successful的。
兴奋了吧,就这么简单就完成了!现在开始build包了哦!
我们在command里键入以下命令!
gradle build
这个时发,已经在build包了!

半个小时完了,你很操蛋地发现,build得也太漫长了吧?对,我也是这么觉得,每个包都build一下工程的c++代码,这个够恶心,当初我接第三方平台的时候就是不想第个平台都要build一次c++,想让cocos2dx的代码能做到最大程度上的通用做了好多工作呀,如果还让你继续build下去,那不是白用功了?不行!所以我决定把每个工程的c++ builder给去掉,然后重新导出一个gralde。但是如果没有c++ builder,那么c++的代码怎么办?在cocos2dx里,如果没有c++的.so库,那么游戏绝对跑不起来!难道要我先编译一次所有的c++代码,然后一个一个地copy到每一个工程里?话说这个主鄣挺不错的,我们用shell去做这些就行啦,一个合格的程序员,如果没有一两门脚本技术,根本就活不下去呀!在某得用到的shell技术,我会另开一个文章说明的!
我用到的方是这样子的!如果的其它方法或不错的建议,可以发到我邮箱戳这,
先copy珍上项目,该项目我们只是需要其帮我们编译c++文件即可!
所以我们修改其build_native.sh文件,让其为我工作!
修改如下:
APPNAME="HeroLegend"

# options

buildexternalsfromsource=

usage(){
cat << EOF
usage: $0 [options]

Build C/C++ code for $APPNAME using Android NDK

OPTIONS:
-s    Build externals from source
-h    this help
EOF
}

while getopts "sh" OPTION; do
case "$OPTION" in
s)
buildexternalsfromsource=1
;;
h)
usage
exit 0
;;
esac
done

# paths

if [ -z "${NDK_ROOT+aaa}" ];then
echo "please define NDK_ROOT"
exit 1
fi

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# ... use paths relative to current directory
COCOS2DX_ROOT="$DIR/../../opencore"
GOODSDK="$DIR/../../SDK/XIAOMISdk"
APP_ROOT="$DIR/.."
APP_ANDROID_ROOT="$DIR"

# run ndk-build
if [[ "$buildexternalsfromsource" ]]; then
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source"
else
    "$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
        "NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt"
fi

 

我已经把cocos2dx里的一些什么asset的复制呀,给去掉了,只留下一个ndk的build。
当该copy出来的项目编译完成,我再将这些.so copy到每个target里!
上我使用的shell
echo ------------------------------------------
echo '现在开始build包了哦,请耐心等待'
echo 'create by Windy Chen'
echo 'if founded the problem, please call me !'
echo 'Email: chiefcto@gmail.com'
echo ------------------------------------------
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

function check() {
bb=`echo $1|grep 'proj.android'|wc -l`
if [ $bb = 0 ]
then
   echo "not an android project"
else
  bbb=`echo $1|grep 'proj.android_pmangplus'|wc -l`
  if [ $bbb = 0 ]
  then
    echo "Copy the *.so file to this project($1)"
    echo 'Please waitting for a while'
    echo ------------------------------------------
    $1/build_native.sh
    echo ------------------------------------------
  else
    echo "This is PmangPlus, not contain"
  fi
fi
}

# 编译c++文件
echo 现在开始做有sdk的游戏原码进行编译
#"$dir"/HeroLegend/proj.android_CPL_SDK/build_native.sh

# 复制.so游戏库
echo 把proj.android_CPL_SDK里的libgdmmo4.so复制到所要的工程下
echo 工程在includeProject里配置
echo 开始copy

cat includeProject | while read project; do
echo 开始copy$project
"$dir"/HeroLegend/"proj.android_$project"/build_native.sh
done

#for file in "$dir"/HeroLegend/*
#do
#  if [ -d "$file" ]; then
#    check $file
#  fi
#done

#当所有的资源都已经复制到游戏目录的时候,开始用gradle打包
echo 现在开始使用gradle打包游戏包
echo 打包所要gradle环境
echo 开始打包
echo waitting for a while
gradle build
echo 如果中途没有中断,没有出现failed,那么就打包成功了!

 



其中,每个项目的buid_native.sh还是会执行一次,在为有些sdk还需要一些特殊的copy!!!所我把.so的copy也放到每个工程的.build_native.sh里去了!
就这样,我每次只要直接执行autoPkg.sh就完成打包了!


大概几分钟后,悲剧了~~一大堆错~~坑爹 !
这么多工程,怎么看呀!
认真看一下根目录,你会发现一个很嚣张的家伙
 
这个家伙里就有很多项目工程里要用的工程,我把那些目前还没有报错和与报错项目不相关的工程移除掉!这样子就能够一个一个地编译,一个个项目的问题来解决了!当所有的问题改完,直接一次出所有包,爽歪歪呀!
但真实情况如下,出完包后,一点就闪退~
问题是这样子的,虽然我们已经把.so放到了对应的目录下了,但gradle并没有把.so copy到打包资源里~所以我们要对每个.gradle进行修改!只要添加以下代码就可以了!
和dependencies,android同一层,直接添加
task copyNativeLibs(type: Copy) {
    from(new File('libs'))
    into new File(buildDir, 'native-libs')
}
tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }
 
clean.dependsOn 'cleanCopyNativeLibs'
 
tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask ->
    pkgTask.jniFolders = new HashSet<File>()
    pkgTask.jniFolders.add(new File(buildDir, 'native-libs'))
}

 


这样子,.so文件就copy进去,出来的包也没有问题!


其它的一些问题,
签名:
android{
}
signingConfigs {
      myConfig{
        storeFile file("../XXX.keystore")
           storePassword "******"
           keyAlias "keyAlias"
           keyPassword “*******"
      }
    }
   
    buildTypes{
      release {
           signingConfig  signingConfigs.myConfig
      }
    }
 
 
忽略一些无关紧要的error
lintOptions{
disable ‘issusid’,“issusid”。。。。。。
其它问题的话,可以自行看gradle报的错误英文。
并且,在每个工程的目录下gradle都会生成一个build文件夹,里面有生成的apk等,其中就有一份lint-results.html文件,打开的话,里机包含gradle对该工程所报的所有错误!
 
 
 
 
这章就完成!
posted on 2014-08-07 14:36  Conerlius  阅读(2036)  评论(0编辑  收藏  举报