1class KotlinExpoModulesCorePlugin implements Plugin<Project> { 2 void apply(Project project) { 3 project.buildscript { 4 project.ext.kotlinVersion = { 5 project.rootProject.ext.has("kotlinVersion") 6 ? project.rootProject.ext.get("kotlinVersion") 7 : "1.6.10" 8 } 9 } 10 } 11} 12 13ext.applyKotlinExpoModulesCorePlugin = { 14 apply plugin: KotlinExpoModulesCorePlugin 15} 16 17// [BEGIN] Remove when we drop SDK 47 18abstract class ExtractReactNativeAARTask extends DefaultTask { 19 @Input 20 abstract Property<String> getBuildType() 21 22 @Input 23 abstract Property<String> getReactNativeDir() 24 25 @TaskAction 26 def taskAction() { 27 def suffix = buildType.get() == 'Debug' ? '-debug' : '-release' 28 def rnAARs = project.fileTree("${reactNativeDir.get()}/android").matching { include "**/react-native/**/*${suffix}.aar" } 29 if (rnAARs.isEmpty()) { 30 rnAARs = project.fileTree("${reactNativeDir.get()}/android").matching { include "**/react-native/**/*.aar" } 31 } 32 if (rnAARs.any()) { 33 // node_modules/react-native has a .aar, extract headers 34 if (rnAARs.size() > 1) { 35 logger.error("More than one React Native AAR file has been found:") 36 rnAARs.each {println(it) } 37 throw new GradleException("Multiple React Native AARs found:\n${rnAARs.join("\n")}" + 38 "\nRemove the old ones and try again") 39 } 40 } 41 def rnAAR = rnAARs.singleFile 42 def file = rnAAR.absoluteFile 43 def packageName = file.name.tokenize('-')[0] 44 project.copy { 45 from project.zipTree(file) 46 into "${project.buildDir}/${packageName}" 47 include "jni/**/*" 48 } 49 } 50} 51 52class LegacyReactNativeLibsExtractionPlugin implements Plugin<Project> { 53 void nativeBuildDependsOn(project, dependsOnTask, buildTypesIncludes) { 54 def buildTasks = project.tasks.findAll { task -> 55 def taskName = task.name 56 if (taskName.contains("Clean")) { return false } 57 if (taskName.contains("externalNative") || taskName.contains("CMake") || taskName.contains("generateJsonModel")) { 58 if (buildTypesIncludes == null) { return true } 59 for (buildType in buildTypesIncludes) { 60 if (taskName.contains(buildType)) { return true } 61 } 62 } 63 return false 64 } 65 buildTasks.forEach { task -> task.dependsOn(dependsOnTask) } 66 } 67 68 void apply(Project project) { 69 def REACT_NATIVE_BUILD_FROM_SOURCE = project.findProject(":ReactAndroid") != null 70 def REACT_NATIVE_DIR = REACT_NATIVE_BUILD_FROM_SOURCE 71 ? project.findProject(":ReactAndroid").getProjectDir().parent 72 : new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, project.rootDir).text.trim()).parent 73 74 def reactProperties = new Properties() 75 new File("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) } 76 def FOLLY_VERSION = reactProperties.getProperty("FOLLY_VERSION") 77 def BOOST_VERSION = reactProperties.getProperty("BOOST_VERSION") 78 def DOUBLE_CONVERSION_VERSION = reactProperties.getProperty("DOUBLE_CONVERSION_VERSION") 79 def REACT_NATIVE_VERSION = System.getenv("REACT_NATIVE_OVERRIDE_VERSION") ?: reactProperties.getProperty("VERSION_NAME") 80 def REACT_NATIVE_TARGET_VERSION = REACT_NATIVE_VERSION.split("\\.")[1].toInteger() 81 82 def isNewArchitectureEnabled = project.findProperty("newArchEnabled") == "true" 83 def customDownloadsDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR") 84 def downloadsDir = customDownloadsDir ? new File(customDownloadsDir) : new File("${project.buildDir}/downloads") 85 def thirdPartyNdkDir = new File("${project.buildDir}/third-party-ndk") 86 def reactNativeThirdParty = new File("$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/third-party") 87 88 def createNativeDepsDirectories = project.tasks.findByName('createNativeDepsDirectories') ?: project.tasks.register('createNativeDepsDirectories') { 89 downloadsDir.mkdirs() 90 thirdPartyNdkDir.mkdirs() 91 } 92 93 def extractReactNativeAARRelease = project.tasks.register('extractReactNativeAARRelease', ExtractReactNativeAARTask) { 94 reactNativeDir = REACT_NATIVE_DIR 95 buildType = 'Release' 96 } 97 def extractReactNativeAARDebug = project.tasks.register('extractReactNativeAARDebug', ExtractReactNativeAARTask) { 98 reactNativeDir = REACT_NATIVE_DIR 99 buildType = 'Debug' 100 } 101 102 def packageReactNdkDebugLibs = project.tasks.register("packageReactNdkDebugLibs", Copy) { 103 dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck") 104 from("$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/prebuilt/lib") 105 into("${project.buildDir}/react-ndk/exported") 106 } 107 def packageReactNdkReleaseLibs = project.tasks.register("packageReactNdkReleaseLibs", Copy) { 108 dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck") 109 from("$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/prebuilt/lib") 110 into("${project.buildDir}/react-ndk/exported") 111 } 112 113 // [BEGIN] Extra libs 114 def downloadDoubleConversion = project.tasks.create('downloadDoubleConversion', project.Download) { 115 dependsOn(createNativeDepsDirectories) 116 src("https://github.com/google/double-conversion/archive/v${DOUBLE_CONVERSION_VERSION}.tar.gz") 117 onlyIfNewer(true) 118 overwrite(false) 119 dest(new File(downloadsDir, "double-conversion-${DOUBLE_CONVERSION_VERSION}.tar.gz")) 120 } 121 122 def prepareDoubleConversion = project.tasks.register('prepareDoubleConversion', Copy) { 123 dependsOn(downloadDoubleConversion) 124 from(project.tarTree(downloadDoubleConversion.dest)) 125 from("$reactNativeThirdParty/double-conversion/Android.mk") 126 include("double-conversion-${DOUBLE_CONVERSION_VERSION}/src/**/*", "Android.mk") 127 filesMatching("*/src/**/*", { fname -> fname.path = "double-conversion/${fname.name}" }) 128 includeEmptyDirs = false 129 into("$thirdPartyNdkDir/double-conversion") 130 } 131 132 def downloadFolly = project.tasks.create('downloadFolly', project.Download) { 133 dependsOn(createNativeDepsDirectories) 134 src("https://github.com/facebook/folly/archive/v${FOLLY_VERSION}.tar.gz") 135 onlyIfNewer(true) 136 overwrite(false) 137 dest(new File(downloadsDir, "folly-${FOLLY_VERSION}.tar.gz")) 138 } 139 140 def prepareFolly = project.tasks.register('prepareFolly', Copy) { 141 dependsOn(downloadFolly) 142 from(project.tarTree(downloadFolly.dest)) 143 from("$reactNativeThirdParty/folly/Android.mk") 144 include("folly-${FOLLY_VERSION}/folly/**/*", "Android.mk") 145 eachFile { fname -> fname.path = (fname.path - "folly-${FOLLY_VERSION}/") } 146 // Fixes problem with Folly failing to build on certain systems. See 147 // https://github.com/software-mansion/react-native-reanimated/issues/1024 148 def follyReplaceContent = ''' 149 ssize_t r; 150 do { 151 r = open(name, flags, mode); 152 } while (r == -1 && errno == EINTR); 153 return r; 154 ''' 155 filter { line -> line.replaceAll("return int\\(wrapNoInt\\(open, name, flags, mode\\)\\);", follyReplaceContent) } 156 includeEmptyDirs = false 157 into("$thirdPartyNdkDir/folly") 158 } 159 // [END] Extra libs 160 161 project.afterEvaluate { 162 if (REACT_NATIVE_BUILD_FROM_SOURCE) { 163 nativeBuildDependsOn(project, ":ReactAndroid:copyReleaseJniLibsProjectOnly", ["Release", "RelWithDebInfo"]) 164 nativeBuildDependsOn(project, ":ReactAndroid:copyDebugJniLibsProjectOnly", ["Debug"]) 165 } else { 166 nativeBuildDependsOn(project, extractReactNativeAARRelease, ["Release", "RelWithDebInfo"]) 167 nativeBuildDependsOn(project, extractReactNativeAARDebug, ["Debug"]) 168 } 169 170 def extraLibs = project.extensions.extraProperties.has('extraLegacyReactNativeLibs') 171 ? project.extensions.extraProperties.get('extraLegacyReactNativeLibs') 172 : [] 173 extraLibs.each { 174 nativeBuildDependsOn(project, project.tasks.named(it), null) 175 } 176 177 if (isNewArchitectureEnabled) { 178 def preDebugBuild = project.tasks.named('preDebugBuild') 179 def preReleaseBuild = project.tasks.named('preReleaseBuild') 180 preDebugBuild.configure { 181 dependsOn(packageReactNdkDebugLibs) 182 } 183 preReleaseBuild.configure { 184 dependsOn(packageReactNdkReleaseLibs) 185 } 186 187 // Due to a bug inside AGP, we have to explicitly set a dependency 188 // between configureCMake* tasks and the preBuild tasks. 189 // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732 190 project.tasks.named('configureCMakeDebug').configure { 191 dependsOn(preDebugBuild) 192 } 193 project.tasks.named('configureCMakeRelWithDebInfo').configure { 194 dependsOn(preReleaseBuild) 195 } 196 def reactNativeArchitectures = project.getProperties().get("reactNativeArchitectures")?.split(",") ?: ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] 197 198 reactNativeArchitectures.each { architecture -> 199 project.tasks.named("configureCMakeDebug[${architecture}]")?.configure { 200 dependsOn("preDebugBuild") 201 } 202 project.tasks.named("configureCMakeRelWithDebInfo[${architecture}]")?.configure { 203 dependsOn("preReleaseBuild") 204 } 205 } 206 } 207 } 208 } 209} 210 211ext.applyLegacyReactNativeLibsExtractionPlugin = { 212 apply plugin: LegacyReactNativeLibsExtractionPlugin 213} 214 215// [END] Remove when we drop SDK 47 216