AAR libraries can contain native dependencies that the Android Gradle Plugin can consume. AGP is also capable of producing AARs that expose native libraries to their consumers.
Using native dependencies
Starting with Android Gradle plugin 4.0, C/C++ dependencies can be imported from
AARs linked in your build.gradle file. Gradle will automatically make these
available to the native build system, but your build system must be configured
to make use of the imported libraries and headers. Since C/C++ dependencies are
distributed as AARs, the following links about generic AARs may be helpful:
- Creating an Android Library for generic AAR documentation and how to integrate it into your project, especially when you want to use the AAR as a local C/C++ dependency.
- Add build dependencies for information on adding dependencies to your
build.gradlefile, especially for the remote dependencies.
This document focuses on how to configure your native build system and assumes you've already added a C/C++ dependency AAR into your project's Gradle build environment.
Native dependencies in AARs
AAR dependencies of your Gradle modules can expose native libraries for use by
your application. Inside the AAR, the prefab directory contains a Prefab
package, which includes the headers and libraries of the native dependency.
Each dependency can expose at most one Prefab package, which comprises one or more modules. A Prefab module is a single library, which could be either a shared, static, or header only library.
The package and module names need to be known to make use of the libraries. By convention the package name will match the Maven artifact name and the module name will match the C/C++ library name, but this is not required. Consult the dependency's documentation to determine what names it uses.
Build system configuration
The prefab feature must be enabled for your Android Gradle module.
To do so, add the following to the android block of your module's
build.gradle file:
Kotlin
buildFeatures { prefab = true }
Groovy
buildFeatures { prefab true }
Optionally, configure a version
in your project's gradle.properties file:
android.prefabVersion=2.0.0
Typically the default version selected AGP will fit your needs. You should only need to select a different version if there is a bug you need to work around or a new feature you want.
Each dependency exposes an Android.mk file to your build. These are
imported with the import-module command. This command searches for Android.mk
files with the given path within the build's import directories (as configured
by import-add-path) and exposes the modules it defines to be used in your
build. For example, if your application defines libapp.so and it uses cURL,
your Android.mk file should include the following:
include $(CLEAR_VARS)
LOCAL_MODULE := libapp
LOCAL_SRC_FILES := app.cpp
LOCAL_SHARED_LIBRARIES := curl
include $(BUILD_SHARED_LIBRARY)
# If you don't need your project to build with NDKs older than r21, you can omit
# this block.
ifneq ($(call ndk-major-at-least,21),true)
$(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH))
endif
$(call import-module,prefab/curl)
Note that the explicit import-add-path is only required when using NDKs prior
to r21. As of r21 NDK_GRADLE_INJECTED_IMPORT_PATH will automatically be
added to the import paths.
app.cpp is now able to #include "curl/curl.h", libapp.so will be
automatically linked against libcurl.so when building, and libcurl.so will
be included with the app.
Publishing native libraries in AARs
The ability to create native AARs was first added in AGP 4.1.
To export your native libraries, add the following to the android block of
your library project's build.gradle.kts file:
Kotlin
buildFeatures { prefabPublishing = true } prefab { create("mylibrary") { headers = "src/main/cpp/mylibrary/include" } create("myotherlibrary") { headers = "src/main/cpp/myotherlibrary/include" } }
Groovy
buildFeatures { prefabPublishing true } prefab { mylibrary { headers "src/main/cpp/mylibrary/include" } myotherlibrary { headers "src/main/cpp/myotherlibrary/include" } }
In this example, the mylibrary and myotherlibrary libraries from either your
ndk-build or CMake external native build will be packaged in the AAR produced by
your build, and each will export the headers from the specified directory to
their dependents.