This is new wiki software and old wiki content. It's a work in progress!
Here's the explanation.
Be gentle, report bugs, leave feedback on pages, or just edit them yourself! Thanks!

SDL Wiki

Building SDL2 for Android

Existing documentation

A lot of information can be found in SDL/docs/README-android.md.

This page is more walkthrough-oriented.

Pre-requisites

* Install minimal Java environment. For instance, in Debian/Ubuntu:

sudo apt install openjdk-8-jdk ant android-sdk-platform-tools-common

* Configure your environment variables, e.g.:

PATH="/usr/src/android-ndk-rXXx:$PATH"                  # for 'ndk-build'
PATH="/usr/src/android-sdk-linux/tools:$PATH"           # for 'android'
PATH="/usr/src/android-sdk-linux/platform-tools:$PATH"  # for 'adb'
export ANDROID_HOME="/usr/src/android-sdk-linux"        # for gradle
export ANDROID_NDK_HOME="/usr/src/android-ndk-rXXx"     # for gradle

Simple builds

SDL wrapper for simple programs

cd /usr/src/SDL2/build-scripts/
./androidbuild.sh org.libsdl.testgles ../test/testgles.c
cd /usr/src/SDL2/build/org.libsdl.testgles/
ant debug install       # SDL <= 2.0.7
./gradlew installDebug  # SDL >= 2.0.8

Notes:

Troubleshooting

```

   repositories {
       jcenter()
   }

``` to ```

   repositories {
       jcenter()
       google()
   }

```

``` classpath 'com.android.tools.build:gradle:3.1.0' ```

``` distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip ```

android {

   buildToolsVersion "28.0.1"
   compileSdkVersion 28

}}}

       externalNativeBuild {
           ndkBuild {
               arguments "APP_PLATFORM=android-14"
               abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'

```

SDL wrapper + SDL_image NDK module

Let's modify SDL2_image/showimage.c to show a simple embedded image (e.g. XPM).

#include "SDL.h"
#include "SDL_image.h"

/* XPM */
static char * icon_xpm[] = {
  "32 23 3 1",
  "     c #FFFFFF",
  ".    c #000000",
  "+    c #FFFF00",
  "                                ",
  "            ........            ",
  "          ..++++++++..          ",
  "         .++++++++++++.         ",
  "        .++++++++++++++.        ",
  "       .++++++++++++++++.       ",
  "      .++++++++++++++++++.      ",
  "      .+++....++++....+++.      ",
  "     .++++.. .++++.. .++++.     ",
  "     .++++....++++....++++.     ",
  "     .++++++++++++++++++++.     ",
  "     .++++++++++++++++++++.     ",
  "     .+++++++++..+++++++++.     ",
  "     .+++++++++..+++++++++.     ",
  "     .++++++++++++++++++++.     ",
  "      .++++++++++++++++++.      ",
  "      .++...++++++++...++.      ",
  "       .++............++.       ",
  "        .++..........++.        ",
  "         .+++......+++.         ",
  "          ..++++++++..          ",
  "            ........            ",
  "                                "};

int main(int argc, char *argv[])
{
  SDL_Window *window;
  SDL_Renderer *renderer;
  SDL_Surface *surface;
  SDL_Texture *texture;
  int done;
  SDL_Event event;

  if (SDL_CreateWindowAndRenderer(0, 0, 0, &window, &renderer) < 0) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
        "SDL_CreateWindowAndRenderer() failed: %s", SDL_GetError());
    return(2);
  }

  surface = IMG_ReadXPMFromArray(icon_xpm);
  texture = SDL_CreateTextureFromSurface(renderer, surface);
  if (!texture) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
        "Couldn't load texture: %s", SDL_GetError());
    return(2);
  }
  SDL_SetWindowSize(window, 800, 480);

  done = 0;
  while (!done) {
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_QUIT)
        done = 1;
    }
    SDL_RenderCopy(renderer, texture, NULL, NULL);
    SDL_RenderPresent(renderer);
    SDL_Delay(100);
  }
  SDL_DestroyTexture(texture);

  SDL_Quit();
  return(0);
}

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
sed -i -e 's/^LOCAL_SHARED_LIBRARIES.*/& SDL2_image/' jni/src/Android.mk
ndk-build -j$(nproc)
ant debug install

Notes:

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!

Note: this environment can be used for CMake too.

Compile a shared binaries bundle for SDL and SDL_*

cd /usr/src/ wget https://libsdl.org/release/SDL2-2.0.5.tar.gz wget https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.1.tar.gz wget https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.tar.gz wget https://www.libsdl.org/projects/SDL_net/release/SDL2_net-2.0.1.tar.gz wget https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-2.0.14.tar.gz

tar xf SDL2-2.0.5.tar.gz tar xf SDL2_image-2.0.1.tar.gz tar xf SDL2_mixer-2.0.1.tar.gz tar xf SDL2_net-2.0.1.tar.gz tar xf SDL2_ttf-2.0.14.tar.gz

ln -s SDL2-2.0.5 SDL2 ln -s SDL2_image-2.0.1 SDL2_image ln -s SDL2_mixer-2.0.1 SDL2_mixer ln -s SDL2_net-2.0.1 SDL2_net ln -s SDL2_ttf-2.0.14 SDL2_ttf ```

cd /usr/src/SDL2/ cd build-scripts/

  1. hg revert --all # remove traces of previous builds
  2. edit androidbuild.sh and modify $ANDROID update project --target android-XX

./androidbuild.sh org.libsdl /dev/null

  1. doesn't matter if the actual build fails, it's just for setup

cd ../build/org.libsdl/ ```

rm -rf jni/src/ ```

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_net jni/ ln -s /usr/src/SDL2_ttf jni/ ```

SUPPORT_MP3_SMPEG := false include $(call all-subdir-makefiles) ```

ndk-build -j$(nproc) ```

Note: no need to add System.loadLibrary calls in SDLActivity.java, your application will be linked to them and Android's ld-linux loads them automatically.

Install SDL in a GCC toolchain

Now:

/usr/src/android-ndk-r8c/build/tools/make-standalone-toolchain.sh \

 --platform=android-14 --install-dir=/usr/src/ndk-standalone-14-arm --arch=arm

```

NDK_STANDALONE=/usr/src/ndk-standalone-14-arm PATH=$NDK_STANDALONE/bin:$PATH ```

cd /usr/src/SDL2/build/org.libsdl/ for i in libs/armeabi/*; do ln -nfs $(pwd)/$i $NDK_STANDALONE/sysroot/usr/lib/; done mkdir $NDK_STANDALONE/sysroot/usr/include/SDL2/ \cp jni/SDL/include/* $NDK_STANDALONE/sysroot/usr/include/SDL2/ \cp jni/*/SDL*.h $NDK_STANDALONE/sysroot/usr/include/SDL2/ ```

VERSION=0.9.12 cd /usr/src/ wget http://rabbit.dereferenced.org/~nenolod/distfiles/pkgconf-$VERSION.tar.gz tar xf pkgconf-$VERSION.tar.gz cd pkgconf-$VERSION/ mkdir native-android/ && cd native-android/ ../configure --prefix=$NDK_STANDALONE/sysroot/usr make -j$(nproc) make install ln -s ../sysroot/usr/bin/pkgconf $NDK_STANDALONE/bin/arm-linux-androideabi-pkg-config mkdir $NDK_STANDALONE/sysroot/usr/lib/pkgconfig/ ```

cat <<'EOF' > $NDK_STANDALONE/sysroot/usr/lib/pkgconfig/sdl2.pc prefix=/usr/src/ndk-standalone-14-arm/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.5 Requires: Conflicts: Libs: -lSDL2 Cflags: -I${includedir}/SDL2 -D_REENTRANT EOF

cat <<'EOF' > $NDK_STANDALONE/sysroot/usr/lib/pkgconfig/SDL2_image.pc prefix=/usr/src/ndk-standalone-14-arm/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' > $NDK_STANDALONE/sysroot/usr/lib/pkgconfig/SDL2_mixer.pc prefix=/usr/src/ndk-standalone-14-arm/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' > $NDK_STANDALONE/sysroot/usr/lib/pkgconfig/SDL2_net.pc prefix=/usr/src/ndk-standalone-14-arm/sysroot/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: SDL2_net Description: net library for Simple DirectMedia Layer Version: 2.0.1 Requires: sdl2 >= 2.0.0 Libs: -L${libdir} -lSDL2_net Cflags: -I${includedir}/SDL2 EOF

cat <<'EOF' > $NDK_STANDALONE/sysroot/usr/lib/pkgconfig/SDL2_ttf.pc prefix=/usr/src/ndk-standalone-14-arm/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.14 Requires: sdl2 >= 2.0.0 Libs: -L${libdir} -lSDL2_ttf Cflags: -I${includedir}/SDL2 EOF ```

Building other dependencies

You can add any other libraries (e.g.: SDL2_gfx, freetype, gettext, gmp...) using commands like: ``` mkdir cross-android/ && cd cross-android/ ../configure --host=arm-linux-androideabi --prefix=$NDK_STANDALONE/sysroot/usr \

 --with-some-option --enable-another-option \
 --disable-shared

make -j$(nproc) make install ```

Static builds (--disable-shared) are recommended for simplicity (no additional .so to declare).

Example with SDL2_gfx: ``` VERSION=1.0.3 wget http://www.ferzkopp.net/Software/SDL2_gfx/SDL2_gfx-$VERSION.tar.gz tar xf SDL2_gfx-$VERSION.tar.gz mv SDL2_gfx-$VERSION/ SDL2_gfx/ cd SDL2_gfx/ mkdir cross-android/ && cd cross-android/ ../configure --host=arm-linux-androideabi --prefix=$NDK_STANDALONE/sysroot/usr \

 --disable-shared --disable-mmx

make -j$(nproc) make install ```

You can compile YOUR application using this technique, with some more steps to tell Android how to run it using JNI.

Build your autotools app

First, prepare an Android project:

mkdir -p libs/armeabi/ for i in /usr/src/SDL2/build/org.libsdl/libs/armeabi/*; do ln -nfs $i libs/armeabi/; done ```

Make your project Android-aware:

AM_CONDITIONAL(ANDROID, test "$host" = "arm-unknown-linux-androideabi") }}}

if ANDROID

 AM_CFLAGS = -fPIC
 AM_LDFLAGS += -shared
 COMMON_OBJS += SDL_android_main.c

endif }}}

PATH=$NDK_STANDALONE/bin:$PATH mkdir cross-android/ && cd cross-android/ ../configure --host=arm-linux-androideabi \

 --prefix=/android-aint-posix \
 --with-your-option --enable-your-other-option ...

make ```

mkdir cross-android-v7a/ && cd cross-android-v7a/

  1. .o: -march=armv5te -mtune=xscale -msoft-float -mthumb => -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb
  2. .so: -march=armv7-a -Wl,--fix-cortex-a8

CFLAGS="-g -O2 -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb" LFDLAGS="-march=armv7-a -Wl,--fix-cortex-a8" \

 ../configure --host=arm-linux-androideabi \
 ...

```

Now you can install your pre-built binaries and build the Android project:

android update project --name your_app --path . --target android-XX ant debug ant installd ```

adb shell am start -a android.intenon.MAIN -n org.libsdl.app/org.libsdl.app.SDLActivity # replace with your app package ```

Build your CMake app

(Work In Progress)

You can use our Android GCC toolchain using a simple toolchain file: ```

  1. CMake toolchain file

SET(CMAKE_SYSTEM_NAME Linux) # Tell CMake we're cross-compiling include(CMakeForceCompiler)

  1. Prefix detection only works with compiler id "GNU"

CMAKE_FORCE_C_COMPILER(arm-linux-androideabi-gcc GNU) SET(ANDROID TRUE) ```

You then call CMake like this: ``` PATH=$NDK_STANDALONE/bin:$PATH cmake \

 -D CMAKE_TOOLCHAIN_FILE=../android_toolchain.cmake \
 ...

```

Troubleshootings

If ```ant installd``` categorically refuses to install with , even if you have free local storage, that may mean anything. Check logcat first: If the error logs are not helpful (likely ;')) try locating all past traces of the application: ``` find / -name "org...." ``` and remove them all.

If the problem persists, you may try installing on the SD card: ``` adb install -s bin/app-debug.apk ```


If you get in your logcat: ``` SDL: Couldn't locate Java callbacks, check that they're named and typed correctly ``` this probably means your ```SDLActivity.java``` is out-of-sync with your libSDL2.so.


[ edit | delete | history | feedback | raw ]

[ front page | index | search | recent changes | git repo | offline html ]

All wiki content is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).
Wiki powered by ghwikipp.