Android AAR package for native library - android

I'm looking for a way to package a native library into an AAR package, so it would be possible to use it via dependencies declaration in gradle script.
By native library I mean set of .cpp files or compiled static library and a set of header files. So, I mean that the app itself will call the library from native code, not from Java. In other words, the library needed to compile app's native code. So that it will be possible to easily manage dependencies of native code.
Is it even possible?
So far I could only find a lot of questions/examples of how to make an AAR of JNI native library with .so file and its Java interface, so the lib just a Java lib with native implementation, but this is not what I need.

= UPDATE 2020-06-20 =
Nowadays, there is a nice plugin for that, works pretty well.
Thanks to its author and to #Paulo Costa for pointing to it.
= OBSOLETE =
Found the following hacky solution to the problem:
Use Android Experimental Gradle plugin version 0.9.1.
The idea is to put library headers and static libraries into .aar.
The headers are put to ndkLibs/include and static libs to ndkLibs/<arch> for each architecture. Then, in the app, or another lib which depends on this packed lib we just extract ndkLibs directory from AAR to the build directory in the project. See the example gradle file below.
The build.gradle file for the library with comments:
apply plugin: "com.android.model.library"
model {
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.2'
defaultConfig {
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 9
versionCode = 1
versionName = '1.0'
}
ndk {
platformVersion = 21
moduleName = "mylib"
toolchain = 'clang'
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64']) //this is default
ldLibs.addAll(['android', 'log'])
stl = 'c++_static'
cppFlags.add("-std=c++11")
cppFlags.add("-fexceptions")
cppFlags.add("-frtti")
//Add include path to be able to find headers from other AAR libraries
cppFlags.add("-I" + projectDir.getAbsolutePath() + "/build/ndkLibs/include")
}
//For each ABI add link-time library search path to be able to link against other AAR libraries
abis {
create("armeabi") {
ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/armeabi")
}
create("armeabi-v7a") {
ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/armeabi-v7a")
}
create("arm64-v8a") {
ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/arm64-v8a")
}
create("x86") {
ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/x86")
}
create("x86_64") {
ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/x86_64")
}
create("mips") {
ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/mips")
}
create("mips64") {
ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/mips64")
}
}
}
//Configure this library source files
android.sources {
main {
jni {
//This does not affect AAR packaging
exportedHeaders {
srcDir "../../src/"
}
//This tells which source files to compile
source {
srcDirs '../../src'
}
}
}
}
}
//Custom Maven repository URLs to download AAR files from
repositories {
maven {
url 'https://dl.bintray.com/igagis/android/'
}
}
//Our custom AAR dependencies, those in turn are also packed to AAR using the same approach
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'io.github.igagis:libutki:+'
compile 'io.github.igagis:libsvgdom:+'
compile 'org.cairographics:cairo:+'
}
//===================================
//=== Extract NDK files from AARs ===
//This is to automatically extract ndkLibs directory from AAR to build directory before compiling any sources
task extractNDKLibs {
doLast {
configurations.compile.each {
def file = it.absoluteFile
copy {
from zipTree(file)
into "build/"
include "ndkLibs/**/*"
}
}
}
}
build.dependsOn('extractNDKLibs')
tasks.whenTaskAdded { task ->
if (task.name.startsWith('compile')) {
task.dependsOn('extractNDKLibs')
}
}
//=================================
//=== pack library files to aar ===
//This stuff re-packs the release AAR file adding headers and static libs to there, but removing all shared (.so) libs, as we don't need them. The resulting AAR is put to the project root directory and can be uploaded to Maven along with POM file (you need to write one by hand).
def aarName = name
task copyNdkLibsToAAR(type: Zip) {
baseName = aarName
version = "\$(version)"
extension = 'aar.in'
destinationDir = file('..') //put resulting AAR file to upper level directory
from zipTree("build/outputs/aar/" + aarName + "-release.aar")
exclude('**/*.so') //do not include shared libraries into final AAR
from("../../src") {
exclude('makefile')
exclude('soname.txt')
exclude('**/*.cpp')
exclude('**/*.c')
into('ndkLibs/include')
}
from("build/intermediates/binaries/debug/lib"){
include('**/*.a')
into('ndkLibs')
}
}
build.finalizedBy('copyNdkLibsToAAR')

Manually hacking the gradle scripts works, but is painful and error-prone.
I've recently found a plugin that magically bundles the headers into the AAR files and extracts them and sets up the build scripts when adding the dependency: https://github.com/howardpang/androidNativeBundle
On the reusable library:
Add the export plugin:
apply plugin: 'com.ydq.android.gradle.native-aar.export'
Define where the header files are:
nativeBundleExport {
headerDir = "${project.projectDir}/src/main/jni/include"
}
On the module that uses it:
Add the import plugin:
apply plugin: 'com.ydq.android.gradle.native-aar.import'
add include ${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK} to each module that depends on it in your Android.mk:
include $(CLEAR_VARS)
LOCAL_SRC_FILES := myapp.cpp \
LOCAL_MODULE := myapp
LOCAL_LDLIBS += -llog
include ${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK}
include $(BUILD_SHARED_LIBRARY)

From this Link, it doesn't look like it is possible. I am pasting below the contents:
Anatomy of an AAR file
The file extension for an AAR file is .aar, and the Maven artifact type should be aar as well. The file itself is a zip file containing the following mandatory entries:
/AndroidManifest.xml
/classes.jar
/res/
/R.txt
Additionally, an AAR file may include one or more of the following optional entries:
/assets/
/libs/name.jar
/jni/abi_name/name.so (where abi_name is one of the Android supported ABIs)
/proguard.txt
/lint.jar
As said above, the mandatory entry includes a jar. You can however can give a try by manually deleting the jar file by unzipping the aar and zip back again. I am not sure whether it will work though.

Although i haven't personally tried to, i found a number of steps here:
Probably indirectly [tried with shared lib once a while ago], and I personally do not think it is worthwhile:
build your lib first to generate a static lib, and one aar
[model.library does not tuck *.a into libs directory though]
unzip your aar, and put *.a into libs folder
find a place for your headers file
zip it up back to aar inside your app, make aar to be your dependent lib, so it will be extracted into exploded-aar folder; then the colorful picture appears.
add the intermediate explodeded aar directory into include path
I think it is too hacky and may not be a good idea to impose those into your customers.
traditional way of distributing lib and header files directly is still better, comparing to the above hacking.
For building libs, cmake way is much better, checkout hello-libs in master-cmake branch, hope this helps

Related

How do I publish an AAR to Maven Local With JavaDocs

I need to publish my android library (aar) using Gradle to Maven local repo.
But the publication script needs to also generate the Javadocs, while ONLY including Public and Protected methods and classes.
Can't seem to find any information online, especially about the Javadocs part...
Help, I never published a library before.
Ok, after much research I found a solution, so I'm going to share it here if anyone will need this. (I don't want you to be frustrated like I was).
1) Create an android library as a new module inside your project.
2) Inside the build gradle of your library place this code:
plugins {
id 'com.android.library'
id 'maven-publish'
}
android {
nothing special here...
}
This is the code for creating the Javadocs(still inside build.gradle):
task androidJavadocs(type: Javadoc){
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
android.libraryVariants.all{ variant->
if (variant.name == 'release'){
owner.classpath += variant.javaCompileProvider.get().classpath
}
}
// excluding a specific class from being documented
exclude '**/NameOfClassToExclude.java'
title = null
options{
doclet = "com.google.doclava.Doclava"
docletpath = [file("libs/doclava-1.0.6.jar")]
noTimestamp = false
// show only Protected & Public
memberLevel = JavadocMemberLevel.PROTECTED
}
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs){
archiveClassifier.set('javadoc')
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar){
archiveClassifier.set('sources')
from android.sourceSets.main.java.srcDirs
}
This is to publish the library to MavenLocal(still inside build.gradle):
afterEvaluate {
publishing{
publications{
release(MavenPublication){
groupId = "com.example.mylibrary"
artifactId = "mycoollibrary"
version = "1.0"
// Applies the component for the release build variant
from components.release
// Adds javadocs and sources as separate jars.
artifact androidSourcesJar
artifact androidJavadocsJar
}
}
}
}
Your default dependencies block:
dependencies {
your dependencies...
}
3) Now you can download the doclava doclet:
Extract the zip, copy the doclava-1.0.6.jar and paste it into your LibraryName/libs folder (can be found using the project view).
You only need doclava if you want to be able to use #hide.
With this annotation, you can exclude specific methods from your Javadocs.
4) Build and publish your library:
Find the gradle tab at the top right side of android studio, or find it from the toolbar View->Tool Windows->Gradle.
Now find your library -> tasks -> publishing -> publishReleasePublicationToMavenLocal.
5) To consume the library from another project:
Go to the settings.gradle file (of the consuming project) and add MavenLocal() as the first repository in the the dependencyResolutionManagement block.
And inside the module build gradle add your library as a dependency:
dependencies{
implementation 'com.example.mylibrary:mycoollibrary:1.0'
}

Error when building project with NDK support after updating to Android Studio 4.0 from 3.6

After updating Android Studio to 4.0 project build finishes with error
More than one file was found with OS independent path 'lib/armeabi-v7a/libdlib.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake
The link leads to the page with New features in Android Studio Preview which is 4.1
EDIT
Actually you can find information that is linked in Google cache:
Automatic packaging of prebuilt dependencies used by CMake
What is stated there is:
Prior versions of the Android Gradle Plugin required that you explicitly package any prebuilt libraries used by your CMake external native build by using jniLibs. With Android Gradle Plugin 4.0, the above configuration is no longer necessary and will result in a build failure:
But it is not the case for me
Here are build.gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
cFlags "-O3"
cppFlags "-std=c++11 -frtti -fexceptions -mfpu=neon"
arguments "-DANDROID_PLATFORM=android-16",
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_STL=c++_shared",
"-DANDROID_ARM_NEON=TRUE",
"-DANDROID_CPP_FEATURES=rtti exceptions"
}
}
}
buildTypes {
debug {}
stage {
debuggable true
minifyEnabled false
}
release {
minifyEnabled false
}
}
kotlinOptions {
jvmTarget = "1.8"
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
packagingOptions {
pickFirst "**/libc++_shared.so"
pickFirst "**/libdlib.so"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.annotation:annotation:1.1.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
and CMakeLists.txt
set(LIB_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs)
#
cmake_minimum_required(VERSION 3.4.1)
add_library(dlib SHARED IMPORTED)
# sets the location of the prebuilt dlib .so
set_target_properties( dlib
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libdlib.so )
# ------------------------------------------------------------------
add_library( # Sets the name of the library.
face-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
face-lib.cpp)
target_include_directories(
face-lib PRIVATE
${CMAKE_SOURCE_DIR}/include
)
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)
target_link_libraries( # Specifies the target library.
face-lib
dlib
# Links the target library to the log library
# included in the NDK.
${log-lib})
Ok, So I have found the solution, I have added this to the module with my native libraries:
packagingOptions {
pickFirst "**/libdlib.so"
}
I don't like it as it, as it fixes the consequences, not the root cause.
If somebody has a better solution please post it here.
Another solution that worked is pointed in #GavinAndre answer
The main point is that if you are using Cmake, then don't store your .so in jniLibs folder.
Move them to another folder for example cmakeLibs.
For example:
set_target_properties( dlib
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../cmakeLibs/${ANDROID_ABI}/libdlib.so )
I faced the same problem.
That is how my gradle file written:
sourceSets {
main {
jniLibs.srcDirs 'src/main/cpp/libs'
}
}
Actually there is two .so files in the folder and since the link see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake seems to show the infomation That Andrioid Stuido will automatic packaging libs for you.
So I just DELETE this content inner my gradle file and everything works fine.
According to https://developer.android.com/studio/projects/gradle-external-native-builds#jniLibs
If you are using Android Gradle Plugin 4.0, move any libraries that are used by IMPORTED CMake targets out of your jniLibs directory to avoid this error.
So you only need to move the ${ANDROID_ABI}/libdlib.so folder to another place such as creating a new directory name cmakeLibs
eg:
set_target_properties( dlib
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../cmakeLibs/${ANDROID_ABI}/libdlib.so )
Ok, So I have found the solution, I have added this to the module with my native libraries:
andrid{
packagingOptions {
pickFirst "**/lib/**"
}
}
On my side seemed that jniLibs as name of the folder was triggering erroneously the error. changing the name of the folder to something else (i used 'libraries') both in the path of filesystem and the cmakelists.txt solved the problem.
cmakelists.txt fragment
# import library and set path
add_library(ixxs-plugin SHARED IMPORTED) # or STATIC instead of SHARED
set_target_properties(ixxs-plugin PROPERTIES
IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/../libraries/${CMAKE_ANDROID_ARCH_ABI}/libixxs-plugin.so"
)
nothing had to be done on the gradle file, it will find automatically the libs and put them into the aar file. you can unzip the aar file to check that. (libs are in {nameofaar}/jni/{arch_type}/{nameoflib}.so)
According to https://developer.android.com/studio/releases/gradle-plugin#cmake-imported-targets, I fix More than one file was found with OS independent path 'lib/armeabi-v7a/libfreetype.so' in my npm package #flyskywhy/react-native-gcanvas when >= com.android.tools.build:gradle:4.0.0 (means react-native >= 0.64) in /androidbuild.gradle
If you have two modules(such as SDKWrapper SDK), SDKWrapper building depends on SDK, you cannot implementation SDK in gradle.
eg.
asks.whenTaskAdded { task ->
if (task.name == 'externalNativeBuildRelease') {
task.dependsOn ":SDK:externalNativeBuildRelease"
} else if (task.name == 'externalNativeBuildDebug') {
task.dependsOn ":SDK:externalNativeBuildDebug"
}}
remove implementation
implementation Project(path:'SDK')

How to extract specific folder contents from jar file using gradle

I am new in gradle and looking a Gradle task to extract some specific folder from dependency(jar file). I have created a nativelib folder under src/main/nativeLib and want to copy all native libraries which are inside of native jar.
Basically this native jar already added in my central repo and it contains native libs(.so files) inside a lib. I have added this native jar as dependencies in my gradle.build and now want to first extract all contents from this jar-->lib folder and place in nativelib and then set a jniLibs like this:
android {
sourceSets
{
main {
jniLibs.srcDirs = ['src/main/nativelib']
}
}
}
gradle dependencies:
dependencies {
compile 'com.hospitality.android:liblinphone-sdk-native:3.2.1'
}
Can someone help me out.
Try using this:
apply plugin: 'java'
apply plugin: 'application'
android {
sourceSets
{
main {
jniLibs.srcDirs = ['src/main/nativelib']
}
}
}
build.dependsOn(copyToLib)
task copyToLib(type: Copy) {
into "$buildDir/output/libs"
from configurations.runtime
}
see if this works and it copies to output/libs.

Android Gradle Adding static library

In old traditional android ndk we will specify the static library to be linked in the Android.mk file.
Android.mk
PLATFORM_PREFIX := /opt/android-ext/
LOCAL_PATH := $(PLATFORM_PREFIX)/lib
include $(CLEAR_VARS)
LOCAL_MODULE := library
LOCAL_SRC_FILES := library.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_STATIC_LIBRARIES := android_native_app_glue library
Here is my Question
I am little bit Confused when switching to Gradle experimental plugin for NDK. Share your ideas on how to link Static library in App build.gradle file.
I had followed the latest gradle experimental plug-in documentation given here.
Have a look at this sample.
Tell the compiler where the headers are (in android.ndk{}):
CFlags += "-I${file("path/to/headers")}".toString()
cppFlags += CFlags
Tell the linker where the .a file is (in android.ndk{} or where
defining the flavors - make sure to add abiFilter - for example
abiFilters += "armeabi-v7")
ldFlags += "-L${file(path/to/library.a)}".toString()
ldLibs += ["nameOfLibrary"]
Note that the name of the library by convention is the string after
"lib" in the .a file name. For example, for a file named libNative.a
you should add ldLibs += ["native"] to gradle.
Create a new module and use apply plugin: 'java' to apply java plugin. In the build.gradle write the necessary code to get and place the .a file in the appropriate directory (where you will get it from your module which is using it). Don't forget to add a dependency in the module using the library (compile project(':libraryModule') in dependencies{}) and to include it in the project in settings.gradle file with include ':libraryModule'. If you want to place the module in a specified by you folder (for example where currently your Android.mk file is), just add project(':libraryModule').projectDir = new File(settingsDir, 'path/to/module').
That should do it.
The above answers work around gradle's prior insufficient NDK integration. This answer illustrates new gradle integration with the NDK.
Take a look at this proposed sample written against gradle 2.9 and the android plugin 0.6.0-alpha1. In constrast to how the question is posed, this answer contains a separate project for the library. This functionality can be explored to allow gradle to build that library before it is used by the app project. The other answers rely on the presumption that the library had already been built.
The :secondlib com.android.model.application builds libsecondlib.so (loaded in Java code with System.loadLibrary("secondlib"). The name 'secondlib' is poorly named. I like to think of it as a .so "wrapper" for all other native libraries linked for use by the app.
That shared library is statically linked against firstlib.a as built by the :firstlib com.android.model.native.
The headers are exported from the :firstlib to any dependent projects (:secondlib in this example) as per the exportedHeaders clause. This way dependent projects know how to link against the .so/.a. This replaces the CFlags+="-I/path/to/headers" syntax in a prior answer.
:secondlib links against :firstlib statically as per the following clause:
android.sources {
main {
jni {
dependencies {
project ":firstlib" buildType "debug" linkage "static"
}
}
// TODO(proppy): show jniLibs dependencies on .so
}
}
As shown by the comment, the example is incomplete. The finishing syntax is shown in the 'NDK Dependencies' section of the experimental android plugin documentation. Within that document the syntax for how to statically link instead of dynamically link should be clear.
There are currently some shortcomings (e.g. the buildType of the dependency shown above is by default 'debug' and not the current buildType being built).
EDIT: Here is a work-in-progress sample of the new dependencies syntax in app/build.gradle pulled out of one of my projects:
android.sources {
main {
jni {
//for exportedHeaders
dependencies { project ":libfoo" linkage "shared" }
}
jniLibs {
//Where the swig wrapped library .so is. I use swig to create code to interface with libfoo.so within :app
source { srcDirs 'libs' }
//for file in $(model.repositories.libs.libfoo)
dependencies { library "libfoo" }
}
}
}
repositories {
libs(PrebuiltLibraries) {
libevdev {
//headers already available from our libfoo project via exportedHeaders
//headers.srcDir "../libfoo/src/main/jni/"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("../libfoo/build/intermediates/binaries/debug/lib/${targetPlatform.getName()}/libfoo.so")
}
}
}
}
Conceptually, apk is zip of manifest,native files and class library.
So if you copy the static library to output it will work.
So in gradle you should use the copy task and make these library as part of output.
I just used below for my so files and it worked.
task copyNativeLibs2h(type: Copy) {
from(new File(getProjectDir(), 'libs')) { include '**/*.so' }
into new File(buildDir, 'native-libs')
}
tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn copyNativeLibs2h }
You cannot build a static library with gradle, even with the experimental plugin. You can use a prebuilt library, or build it with ndk-build and link it into the shared object with the gradle plugin.
Here is an example:
Assume that we have this directory structure:
project (build.gradle, gradle.properties, etc.)
jni_static (Application.mk, Android.mk, cpp files for the static lib)
app (build.gradle, src/main, etc.)
jni_shared (cpp files for the shared lib)
And here are the relevant pieces of project/app/build.gradle:
// look for NDK directory
import org.apache.tools.ant.taskdefs.condition.Os
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkBuild = properties.getProperty('ndk.dir') + '/ndk-build'
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
ndkBuild += '.cmd'
}
apply plugin: 'com.android.model.application'
… dependencies, model { compileOptions, etc.
// static lib is built with ndk-build
def LOCAL_MODULE = "static"
def appAbi = "armeabi-v7a"
def ndkOut = "build/intermediates/$LOCAL_MODULE"
def staticLibPath = "$ndkOut/local/$appAbi/lib${LOCAL_MODULE}.a"
// To guarantee that the intermediates shared library is always refreshed,
// we delete it in gradle task rmSO.
task rmSO(type: Delete) {
delete 'build/intermediates/binaries/debug/lib/armeabi-v7a', 'libshared.so'
delete 'build/intermediates/binaries/debug/obj/armeabi-v7a', 'libshared.so'
}
// in file jni/Android.mk there is a section for LOCAL_MODULE=static
// which builds the static library
task buildStaticLib(type: Exec, description: 'Compile Static lib via NDK') {
commandLine "$ndkBuild", "$staticLibPath", "NDK_APPLICATION_MK=../jni_static/Application.mk",
"NDK_PROJECT_PATH=../jni_static", "NDK_OUT=$ndkOut"
dependsOn rmSO
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
commandLine "$ndkBuild", "clean", "NDK_APPLICATION_MK=../jni_static/Application.mk",
"NDK_PROJECT_PATH=../jni_static", "NDK_OUT=$ndkOut"
}
clean.dependsOn cleanNative
tasks.all {
task ->
// link of the shared library depends on build of the static lib
if (task.name.startsWith('link')) {
task.dependsOn buildStaticLib
}
// before build, make sure the intermediate so is not stuck there
if (task.name.startsWith('package')) {
task.dependsOn rmSO
}
}
// build the wrapper shared lib around the static lib using the experimental plugin
model {
android.ndk {
moduleName = "shared"
cppFlags += "-std=c++11"
ldFlags += "$staticLibPath".toString()
ldLibs += "log"
stl = "gnustl_static"
abiFilters += "$appAbi".toString()
}
android.sources {
main.jni.source {
srcDirs = ["jni_shared"]
}
}
}
Important: the sources for the shared lib should be in a separate directory, so that the sources of the static library are not in it or under it. This because the experimental plugin cannot exclude some files under srcDirs.

Android library project is not getting included in Gradle build

This query is continuation to my previous question as i did not get answer so i am requesting here. My previous question can be found here (android - gradle multiproject include and exclude libraries)
With productFlavors, one can avoid include and exclude library projects to main project.
In my case,
ProjectA----- MainProject,
LibA ---- Library project,
LibB ---- Library project,
....
LibA classes are used in ProjectA.
LibB classes are not used any where. Its just a library but required as part of ProjectA.apk(Mentioned only in ProjectA manifest file)
After "gradle build", in build/classes/flavor/debug or release/packageName/.. only LibA classes are there. LibB classes are not there in build/classes/.. path and LibB functionality is not working. (Note: The same is working fine with eclipse build)
LibB classes are getting included if by importing LibB classes in ProjectA but LibB is like plug and play type library and not required for all the time.
LibB build.gradle file is as follows:
buildscript {
repositories {mavenCentral()}
dependencies {
classpath 'com.android.tools.build:gradle:0.3'}
}
apply plugin: 'android-library'
android {
compileSdkVersion 14
sourceSets {
main {
manifest {srcFile 'AndroidManifest.xml'}
java {srcDir 'src'}
res {srcDir 'res'}
assets {srcDir 'assets'}
resources {srcDir 'src'}
jni {srcDir 'jni'}
}
}
task configureRelease << {
proguard.enabled = true
}
}
How to get include LibB? Please guide me resolving this issue.
Thanks in advance
You need add dependencies node...
dependencies {
compile project(':LibB')
}
android {
XXX
}

Categories

Resources