xref: /aosp_15_r20/external/fbjni/docs/android_setup.md (revision 65c59e023c5336bbd4a23be7af78407e3d80e7e7)
1## Android Build Setup
2
3**These instructions require the Android Gradle Build Plugin 4.0.0 or newer
4as it relies on the new [prefab](https://android-developers.googleblog.com/2020/02/native-dependencies-in-android-studio-40.html) integration.
5Check below for a pre-4.0.0 workaround.**
6
7```groovy
8repositories {
9  maven {
10    mavenCentral()
11  }
12}
13
14android {
15  dependencies {
16    implementation 'com.facebook.fbjni:fbjni:0.2.2'
17  }
18}
19```
20
21Now, in your CMake setup, you can refer to the `fbjni` package. The header files (e.g. `fbjni.h`)
22will available implicitly.
23
24```cmake
25set(build_DIR ${CMAKE_SOURCE_DIR}/build)
26set(PACKAGE_NAME "myapp")
27
28find_package(fbjni REQUIRED CONFIG)
29
30target_link_libraries(${PACKAGE_NAME} fbjni::fbjni mylibrary)
31```
32
33## Android Build Setup (pre-4.0.0)
34
35The Android Gradle plugin does not provide built-in support for artifacts that
36include native libraries (for linking against) and header files. Because of
37that, some manual additions to your build system are required. The following
38is an example of what this can look like but by no means prescriptive.
39
40In your app-specific `build.gradle`:
41
42```groovy
43repositories {
44  maven {
45    jcenter()
46  }
47}
48
49android {
50  // Create new configurations that can be referred to in dependencies.
51  // The Android Gradle Plugin 3.* does not allow hooking into existing
52  // configurations like `implementation`.
53  configurations {
54    extractHeaders
55    extractJNI
56  }
57
58  dependencies {
59    implementation 'com.facebook.fbjni:fbjni:0.0.1'
60    // If headers are required.
61    extractHeaders 'com.facebook.fbjni:fbjni:0.0.1:headers'
62    // If the `.so` files are required for linking.
63    extractJNI 'com.facebook.fbjni:fbjni:0.0.1'
64  }
65}
66
67task extractAARHeaders {
68    doLast {
69        configurations.extractHeaders.files.each {
70            def file = it.absoluteFile
71            copy {
72                from zipTree(file)
73                into "$buildDir/$file.name"
74                include "**/*.h"
75            }
76        }
77    }
78}
79
80task extractJNIFiles {
81    doLast {
82        configurations.extractJNI.files.each {
83            def file = it.absoluteFile
84            copy {
85                from zipTree(file)
86                into "$buildDir/$file.name"
87                include "jni/**/*"
88            }
89        }
90    }
91}
92
93tasks.whenTaskAdded { task ->
94    if (task.name.contains('externalNativeBuild')) {
95        task.dependsOn(extractAARHeaders)
96        task.dependsOn(extractJNIFiles)
97    }
98}
99```
100
101With this setup in place, prior to any native build jobs, the header files
102and JNI shared libraries will be extracted under the build directory.
103
104Now, in your CMake setup, you can refer to the extracted paths:
105
106```cmake
107set(build_DIR ${CMAKE_SOURCE_DIR}/build)
108set(PACKAGE_NAME "myapp")
109
110file(GLOB libfbjni_link_DIRS "${build_DIR}/fbjni*.aar/jni/${ANDROID_ABI}")
111file(GLOB libfbjni_include_DIRS "${build_DIR}/fbjni-*-headers.jar/")
112
113find_library(FBJNI_LIBRARY fbjni PATHS ${libfbjni_link_DIRS}
114NO_CMAKE_FIND_ROOT_PATH)
115
116target_include_directories(${PACKAGE_NAME} PRIVATE
117  // Additional header directories here
118  ${libfbjni_include_DIRS}
119)
120target_link_libraries(${PACKAGE_NAME} ${FBJNI_LIBRARY} mylibrary)
121```
122