Compiling for Android
Our port to Android makes use of the commandergenius project, which includes a port of SDL1.2 (and many other libraries and applications). It supposedly requires Unix to compile. It seems that requirement is only due to the build scripts. Our branch unfortunately has diverged significantly since 2013.
The Android Port page discusses details of the port project.
Currently the armeabi and x86 targets are tested, but other android architectures will probably work with minimal changes to makefiles. (armeabi-v7a probably works without changes.)
Setup[edit]
- A working install of FB (with which to compile FB).
- Naturally you need the latest SVN revision of the OHR source
- Install Apache Ant
- Install the Android SDK. (I think that if you install the "SDK Tools" only then you'll need to run sudo android and download the rest of the SDK, while the 'ADT Bundle' includes all of that.) You'll probably want to add tools/ and platform-tools/ to your PATH
- Install the Android NDK. The NDK directory (containing ndk-build) will need to be in your PATH (as well as ant).
Both NDK version r8e (now getting old), and r12b (the latest as of Sept 2016) have been tested to work. However, if you use r12b you can compile for android 2.3 (api level 9) at the earliest.
- Get this fork of FB:
- git clone --branch android https://github.com/rversteegen/fbc.git freebasic
- Compile fbc (just the compiler, FB rtlib and gfxlib libraries not required):
- (Optional) I recommend creating a config.mk file in the freebasic directory with config settings. Instructions are at the top of the amazingly clean makefile. I strongly recommend not using the ENABLE_STANDALONE or ENABLE_PREFIX options. Set prefix to the install path. You can't run fbc without installing unless you symlink include to inc. Don't use ~ in paths!
CFLAGS := -Wfatal-errors -g FBCFLAGS := -g FBLFLAGS := -g prefix=$(HOME)/local/fbc-1.06-android
- Run make compiler
- Run make install-compiler install-includes to install to prefix. You can add prefix=path/to/whereever to the make commandline if you don't have a config.mk file.
- A clone of one of the following "commandergenius" sdl-android repository forks. Hopefully either one should work, but depending on which developer has been adding features recently, sometimes only one will work.
- git clone git://github.com/bob-the-hamster/commandergenius.git sdl-android (usually most up to date)
- git clone git://github.com/rversteegen/commandergenius.git sdl-android
- (Optional) I suggest following the sdl-android/readme.txt instructions to try out building a sample application. (Note: all applications aside from ohrrpgce are removed in the ohrrpgce branch, use James' sdl_android branch for this instead.) Note that the suggested sample application (ballfield) isn't quite interactive. At the bottom right are four buttons that do nothing. Bottom left is an emulated joystick (drag to use). Little rectangles are drawn on screen to indicate positions of emulated joysticks. Gyroscope and accelerator appear as a joystick each.
- Use the ohrrpgce git branch. Fetch it with git checkout --track origin/ohrrpgce
- This targets android 1.6. If you want to compile for a cpu architecture/abi other than ARM/armeabi you will need to target a later Android (e.g. x86 requires API level 9 aka android 2.3). Also, if you want to use a recent NDK you need to change the target to something that NDK supports:
- Change the APP_PLATFORM in project/jni/Application.mk
- Change android:minSdkVersion in project/AndroidManifestTemplate.xml
- This targets android 1.6. If you want to compile for a cpu architecture/abi other than ARM/armeabi you will need to target a later Android (e.g. x86 requires API level 9 aka android 2.3). Also, if you want to use a recent NDK you need to change the target to something that NDK supports:
- You can use Ralph's (rversteegen) ndk-r12b branch, which patches these two files to target android 2.3 and later.
- Create a symlink from sdl-android/project/jni/freebasic/rtlib to freebasic/src/rtlib
- cd sdl-android && ln -s /path/to/freebasic/src/rtlib project/jni/freebasic/rtlib
- Create a symlink from sdl-android/project/jni/application/ohrrpgce to wip/android in the OHR repository
- cd sdl-android && ln -s /path/to/OHR/wip/android project/jni/application/ohrrpgce
- Create a symlink from sdl-android/project/jni/application/src to sdl-android/project/jni/application/ohrrpgce
- cd sdl-android && ln -s ohrrpgce project/jni/application/src
Compiling Game or Custom[edit]
- Compile Game with the FB you built earlier with the android-source=1 flag: scons fbc=path/to/fbc android-source=1 debug=0 game This should create a bunch of C source files and place symlinks to them in wip/android/tmp/. It also does a useless linking step which doesn't produce anything.
- You can target a different cpu architecture/abi if you want. Only x86 (Atom) has been tested. Add arch=x86 for that. arch=armeabi-v7a might also work.
- sdl-android supports building .apks with multiple ABIs using an option like MultiABI="armeabi x86" in android/AndroidAppSettings.cfg, but that won't work directly because the .c files produced by FB only work for the single intended arch. So you will need to build each libapplication.so separately something.
- You can target a different cpu architecture/abi if you want. Only x86 (Atom) has been tested. Add arch=x86 for that. arch=armeabi-v7a might also work.
- cd to sdl-android.
- Run ./build.sh. If successful this creates a package named sdl-android/project/bin/MainActivitiy-debug.apk
(I think it would be easy to make scons produce libapplication.so itself, which can be zipped into the .apk)
Installing and debugging[edit]
- You can install it on your attached device or running emulator with adb install -r project/bin/MainActivity-debug.apk
- You can run it and attach gdb with cd project && ndk-gdb --start (or ndk-gdb --launch in more recent NDKs). You might want to adjust the default delay before it tries to attach with --delay <seconds> if your emulator is really slow, or it crashes quickly.
Cross-compiling FB and command line programs[edit]
To compile command-line FB (or C) programs (such as the commandline testcases), you don't need to use the SDK's ant-based build system as the commandergenius project does. Instead, you create a normal cross-compiling build of FB. Then you can compile FB code and OHRRPGCE utilities with fbc (with -target and optionally -arch options) and scons target=... respectively.
Here are the complete instructions to set up a FB crosscompiler:
- Get the Android SDK, NDK (see above)
- Get source for my FB fork (see above)
- Set up a standalone toolchain targetting a specific target arch and Android version
- If you really want, you can instead call gcc etc from the appropriate NDK subdirectory directly, passing the appropriate --sysroot option. But it's much more work
- Either edit and run the script wip/android/compiling-using-toolchain.sh which will install the toolchain the first time it is run (It'll also try to compile stuff, which will fail because FB isn't built yet.)....
- ...equivalently run an appropriately edited version of this:
NDK=/opt/android-ndk-r8e # Where to put the standalone toolchain TOOLCHAIN=$(HOME)/local/android-toolchain ARCH=arm # or x86, x86_64, arm64, mips, mips64 API=9 # android-9 = 2.3. Oldest version to support x86, and oldest supported by the latest NDK #API=21 # Oldest version to support x86_64 (version for newer NDKs like r12) $NDK/build/tools/make_standalone_toolchain.py --arch $ARCH --api $API --install-dir $TOOLCHAIN (version for older NDKs like r8) HOST=linux-$(uname -m) #$NDK/build/tools/make-standalone-toolchain.sh --arch=$ARCH --system=$HOST --platform=android-$API --install-dir=$TOOLCHAIN
- Put the standalone toolchain bin/ dir in your $PATH
- Compile FB. Go to the FB source directory and run:
- make prefix=/install/path compiler install-compiler install-includes -j4
- make prefix=/install/path TARGET=arm-linux-androideabi rtlib install-rtlib -j4
- Other targets include i686-linux-android for x86-based android and x86_64-linux-android
To use:
- Make sure fbc and the appropriate toolchain is in your path and run fbc -target arm-linux-androideabi test.bas to compile.
- Or to target more capable ARMs, add -arch armv7a (enable FPU) or -fpu neon (SIMD, implies armv7a)
- Compiling OHR utilities likewise: scons -j6 fbc=$FBC target=arm-linux-androideabi unlump relump, etc
- Or edit and run wip/android/compiling-using-toolchain.sh to invoke scons correctly. Everything except xml2reload and hspeak (haven't considered it actually) should compile. You can even compile Game or Custom using gfx=console music=silence, and they will run (badly), as long as you remove all the ncurses stuff from gfx_console.bas (this isn't worth doing)
Compiling and pushing a command line programs[edit]
First read the above sections for compiling FB and installing the NDK. The following script gives the minimal steps needs to compile, link, push to device, and run an arbitrary FB program:
FBC=~/local/fbc-1.06-android/bin/fbc TOOLCHAIN=~/local/android-toolchain PATH=$TOOLCHAIN/bin:$PATH echo 'print "hello world!"' > hello.bas $FBC -target arm-linux-androideabi hello.bas || exit # On an un-rooted Android 2.2 device, /data/HWUserData/ # is about the only writable location that isn't noexec. # The first time adb is invoked it needs to be run as root. sudo adb push hello /data/HWUserData/hello adb shell /data/HWUserData/hello