Tuesday, May 22, 2018

Android Gradle - how to include shared object with specific folder structure?

Leave a Comment

Normally when you use Android Gradle package, you can include individual shared objects (.so's) using configuration parameter jniLibs.srcDirs. .so file gets included in flat manner. But what if I want to include plugins into their own correspondent sub-folders ?

Also taking into account product flavors ?

I have uploaded at least one demo project over here:

https://sourceforge.net/p/syncproj/code/HEAD/tree/sampleScripts/AndroidGradlePackage

(In case if you want to play around by yourself - it's slightly simplified Android java-c++ project).

Currently folder structure is following:

bin\Debug\armeabi-v7a\libnative_lib.so 

I want to add folder structure like this:

bin\Debug\armeabi-v7a\plugins bin\Debug\armeabi-v7a\plugins\test1 bin\Debug\armeabi-v7a\plugins\test1\test1.so 

There exists bug report over here: https://issuetracker.google.com/issues/63707864

with status 'Won't fix' - but if this is not fixed - maybe there are some walkaround to it ?

I have tried at least what is mentioned on that page - plugins folder structure gets created, with *so.recipe files inside, but no .so files for some reason - someone seems to filter .so out of there.

Most interesting thing is that generated file build\native-libs\native-libs.jar indeed contains 1. *.so and 2. *.so.recipe files, but only 2nd gets included.

One of solutions mentioned over here:

https://medium.com/keepsafe-engineering/the-perils-of-loading-native-libraries-on-android-befa49dce2db

Attempts to replace java's 'System.loadLibrary' - but aren't there any simpler solution to this ?

So this solution can include *.so.recipe into .apk package: (Just in case if you want to try to continue with my approach) (Must be applied to project link above after dependencies)

dependencies {         implementation 'com.android.support.constraint:constraint-layout:1.0.2'         // See (*)         compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')     }    // See (*) task nativeLibsToJar(type: Zip) {     destinationDir file("$buildDir/native-libs")     baseName 'native-libs'     extension 'jar'     from fileTree(dir: getCurrentConfigAbiDir() + "/plugins", include: '**/*.so*')     // '/lib/armeabi-v7a' - same folder as in .apk package     into '/lib/' + getCurrentAbiFolder() + "/plugins" }  // // (*) Walk around issue of not being able to add files recursively from sub-folders as well. // https://issuetracker.google.com/issues/63707864 // tasks.withType(JavaCompile) {     compileTask -> compileTask.dependsOn(nativeLibsToJar) }  //------------------------------------------------------------------------------------------------ // Helper functions //------------------------------------------------------------------------------------------------  // //  Gets current Abi folder name, empty if not detected - for example "armeabi-v7a" // String getCurrentAbiFolder() {     String[] props = getCommandLineArgs()     if( props.length != 2 )         return ""      String platform = props[0]     String config = props[1]     String r = ""      android.productFlavors.all { flavour ->         if( flavour.name.toLowerCase() == platform.toLowerCase() )             r = flavour.ndk.abiFilters.first().toLowerCase()     }      // println r     return r }   String getCurrentConfigAbiDir() {     String dirToZip = "DoesNotExists"      String[] props = getCommandLineArgs()     if( props.length != 2 )         return dirToZip      String platform = props[0]     String config = props[1]      android.productFlavors.all { flavour ->         if( flavour.name.toLowerCase() == platform.toLowerCase() )             dirToZip = "bin/" + config + "/" + flavour.ndk.abiFilters.first().toLowerCase()     }      // println dirToZip     return dirToZip } 

0 Answers

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment