Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 12 additions & 54 deletions ReactAndroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ plugins {
id("de.undercouch.download")
}

import com.facebook.react.tasks.internal.*

import java.nio.file.Paths

import de.undercouch.gradle.tasks.download.Download
Expand Down Expand Up @@ -120,26 +122,12 @@ task downloadLibevent(dependsOn: createNativeDepsDirectories, type: Download) {
dest(new File(downloadsDir, "libevent-${LIBEVENT_VERSION}.tar.gz"))
}

task prepareLibevent(dependsOn: dependenciesPath ? [] : [downloadLibevent], type: Copy) {
from(dependenciesPath ?: tarTree(downloadLibevent.dest))
from("src/main/jni/third-party/libevent/Android.mk")
from("src/main/jni/third-party/libevent/event-config.h")
from("src/main/jni/third-party/libevent/evconfig-private.h")
include(
"libevent-${LIBEVENT_VERSION}-stable/*.c",
"libevent-${LIBEVENT_VERSION}-stable/*.h",
"libevent-${LIBEVENT_VERSION}-stable/include/**/*",
"evconfig-private.h",
"event-config.h",
"Android.mk"
)
eachFile { fname -> fname.path = (fname.path - "libevent-${LIBEVENT_VERSION}-stable/") }
includeEmptyDirs = false
into("$thirdPartyNdkDir/libevent")

doLast {
ant.move(file: "$thirdPartyNdkDir/libevent/event-config.h", tofile: "$thirdPartyNdkDir/libevent/include/event2/event-config.h")
}
final def prepareLibevent = tasks.register("prepareLibevent", PrepareLibeventTask) {
it.dependsOn(dependenciesPath ? [] : [downloadLibevent])
it.libeventPath.setFrom(dependenciesPath ?: tarTree(downloadLibevent.dest))
it.libeventVersion.set(LIBEVENT_VERSION)
it.outputDir.set(new File(thirdPartyNdkDir, "libevent"))
}

task prepareHermes(dependsOn: createNativeDepsDirectories, type: Copy) {
Expand Down Expand Up @@ -169,41 +157,11 @@ task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {

// Prepare glog sources to be compiled, this task will perform steps that normally should've been
// executed by automake. This way we can avoid dependencies on make/automake
task prepareGlog(dependsOn: dependenciesPath ? [] : [downloadGlog], type: Copy) {
duplicatesStrategy("warn")
from(dependenciesPath ?: tarTree(downloadGlog.dest))
from("src/main/jni/third-party/glog/")
include("glog-${GLOG_VERSION}/src/**/*", "Android.mk", "config.h")
includeEmptyDirs = false
filesMatching("**/*.h.in") {
filter(ReplaceTokens, tokens: [
ac_cv_have_unistd_h : "1",
ac_cv_have_stdint_h : "1",
ac_cv_have_systypes_h : "1",
ac_cv_have_inttypes_h : "1",
ac_cv_have_libgflags : "0",
ac_google_start_namespace : "namespace google {",
ac_cv_have_uint16_t : "1",
ac_cv_have_u_int16_t : "1",
ac_cv_have___uint16 : "0",
ac_google_end_namespace : "}",
ac_cv_have___builtin_expect : "1",
ac_google_namespace : "google",
ac_cv___attribute___noinline : "__attribute__ ((noinline))",
ac_cv___attribute___noreturn : "__attribute__ ((noreturn))",
ac_cv___attribute___printf_4_5: "__attribute__((__format__ (__printf__, 4, 5)))"
])
it.path = (it.name - ".in")
}
into("$thirdPartyNdkDir/glog")

doLast {
copy {
from(fileTree(dir: "$thirdPartyNdkDir/glog", includes: ["stl_logging.h", "logging.h", "raw_logging.h", "vlog_is_on.h", "**/src/glog/log_severity.h"]).files)
includeEmptyDirs = false
into("$thirdPartyNdkDir/glog/exported/glog")
}
}
final def prepareGlog = tasks.register("prepareGlog", PrepareGlogTask) {
it.dependsOn(dependenciesPath ? [] : [downloadGlog])
it.glogPath.setFrom(dependenciesPath ?: tarTree(downloadGlog.dest))
it.glogVersion.set(GLOG_VERSION)
it.outputDir.set(new File(thirdPartyNdkDir, "glog"))
}

// Create Android.mk library module based on jsc from npm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class ReactPlugin : Plugin<Project> {
}

private fun applyAppPlugin(project: Project, config: ReactExtension) {
if (config.applyAppPlugin.getOrElse(false)) {
project.afterEvaluate {
project.afterEvaluate {
if (config.applyAppPlugin.getOrElse(false)) {
val androidConfiguration = project.extensions.getByType(BaseExtension::class.java)
project.configureDevPorts(androidConfiguration)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,23 +165,23 @@ internal fun Project.configureReactTasks(variant: BaseVariant, config: ReactExte
packageTask.configure {
if (config.enableVmCleanup.get()) {
val libDir = "$buildDir/intermediates/transforms/"
val targetVariant = ".*/transforms/[^/]*/$targetPath/.*".toRegex()
val targetVariant = ".*/transforms/[^/]*/${variant.name}/.*".toRegex()
it.doFirst { cleanupVMFiles(libDir, targetVariant, enableHermes, cleanup) }
}
}

stripDebugSymbolsTask?.configure {
if (config.enableVmCleanup.get()) {
val libDir = "$buildDir/intermediates/stripped_native_libs/${targetPath}/out/lib/"
val targetVariant = ".*/stripped_native_libs/$targetPath/out/lib/.*".toRegex()
val libDir = "$buildDir/intermediates/stripped_native_libs/${variant.name}/out/lib/"
val targetVariant = ".*/stripped_native_libs/${variant.name}/out/lib/.*".toRegex()
it.doLast { cleanupVMFiles(libDir, targetVariant, enableHermes, cleanup) }
}
}

mergeNativeLibsTask?.configure {
if (config.enableVmCleanup.get()) {
val libDir = "$buildDir/intermediates/merged_native_libs/${targetPath}/out/lib/"
val targetVariant = ".*/merged_native_libs/$targetPath/out/lib/.*".toRegex()
val libDir = "$buildDir/intermediates/merged_native_libs/${variant.name}/out/lib/"
val targetVariant = ".*/merged_native_libs/${variant.name}/out/lib/.*".toRegex()
it.doLast { cleanupVMFiles(libDir, targetVariant, enableHermes, cleanup) }
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.tasks.internal

import java.io.File
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*

/**
* A task that takes care of extracting Glog from a source folder/zip and preparing it to be
* consumed by the NDK. This task will also take care of applying the mapping for Glog parameters.
*/
abstract class PrepareGlogTask : DefaultTask() {

@get:InputFiles abstract val glogPath: ConfigurableFileCollection

@get:Input abstract val glogVersion: Property<String>

@get:OutputDirectory abstract val outputDir: DirectoryProperty

@TaskAction
fun taskAction() {
project.copy {
it.from(glogPath)
it.from(project.file("src/main/jni/third-party/glog/"))
it.include("glog-${glogVersion.get()}/src/**/*", "Android.mk", "config.h")
it.duplicatesStrategy = DuplicatesStrategy.WARN
it.includeEmptyDirs = false
it.filesMatching("**/*.h.in") { matchedFile ->
matchedFile.filter(
mapOf(
"tokens" to
mapOf(
"ac_cv_have_unistd_h" to "1",
"ac_cv_have_stdint_h" to "1",
"ac_cv_have_systypes_h" to "1",
"ac_cv_have_inttypes_h" to "1",
"ac_cv_have_libgflags" to "0",
"ac_google_start_namespace" to "namespace google {",
"ac_cv_have_uint16_t" to "1",
"ac_cv_have_u_int16_t" to "1",
"ac_cv_have___uint16" to "0",
"ac_google_end_namespace" to "}",
"ac_cv_have___builtin_expect" to "1",
"ac_google_namespace" to "google",
"ac_cv___attribute___noinline" to "__attribute__ ((noinline))",
"ac_cv___attribute___noreturn" to "__attribute__ ((noreturn))",
"ac_cv___attribute___printf_4_5" to
"__attribute__((__format__ (__printf__, 4, 5)))")),
ReplaceTokens::class.java)
matchedFile.path = (matchedFile.name.removeSuffix(".in"))
}
it.into(outputDir)
}
val exportedDir = File(outputDir.asFile.get(), "exported/glog/").apply { mkdirs() }
project.copy {
it.from(outputDir)
it.include(
"stl_logging.h",
"logging.h",
"raw_logging.h",
"vlog_is_on.h",
"**/src/glog/log_severity.h")
it.eachFile { file -> file.path = file.name }
it.includeEmptyDirs = false
it.into(exportedDir)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.tasks.internal

import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*

/**
* A task that takes care of extracting Libevent from a source folder/zip and preparing it to be
* consumed by the NDK.
*/
abstract class PrepareLibeventTask : DefaultTask() {

@get:InputFiles abstract val libeventPath: ConfigurableFileCollection

@get:Input abstract val libeventVersion: Property<String>

@get:OutputDirectory abstract val outputDir: DirectoryProperty

@TaskAction
fun taskAction() {
project.copy { it ->
it.from(libeventPath)
it.from(project.file("src/main/jni/third-party/libevent/Android.mk"))
it.from(project.file("src/main/jni/third-party/libevent/event-config.h"))
it.from(project.file("src/main/jni/third-party/libevent/evconfig-private.h"))
it.include(
"libevent-${libeventVersion.get()}-stable/*.c",
"libevent-${libeventVersion.get()}-stable/*.h",
"libevent-${libeventVersion.get()}-stable/include/**/*",
"evconfig-private.h",
"event-config.h",
"Android.mk")
it.eachFile { it.path = it.path.removePrefix("libevent-${libeventVersion.get()}-stable/") }
it.includeEmptyDirs = false
it.into(outputDir)
}
File(outputDir.asFile.get(), "event-config.h").apply {
val destination =
File(this.parentFile, "include/event2/event-config.h").apply { parentFile.mkdirs() }
renameTo(destination)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react

import com.android.build.gradle.AppExtension
import org.gradle.testfixtures.ProjectBuilder
import org.junit.Assert.assertTrue
import org.junit.Test

class ReactPluginTest {

@Test
fun reactPlugin_withApplyAppPluginSetToTrue_addsARelevantTask() {
val project = ProjectBuilder.builder().build()
project.plugins.apply("com.android.application")
project.plugins.apply("com.facebook.react")

project.extensions.getByType(AppExtension::class.java).apply { compileSdkVersion(30) }
project.extensions.getByType(ReactExtension::class.java).apply {
applyAppPlugin.set(true)
cliPath.set(".")
}

// We check if the App Plugin si applied by finding one of the added task.
assertTrue(project.getTasksByName("bundleDebugJsAndAssets", false).isNotEmpty())
}

@Test
fun reactPlugin_withApplyAppPluginSetToFalse_doesNotApplyTheAppPlugin() {
val project = ProjectBuilder.builder().build()
project.plugins.apply("com.android.application")
project.plugins.apply("com.facebook.react")

project.extensions.getByType(AppExtension::class.java).apply { compileSdkVersion(30) }
project.extensions.getByType(ReactExtension::class.java).apply { applyAppPlugin.set(false) }

assertTrue(project.getTasksByName("bundleDebugJsAndAssets", false).isEmpty())
}

@Test
fun reactPlugin_withApplyAppPluginSetToFalse_codegenPluginIsApplied() {
val project = ProjectBuilder.builder().build()
project.plugins.apply("com.android.application")
project.plugins.apply("com.facebook.react")

project.extensions.getByType(AppExtension::class.java).apply { compileSdkVersion(30) }
project.extensions.getByType(ReactExtension::class.java).apply { applyAppPlugin.set(false) }

assertTrue(project.getTasksByName("buildCodegenCLI", false).isNotEmpty())
}
}
Loading