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 | |
| 189 | First download a recent version of SDL 2.0: |
| 190 | {{{ |
| 191 | cd build/android/sdl-project/jni/ |
| 192 | hg clone http://hg.libsdl.org/SDL |
| 193 | }}} |
| 194 | |
| 195 | Then build SDL and the .apk (the installable application that invokes the external game engine code): |
| 196 | {{{ |
| 197 | cd build/android/sdl-project/ |
| 198 | make |
| 199 | }}} |
| 200 | (Dependency checking is probably broken, so run "`make clean`" if you need to rebuild after changing stuff.) |
| 201 | |
| 202 | Then install all the dependencies: |
| 203 | {{{ |
| 204 | cd build/android/ |
| 205 | ./setup-libs.sh |
| 206 | }}} |
| 207 | The 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 | |
| 209 | Build the game like: |
| 210 | {{{ |
| 211 | cd 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 | |
| 214 | cd gcc/ |
| 215 | TOOLCHAIN=${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 | |
| 218 | Then 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 | |
| 220 | The .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 | |
| 222 | You 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 | |
| 224 | Also, 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 | |
| 226 | Then try running the game, and use "`adb logcat`" to see what fails, and fix it. |