Building SDL2 for Android
Contents
1. Existing documentation
A lot of information can be found in SDL2/README-android.txt.
This page is more walkthrough-oriented.
2. Pre-requisites
Install minimal Java environment. For instance, in Debian/Ubuntu:
sudo apt-get install openjdk-7-jdk ant
- Install NDK (tested with r9d)
Install the latest SDK, run android and install API 12
Configure your environment variables, e.g.:
PATH="$PATH:/usr/src/android-ndk-r9d" PATH="$PATH:/usr/src/android-sdk-linux/tools"
3. Simple builds
3.1. SDL wrapper for simple programs
Compile a sample app (calls ndk-build):
cd /usr/src/SDL2/build-scripts/ ./androidbuild.sh org.libsdl.testgles ../test/testgles.c
Follow the instructions to install on your device:
cd /usr/src/SDL2/build/org.libsdl.testgles/ ant debug install
Notes:
- triple target armeabi/armeabi-v7a/x86 compilation!
- application doesn't quit
3.2. SDL wrapper + SDL_image NDK module
Let's modify SDL2_image/showimage.c to show a simple embedded image (e.g. XPM).
Then let's make an Android app out of it. To compile:
cd /usr/src/SDL2/build-scripts/
./androidbuild.sh org.libsdl.showimage /usr/src/SDL2_image/showimage.c
cd /usr/src/SDL2/build/org.libsdl.showimage/
ln -s /usr/src/SDL2_image jni/
ln -s /usr/src/SDL2_image/external/libwebp-0.3.0 jni/webp
# - Edit jni/src/Android.mk
# LOCAL_SHARED_LIBRARIES := ... SDL2_image
# - Edit android-project/src/org/libsdl/app/SDLActivity.java:
# System.loadLibrary("SDL2_image");
# - Edit jni/Application.mk: remove x86 where jpeg-9 doesn't build
ndk-build -j$(nproc)
ant debug installNotes:
- application doesn't restart properly
4. Build an autotools-friendly environment
You use autotools in your project and can't be bothering understanding ndk-build's cryptic errors? This guide is for you!
4.1. Compile a shared binaries bundle for SDL and SDL_*
Start with a minimal build:
cd /usr/src/SDL2/ cd build-scripts/ ./androidbuild.sh org.libsdl /dev/null cd ../build/org.libsdl/
Reference SDL_image, SDL_mixer, SDL_ttf, and their dependencies, as NDK modules:
ln -s /usr/src/SDL2_image jni/ ln -s /usr/src/SDL2_image/external/libwebp-0.3.0 jni/webp ln -s /usr/src/SDL2_mixer jni/ ln -s /usr/src/SDL2_mixer/external/libmikmod-3.1.12 jni/libmikmod ln -s /usr/src/SDL2_mixer/external/smpeg2-2.0.0 jni/smpeg2 ln -s /usr/src/SDL2_ttf jni/
Reference the libraries to the NDK build system: edit jni/src/Android.mk:
LOCAL_SHARED_LIBRARIES := ... SDL2_image SDL2_mixer SDL2_ttf
Optionnaly edit jni/SDL2_mixer/Android.mk to disable some formats
Reference the libraries in the Java bootstrap: edit android-project/src/org/libsdl/app/SDLActivity.java:
// Load the .so static { System.loadLibrary("SDL2"); System.loadLibrary("SDL2_image"); System.loadLibrary("SDL2_mixer"); //System.loadLibrary("SDL2_net"); // TODO System.loadLibrary("SDL2_ttf"); System.loadLibrary("main"); }Edit jni/Application.mk and remove x86 where jpeg-9 doesn't build (as of 2014-06)
Launch the build!
ndk-build -j$(nproc)
4.2. Install SDL in a GCC toolchain
Now:
Copy the NDK into a traditional GCC toolchain:
/usr/src/android-ndk-r9d/build/tools/make-standalone-toolchain.sh \ --platform=android-12 --install-dir=/usr/src/ndk-standalone-12 --arch=arm
Set your PATH (important, do it before any build):
PATH=/usr/src/ndk-standalone-12/bin:$PATH
Install the SDL2 binaries in the toolchain:
cd /usr/src/SDL2/build/ rm libs/armeabi/libmain.so for i in libs/armeabi/*; do ln -nfs $(pwd)/$i /usr/src/ndk-standalone-12/sysroot/usr/lib/; done mkdir /usr/src/ndk-standalone-12/sysroot/usr/include/SDL2/ cp jni/SDL/include/* /usr/src/ndk-standalone-12/sysroot/usr/include/SDL2/ cp jni/*/SDL*.h /usr/src/ndk-standalone-12/sysroot/usr/include/SDL2/
Install pkg-config .pc files for SDL:
cat <<'EOF' > /usr/src/ndk-standalone-12/sysroot/usr/lib/pkgconfig/sdl2.pc prefix=/usr/src/ndk-standalone-12/sysroot/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: sdl2 Description: Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. Version: 2.0.3 Requires: Conflicts: Libs: -lSDL2 Cflags: -I${includedir}/SDL2 -D_REENTRANT EOF cat <<'EOF' > /usr/src/ndk-standalone-12/sysroot/usr/lib/pkgconfig/SDL2_image.pc prefix=/usr/src/ndk-standalone-12/sysroot/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: SDL2_image Description: image loading library for Simple DirectMedia Layer Version: 2.0.1 Requires: sdl2 >= 2.0.0 Libs: -L${libdir} -lSDL2_image Cflags: -I${includedir}/SDL2 EOF cat <<'EOF' > /usr/src/ndk-standalone-12/sysroot/usr/lib/pkgconfig/SDL2_mixer.pc prefix=/usr/src/ndk-standalone-12/sysroot/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: SDL2_mixer Description: mixer library for Simple DirectMedia Layer Version: 2.0.1 Requires: sdl2 >= 2.0.0 Libs: -L${libdir} -lSDL2_mixer Cflags: -I${includedir}/SDL2 EOF cat <<'EOF' > /usr/src/ndk-standalone-12/sysroot/usr/lib/pkgconfig/SDL2_ttf.pc prefix=/usr/src/ndk-standalone-12/sysroot/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: SDL2_ttf Description: ttf library for Simple DirectMedia Layer with FreeType 2 support Version: 2.0.13 Requires: sdl2 >= 2.0.0 Libs: -L${libdir} -lSDL2_ttf Cflags: -I${includedir}/SDL2 EOFInstall pkg-config and install a host-triplet-prefixed symlink in the PATH:
VERSION=0.9.6 $WGET http://rabbit.dereferenced.org/~nenolod/distfiles/pkgconf-$VERSION.tar.gz tar xf pkgconf-$VERSION.tar.gz cd pkgconf-$VERSION mkdir cross-android/ && cd cross-android/ ../configure --host=arm-linux-androideabi --prefix=/usr/src/ndk-standalone-12/sysroot/usr make -j$(nproc) make install ln -s ../sysroot/usr/bin/pkgconf /usr/src/ndk-standalone-12/bin/arm-linux-androideabi-pkg-config mkdir /usr/src/ndk-standalone-12/sysroot/usr/lib/pkgconfig/
Note: you can add any other library using the same instructions (e.g.: freetype, gettext, gmp... and yours!):
mkdir cross-android/ && cd cross-android/ ../configure --host=arm-linux-androideabi --prefix=/usr/src/ndk-standalone-12/sysroot/usr \ --with-some-option --enable-another-option \ --disable-shared make -j$(nproc) make install
Static builds (--disable-shared) is recommended for simplificity (no additional .so to declare).
4.3. Build your autotools app
First, prepare an Android project:
Copy and adapt the /usr/src/SDL2/android-project skeleton as explained in README-android.txt. You can leave it as-is in a first step (but apply the bundle fixes to SDLActivity.java) .
Copy the SDL binaries as well:
cp -a /usr/src/SDL2/build/org.libsdl/libs/armeabi/* libs/armeabi/
Make your project Android-aware:
Add /usr/src/SDL2/src/main/android/SDL_android_main.c in your project (comment out the line referencing "SDL_internal.h")
In your configure.ac, detect Android:
AM_CONDITIONAL(ANDROID, test "$host" == "arm-unknown-linux-androideabi")
In your Makefile.am, tell Automake you'll build executables as libraries, using something like:
if ANDROID # Build .so JNI libs rather than executables AM_CFLAGS = -fPIC AM_LDFLAGS += -shared COMMON_OBJS += SDL_android_main.c endif
Cross-compile your project using the GCC toolchain environment we created:
PATH=/usr/src/ndk-standalone-12/bin:$PATH mkdir cross-android/ cd cross-android/ ../configure --host=arm-linux-androideabi \ --with-your-option --enable-your-other-option ... make
Do this again for any additional arch you want to support (TODO: see how to support armeabi-v7a and document what devices support it)
Now you can install your pre-built binaries and build the Android project:
Copy your program in android-project/libs/armeabi/libmain.so.
Build your Android .apk:
android update project --name your_app --path . --target "android-12" ant debug ant installd
You can run the application remotely:
adb shell am start -a android.intenon.MAIN -n org.libsdl.app/org.libsdl.app.SDLActivity # replace with your app package
- Your SDL2 Android app is running!
