Android NDK Notes

Sun 05 July 2015
By stu

Some notes on NDK problems I've had to overcome in the last few days, there are bound to be corrections needed, I'll try and update these based on any comments.

Environment variables

Various scripts use different ones to discover the location of the NDK - so don't be surprised when you see ANDROID_NDK, ANDROID_NDK_ROOT, ANDROID_NDK_HOME, or anything else - they mean the same thing, right now I'm using ANDROID_NDK currently.

Cmake

There are lots of different versions of android_cmake, subtly incompatible, you probably will need to edit scripts.

Before trying to use cmake with Android, make sure you can build some apps using the standard tools, or the scripts that come with them

This is something I'll probably come back to, as I'm using gradle and Android.mk right now.

Android Studio

In transition

Android used to use Eclipse and ANT, now it's in transition to Android Studio and Gradle, hence some things don't work, but they can be tweaked - this situation will probably change.

Installing NDK

Has it's own copy of the NDK, you can install it from the preferences in the Android SDK section, if you already installed a copy it won't automatically find it.

Build works when launching from terminal, but not using desktop icon

Android Studio doesn't pick up variables set in '.bashrc' - this means scripts may work if you launch it from a terminal, but not from the desktop.

Taking ages opening project, message about gradle

Android studio downloads this the first time, if you want more information load it from the terminal and you will see some info as it downloads.

Error about "JCenter" when trying to build

This can be because you have a really old version of gradle installed (ie the one that comes with Ubuntu 15.04) - if on Ubuntu you can test this by building using the "gradlew" script in your project, if this works then upgrade gradle - on Ubuntu there is a gradle PPA.

Not picking up settings in local.properties

You can add this at the top of your app.gradle

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def sdkDir = properties.getProperty('sdk.dir')
def ndkDir = properties.getProperty('ndk.dir')

Then add ndkDir to your ndkBuild section

// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine ndkDir + '/ndk-build.cmd', '-C', file('src/main').absolutePath
    } else {
        commandLine ndkDir + '/ndk-build', '-C', file('src/main').absolutePath
    }
}

Android.mk

Including other Android.mk files

You can do this like this

include $(LOCAL_PATH)/../assimp/workspaces/Android-NDK/jni/Android.mk

Make sure to do these includes at the end of your own file  as they may overwrite variables like LOCAL_PATH, also \$(call my-dir) returns the name of the latest included file.

http://grokbase.com/t/gg/android-ndk/128zkazrb1/unable-to-generate-multiple-so-files-for-native-libraries-using-a-single-make-file

http://stackoverflow.com/a/4650113/62709

No rule to make target

The build couldn't find the mentioned file, if you use a variable like LOCAL_PATH, maybe it was overwritten - see the section on includes

Outputting values from Android.mk

$(info hi, LOCAL_PATH is $(LOCAL_PATH))
$(warning Uh oh...)
$(error this is the error message that will stop the build process)

http://stackoverflow.com/a/26204506/62709

Running on a real device

cannot locate symbol “srand”


Android 21 changed the location of some symbols - either set your minimum sdk to 21 and build with that, or have a lower one (e.g. 19) and build with that SDK

http://discuss.cocos2d-x.org/t/android-debug-mode-works-but-release-dont-crashes-at-launch/20247/5

Everything else

Expect to do a lot of googling, expect to have to change makefiles. ... look at other projects using the libraries you use and see how they work, good luck !