268 lines
9.2 KiB
Groovy
268 lines
9.2 KiB
Groovy
|
/*
|
||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||
|
*
|
||
|
* This source code is licensed under the MIT license found in the
|
||
|
* LICENSE file in the root directory of this source tree.
|
||
|
*/
|
||
|
|
||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||
|
|
||
|
plugins {
|
||
|
id("de.undercouch.download")
|
||
|
id("com.android.library")
|
||
|
id("maven-publish")
|
||
|
id("signing")
|
||
|
}
|
||
|
|
||
|
group = "com.facebook.react"
|
||
|
version = parent.publishing_version
|
||
|
def cmakeVersion = parent.cmake_version
|
||
|
|
||
|
/**
|
||
|
* We use the bundled version of CMake in the Android SDK if available, to don't force Android
|
||
|
* users to install CMake externally.
|
||
|
*/
|
||
|
def findCmakePath(cmakeVersion) {
|
||
|
def cmakeRelativePath = "/cmake/${cmakeVersion}/bin/cmake"
|
||
|
if (System.getenv("ANDROID_SDK_ROOT") && new File("${System.getenv("ANDROID_SDK_ROOT")}/${cmakeRelativePath}").exists()) {
|
||
|
return "${System.getenv("ANDROID_SDK_ROOT")}/${cmakeRelativePath}"
|
||
|
}
|
||
|
if (System.getenv("ANDROID_HOME") && new File("${System.getenv("ANDROID_HOME")}/${cmakeRelativePath}").exists()) {
|
||
|
return "${System.getenv("ANDROID_HOME")}/${cmakeRelativePath}"
|
||
|
}
|
||
|
return "cmake"
|
||
|
}
|
||
|
|
||
|
def reactNativeRootDir = project(':packages:react-native:ReactAndroid').projectDir.parent;
|
||
|
def customDownloadDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
|
||
|
def downloadsDir = customDownloadDir ? new File(customDownloadDir) : new File(reactNativeRootDir, "sdks/download")
|
||
|
|
||
|
// By default we are going to download and unzip hermes inside the /sdks/hermes folder
|
||
|
// but you can provide an override for where the hermes source code is located.
|
||
|
def overrideHermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") != null
|
||
|
def hermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") ?: new File(reactNativeRootDir, "sdks/hermes")
|
||
|
def hermesBuildDir = new File("$buildDir/hermes")
|
||
|
|
||
|
def hermesVersion = "main"
|
||
|
def hermesVersionFile = new File(reactNativeRootDir, "sdks/.hermesversion")
|
||
|
if (hermesVersionFile.exists()) {
|
||
|
hermesVersion = hermesVersionFile.text
|
||
|
}
|
||
|
def ndkBuildJobs = Runtime.runtime.availableProcessors().toString()
|
||
|
def prefabHeadersDir = new File("$buildDir/prefab-headers")
|
||
|
|
||
|
// By setting REACT_NATIVE_HERMES_SKIP_PREFAB you can skip prefab publishing, to
|
||
|
// reduce the size of the Hermes published .AAR.
|
||
|
def skipPrefabPublishing = System.getenv("REACT_NATIVE_HERMES_SKIP_PREFAB") != null
|
||
|
|
||
|
// We inject the JSI directory used inside the Hermes build with the -DJSI_DIR config.
|
||
|
def jsiDir = new File(reactNativeRootDir, "ReactCommon/jsi")
|
||
|
|
||
|
task downloadHermes(type: Download) {
|
||
|
src("https://github.com/facebook/hermes/tarball/${hermesVersion}")
|
||
|
onlyIfModified(true)
|
||
|
overwrite(true)
|
||
|
useETag("all")
|
||
|
retries(5)
|
||
|
dest(new File(downloadsDir, "hermes.tar.gz"))
|
||
|
}
|
||
|
|
||
|
task installArchives {
|
||
|
dependsOn("publishAllPublicationsToNpmRepository")
|
||
|
}
|
||
|
|
||
|
task unzipHermes(dependsOn: downloadHermes, type: Copy) {
|
||
|
from(tarTree(downloadHermes.dest)) {
|
||
|
eachFile { file ->
|
||
|
// We flatten the unzip as the tarball contains a `facebook-hermes-<SHA>`
|
||
|
// folder at the top level.
|
||
|
if (file.relativePath.segments.size() > 1) {
|
||
|
file.relativePath = new org.gradle.api.file.RelativePath(!file.isDirectory(), file.relativePath.segments.drop(1))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
into(hermesDir)
|
||
|
}
|
||
|
|
||
|
task configureBuildForHermes(type: Exec) {
|
||
|
workingDir(hermesDir)
|
||
|
commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), Os.isFamily(Os.FAMILY_WINDOWS) ? "-GNMake Makefiles" : "", "-S", ".", "-B", hermesBuildDir.toString(), "-DJSI_DIR=" + jsiDir.absolutePath))
|
||
|
}
|
||
|
|
||
|
task buildHermes(dependsOn: configureBuildForHermes, type: Exec) {
|
||
|
workingDir(hermesDir)
|
||
|
commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), "--build", hermesBuildDir.toString(), "--target", "hermesc", "-j", ndkBuildJobs))
|
||
|
}
|
||
|
|
||
|
task prepareHeadersForPrefab(type: Copy) {
|
||
|
from("$hermesDir/API")
|
||
|
from("$hermesDir/public")
|
||
|
include("**/*.h")
|
||
|
exclude("jsi/**")
|
||
|
into(prefabHeadersDir)
|
||
|
}
|
||
|
|
||
|
static def windowsAwareCommandLine(String... commands) {
|
||
|
def newCommands = []
|
||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||
|
newCommands = ['cmd', '/c']
|
||
|
}
|
||
|
newCommands.addAll(commands)
|
||
|
return newCommands
|
||
|
}
|
||
|
|
||
|
def reactNativeArchitectures() {
|
||
|
def value = project.getProperties().get("reactNativeArchitectures")
|
||
|
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||
|
}
|
||
|
|
||
|
repositories {
|
||
|
// Normally RNGP will set repositories for all modules,
|
||
|
// but when consumed from source, we need to re-declare
|
||
|
// those repositories as there is no app module there.
|
||
|
mavenCentral()
|
||
|
google()
|
||
|
}
|
||
|
|
||
|
android {
|
||
|
compileSdkVersion 31
|
||
|
buildToolsVersion = "31.0.0"
|
||
|
namespace "com.facebook.hermes"
|
||
|
|
||
|
// Used to override the NDK path/version on internal CI or by allowing
|
||
|
// users to customize the NDK path/version from their root project (e.g. for M1 support)
|
||
|
if (rootProject.hasProperty("ndkPath")) {
|
||
|
ndkPath rootProject.ext.ndkPath
|
||
|
}
|
||
|
if (rootProject.hasProperty("ndkVersion")) {
|
||
|
ndkVersion rootProject.ext.ndkVersion
|
||
|
}
|
||
|
|
||
|
defaultConfig {
|
||
|
minSdkVersion 21
|
||
|
|
||
|
externalNativeBuild {
|
||
|
cmake {
|
||
|
arguments "-DHERMES_IS_ANDROID=True"
|
||
|
arguments "-DANDROID_STL=c++_shared"
|
||
|
arguments "-DANDROID_PIE=True"
|
||
|
arguments "-DIMPORT_HERMESC=${new File(hermesBuildDir, "ImportHermesc.cmake").toString()}"
|
||
|
arguments "-DJSI_DIR=${jsiDir}"
|
||
|
arguments "-DHERMES_SLOW_DEBUG=False"
|
||
|
arguments "-DHERMES_BUILD_SHARED_JSI=True"
|
||
|
arguments "-DHERMES_RELEASE_VERSION=for RN ${version}"
|
||
|
// We intentionally build Hermes with Intl support only. This is to simplify
|
||
|
// the build setup and to avoid overcomplicating the build-type matrix.
|
||
|
arguments "-DHERMES_ENABLE_INTL=True"
|
||
|
// Due to https://github.com/android/ndk/issues/1693 we're losing Android
|
||
|
// specific compilation flags. This can be removed once we moved to NDK 25/26
|
||
|
arguments "-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON"
|
||
|
targets "libhermes"
|
||
|
}
|
||
|
}
|
||
|
ndk {
|
||
|
abiFilters (*reactNativeArchitectures())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
externalNativeBuild {
|
||
|
cmake {
|
||
|
version cmakeVersion
|
||
|
path "$hermesDir/CMakeLists.txt"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
buildTypes {
|
||
|
debug {
|
||
|
externalNativeBuild {
|
||
|
cmake {
|
||
|
// JS developers aren't VM developers.
|
||
|
// Therefore we're passing as build type Release, to provide a faster build.
|
||
|
// This has the (unlucky) side effect of letting AGP call the build
|
||
|
// tasks `configureCMakeRelease` while is actually building the debug flavor.
|
||
|
arguments "-DCMAKE_BUILD_TYPE=Release"
|
||
|
// Adding -O3 to patch the issue here: https://github.com/android/ndk/issues/1740#issuecomment-1198438260
|
||
|
cppFlags "-O3"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
release {
|
||
|
externalNativeBuild {
|
||
|
cmake {
|
||
|
arguments "-DCMAKE_BUILD_TYPE=MinSizeRel"
|
||
|
// For release builds, we don't want to enable the Hermes Debugger.
|
||
|
arguments "-DHERMES_ENABLE_DEBUGGER=False"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sourceSets {
|
||
|
main {
|
||
|
manifest.srcFile "$hermesDir/android/hermes/src/main/AndroidManifest.xml"
|
||
|
java.srcDirs = [
|
||
|
"$hermesDir/lib/Platform/Intl/java"
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
buildFeatures {
|
||
|
prefab true
|
||
|
prefabPublishing !skipPrefabPublishing
|
||
|
}
|
||
|
|
||
|
dependencies {
|
||
|
implementation("com.facebook.fbjni:fbjni:0.3.0")
|
||
|
implementation("com.facebook.soloader:soloader:0.10.4")
|
||
|
implementation("com.facebook.yoga:proguard-annotations:1.19.0")
|
||
|
implementation("androidx.annotation:annotation:1.3.0")
|
||
|
}
|
||
|
|
||
|
packagingOptions {
|
||
|
exclude "**/libc++_shared.so"
|
||
|
exclude "**/libjsi.so"
|
||
|
exclude "**/libfbjni.so"
|
||
|
}
|
||
|
|
||
|
publishing {
|
||
|
multipleVariants {
|
||
|
withSourcesJar()
|
||
|
allVariants()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
prefab {
|
||
|
libhermes {
|
||
|
headers prefabHeadersDir.absolutePath
|
||
|
libraryName "libhermes"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
afterEvaluate {
|
||
|
if (!overrideHermesDir) {
|
||
|
// If you're not specifying a Hermes Path override, we want to
|
||
|
// download/unzip Hermes from Github then.
|
||
|
configureBuildForHermes.dependsOn(unzipHermes)
|
||
|
prepareHeadersForPrefab.dependsOn(unzipHermes)
|
||
|
}
|
||
|
preBuild.dependsOn(buildHermes)
|
||
|
preBuild.dependsOn(prepareHeadersForPrefab)
|
||
|
prepareHeadersForPrefab.dependsOn(buildHermes)
|
||
|
}
|
||
|
|
||
|
/* Publishing Configuration */
|
||
|
apply from: "../publish.gradle"
|
||
|
|
||
|
// We need to override the artifact ID as this project is called `hermes-engine` but
|
||
|
// the maven coordinates are on `hermes-android`.
|
||
|
// Please note that the original coordinates, `hermes-engine`, have been voided
|
||
|
// as they caused https://github.com/facebook/react-native/issues/35210
|
||
|
publishing {
|
||
|
publications {
|
||
|
getByName("release") {
|
||
|
artifactId 'hermes-android'
|
||
|
}
|
||
|
}
|
||
|
}
|