10

I have an android_library.aar file that containing library.so and some other resources and java files.

I imported android_library.aar to my project. My project uses c++ code with NDK. My problem is I can not compile C++ code that dependent with library.so with CMake. How could I extract library.so from aar before CMake compile? I want to include library.so to my C++ code directly without java. I know how to include .so in a project but I don't know how to do it from inside of aar.

4
  • 1
    Very nice indeed! I believe that gradle does extract the .so files if the .aar is a dependency. Commented Sep 3, 2018 at 14:50
  • I thought so. But it does not extract before cmake build. I don't know why. I searched for it and did not find any answer easy than this method. Commented Sep 6, 2018 at 0:05
  • … but in your solution the aar is not declared as dependency of your project, s it? Commented Sep 6, 2018 at 4:54
  • 1
    It's also must declare library as dependency. Because of Java part of library. I don't know much about dependency decleration also affecting to JNI part or not. Commented Sep 6, 2018 at 15:09

2 Answers 2

3

I found a solution on my own after 1-week research. I found some code from Google GVR code. But it hasn't worked for my case. I changed build.dependsOn to preBuild.dependsOn then it worked. It might help some people in the future.

Here is the example code:

In the module's build.gradle file:

sourceSets { main { jniLibs.srcDirs = ["jniLibs"] } } task extractSo(type: Copy) { println 'Extracting *.so file(s)....' from zipTree("${project.rootDir}/ModuleName/ModuleName.aar") into "${project.rootDir}/${project.name}/src/main/jniLibs/" include "jni/**/*.so" eachFile { def segments = it.getRelativePath().getSegments() as List println segments it.setPath(segments.tail().join("/")) return it } includeEmptyDirs = false } preBuild.dependsOn extractSo 
Sign up to request clarification or add additional context in comments.

Comments

2

Nowadays this is possible without much boiler plate. Prerequisite is that your AAR file includes a prefab folder. So the library maintainer needs to properly set things up.

If this is the case then it's as easy as adding following to app/build.gradle:

android { // ... buildFeatures { prefab true // extracts native libraries from AAR for usage in C++ } } 

Then in CMakeLists.txt you can find and register the lib:

# Locate the native library: find_package(ModuleName REQUIRED CONFIG) # Replace ModuleName with the actual name of your module. # It can be found in `prefab/prefab.json` file of your AAR. target_link_libraries( app ModuleName::nameOfSoFileWithoutFileEnding ) 

Example with the OpenCV AAR library on Maven:

# ... find_package(OpenCV REQUIRED CONFIG) target_link_libraries( app OpenCV::opencv_java4 ) 

This will register opencv_java4.so that is part of the AAR file. The C++ header files would be added as well.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.