Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include Pre-compiled Static LIbrary using NDK

I am looking to include a static library that is pre-compiled in my Android Studio NDK project. I am using Android Studio 1.0.1, and any solutions that attempt this problem on SO seem outdated (or involves creating a library project and including it).

The structure is as follows:

app
/--src
/--main
/--java
+--jni
+--jniLibs
   /--armeabi
       /--libpng.a
    --armeabiv7
       /--libpng.a
    ...(for each abi)

I am attempting to include the library libpng. I tried creating jniLibs (as per ph0b (awesome guide, btw) and adding libpng.a to the respective ABI folder. This still gives me the error - cannot find -llibpng when I try to compile with the below code:

ndk {
        moduleName "game" 
        cFlags "-std=c++11 -fexceptions -DANDROID -I${project.buildDir}/../src/main/jni/include \
                -I${project.buildDir}/../src/main/jni/include/png"
        ldLibs "EGL", "GLESv3", "dl", "log", "android", "libpng"
        stl "gnustl_static"
}
like image 203
zmartin Avatar asked Dec 17 '14 18:12

zmartin


People also ask

What compiler does NDK use?

Overview. The Clang compiler in the NDK is useable with only minimal configuration required to define your target environment.


3 Answers

This now works properly via the experimental plugin.

For a full description, see this whole excellent article, which is where I'm taking this from, but I am also using it myself and it works.

This is my build.gradle - note that in my case it's for a library project, and I'm using static links rather than shared.

buildscript {
    dependencies
            {
                classpath "com.android.tools.build:gradle-experimental:0.7.0-alpha3"
            }
}
apply plugin: 'com.android.model.library'

model {
    repositories {
        libs(PrebuiltLibraries) {
            v8_base {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_base.a")
                }
            }
            v8_libbase {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_libbase.a")
                }
            }
            v8_libplatform {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_libplatform.a")
                }
            }
            v8_nosnapshot {
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("src/main/jni/libs/${targetPlatform.getName()}/libv8_nosnapshot.a")
                }
            }
        }
    }

    android {

        compileSdkVersion 23
        buildToolsVersion "23.0.2"

        sources {
            main {
                jni {
                    source {
                        srcDir "src/main/jni"
                    }
                    dependencies {
                        library "v8_base" linkage "static"
                        library "v8_libbase" linkage "static"
                        library "v8_libplatform" linkage "static"
                        library "v8_nosnapshot" linkage "static"
                    }
                }
            }
        }

        ndk {
            moduleName "v8example"
            cppFlags.add("-std=c++11")
            cppFlags.add("-I${file("src/main/jni/include")}".toString())
            cppFlags.add("-fexceptions")
            ldLibs.add("log")
            stl "stlport_static"
            abiFilters.add("armeabi armeabi-v7a x86")
        }
    }
}

The alternative is that you use the old Gradle approach of calling ndkBuild yourself, thus using the .mk files. That also works fine but you lose the nice integration with Android Studio, e.g. your jni files showing up appropriately.

like image 55
Rob Pridham Avatar answered Nov 05 '22 07:11

Rob Pridham


Adding .so Library in Android Studio 1.0.2

  1. Create Folder "jniLibs" inside "src/main/"
  2. Put all your .so libraries inside "src/main/jniLibs" folder
  3. Folder structure looks like,
    |--app:
    |--|--src:
    |--|--|--main
    |--|--|--|--jniLibs
    |--|--|--|--|--armeabi
    |--|--|--|--|--|--.so Files
  4. No extra code requires just sync your project and run your application.

    Reference
    https://github.com/commonsguy/sqlcipher-gradle/tree/master/src/main
like image 20
Vasanth Avatar answered Nov 05 '22 08:11

Vasanth


As ndk support is now limited in gradle, you could try this for static libraries of different abi.

    ndk {
        moduleName "game" 
        ....
        ldLibs ..., file(projectDir).absolutePath+"/src/main/jniLibs/\$(TARGET_ARCH_ABI)/libpng.a"
        ....
    }
like image 1
user4958329 Avatar answered Nov 05 '22 09:11

user4958329