Android Studio ndk project asset_manager_jni.h – no such file or directory error

Problem

While building an Android java library project with Android Studio, a compiler error occurs: “android/asset_manager_jni.h: No such file or directory“. Java sources are in the main/java folder. C++ native sources are placed into the main/jni folder. When I try to compile the whole library without my custom Android.mk, there is no error! When using it, my own ndkbuild in the build.gradle fails with the above error. I searched for solutions but none helped me. Environment: MacBook, OS X: Yosemite, IDE: Android Studio 1.1.0. I installed the latest NDK android-ndk-r10d. What do I miss? (Project code was included).

Solution

A lot can go wrong. Our general checklist:

1. Check out your NDK installation. Download and install the latest version. In the absolute path to the installation folder, do not use space or special characters other than – or _. This place is perfect: /Users/me/SDKS/android-ndk-r10d. If you have an ANDROID_NDK_HOME environment key in your Mac’s .bash-profile, actualize it. Download AndroidStudio from here. Download the latest NDK from here.

2. In the Android Studio, open your project local.properties file. Find ndk.dir=. If missing, add as ndk.dir=pathtondk. For example: ndk.dir=/Users/me/SDKS/android-ndk-r10d

3. Open build.gradle. Disable automatic ndk-build call by adding sourceSets.main.jni.srcDirs = [] to the android section, like this:

android {
    compileSdkVersion 21
    buildToolsVersion '21.1.2'
    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 21
        ndk {
            moduleName "myndklib"       // the name of the actual native module
            // ldLibs "log", "android"  // when building without Android.mk
        }
    }
    sourceSets.main {
        jni.srcDirs = []  // <-- disable automatic ndk-build call
    }
    // ......etc
}

4. To be sure, look at your Android.mk once again. It should look like this:

    # Must have:
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    # Module name
    LOCAL_MODULE := myndklib
    LOCAL_MODULE_FILENAME:= libmyndklib
    # Add all source file names to be included in lib separated by a whitespace
    LOCAL_SRC_FILES := myndklib.c
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/include-all
    # Include header files, modules you need
    LOCAL_LDLIBS += -landroid -llog
    include $(BUILD_SHARED_LIBRARY)
    # ... etc

Try to clean and rebuild your project.

5. If it still can’t compile without any error, then use the next solution I personally hate, but OK-ish. It helps when Android Studio – NDK marriage is not perfect in finding the correct platform version. In the build.gradle:

    task ndkBuild(type: Exec) {
        // def MainDirectory = file('src/main/jni').absolutePath  // <-- we do not need it any longer
        def ndkBuildPath = project.plugins.findPlugin('com.android.library').sdkHandler.getNdkFolder().absolutePath + File.separator
        if (Os.isFamily(Os.FAMILY_WINDOWS)) {
            ndkBuildPath += 'ndk-build.cmd'
        } else {
            ndkBuildPath += 'ndk-build'
        }
        // commandLine ndkBuildPath, '-C', MainDirectory    // <-- I removed this original call
        commandLine ndkBuildPath,                           // <-- Use this one instead
                'NDK_PROJECT_PATH=build',
                'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
                'NDK_APPLICATION_MK=src/main/jni/Application.mk'
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }

To let it work add Application.mk to the jni folder. APP_PLATFORM := android-14 is the minimum platform we recommend. Sample Application.mk:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := all
APP_PLATFORM := android-14

6. Android Studio places all the compiled .so files into the build/libs folder. You can pack them into a .jar (zip) file for distribution. APP_ABI := all in your Application.mk will build for all (armeabi, mips, x86) chipsets. Otherwise as a minimum declare armeabi-v7a and x86, for example APP_ABI := armeabi armeabi-v7a x86 is usually sufficient.