nativeBundle plugin is a gradle plugin that extend bundle task provided by android gradle plugin,it can help you publish c/c++ headers and other module that contain native source can dependent those module directly
- android gradle plugin 3.0.0 - 8.0.2
1.Android studio import this project
2.Enter 'gradlew publishToMavenLocal' command in Terminal or click 'publishToMavenLocal' task in gradle task list
3.Open settings.gradle, include 'app' project and build it
1.Edit your root build.gradle file, add classpath 'io.github.howardpang:androidNativeBundle:1.1.4' to the file
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
//Add androidNativeBundle dependency
classpath "io.github.howardpang:androidNativeBundle:1.1.4"
}
}
apply plugin: 'com.android.library'
apply plugin: 'com.ydq.android.gradle.native-aar.export' // must below android gradle plugin
2. Specify header path that you want to export, add following code segment to your lib build.gradle;
nativeBundleExport {
headerDir = "${project.projectDir}/src/main/jni/include"
//excludeHeaderFilter.add("**/**.cpp")
//includeHeaderFilter.add("**/**.h")
//bundleStatic = true
//extraStaticLibDir = "${project.projectDir}/xx"
//excludeStaticLibs.add("**/libmylib.a")
//excludeStaticLibs.add("**/libxx.a")
}
productFlavors {
flavorDimensions "default"
export {
dimension "default"
nativeBundleExport {
headerDir = "${project.projectDir}/src/main/jni/include"
//excludeHeaderFilter.add("**/**.cpp")
//includeHeaderFilter.add("**/**.h")
//bundleStatic = true
//extraStaticLibDir = "${project.projectDir}/xx"
//excludeStaticLibs.add("**/libmylib.a")
//excludeStaticLibs.add("**/libxx.a")
}
}
}
4.Because publish more than one static library will cause link order problem, so you can specify link order, for example libxx.a should link before libyy.a, like this:
nativeBundleExport {
headerDir = "${project.projectDir}/src/main/jni/include"
//excludeHeaderFilter.add("**/**.cpp")
//includeHeaderFilter.add("**/**.h")
bundleStatic = true
//extraStaticLibDir = "${project.projectDir}/xx"
//excludeStaticLibs.add("**/libmylib.a")
//excludeStaticLibs.add("**/libxx.a")
linkOrder = "libxx.a:libyy.a"
}
5. Android lib only packet shared library(so) to aar, this plugin can generate another aar to packet static library ,if you set 'bundleStatic',the plugin will gather static lib from 'externalNativeBuild' output dir default, you can specify other dir by set 'extraStaticLibDir' in 'nativeBundleExport', you can also exclude some static lib;
Default, the plugin will create a "bundleStaticLibRelease" task to packet the static bundle, but if you use flavours feature, the plugin will create "bundleStaticLib${flavourName}Release" for every flavour;
After you configure, you can add static publication to your publish script, like this:
publishing {
publications {
maven(MavenPublication) {
groupId 'com.ydq.android.native-aar'
artifactId "mylib"
artifact bundleRelease
}
mavenStaticBundle(MavenPublication) {
groupId 'com.ydq.android.native-aar'
artifactId "mylib-static"
artifact bundleStaticLibRelease
}
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.ydq.android.gradle.native-aar.import' // must below android gradle plugin
- ndkBuild: Add this line
include ${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK} #must be before "include $(BUILD_SHARED_LIBRARY)" or "include $(BUILD_STATIC_LIBRARY)"
to every module that you want in Android.mk, like this
include $(CLEAR_VARS)
LOCAL_SRC_FILES := myapp.cpp \
LOCAL_MODULE := myapp
LOCAL_LDLIBS += -llog
include ${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK} #must followed by "include $(BUILD_SHARED_LIBRARY)" or "include $(BUILD_STATIC_LIBRARY)"
include $(BUILD_SHARED_LIBRARY)
- cmake: Add this line
include (${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK})
to CMakeLists.txt; Then link modules if the target needed
target_link_libraries(<target> ${ANDROID_GRADLE_NATIVE_MODULES})
like this
cmake_minimum_required(VERSION 3.4.1)
project(echo LANGUAGES C CXX)
add_library(myapp
SHARED
myapp.cpp)
target_link_libraries(myapp
log
)
include (${ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK})
target_link_libraries(myapp ${ANDROID_GRADLE_NATIVE_MODULES})
target_compile_options(myapp
PRIVATE
-Wall -Werror)
- Add following line to every module you want like "externalNativeBuild:ndkBuild"
- Add macro
"ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK=${nativeBundleImport.ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK}"
to your ndk-build, like this
def execmd = ["$ndkbuildcmd", "-j${coreNum}", "V=1", "NDK_PORJECT_PATH=$buildDir",
"APP_BUILD_SCRIPT=$androidMKfile", "NDK_APPLICATION_MK=$applicationMKfile", "ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK=${nativeBundleImport.ANDROID_GRADLE_NATIVE_BUNDLE_PLUGIN_MK}"]
4. If you want to link some static library with whole archive, you can set it in build.gradle like this
nativeBundleImport {
wholeStaticLibs = "libxx.a:libyy.a" // Library is seperated by colon
}
5. If your module have below dependency , the plugin will put the so in to 'aar' and add it to native compile
dependencies {
implementation "com.my.group:module:1.0.0:armeabi-v7a@so"
implementation "com.my.group:module:1.0.0:armeabi-v7a@har" // contain 'headers'
}
6. If you don't want to add some dependency to native compile, for example, you have 'implementation "com.my.group:moduleA:1.0.0" ' dependency and it contain native interface, you can do like this
nativeBundleImport {
//wholeStaticLibs = "libxx.a:libyy.a" // Library is seperated by colon
excludeDependencies.add("com.my.group:moduleA")
excludeDependencies.add("com.my.group:moduleB")
}