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:
4. To be sure, look at your Android.mk once again. It should look like this:
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:
// 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_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.
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
}