Wiki Page Content

Differences between revisions 8 and 9
Revision 8 as of 2014-06-22 10:42:36
Size: 9506
Comment: precise the reason for each added PATH
Revision 9 as of 2014-06-22 10:48:12
Size: 9518
Comment: Fix path to built SDL2 + use "\rm" to avoid being prompted if alias rm='rm -i'
Deletions are marked like this. Additions are marked like this.
Line 122: Line 122:
cd /usr/src/SDL2/build/
rm libs/armeabi/libmain.so
cd /usr/src/SDL2/build/org.libsdl/
\rm libs/armeabi/libmain.so

Building SDL2 for Android

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"          # for 'ndk-build'
    PATH="$PATH:/usr/src/android-sdk-linux/tools"  # for 'android'

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 install

Notes:

  • 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!

Note: this environment can be used for CMake too.

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/org.libsdl/
    \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
    EOF
  • Install 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!

4.4. Build your CMake app

(Work In Progress)

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

# CMake toolchain file
SET(CMAKE_SYSTEM_NAME Linux)  # Tell CMake we're cross-compiling
include(CMakeForceCompiler)
# 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=/usr/src/ndk-standalone-12/bin:$PATH
cmake \
  -D CMAKE_TOOLCHAIN_FILE=../android_toolchain.cmake \
  ...

None: Android (last edited 2018-11-21 16:00:50 by SylvainBeucler)

Feedback
Please include your contact information if you'd like to receive a reply.
Submit