Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export prepareGlog to an internal task #32421

Closed
wants to merge 3 commits into from
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
42 changes: 7 additions & 35 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 @@ -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
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,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())
}
}
Original file line number Diff line number Diff line change
@@ -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())
}
}
10 changes: 5 additions & 5 deletions react.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,9 @@ afterEvaluate {
}
}
}.visit { details ->
def targetVariant1 = ".*/transforms/[^/]*/${targetPath}/.*"
def targetVariant2 = ".*/merged_native_libs/${targetPath}/out/lib/.*"
def targetVariant3 = ".*/stripped_native_libs/${targetPath}/out/lib/.*"
def targetVariant1 = ".*/transforms/[^/]*/${variant.name}/.*"
def targetVariant2 = ".*/merged_native_libs/${variant.name}/out/lib/.*"
def targetVariant3 = ".*/stripped_native_libs/${variant.name}/out/lib/.*"
def path = details.file.getAbsolutePath().replace(File.separatorChar, '/' as char)
if ((path.matches(targetVariant1) || path.matches(targetVariant2) || path.matches(targetVariant3)) && details.file.isFile()) {
details.file.delete()
Expand All @@ -386,13 +386,13 @@ afterEvaluate {

def sTask = tasks.findByName("strip${targetName}DebugSymbols")
if (sTask != null) {
def strippedLibDir = "$buildDir/intermediates/stripped_native_libs/${targetPath}/out/lib/"
def strippedLibDir = "$buildDir/intermediates/stripped_native_libs/${variant.name}/out/lib/"
sTask.doLast { vmSelectionAction(strippedLibDir) }
}

def mTask = tasks.findByName("merge${targetName}NativeLibs")
if (mTask != null) {
def mergedLibDir = "$buildDir/intermediates/merged_native_libs/${targetPath}/out/lib/"
def mergedLibDir = "$buildDir/intermediates/merged_native_libs/${variant.name}/out/lib/"
mTask.doLast { vmSelectionAction(mergedLibDir) }
}
}
Expand Down