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