Jona
Jona

Reputation: 13545

How do we define multiple modules with the new NDK gradle based builder?

I'm attempting to learn and try using the new Android Studio gradle based ndk build support.

I'm having a hard time figuring out how to define PREBUILT_SHARED_LIBRARY ndk modules so that my main ndk module can use it. I have these setup using Android.mk but can't figure out how to convert that to gradle. :/

// SHARED LIBRARY
android.ndk {
    moduleName = "skia_android"
    cppFlags += "-I${file("src/main/jni/skia/skia/out/config/android-nexus_4/Debug/lib/libskia_android.so")}".toString()
    cppFlags += "-I${file("src/main/jni/skia/skia/include/core")}".toString()
    cppFlags += "-I${file("src/main/jni/skia/skia/include/utils")}".toString()
    cppFlags += "-I${file("src/main/jni/skia/skia/include/gpu")}".toString()
    cppFlags += "-I${file("src/main/jni/skia/skia/include/private")}".toString()
    ldLibs += ["EGL", "GLESv2"]
    stl    = "c++_static"
}

// MAIN LIBRARY
android.ndk {
    moduleName = "smasher"
    cppFlags += "-I${file("src/main/jni/smasher/include")}".toString()
    cppFlags += "-I${file("src/main/jni/smasher/src")}".toString()
    cppFlags += "-I${file("src/main/jni/smasher")}".toString()
    ldLibs += ["skia_android", "log", "android", "EGL", "GLESv2"]
    stl    = "c++_static"
    abiFilter "armeabi-v7a"
}

Upvotes: 5

Views: 3816

Answers (2)

dcow
dcow

Reputation: 7975

You can do this with the native standalone plugin. Just make sure you put the different libraries in different sub-projects as the experimental plugin does not support multiple modules in the same project (which is odd, because the native gradle plugins do).

http://tools.android.com/tech-docs/new-build-system/gradle-experimental

root
+ lib -> apply plugin: 'com.android.model.native'
+ app -> apply plugin: 'com.android.model.application'

app/build.gradle

model {
    android.sources {
        main {
            jni {
                dependencies {
                    project ":lib" 
                    // optional: 
                    // buildType "debug" productFlavor "flavor" linkage "static"
                }
            }
        }
    }
}

Upvotes: 0

Alex Cohn
Alex Cohn

Reputation: 57173

Update (Feb '16): the experimantal plugin allows native modules now! Not in the main, yet.


Unfortunately this is not supported by current gradle plugins. Specifically, currently there is no way to define native-only modules. I recommend to keep the traditional Android.mk which does this job reliably.

The trick is to disable the regular NDK build tasks, and inject a buildNative task instead:

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkBuild = properties.getProperty('ndk.dir') + '/ndk-build'

import org.apache.tools.ant.taskdefs.condition.Os
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
    ndkBuild += '.cmd'
}

task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
    commandLine '$ndkBuild', 'NDK_PROJECT_PATH="$jniSrc/..'
}

task cleanNative(type: Exec, description: 'Clean JNI object files') {
    commandLine '$ndkBuild', 'clean', 'NDK_PROJECT_PATH="$jniSrc/..'
}

clean.dependsOn 'cleanNative'

tasks.all {
    task ->
        if (task.name.startsWith('compile') && task.name.contains('MainC')) {
            task.enabled = false
        }
        if (task.name.startsWith('link')) {
            task.enabled = false
        }
        if (task.name.endsWith("SharedLibrary") ) {
            task.dependsOn buildNative
        }
}

Upvotes: 1

Related Questions