Changes between Version 236 and Version 237 of AndroidPort


Ignore:
Timestamp:
Apr 23, 2012, 6:30:53 PM (12 years ago)
Author:
Philip Taylor
Comment:

rough but basically-working Android build instructions

Legend:

Unmodified
Added
Removed
Modified
  • AndroidPort

    v236 v237  
    161161A window with installable packages should open. In addition to any packages checked by default, make sure 'Android SDK Platform-tools' is checked and click 'Install packages'.
    162162
    163 Google publishes a [http://developer.android.com/sdk/ndk/index.html Native Development Kit] (NDK), which is a set of tools for building native applications for the Android platform. Unfortunately, the official NDK does not and will not support the `std::wstring` (wide characters) datatype, which is required by the game, so we'll have to use the unofficial [http://www.crystax.net/android/ndk.php Crystax NDK]. This is merely an extension of the official NDK, adding support for wide characters and other features maligned by Google.
    164 
    165 Download the latest release from [http://www.crystax.net/en/android/ndk this page] to the working directory and then unpack there, e.g.:
    166 
    167 {{{
    168 $ cd ~/android
    169 $ tar -xvf android-ndk-r7-crystax-4-linux-x86.tar.bz2
    170 }}}
    171 Now use the NDK to set up a standalone toolchain:
    172 
    173 {{{
    174 $ ~/android/android-ndk-r7-crystax-4/build/tools/make-standalone-toolchain.sh --platform=android-9 --install-dir=$HOME/android/toolchain
    175 }}}
     163Google publishes a [http://developer.android.com/sdk/ndk/index.html Native Development Kit] (NDK), which is a set of tools for building native applications for the Android platform. Unfortunately, the official NDK does not and will not support the `std::wstring` (wide characters) datatype, which is required by the game, so we'll have to use the unofficial [http://www.crystax.net/android/ndk.php Crystax NDK]. This is merely an extension of the official NDK, adding support for wide characters and other features maligned by Google. This is installed automatically by the `setup-libs.sh` script (see next section).
     164
    176165You also must install a Java Development Kit (JDK) if you haven't already, e.g. [https://apps.ubuntu.com/cat/applications/oneiric/default-jdk/ the standard JDK from Ubuntu Software Center]:
    177 
    178166{{{
    179167$ sudo apt-get install default-jdk
    180168}}}
     169
    181170Make sure [http://ant.apache.org/ Ant], [http://subversion.tigris.org/ Subversion] and [http://www.gnu.org/software/autoconf/ autoconf] 2.13 is installed:
    182 
    183171{{{
    184172$ sudo apt-get install ant subversion autoconf2.13
    185173}}}
     174
    186175On 64-bit Ubuntu you may need to install some 32-bit libraries:
    187 
    188176{{{
    189177$ sudo apt-get install ia32-libs
    190178}}}
     179
    191180Finally, download the game sources from SVN to any location, e.g.:
    192 
    193181{{{
    194182$ svn co http://svn.wildfiregames.com/public/ps/trunk/ ~/android/0ad-game
    195183}}}
    196 === Installing dependencies ===
    197 The game has a range of external dependencies. Each of these has to be compiled for the target device's processor architecture and installed in the compiler toolchain's sysroot, so we can link against them when building the game itself.
    198 
    199 First set a few shell variables to the paths of tools that were installed in the previous section, e.g.:
    200 
    201 {{{
    202 $ SDK=$HOME/android/android-sdk-linux/
    203 $ NDK=$HOME/android/android-ndk-r7-crystax-4
    204 $ TOOLCHAIN=$HOME/android/toolchain
    205 $ SYSROOT=$TOOLCHAIN/sysroot
    206 $ GAME=$HOME/android/0ad-game
    207 }}}
    208 Download the !MysticTreeGames [https://github.com/MysticTreeGames/Boost-for-Android/tarball/master port of the Boost C++ Libraries] to the working directory and unpack it there, e.g.:
    209 
    210 {{{
    211 $ cd ~/android
    212 $ tar -xvf MysticTreeGames-Boost-for-Android-70838fc.tar.gz
    213 }}}
    214 Now change directory to the directory that was unpacked, e.g.:
    215 
    216 {{{
    217 $ cd MysticTreeGames-Boost-for-Android-70838fc
    218 }}}
    219 Apply [http://www.wildfiregames.com/forum/index.php?showtopic=15436&view=findpost&p=234163 this patch] somehow.
    220 
    221 Then execute the following command to download the Boost C++ Libraries package and compile it for the target device:
    222 
    223 {{{
    224 $ ./build-android.sh $TOOLCHAIN
    225 }}}
    226 Copy the resulting headers and library files into the `usr` directory in the toolchain's sysroot:
    227 
    228 {{{
    229 $ cp -r build/* $SYSROOT/usr/
    230 }}}
    231 Fix some weird path issue:
    232 
    233 {{{
    234 $ mv $SYSROOT/usr/include/boost-1_45/boost $SYSROOT/usr/include
    235 }}}
    236 Spidermonkey is designed to build against an older version of the NDK than that of our main compiler toolchain. Download [http://ftp.mozilla.org/pub/mozilla.org/mobile/source/android-ndk-r4c-0moz3.tar.bz2 Mozilla's own toolchain] to the working directory and then unpack it there, e.g.:
    237 
    238 {{{
    239 $ cd ~/android
    240 $ tar -xvf android-ndk-r4c-0moz3.tar.bz2
    241 }}}
    242 Set the `NDK_MOZ` shell variable to the path of the directory that was unpacked, e.g.:
    243 
    244 {{{
    245 $ NDK_MOZ=~/android/android-ndk-r4c
    246 }}}
    247 Copy the Spidermonkey source directory from the game sources to the working directory, e.g.:
    248 
    249 {{{
    250 $ cp -r $GAME/libraries/spidermonkey/js-1.8.5 ~/android/
    251 }}}
    252 Apply [https://gist.github.com/1754817 this patch] somehow.
    253 
    254 Regenerate the `configure` script in the new Spidermonkey source directory, e.g.:
    255 
    256 {{{
    257 $ cd ~/android/js-1.8.5/js/src
    258 $ autoconf2.13
    259 }}}
    260 Then create a temporary directory for building Spidermonkey, e.g.:
    261 
    262 {{{
    263 $ mkdir /tmp/js
    264 }}}
    265 Change directory to the temporary building directory, compile the package for the target device there and install it in the main toolchain's sysroot, e.g.:
    266 
    267 {{{
    268 $ cd /tmp/js
    269 $ ~/android/js-1.8.5/js/src/configure \
    270   --target=arm-android-eabi \
    271   --prefix=$SYSROOT/usr/local \
    272   --with-android-ndk=$NDK_MOZ \
    273   --with-android-sdk=$SDK \
    274   --with-endian=little \
    275   --with-arm-kuser \
    276   --disable-shared-js \
    277   --enable-static
    278 $ make
    279 $ make install
    280 }}}
    281 Finally, hand-edit the mozjs185.pc file to remove the requirement for NSPR somehow.
    282 
    283 Set up the environment for cross-compiling using the main standalone toolchain:
    284 
    285 {{{
    286 $ HOSTCONF=arm-eabi-linux
    287 $ BUILDCONF=i686-pc-linux-gnu
    288 $ export ARCH=armv7-a
    289 $ export SYSROOT=$SYSROOT
    290 $ export PATH=$PATH:$TOOLCHAIN/bin:$SYSROOT/usr/local/bin
    291 $ export CROSS_COMPILE=arm-linux-androideabi
    292 $ export CC=${CROSS_COMPILE}-gcc
    293 $ export CXX=${CROSS_COMPILE}-g++
    294 $ export AR=${CROSS_COMPILE}-ar
    295 $ export AS=${CROSS_COMPILE}-as
    296 $ export LD=${CROSS_COMPILE}-ld
    297 $ export RANLIB=${CROSS_COMPILE}-ranlib
    298 $ export NM=${CROSS_COMPILE}-nm
    299 $ export STRIP=${CROSS_COMPILE}-strip
    300 $ export CFLAGS="-DANDROID -mandroid -fomit-frame-pointer --sysroot=$SYSROOT -march=$ARCH -mfloat-abi=softfp -mfpu=vfp -mthumb"
    301 $ export CXXFLAGS=$CFLAGS
    302 $ export LDFLAGS="-L${NDK}/sources/crystax/libs/armeabi-v7a -lcrystax"
    303 }}}
    304 Download the development snapshot for SDL 1.3 from [http://www.libsdl.org/hg.php this page] to the working directory and then unpack it there, e.g.:
    305 
    306 {{{
    307 $ cd ~/android
    308 $ tar -xvf SDL-1.3.tar.gz
    309 }}}
    310 Now change directory to the directory that was unpacked, e.g.:
    311 
    312 {{{
    313 $ cd ~/android/SDL-1.3.0-6235
    314 }}}
    315 Then execute the following commands to compile the package for the target device:
    316 
    317 {{{
    318 $ ./configure --host=$HOSTCONF --build=$BUILDCONF  --with-sysroot=$SYSROOT --prefix=$SYSROOT/usr/local --disable-joystick
    319 $ make
    320 $ make install
    321 }}}
    322 Download the latest version of cURL from [http://curl.haxx.se/download.html this page] to the working directory and then unpack it there, e.g.:
    323 
    324 {{{
    325 $ cd ~/android
    326 $ tar -xvf curl-7.24.0.tar.bz2
    327 }}}
    328 Now change directory to the directory that was unpacked, e.g.:
    329 
    330 {{{
    331 $ cd ~/android/curl-7.24.0
    332 }}}
    333 Then execute the following commands to compile the package for the target device:
    334 
    335 {{{
    336 $ ./configure --host=$HOSTCONF --build=$BUILDCONF  --with-sysroot=$SYSROOT --prefix=$SYSROOT/usr/local
    337 $ make
    338 $ make install
    339 }}}
    340 Download the latest version of libpng from [http://www.libpng.org/pub/png/libpng.html this page] to the working directory and then unpack it there, e.g.:
    341 
    342 {{{
    343 $ cd ~/android
    344 $ tar -xvf libpng-1.5.7.tar.xz
    345 }}}
    346 Now change directory to the directory that was unpacked, e.g.:
    347 
    348 {{{
    349 $ cd ~/android/libpng-1.5.7
    350 }}}
    351 Then execute the following commands to compile the package for the target device:
    352 
    353 {{{
    354 $ ./configure --host=$HOSTCONF --build=$BUILDCONF  --with-sysroot=$SYSROOT --prefix=$SYSROOT/usr
    355 $ make
    356 $ make install
    357 }}}
    358 The game depends on libjpeg. We will use libjpeg-turbo, an ABI-compatible fork of libjpeg that adds support for SIMD processing, giving us maximal performance with the target processor's ARM NEON engine.
    359 
    360 Download the latest version of libjpeg-turbo from [http://sourceforge.net/projects/libjpeg-turbo/files/ this page] to the working directory and then unpack it there, e.g.:
    361 
    362 {{{
    363 $ cd ~/android
    364 $ tar -xvf libjpeg-turbo-1.1.1.tar.gz
    365 }}}
    366 Now change directory to the directory that was unpacked, e.g.:
    367 
    368 {{{
    369 $ cd ~/android/libjpeg-turbo-1.1.1
    370 }}}
    371 Then execute the following commands to compile the package for the target device:
    372 
    373 {{{
    374 $ ./configure --host=$HOSTCONF --build=$BUILDCONF  --with-sysroot=$SYSROOT --prefix=$SYSROOT/usr
    375 $ make
    376 $ make install
    377 }}}
    378 Download the latest version of libxml2 from [http://xmlsoft.org/downloads.html this page] to the working directory and then unpack it there, e.g.:
    379 
    380 {{{
    381 $ cd ~/android
    382 $ tar -xvf libxml2-2.7.8.tar.gz
    383 }}}
    384 Now change directory to the directory that was unpacked, e.g.:
    385 
    386 {{{
    387 $ cd ~/android/libxml2-2.7.8
    388 }}}
    389 Then execute the following command to configure the package for the target device:
    390 
    391 {{{
    392 $ ./configure --host=$HOSTCONF --build=$BUILDCONF --prefix=$SYSROOT/usr --without-threads --without-iconv --without-python --enable-shared
    393 }}}
    394 Hand-edit the Makefile to remove `runtest$(EXEEXT)` and `testrecurse$(EXEEXT)` from the `noinst_PROGRAMS` definition, e.g.
    395 
    396 {{{
    397 noinst_PROGRAMS = testSchemas$(EXEEXT) testRelax$(EXEEXT) \
    398         testSAX$(EXEEXT) testHTML$(EXEEXT) testXPath$(EXEEXT) \
    399         testURI$(EXEEXT) testThreads$(EXEEXT) testC14N$(EXEEXT) \
    400         testAutomata$(EXEEXT) testRegexp$(EXEEXT) testReader$(EXEEXT) \
    401         testapi$(EXEEXT) testModule$(EXEEXT) \
    402         runsuite$(EXEEXT) testchar$(EXEEXT) testdict$(EXEEXT) \
    403         runxmlconf$(EXEEXT)
    404 }}}
    405 Finally, execute the following commands to compile the package:
    406 
    407 {{{
    408 $ make
    409 $ make install
    410 }}}
    411 Download the latest version of ENet 1.3 from [http://enet.bespin.org/download/ this page] to the working directory and then unpack it there, e.g.:
    412 
    413 {{{
    414 $ cd ~/android
    415 $ tar -xvf enet-1.3.3.tar.gz
    416 }}}
    417 Now change directory to the directory that was unpacked, e.g.:
    418 
    419 {{{
    420 $ cd ~/android/enet-1.3.3
    421 }}}
    422 Then execute the following commands to compile the package for the target device:
    423 
    424 {{{
    425 $ ./configure --host=$HOSTCONF --build=$BUILDCONF --prefix=$SYSROOT/usr
    426 $ make
    427 $ make install
    428 }}}
    429 === Porting graphics ===
    430 See [wiki:GLESPort].
    431 
    432 === Porting sound ===
    433 Audio can be disabled for now.
    434 
    435 === Building the game ===
    436 The native library (i.e. the actual game) is built using the standard Premake build system as follows.
    437 
    438 ''(Note: You currently need to reset your environment if it is still set up for cross-compiling from the previous section. Close any open terminal windows and open a new one.)''
    439 
    440 Build the game as normal, but with:
    441 
    442 {{{
    443 $ cd ~/android/0ad-game/build/workspaces
    444 $ ./update-workspaces.sh --gles --android --without-fam --without-audio --disable-atlas --with-system-mozjs185
    445 $ TOOLCHAIN=$HOME/android/toolchain
    446 $ export SYSROOT=$TOOLCHAIN/sysroot
    447 $ export PATH=$PATH:$TOOLCHAIN/bin:$SYSROOT/usr/local/bin
    448 $ export CXX=arm-linux-androideabi-g++
    449 $ export PKG_CONFIG_DIR=
    450 $ export PKG_CONFIG_LIBDIR=$SYSROOT/usr/lib/pkgconfig:$SYSROOT/usr/share/pkgconfig:$SYSROOT/usr/local/lib/pkgconfig:$SYSROOT/usr/local/share/pkgconfig
    451 $ cd gcc
    452 $ make config=debug -k pyrogenesis
    453 }}}
    454 See loads of build errors.
    455 
    456 Fix all the build errors.
    457 
    458 Fix the build system.
    459 
    460 === Setting up an Android project ===
    461 All data that is to be compiled and packaged into the Android application must be assembled in an Android ''project''.
    462 
    463 We'll use the template provided by SDL. Move the project template to a fitting name under the working directory, e.g.:
    464 
    465 {{{
    466 $ mv SDL-1.3.0-6172/android-project/ ~/android/0ad
    467 }}}
    468 This is your ''project directory''.
     184
     185=== Compiling dependencies and game ===
     186
     187(These instructions are pretty imprecise, but in practice it's possible to get them to work with at least some versions of the game.)
     188
     189First download a recent version of SDL 2.0:
     190{{{
     191cd build/android/sdl-project/jni/
     192hg clone http://hg.libsdl.org/SDL
     193}}}
     194
     195Then build SDL and the .apk (the installable application that invokes the external game engine code):
     196{{{
     197cd build/android/sdl-project/
     198make
     199}}}
     200(Dependency checking is probably broken, so run "`make clean`" if you need to rebuild after changing stuff.)
     201
     202Then install all the dependencies:
     203{{{
     204cd build/android/
     205./setup-libs.sh
     206}}}
     207The script hardcodes the expected locations of NDK and SDK, so put them there or adjust the script, and it will output to `~/android/toolchain-0ad`. That should download and compile loads of stuff.
     208
     209Build the game like:
     210{{{
     211cd build/workspaces/
     212./update-workspaces.sh --gles --android --without-fam --without-audio --disable-atlas --with-system-mozjs185 --with-system-enet --with-system-nvtt --without-nvtt
     213
     214cd gcc/
     215TOOLCHAIN=${HOME}/android/toolchain-0ad PKG_CONFIG_LIBDIR=${TOOLCHAIN}/sysroot/usr/local/lib/pkgconfig LDFLAGS="-lSDL2 -L=/usr/local/lib -L../../android/sdl-project/libs/armeabi" INCLUDES="--sysroot=${TOOLCHAIN}/sysroot -I${TOOLCHAIN}/arm-linux-androideabi/include/c++/4.4.3/arm-linux-androideabi/armv7-a/ -I../../android/sdl-project/jni/SDL/include -isystem=/usr/local/include/boost-1_45" CXX=${TOOLCHAIN}/bin/arm-linux-androideabi-g++ make pyrogenesis -j3 config=debug
     216}}}
     217
     218Then attach a device, and in `build/android/sdl-project/` run "`make push-apk`" and "`make push-so`". Run `/sdcard/0ad.apk` on the device to install.
     219
     220The .apk is basically just the standard SDL android-project, and it loads `/data/local/libpyrogenesis_dbg.so` which contains all the engine code. That means you can recompile and then upload the engine code (via "`make push-so`") on the host PC, and don't have to manually reinstall the app after each change. If you want a non-debug build, remove the "`config=debug`" when building the game, then copy `binaries/system/libpyrogenesis.so` to `libpyrogenesis_dbg.so` before running "`make push-so`".
     221
     222You need to use the game engine to create `public.zip` for data files, since it has to convert all the textures/models/animations/etc into a different format before zipping them up. Build a standard non-Android copy of the game, then run it like "`binaries/system/pyrogenesis -archivebuild=binaries/data/mods/public -archivebuild-output=temp/public.zip -archivebuild-compress`" and it should print lots of output and will take a while (maybe ten minutes or more). Then copy to `/sdcard/0ad/data/mods/public/public.zip` and the game should see it. (If you want to change a few data files after that, you don't need to regenerate `public.zip` - just copy the individual files straight into `mods/public/` and they'll override the zipped version.)
     223
     224Also, copy `binaries/data/config/default.cfg` into `/sdcard/0ad/appdata/config/`, and optionally set any local configuration values in `/sdcard/0ad/appdata/config/local.cfg`.
     225
     226Then try running the game, and use "`adb logcat`" to see what fails, and fix it.