Export prepareGlog to an internal task (#32421)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/32421

This diff refactors the `prepareGlog` task to a separate Gradle task in the `.internal` package.
The reason for this change is that `prepareGlog` was defining a `doLast` action and would result in being
invalidated whenever the `build.gradle` file would change. This means that the Glog headers/source files
would have been extracted again, effectively invalidating the timestamps for the native build.

Changelog:
[Internal] [Changed] - Export prepareGlog to an internal task

Reviewed By: ShikaSD

Differential Revision: D31661668

fbshipit-source-id: efcd5505a67d6c9f02fcab7a5c3255a160215661
This commit is contained in:
Nicola Corti
2021-10-18 04:34:43 -07:00
committed by Facebook GitHub Bot
parent a2b5e4cd82
commit c3e7ea0b5b
3 changed files with 216 additions and 35 deletions
+7 -35
View File
@@ -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
@@ -169,41 +171,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
@@ -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)
}
}
}
@@ -0,0 +1,130 @@
/*
* 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 com.facebook.react.tests.createProject
import com.facebook.react.tests.createTestTask
import java.io.*
import org.junit.Assert.*
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
class PrepareGlogTaskTest {
@get:Rule val tempFolder = TemporaryFolder()
@Test(expected = IllegalStateException::class)
fun prepareGlogTask_withMissingConfiguration_fails() {
val task = createTestTask<PrepareGlogTask>()
task.taskAction()
}
@Test
fun prepareGlogTask_copiesMakefile() {
val glogpath = tempFolder.newFolder("glogpath")
val output = tempFolder.newFolder("output")
val project = createProject()
val task =
createTestTask<PrepareGlogTask>(project = project) {
it.glogPath.setFrom(glogpath)
it.glogVersion.set("1.0.0")
it.outputDir.set(output)
}
File(project.projectDir, "src/main/jni/third-party/glog/Android.mk").apply {
parentFile.mkdirs()
createNewFile()
}
task.taskAction()
assertTrue(output.listFiles()!!.any { it.name == "Android.mk" })
}
@Test
fun prepareGlogTask_copiesConfigHeaderFile() {
val glogpath = tempFolder.newFolder("glogpath")
val output = tempFolder.newFolder("output")
val project = createProject()
val task =
createTestTask<PrepareGlogTask>(project = project) {
it.glogPath.setFrom(glogpath)
it.glogVersion.set("1.0.0")
it.outputDir.set(output)
}
File(project.projectDir, "src/main/jni/third-party/glog/config.h").apply {
parentFile.mkdirs()
createNewFile()
}
task.taskAction()
assertTrue(output.listFiles()!!.any { it.name == "config.h" })
}
@Test
fun prepareGlogTask_copiesSourceCode() {
val glogpath = tempFolder.newFolder("glogpath")
val output = tempFolder.newFolder("output")
val task =
createTestTask<PrepareGlogTask> {
it.glogPath.setFrom(glogpath)
it.glogVersion.set("1.0.0")
it.outputDir.set(output)
}
File(glogpath, "glog-1.0.0/src/glog.cpp").apply {
parentFile.mkdirs()
createNewFile()
}
task.taskAction()
assertTrue(File(output, "glog-1.0.0/src/glog.cpp").exists())
}
@Test
fun prepareGlogTask_replacesTokenCorrectly() {
val glogpath = tempFolder.newFolder("glogpath")
val output = tempFolder.newFolder("output")
val task =
createTestTask<PrepareGlogTask> {
it.glogPath.setFrom(glogpath)
it.glogVersion.set("1.0.0")
it.outputDir.set(output)
}
File(glogpath, "glog-1.0.0/src/glog.h.in").apply {
parentFile.mkdirs()
writeText("ac_google_start_namespace")
}
task.taskAction()
val expectedFile = File(output, "glog.h")
assertTrue(expectedFile.exists())
assertEquals("ac_google_start_namespace", expectedFile.readText())
}
@Test
fun prepareGlogTask_exportsHeaderCorrectly() {
val glogpath = tempFolder.newFolder("glogpath")
val output = tempFolder.newFolder("output")
val task =
createTestTask<PrepareGlogTask> {
it.glogPath.setFrom(glogpath)
it.glogVersion.set("1.0.0")
it.outputDir.set(output)
}
File(glogpath, "glog-1.0.0/src/logging.h.in").apply {
parentFile.mkdirs()
writeText("ac_google_start_namespace")
}
task.taskAction()
assertTrue(File(output, "exported/glog/logging.h").exists())
}
}