I've been trying to hack on a Gradle managed Android project that uses JNI and I'm having a bit of trouble. I understand NDK support is still relatively new and mostly undocumented, but I have managed to find the basic elements for shoe-horning it into a Gradle build. Apparently the trick is to include all of your native code under src/main/jni
and drop the following in one of your configs (e.g. in the defaultConfig
block):
ndk {
moduleName "mylib"
}
The problem is that when I try to build my project, the ndk plugin generates an Android.mk file which includes absolute paths to the native source. This causes make
to choke as it STILL considers the paths to be relative. In my case I have a simple library project with 1 cpp source/header combo under src/main/jni
and I use this gradle.build
:
apply plugin: 'android-library'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 9
targetSdkVersion 19
versionCode 1
versionName "1.0"
ndk {
moduleName "mylib"
}
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.+'
}
Running the build generates this Android.mk under build/ndk/debug:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := \
/Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/Android.mk \
/Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/myNativeSectionTextProvider.cpp \
LOCAL_C_INCLUDES += /Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni
LOCAL_C_INCLUDES += /Users/clifton/dev/Multi/MultiAndroid/lib/src/debug/jni
include $(BUILD_SHARED_LIBRARY)
…which, when run generates this error:
make: *** No rule to make target `/Users/clifton/dev/Multi/MultiAndroid/lib/build/ndk/debug//Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/myNativeSectionTextProvider.cpp', needed by `/Users/clifton/dev/Multi/MultiAndroid/lib/build/ndk/debug/obj/local/armeabi-v7a/objs/mylib//Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/myNativeSectionTextProvider.o'. Stop.
…because the absolute paths are converted mistakenly to relative. If I manually edit the file and change the paths to relative like so:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := \
../../../src/main/jni/Android.mk \
../../../src/main/jni/myNativeSectionTextProvider.cpp \
LOCAL_C_INCLUDES += ../../../src/main/jni
LOCAL_C_INCLUDES += ../../../src/debug/jni
include $(BUILD_SHARED_LIBRARY)
...I then get this error:
/Users/clifton/dev/Multi/MultiAndroid/lib/build/ndk/debug/../../../src/main/jni/com_craig_multiandroid_app_NativeSectionTextProvider.h:2:17: fatal error: jni.h: No such file or directory
My question is what can I do to fix this? I started to hack my own custom gradle support for .aar builds but got lost trying to figure out which Gradle task is responsible for generating the .aar file. (The Gradle docs, while plentiful, make it difficult to find the details on a specific Android Gradle task API.) I have a partially working gradle.build which will run ndk-build via cmd line, generate the .so but I can't figure out how to (or even if I should) inline the .so inside the .aar. I am using Android Studio 0.5.7 and Gradle 1.11. I've pulled Gradle source a few months ago which is how I figured out how to inline the .so and gdbserver files in a regular .apk project but those rules don't seem to apply to .aar projects. Has anyone else attempted this? Where can I go for answers?