13. June 2018

Android Studio NDK could not start mips64el-linux-android-strip

If you’re using Android Studio to build C++ application with NDK you might encounter following error during build:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformNativeLibsWithStripDebugSymbolForDebug'.
...
Caused by: java.io.IOException: Cannot run program ".../Android/Sdk/ndk-bundle/toolchains/mips64el-linux-android-4.9/prebuilt/linux-x86_64/bin/mips64el-linux-android-strip": 
error=2, No such file or directory

The problem is caused by the upgrade of NDK in Android Studio to NDK v17. This version has a different structure of tools. It’s not compatible with Android Experimental Plugin v0.11.

The directory which should contain binary of tools contains just file NOTICE-MIPS64:

This mips64el-linux-android-4.9 directory exists to make the NDK compatible with the Android
SDK's Gradle plugin, version 3.0.1 and earlier, which expects the NDK
to have a MIPS64 toolchain directory.

The solution is to download NDK v16 from NDK older releases. Extract it and replace former ndk-bundle directory.

Commands for macOS or Linux users:

cd ~/Android
unzip ~/Downloads/android-ndk-r16b-linux-x86_64.zip
mv ndk-bundle ndk-bundle-v17
mv android-ndk-r16b ndk-bundle

If you’re Windows user the location of NDK is typically in your profile AppData\Local\Android. Do not forget to unblock the ZIP after downloading (right click, Properties, Unblock, Ok)

Commands for Windows users:

cd ~\AppData\Local\Android
unzip ~\Downloads\android-ndk-r16b-windows-x86_64.zip
mv ndk-bundle ndk-bundle-v17
mv android-ndk-r16b ndk-bundle

Start Android Studio. It should prompt you to update NDK. Do not confirm this request, it will replace NDK with v17. You should see the following screen in SDK Manager:

You can find related sample source code at GitHub in sdl2-android-example repository. Further articles about SDL2 and Android are available under the tag SDL2.

10. May 2018

SDL2_gfx for Android – Graphic primitives

In previous article, we were talking about drawing pictures in JPEG format. Let’s look how to draw some graphic primitives like a line. SDL2_gfx is small library which has support for graphic primitives and some surface functions.

The initial steps to add SDL2_gfx to Android project is the same like in case of SDL2_jpeg.

Register library in settings.gradle:

include ':SDL2_gfx'

The library should be stored in SDL2_gfx directory with build.gradle.

Now update our C application.

Here is simple example which draws a line:

thickLineColor(renderer, 0, 300, 300, 300, 20, 0xFF00FFFF);

You can find the source code at GitHub in sdl2-android-example repository. Further articles about SDL2 and android are available under the tag SDL2.

Special thanks for this extension of SDL2 Android example goes to jojomickymack who suggested how to add support for SDL2_gfx to Android project. Thank you.

13. September 2017

SDL2_mixer for Android playing WAV file

In previous articles, we were talking about PNG and JPEG support in SDL2 for Android. Let’s add some sounds to our application.

The initial steps are same as in case of SDL2_image.

Register library in settings.gradle:

include ':SDL2_mixer'

The library should be stored in SDL2_mixer directory with build.gradle that written in style for a library.

Now update our C application.

First of all, it is necessary to initialize the library. Then it is possible to load the sound file.

    if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096) == -1 ) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                     "Couldn't open mixer: %s", SDL_GetError());
        return 2;
    }
    Mix_Chunk *sample = Mix_LoadWAV("cuckoo.wav");
    if (sample == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 
                     "Unable to load wave file\n");
        return 3;
    }

The file WAV should be stored in app/src/main/assets. Just small reminder: this is just a virtual directory, and you won’t be able to access it from other application on Android.

Playing the sound is simple:

Mix_PlayChannel(-1, sample, 0);

The last important thing about SDL2_mixer is that you should close SDL2_mixer when exiting the main. Otherwise, when you relaunch SDLActivity, it won’t be able to play any sound.

Mix_CloseAudio();

You can find the source code at GitHub in sdl2-android-example repository. Further articles about SDL2 and android are available under the tag SDL2.

8. July 2017

SDL2_image for Android with XPM image format

In the previous article, we were discussing how to start building SDL2 application for Android. Let’s add some images.

SDL2 library does not contain support for any image formats, you have to add further library SDL2_image which has support for several formats.

In order to add SDL2_image into Android project it is necessary to add a new module to settings.gradle:

include ':SDL2_image'

The module itself will be stored in SDL2_image directory with build.gradle which contains reference to main SDL2 library:

model {
    repositories {
        libs(PrebuiltLibraries) {
            SDL2 {
                headers.srcDir "../SDL2/include"
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("${lib_distribution_root}/SDL2/lib/${targetPlatform.getName()}/libSDL2.so")
                }
            }
        }
    }

SDL2_image has support for several formats. You need to turn them on based on your requirements. It’s easy, just add proper define to compiler. Let’s start with simplest format XPM:

ndk { 
...
   CFlags.addAll(["-DLOAD_XPM"])
...
}

X PixMap (or XPM) is very simple image format which could be embedded directly into the source code.

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

The next step is to transform XPM from the source code into memory structure which could be rendered on the screen.

SDL_Surface *surface;
surface = IMG_ReadXPMFromArray(icon_xpm);
texture = SDL_CreateTextureFromSurface(renderer, surface);

The last part is to call render function. You can find whole source code at https://github.com/georgik/sdl2-android-example.

We will discuss how to use further SDL2 libraries in next articles. You can find more under topic SDL2.

5. July 2017

SDL2 application for Android built by Gradle 4

SDL2 is a well known library for making games or interactive application for Linux, Windows or macOS. The library has also support for mobile devices. Building application for Android requires a little bit more effort than build for desktops.

Let’s go step-by-step.

First of all download Gradle 4 and add bin directory with gradle to your PATH environment variable.

Download and install Android Studio.

Clone sdl2-android-example project from GitHub.

Open the repo in Android Studio and open SDK Manager. Go to Tools, select menu Android, and select item SDK Manager.

In the lower right corner check option Show Package Details. Install Android SDK Build Tool e.g. version 28.0.0 and NDK.

When you open the sdl2-android-example you will see following structure. There are two gradle files in the top level directory. The first is build.gradle. The file contains a dependency on gradle-experimental plugin which is recommended for NDK builds for Android.

buildscript {
    repositories {
       jcenter()
    }
    dependencies {
        // Android native build plugin compatible with Gradle 4
        classpath 'com.android.tools.build:gradle-experimental:0.11.0-alpha-preview-02'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

The second Gradle file is settings.gradle. The file contains a list of modules which are in the project. One module is SDL2 library. Then there are two further modules app and main. The app module is the bridge between Java and SDL2. The main module contains C code for the application.

gradle.ext.sdkVersion = 21

include ':app'
include ':SDL2'
include ':main'

These two files provide a skeleton for the build of the application. Each module SDL2, app and main are stored in the directory that matches the name a of module. Each module contains its own build.gradle which describes how to build the module.

The module file SDL2/build.gradle is interesting because it contains many excludes. It does not make sense to build all C files from SDL2 for Android.

The module file main/build.gradle contains information for linking the C application with SDL2 library.

The module file app/build.gradle contains information how to wrap all the C source code into final application.

First of all, it is necessary to build the libraries (.so files):

gradle distributeLib

If you want to build just one library, you can type:

gradle :SDL2:distributeLib

Gradle will build all flavors. If you’re experiencing problems with Android Studio, just sync the project after executing this command from command line.

Now you can deploy the application to a device or an emulator. Go to Gradle projects, expand :app module, expand Tasks, expand install and double click installDebug target.

We will discuss how to use further SDL2 libraries in next articles. You can find more under topic SDL2.

Note: the sample projet at GitHub already contains reference to other libraries like PNG. Please follow instructions described in the article SDL2_image for Android with PNG image format. The other option is to clone older version of application without PNG.