Files
Schnappix/node_modules/react-native-reanimated/android/build.gradle
T

367 lines
13 KiB
Groovy

import com.android.build.gradle.tasks.ExternalNativeBuildJsonTask
import groovy.json.JsonSlurper
import java.nio.file.Paths
import org.apache.tools.ant.taskdefs.condition.Os
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
def safeAppExtGet(prop, fallback) {
def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
appProject?.ext?.has(prop) ? appProject.ext.get(prop) : fallback
}
def isNewArchitectureEnabled() {
// To opt-in for the New Architecture, you can either:
// - Set `newArchEnabled` to true inside the `gradle.properties` file
// - Invoke gradle with `-newArchEnabled=true`
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}
def resolveReactNativeDirectory() {
def reactNativeLocation = safeAppExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
if (reactNativeLocation != null) {
return file(reactNativeLocation)
}
// Fallback to node resolver for custom directory structures like monorepos.
def reactNativePackage = file(
providers.exec {
workingDir(rootDir)
commandLine("node", "--print", "require.resolve('react-native/package.json')")
}.standardOutput.asText.get().trim()
)
if (reactNativePackage.exists()) {
return reactNativePackage.parentFile
}
throw new GradleException(
"[Reanimated] Unable to resolve react-native location in node_modules. You should set project extension property (in `app/build.gradle`) named `REACT_NATIVE_NODE_MODULES_DIR` with the path to react-native in node_modules."
)
}
def resolveReactNativeWorkletsDirectory() {
def reactNativeWorkletsLocation = safeAppExtGet("REACT_NATIVE_WORKLETS_NODE_MODULES_DIR", null)
if (reactNativeWorkletsLocation != null) {
return file(reactNativeWorkletsLocation)
}
// Fallback to node resolver for custom directory structures like monorepos.
def reactNativeWorkletsPackage = file(
providers.exec {
workingDir(rootDir)
commandLine("node", "--print", "require.resolve('react-native-worklets/package.json')")
}.standardOutput.asText.get().trim()
)
if (reactNativeWorkletsPackage.exists()) {
return reactNativeWorkletsPackage.parentFile
}
throw new GradleException(
"[Reanimated] Unable to resolve react-native-worklets location in node_modules. You should set project extension property (in `app/build.gradle`) named `REACT_NATIVE_WORKLETS_NODE_MODULES_DIR` with the path to react-native-worklets in node_modules."
)
}
def getReactNativeVersion() {
def reactNativeRootDir = resolveReactNativeDirectory()
def reactProperties = new Properties()
file("$reactNativeRootDir/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
return reactProperties.getProperty("VERSION_NAME")
}
def getReactNativeMinorVersion() {
def reactNativeVersion = getReactNativeVersion()
return reactNativeVersion.startsWith("0.0.0-") ? 1000 : reactNativeVersion.split("\\.")[1].toInteger()
}
def getReanimatedVersion() {
def inputFile = file(projectDir.path + '/../package.json')
def json = new JsonSlurper().parseText(inputFile.text)
return json.version
}
def toPlatformFileString(String path) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
path = path.replace(File.separatorChar, '/' as char)
}
return path
}
def getReanimatedStaticFeatureFlags() {
def featureFlags = new HashMap<String, String>()
def staticFeatureFlagsFile = file(projectDir.path + "/../src/featureFlags/staticFlags.json")
if (!staticFeatureFlagsFile.exists()) {
throw new GradleException("[Reanimated] Feature flags file not found at ${staticFeatureFlagsFile.absolutePath}.")
}
new JsonSlurper().parseText(staticFeatureFlagsFile.text).each { key, value ->
featureFlags[key] = value.toString()
}
def packageJsonFile = file(rootDir.path + "/../package.json")
if (packageJsonFile.exists()) {
def packageJson = new JsonSlurper().parseText(packageJsonFile.text)
packageJson.reanimated?.staticFeatureFlags?.each { key, value ->
featureFlags[key] = value.toString()
}
}
return featureFlags.collect { key, value -> "[${key}:${value}]" }.join("")
}
if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}
def packageDir = project.projectDir.parentFile
def reactNativeRootDir = resolveReactNativeDirectory()
def reactNativeWorkletsRootDir = resolveReactNativeWorkletsDirectory()
def REACT_NATIVE_MINOR_VERSION = getReactNativeMinorVersion()
def REACT_NATIVE_VERSION = getReactNativeVersion()
def REANIMATED_VERSION = getReanimatedVersion()
def IS_NEW_ARCHITECTURE_ENABLED = isNewArchitectureEnabled()
def IS_REANIMATED_EXAMPLE_APP = safeAppExtGet("isReanimatedExampleApp", false)
def REANIMATED_PROFILING = safeAppExtGet("enableReanimatedProfiling", false)
def REANIMATED_FEATURE_FLAGS = getReanimatedStaticFeatureFlags()
// Set version for prefab
version REANIMATED_VERSION
def reanimatedPrefabHeadersDir = project.file("$buildDir/prefab-headers/reanimated")
def reactNativeArchitectures() {
def value = project.getProperties().get("reactNativeArchitectures")
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:8.2.1"
classpath "de.undercouch:gradle-download-task:5.6.0"
classpath "com.diffplug.spotless:spotless-plugin-gradle:6.25.0"
}
}
if (project == rootProject) {
apply from: "spotless.gradle"
}
apply plugin: "com.android.library"
apply plugin: "maven-publish"
apply plugin: "de.undercouch.download"
android {
compileSdkVersion safeExtGet("compileSdkVersion", 34)
namespace "com.swmansion.reanimated"
if (rootProject.hasProperty("ndkPath")) {
ndkPath rootProject.ext.ndkPath
}
if (rootProject.hasProperty("ndkVersion")) {
ndkVersion rootProject.ext.ndkVersion
}
buildFeatures {
prefab true
prefabPublishing true
buildConfig true
}
prefab {
reanimated {
headers reanimatedPrefabHeadersDir.absolutePath
}
}
defaultConfig {
minSdkVersion safeExtGet("minSdkVersion", 23)
targetSdkVersion safeExtGet("targetSdkVersion", 34)
versionCode 1
versionName REANIMATED_VERSION
buildConfigField("boolean", "REANIMATED_PROFILING", REANIMATED_PROFILING.toString())
buildConfigField("String", "REANIMATED_VERSION_JAVA", "\"${REANIMATED_VERSION}\"")
buildConfigField("boolean", "IS_INTERNAL_BUILD", "false")
buildConfigField("int", "EXOPACKAGE_FLAGS", "0")
buildConfigField("int", "REACT_NATIVE_MINOR_VERSION", REACT_NATIVE_MINOR_VERSION.toString())
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared",
"-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
"-DANDROID_TOOLCHAIN=clang",
"-DREACT_NATIVE_DIR=${toPlatformFileString(reactNativeRootDir.path)}",
"-DREACT_NATIVE_WORKLETS_DIR=${toPlatformFileString(reactNativeWorkletsRootDir.path)}",
"-DIS_REANIMATED_EXAMPLE_APP=${IS_REANIMATED_EXAMPLE_APP}",
"-DREANIMATED_PROFILING=${REANIMATED_PROFILING}",
"-DREANIMATED_VERSION=${REANIMATED_VERSION}",
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON",
"-DREANIMATED_FEATURE_FLAGS=${REANIMATED_FEATURE_FLAGS}"
abiFilters (*reactNativeArchitectures())
targets("reanimated")
}
}
consumerProguardFiles 'proguard-rules.pro'
}
externalNativeBuild {
cmake {
version = System.getenv("CMAKE_VERSION") ?: "3.22.1"
path "CMakeLists.txt"
}
}
buildTypes {
debug {
packagingOptions {
doNotStrip "**/**/*.so"
}
}
}
lintOptions {
abortOnError false
}
packagingOptions {
// For some reason gradle only complains about the duplicated version of librrc_root and libreact_render libraries
// while there are more libraries copied in intermediates folder of the lib build directory, we exclude
// only the ones that make the build fail (ideally we should only include libreanimated but we
// are only allowed to specify exclude patterns)
excludes = [
"META-INF",
"META-INF/**",
"**/libc++_shared.so",
"**/libfbjni.so",
"**/libjsi.so",
"**/libfolly_json.so",
"**/libfolly_runtime.so",
"**/libglog.so",
"**/libhermes.so",
"**/libhermesvm.so",
"**/libhermes-executor-debug.so",
"**/libhermes_executor.so",
"**/libhermestooling.so",
"**/libreactnativejni.so",
"**/libturbomodulejsijni.so",
"**/libreactnative.so",
"**/libreact_nativemodule_core.so",
"**/libreact_render*.so",
"**/librrc_root.so",
"**/libjscexecutor.so",
]
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
tasks.withType(ExternalNativeBuildJsonTask) {
compileTask ->
compileTask.doLast {
if (!IS_REANIMATED_EXAMPLE_APP) {
return
}
def generated = new File("${compileTask.abi.getCxxBuildFolder()}/compile_commands.json")
def output = new File("${packageDir}/compile_commands.json")
output.text = generated.text
println("Generated clangd metadata.")
}
}
}
def validateReactNativeVersionResult = providers.exec {
workingDir(projectDir.path)
commandLine("node", "./../scripts/validate-react-native-version.js", REACT_NATIVE_VERSION.toString())
ignoreExitValue = true
}
task assertMinimalReactNativeVersionTask {
doFirst {
if (validateReactNativeVersionResult.getResult().get().exitValue != 0) {
throw new GradleException(validateReactNativeVersionResult.getStandardError().getAsText().get().trim())
}
}
}
preBuild.dependsOn(assertMinimalReactNativeVersionTask)
task assertNewArchitectureEnabledTask {
onlyIf { !IS_NEW_ARCHITECTURE_ENABLED }
doFirst {
throw new GradleException("[Reanimated] Reanimated requires new architecture to be enabled. Please enable it by setting `newArchEnabled` to `true` in `gradle.properties`.")
}
}
preBuild.dependsOn(assertNewArchitectureEnabledTask)
def validateWorkletsBuildResult = providers.exec {
workingDir(projectDir.path)
commandLine("node", "./../scripts/validate-worklets-build.js")
ignoreExitValue = true
}
task assertWorkletsVersionTask {
doFirst {
if (validateWorkletsBuildResult.getResult().get().exitValue != 0) {
throw new GradleException(validateWorkletsBuildResult.getStandardError().getAsText().get().trim())
}
}
}
preBuild.dependsOn(assertWorkletsVersionTask)
task prepareReanimatedHeadersForPrefabs(type: Copy) {
from("$projectDir/src/main/cpp")
from("$projectDir/../Common/cpp")
include("reanimated/**/*.h")
into(reanimatedPrefabHeadersDir)
}
task cleanCmakeCache() {
tasks.getByName("clean").dependsOn(cleanCmakeCache)
doFirst {
delete "${projectDir}/.cxx"
}
}
repositories {
mavenCentral()
google()
}
dependencies {
implementation "com.facebook.yoga:proguard-annotations:1.19.0"
implementation "androidx.transition:transition:1.1.0"
implementation "androidx.core:core:1.6.0"
implementation "com.facebook.react:react-android" // version substituted by RNGP
if (project == rootProject) {
// This is needed for linting in Reanimated's repo.
} else {
if (rootProject.subprojects.find { it.name == "react-native-worklets" }) {
implementation project(":react-native-worklets")
} else {
throw new GradleException("[Reanimated] `react-native-worklets` library not found. Please install it as a dependency in your project. Install `react-native-worklets` with your package manager, i.e. `yarn add react-native-worklets` or `npm i react-native-worklets`. Read the documentation for more details: https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#unable-to-find-a-specification-for-rnworklets-depended-upon-by-rnreanimated")
}
}
}
preBuild.dependsOn(prepareReanimatedHeadersForPrefabs)
if (project != rootProject) {
evaluationDependsOn(":react-native-worklets")
afterEvaluate {
tasks.getByName("externalNativeBuildDebug").dependsOn(findProject(":react-native-worklets").tasks.getByName("externalNativeBuildDebug"))
tasks.getByName("externalNativeBuildRelease").dependsOn(findProject(":react-native-worklets").tasks.getByName("externalNativeBuildRelease"))
}
}