Link the static library to the Android JNI shared library

I'm new to Android, so forgive me if this seems a bit interesting. I have two ready-made static libraries, feta ( ../../feta/build/libfeta.a ) and mish ( ../../mish/build/libmish.a ), and I have a common JNI library. Using the JNI library works fine, but I'm trying to access feta and mish through the JNI library. These two libraries are constantly changing and updating with the Android project, so copying them every time they are created is actually not an option (if that even fixed the binding problem), and I would prefer not to simply copy the source files to the project Android

I tried searching, but most answers use the old version of the system and want me to change Android.mk , which I don’t have. I use the latest version of Android Studio, it uses the Gradle plugin.

I tried using the entire configuration from over a dozen Stackoverflow guides and answers in different settings, but no luck.

If you answer, provide a complete and working build.gradle , so I do not encounter the same problems that I received from the other answers (thanks!).

I asked this question after the next this tutorial, so all files will reflect this.

Here is the build error I get:

 Error:A problem occurred configuring project ':app'. > The following model rules could not be applied due to unbound inputs and/or subjects: android.sources { ... } @ app/build.gradle line 58, column 5 subject: - android.sources Object [*] repositories { ... } @ app/build.gradle line 39, column 5 subject: - repositories Object [*] [*] - indicates that a model item could not be found for the path or type. 

Here is my build.gradle file inside the app module:

 apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.neonorb.mish_android" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags "-std=c++14 -Wno-implicit-exception-spec-mismatch" } } ndk { // ${targetPlatform.getName()} // ${buildType.getName()} stl "c++_static" abiFilters "x86_64" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } externalNativeBuild { cmake { path "CMakeLists.txt" } } } model { repositories { libs(PrebuiltLibraries) { feta { headers.srcDir "../../feta/include/" binaries.withType(StaticLibraryBinary) { staticLibraryFile = file("../../feta/build/libfeta.a") } } } libs(PrebuiltLibraries) { mish { headers.srcDir "../../mish/include/" binaries.withType(StaticLibraryBinary) { staticLibraryFile = file("../../mish/build/libmish.a") } } } } android.sources { main { jni { dependencies { library "feta" linkage "static" library "mish" linkage "static" } } } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.1.0' compile 'com.google.android.gms:play-services-ads:10.0.1' compile 'com.android.support:design:25.1.0' testCompile 'junit:junit:4.12' } 

And here is the root directory ( mish-android ) one:

 // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir } 

And here is my CMakeLists.txt :

 # Sets the minimum version of CMake required to build the native # library. You should either keep the default value or only pass a # value of 3.4.0 or lower. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds it for you. # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. mish-android # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). # Associated headers in the same location as their source # file are automatically included. src/main/cpp/mish.cpp ) # Searches for a specified prebuilt library and stores the path as a # variable. Because system libraries are included in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in the # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. mish-android # Links the target library to the log library # included in the NDK. ${log-lib} ) 

Here's my directory structure, if it helps at all.

enter image description here

+5
source share
1 answer

As it turned out, I needed to update the Gradle plugin. I was able to remove CMakeLists.txt . I also needed to upgrade the Gradle version of the wrapper version 3.2 to support the new experimental plugin.

Here is my build.gradle root:

 // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { //classpath 'com.android.tools.build:gradle:2.2.3' classpath 'com.android.tools.build:gradle-experimental:0.9.0-beta1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir } 

Here is my app build.gradle :

 apply plugin: 'com.android.model.application' model { android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.neonorb.mish_android" minSdkVersion.apiLevel 15 targetSdkVersion.apiLevel 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } ndk { moduleName "mish-android" ldLibs.add("log") cppFlags.add("-std=c++14") cppFlags.add("-Wno-implicit-exception-spec-mismatch") // ${targetPlatform.getName()} // ${buildType.getName()} stl "c++_static" abiFilters.addAll(["x86_64"]) // only build for x86_64 because that all Feta and Mish support atm } buildTypes { release { minifyEnabled false proguardFiles.add(file("proguard-rules.pro")) } } sources { main { jni { source { srcDir "src" } dependencies { library "feta" linkage "static" library "mish" linkage "static" } } } } } repositories { libs(PrebuiltLibraries) { feta { headers.srcDir "../../feta/include/" binaries.withType(StaticLibraryBinary) { staticLibraryFile = file("../../feta/build/libfeta.a") } } } libs(PrebuiltLibraries) { mish { headers.srcDir "../../mish/include/" binaries.withType(StaticLibraryBinary) { staticLibraryFile = file("../../mish/build/libmish.a") } } } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.1.0' testCompile 'junit:junit:4.12' } 
0
source

Source: https://habr.com/ru/post/1262226/


All Articles