= 2020 年 6 月 20 日更新 =
如今,有一个不错的插件,效果很好。感谢它的作者和@Paulo Costa 指向它。
= 已过时 =
找到了以下解决问题的方法:
使用 Android Experimental Gradle 插件版本 0.9.1。这个想法是将库头和静态库放入.aar。每个架构的头文件ndkLibs/include
和静态库都被放入。ndkLibs/<arch>
然后,在应用程序或依赖于这个打包库的另一个库中,我们只需ndkLibs
将目录从 AAR 提取到build
项目中的目录。请参阅下面的示例 gradle 文件。
带有注释的build.gradle
库文件:
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')