前言

要分享的这个东西可能大部分开发者不需要纠结,不过工作最近花了几个星期在这个东西上面,中间调试也多多少少遇到些问题,这里还是记录下。为了推行64位应用,Google宣布2019 年 8 月 1 日开始,Google Play 上发布的应用必须支持 64 位架构。对于使用传统的第三方游戏引擎的开发者来说,这个升级只是个工作量的问题,Unreal、Cocos2dx、Unity这三大常用游戏引擎都已经支持64位架构,正常来说升级引擎版本,客户端做下接口的兼容性支持,也就没啥问题了。不过因为历史的原因,我们公司部分项目组还是用的基于Cocos2dx和Unity的半自研引擎,这是一个我们一直沿用下来的mmoarpg项目专用的引擎,早些年Cocos2dx支持这类游戏还太勉强,只能对引擎做大量的修改,后来为了添加3d支持,整合了部分Unity4.x的源码。因为整体代码都是基于老版本的引擎源码,所以自然是不支持64位架构的。Google的这个决定使得我们必须要添加64位支持,不然海外Android的发行无法推进。

传统引擎的升级以及Android部分的修改就不赘述了,Google给的链接也有提这部分,这里只把引擎源码编译、修改以及第三方库升级的过程记录下。

MakeFile修改

引擎编译沿袭了cocos2dx的ndk-build的方式,为了编译arm64-v8a,ndk版本至少要选择支持android21(android 5.0)以上,我这里用的是android-ndk-r11c,platform是android 23。因为编译器升级为了gcc-4.9,编译选项也会有一些变化,大部分根据ndk编译过程中的error以及warning提示进行修改即可,如果是一些ABI专用的指令集的话需要留意,比如armeabi-v7a的FPU指令在arm64-v8a就不支持,如果还有疑问就参考官方ABI文档

第三方库升级和编译

Backtrace、。引擎的大部分基础库升级64位比较简单,因为基础库的接口变化一般都不大,例如luajit、png、jpeg这些。

Backtrace库是Android源码的一部分,引擎接入用来解析Android crash日志的,核心是libcorkscrew、debuggerd、libbacktrace。因为platform的变化,需要重新抓取Android 6.0的源码来编译,同时5.0以上的系统使用了libunwind来代替libcorkscrew,打印堆栈日志部分的代码要重写,加上引用到了Android源码中的一些基础库的代码,相比之前的版本改动有挺大的,编译起来挺麻烦的。欣慰的是google的android源码有很好的版本管理控制,在官网可以找到任意版本的代码。

Backtrace库目录

AndroidJNIBridge根据platform编译对应版本即可,简单配置下Perl编译环境即可,就是仓库找的头疼,最终还是没找到官方的库目录。

音频库用的是FMOD,因为版本差了太多并且不开源,只能直接升级到最新版本,本来还想找到最早支持64位的版本,想着可能接口变化没那么大,发现FMOD就是在大改版之后才支持的64位,并且官网也没有改版前的历史版本记录,索性就直接升级到最新版本了。接口上主要是ChannelGroup和DSP部分改动比较大,刚好这两部分我们用的接口比较少,几番调试下来基本就正常了。

最后就是物理引擎部分了,用的是Physx2.8,因为Physx是从2014年开始开源的也就是3.4的版本,引擎里面的链接库应该是Unity编译好的版本,是没有源码的,想直接编译arm64的计划泡汤了,只好拿官方github上的3.4版本开始编译和接入。Android平台的编译文档让我们安装mingw和msys,用msys编译源码,我这边遇到了问题,mingw目录下已经有了gcc和g++,我直接用mingw进行编译反而非常的顺利。官网3.4的文档以及仓库还是编译armv7的版本,需要对编译脚本进行修改。编译完成后开始了正常的版本升级,这里不得不说Nvidia官方的pvd调试真的非常方便,原本卡住的射线命中问题,在pvd工具里面很方便地找到了原因,CapsuleShape的SceneQuery Flag在其他地方被设为了False,导致Raycast筛选的时候一直无法命中。GPU蒙皮部分也因为物理引擎升级出了问题,暂时为了更快的地出版本屏蔽了GPU蒙皮。

年纪大了以后对自研引擎的态度也有了改观,公司规模比较小的话建议还是不要对引擎做太多大刀阔斧的修改,不然从长远的角度来看,需要不小的升级维护成本。