I have an Android project that links together a bunch of sources into a single monolithic JNI library. I would like to split this single library out into multiple smaller libraries with some dependencies between them. How can I achieve this with the new gradle build system?
-
1Hello, I have the exact same concern, have you found a way to achieve this? Regards. – Alejandro Zurcher Apr 01 '16 at 18:11
1 Answers
You can achieve this with the standalone android native plugin from the experimental gradle plugin family. The new plugins are based on the gradle component approach towards modeling builds. There are many advantages to using the new system.
For example:
root
+ lib -> 'com.android.model.native'
+ lub -> 'com.android.model.native'
+ aar -> 'com.android.model.library'
+ app -> 'com.android.model.application'
build.gradle
configure([project(':lib'), project(':lub'), project(':aar'), project(':app')]) {
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha5'
}
}
}
lib/build.gradle
apply plugin: "com.android.model.native"
model {
android {
compileSdkVersion 23
ndk {
moduleName "foo"
}
sources {
main {
jni {
exportedHeaders {
srcDir "src/main/headers"
}
}
}
}
}
lub/build.gradle
apply plugin: "com.android.model.native"
model {
android {
compileSdkVersion 23
ndk {
moduleName "bar"
}
sources {
main {
jni {
exportedHeaders {
srcDir "include"
}
}
}
}
}
aar/build.gradle
apply plugin: "com.android.model.library"
model {
android {
buildToolsVersion '23.0.2'
compileSdkVersion 23
ndk {
moduleName "aggregate-jni"
stl "stlport_shared" // using cpp?
}
sources {
main {
jni {
dependencies {
project ":lib"
project ":lub"
}
}
}
}
}
app/build.gradle
apply plugin: 'com.android.model.application'
model {
android {
buildToolsVersion '23.0.2'
compileSdkVersion 23
defaultConfig {
applicationId "com.example.app"
minSdkVersion.apiLevel 21
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
}
}
}
dependencies {
compile project(':aar')
}
If linkage is dynamic (default for ndk), the aar will contain:
libfoo.so libbar.so libaggregate-jni.so libstlport.so
and your mirror java classes. You can simply
System.load("aggregate-jni");
in your java classes and referenced libraries will load too. If linkage is static, you'll end up with a single libaggregate-jni.so
anyway. Note that it's bad to link a bunch of things statically against the stl as you will end up with multiple copies of the stl in your binary. This can really mess things up.
Note that the default gcc
toolchain is now deprecated. It's probably best to use:
model {
android {
ndk {
toolchain 'clang'
stl 'c++_shared'
}
}
}
Finally, you absolutely don't need an aar, I simply included it for completeness. The app project can depend directly on standalone native lib projects as the application plugin fully support the ndk, too.
-
My experience in c is limited, so excuse a couple ignorant questions: 1) What is 'lub'? 2) The exported headers field is just the location of the c header files, nothing special? Same thing we'd feed to LOCAL_C_INCLUDES before? – Anthony Mar 08 '16 at 18:47
-
@Anthony re #2 yes. It's the location of headers which constitute the public API of the component you are linking against. Other gradle projects need to know where to find headers for components they depend upon. – dcow Mar 08 '16 at 22:38
-
Have you successfully created multiple dependencies? `dependencies { project ":lib" project ":lub" }` only grabs the first project. If I swap them the missing dependencies switch, but it doesn't seem to add both. – Anthony Mar 12 '16 at 22:41
-
@Anthony multiple dependencies work for me. What aspect isn't working for you? – dcow Mar 13 '16 at 15:55
-
Basically whichever dependency comes second leads to a ton of "undefined reference" related to the second dependency. If I swap the order of the dependencies then I get the same thing in the other library. I started a question for it, we could continue discussion there so credit can be given if we figure it out: http://stackoverflow.com/questions/35964577/android-native-dependencies – Anthony Mar 13 '16 at 20:01