从零开始手敲次世代游戏引擎(Android特别篇)-1

本篇开始我们将我们开发的引擎移植到Android上面去。
首先我们需要构建Android的开发环境。无论是基于Windows的Visual Studio,还是基于mac OS的XCode,亦或是基于java的Eclipse,以及google的Android Studio,都能够支持Android的开发。
不过一如既往的,我讨厌在项目代码树当中混进某种IDE的杂七杂八的文件,所以我选择使用命令行环境。当然,IDE环境在调试的时候很方便,我们可以用cmake随时生成IDE的项目配置文件,在IDE当中进行编辑调试。
由于我们的代码支持多平台,我时常需要在不同的操作系统之间切换编写确认代码。在每一个系统上安装一套android SDK/NDK环境会变得费时费力,且不容易保持环境的一致性。况且我们需要使用Circle CI进行连续集成,这个环境最好是能够很容易在不同的物理机/操作系统间迁移的。docker能很好的解决这个问题,参考引用*2展示了一个基于Ubuntu的安装了android SDK/NDK的典型docker环境的构筑方法。
为了能够在Mac上面使用Docker,我们首先需要安装Docker服务。安装的方法请参考参考引用*1。如果是Windows或者Linux环境,其安装方法也可以在该页面的左侧导航栏当中找到。
安装完成之后,在命令行通过下面的命令,就可以启动并进入这个环境:
参数选项“-it”表示我们需要以交互的方式进入这个docker,“-v $(pwd):/project”表示把当前的目录映射到docker当中的/project目录,也就是将我们的代码树挂载到docker当中的/project目录。这也隐含着执行这个命令的时候需要在我们的项目代码根目录下。“tim03/android-sdk-ndk”是使用参考引用*2构建的docker容器名称,也就是包含了android SDK NDK的开发环境。“bash”是指docker启动之后进入Linux的BASH命令行。
进入之后,缺省是在根目录下,执行“cd”命令切换当前目录到项目根目录:
执行ls命令查看当前目录下是否包括了我们的源代码文件:
在之前我们虽然做了Windows / Linux / Mac OS三种平台的开发,但是这三种平台都是基于PC的平台,我们都是在其自身进行开发并编译的。(虽然其实我们在从零开始手敲次世代游戏引擎(七)当中简要介绍了一点儿在Linux平台编译测试Windows平台程序的一种方法)
而对于诸如Android平台(或者IOS平台,以及无法在这里公开介绍细节的PS4/PSV平台)的开发,是通过在PC平台编译程序,然后再推送到目标平台进行执行的。这种方式被称为交叉编译,是嵌入式开发的一种比较基本的流程。
对于用惯IDE或者商用游戏引擎的人来说,可能不太会注意到这里面的区别(因为在IDE或者商用游戏引擎当中,基本上只要在平台选项当中切换一下就好了,整个流程与PC开发基本相同)。但是如果深入到细节,那么会发现两者有着很多不同。总的来说,嵌入式开发要麻烦一些。
坚持使用命令行的一个好处就是,我们可以精确知道实际的步骤,了解当中的细节。在这个基础之上,选用IDE/商用引擎进行开发,提高工作效率;而当我们遇到一些难解的问题的时候,又有能力将IDE/商用引擎打包好的一系列自动化步骤进行手动拆解,查找问题,从而获得超越“泛泛之辈”的能力。
因为我们的项目是基于CMake的。CMake下进行交叉编译的方法是通过建立TOOLCHAIN File来实现的。
基于参考引用*3所提供的CMake文法规格,我们项目根目录下建立cmake/android.cmake文件如下:
  1. 第一行是告诉CMake我们要交叉编译的目标平台是Android。因为Android是CMake已经知道的平台,写入这一条能够让CMake找到正确的交叉编译工具;
  2. 第二行是指定我们程序对应的Android的API Level。因为我们的程序其实并没有什么很特别依赖Android功能的地方,这个版本其实不是非常的重要;
  3. 第三行是指定目标CPU的ABI(Application Binary Interface,应用二进制接口)。Android其实是支持诸如x86, x86-64, arm, arm64, mips, mips64等多个架构的。这里为了简便起见,我们只指定了armeabi-v7a接口。这个接口是32bit的接口,相对较老,但是支持浮点的硬件加速,在当今大多数基于arm的手机上都支持;
  4. 第四行是告诉CMake在编译的时候生成NEON代码。NEON是arm CPU上的SIMD代码集,相当于Intel CPU的SSE系列;
  5. 第五行其实在armeabi-v7a的时候没有啥用。如果我们在第三行指定的是armeabi,那么这行是告诉CMake生成32位代码,而不是16位代码;(嗯,在arm64满天飞的今天,16位代码的确已经很老了)
  6. 第六行是告诉CMake关于Android NDK的安装位置。这个“ANDROID_NDK_HOME”环境变量是我们在创建编译环境的时候导出的。具体可以参看参考引用*2的Dockerfile;
  7. 第七行是告诉CMake在编译的时候链接GNU c++库。Android NDK提供了好几套c++库,缺省是一套被称为“c++_static”的经过大量裁剪的c++库。因为我们的代码基于C++ 11,当中使用了一些c++_static当中不支持的功能,因此需要在这里指定gnustl_static。
好了。有了这个TOOLCHAIN文件之后,我们只需要在使用CMake进行编译的命令行当中,加入如下的参数选项,告诉CMake使用这个TOOLCHAIN文件,就可以实现PC->Android的交叉编译了:
完整的命令行可以参考本篇文章对应的代码当中的build_crossguid_android.sh
通过同样的方式修改项目根目录下的build_opengex.sh / build.sh,我们就能实现整个引擎到Android的交叉编译。当然,因为Android并不支持OpenGL(Android支持的是OpenGL ES,是OpenGL的一个子集)和DirectX,其实我们还需要修改RHI下面的CMake文件,以及Platform下面的CMake文件,去除这些库的编译。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

您正在使用您的 WordPress.com 账号评论。 注销 /  更改 )

Facebook photo

您正在使用您的 Facebook 账号评论。 注销 /  更改 )

Connecting to %s

%d 博主赞过: