mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Refactor Extract Headers and JNI from AARs to an internal task (#32426)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/32426 This diff refactors the extractHeader and extractJni tasks to a single Gradle task in the `.internal` package. The reason for this change is that those two tasks were always running, therefore invalidating the whole native build cache. Changelog: [Internal] [Changed] - Refactor Extract Headers and JNI from AARs to an internal task Reviewed By: mdvacca, ShikaSD Differential Revision: D31682942 fbshipit-source-id: 191cc77902e82c0425949cee743d240ded790137
This commit is contained in:
committed by
Facebook GitHub Bot
parent
75b2e5cc97
commit
bc93fefe13
+13
-27
@@ -284,7 +284,7 @@ def getNdkBuildFullPath() {
|
||||
}
|
||||
|
||||
def buildReactNdkLib = tasks.register("buildReactNdkLib", Exec) {
|
||||
dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFmt, prepareFolly, prepareGlog, prepareLibevent, extractAARHeaders, extractJNIFiles)
|
||||
dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFmt, prepareFolly, prepareGlog, prepareLibevent, extractNativeDependencies)
|
||||
dependsOn("generateCodegenArtifactsFromSchema");
|
||||
|
||||
inputs.dir("$projectDir/../ReactCommon")
|
||||
@@ -343,32 +343,18 @@ def packageReactNdkLibsForBuck = tasks.register("packageReactNdkLibsForBuck", Co
|
||||
into("src/main/jni/prebuilt/lib")
|
||||
}
|
||||
|
||||
task extractAARHeaders {
|
||||
doLast {
|
||||
configurations.extractHeaders.files.each {
|
||||
def file = it.absoluteFile
|
||||
def packageName = file.name.tokenize('-')[0]
|
||||
copy {
|
||||
from zipTree(file)
|
||||
into "$projectDir/src/main/jni/first-party/$packageName/headers"
|
||||
include "**/*.h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task extractJNIFiles {
|
||||
doLast {
|
||||
configurations.extractJNI.files.each {
|
||||
def file = it.absoluteFile
|
||||
def packageName = file.name.tokenize('-')[0]
|
||||
copy {
|
||||
from zipTree(file)
|
||||
into "$projectDir/src/main/jni/first-party/$packageName/"
|
||||
include "jni/**/*"
|
||||
}
|
||||
}
|
||||
}
|
||||
final def extractNativeDependencies = tasks.register('extractNativeDependencies', ExtractJniAndHeadersTask) {
|
||||
it.extractHeadersConfiguration.setFrom(configurations.extractHeaders)
|
||||
it.extractJniConfiguration.setFrom(configurations.extractJNI)
|
||||
it.baseOutputDir = project.file("src/main/jni/first-party/")
|
||||
// Sadly this task as an output folder path that is directly dependent on
|
||||
// the task input (i.e. src/main/jni/first-party/<package-name>/...
|
||||
// This means that this task is using the parent folder (first-party/) as
|
||||
// @OutputFolder. The `prepareHermes` task will also output inside that
|
||||
// folder and if the two tasks happen to be inside the same run, we want
|
||||
// `extractNativeDependencies` to run after `prepareHermes` to do not
|
||||
// invalidate the input/output calculation for this task.
|
||||
it.mustRunAfter(prepareHermes)
|
||||
}
|
||||
|
||||
task installArchives {
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.tasks.*
|
||||
|
||||
/**
|
||||
* A task that takes care of extracting JNIs and Headers from a custom Gradle configuration into an
|
||||
* output folder. Users are most likely not going to use this task but it will be used when building
|
||||
* the React Native project.
|
||||
*/
|
||||
abstract class ExtractJniAndHeadersTask : DefaultTask() {
|
||||
|
||||
@get:InputFiles abstract val extractHeadersConfiguration: ConfigurableFileCollection
|
||||
|
||||
@get:InputFiles abstract val extractJniConfiguration: ConfigurableFileCollection
|
||||
|
||||
@get:OutputDirectory abstract val baseOutputDir: DirectoryProperty
|
||||
|
||||
@TaskAction
|
||||
fun taskAction() {
|
||||
extractJniConfiguration.files.forEach {
|
||||
val file = it.absoluteFile
|
||||
val packageName = file.name.split("-", ".").first()
|
||||
project.copy { copySpec ->
|
||||
copySpec.from(project.zipTree(file))
|
||||
copySpec.into(baseOutputDir.dir(packageName))
|
||||
copySpec.include("jni/**/*")
|
||||
}
|
||||
}
|
||||
extractHeadersConfiguration.files.forEach {
|
||||
val file = it.absoluteFile
|
||||
val packageName = file.name.split("-", ".").first()
|
||||
project.copy { copySpec ->
|
||||
copySpec.from(project.zipTree(file))
|
||||
copySpec.into(baseOutputDir.get().dir("$packageName/headers"))
|
||||
copySpec.include("**/*.h")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 com.facebook.react.tests.zipFiles
|
||||
import java.io.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
|
||||
class ExtractJniAndHeadersTaskTest {
|
||||
|
||||
@get:Rule val tempFolder = TemporaryFolder()
|
||||
|
||||
@Test
|
||||
fun extractJniAndHeadersTask_extractsHeadersCorrectly() {
|
||||
val project = createProject()
|
||||
val aarFile = File(project.projectDir, "libheader.aar")
|
||||
val headerFile = tempFolder.newFile("justaheader.h")
|
||||
val output = tempFolder.newFolder("output")
|
||||
zipFiles(aarFile, listOf(headerFile))
|
||||
|
||||
val task =
|
||||
createTestTask<ExtractJniAndHeadersTask>(project = project) {
|
||||
it.extractHeadersConfiguration.setFrom(aarFile)
|
||||
it.baseOutputDir.set(output)
|
||||
}
|
||||
|
||||
task.taskAction()
|
||||
|
||||
assertTrue(File(output, "libheader/headers/justaheader.h").exists())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun extractJniAndHeadersTask_extractsJniCorrectly() {
|
||||
val project = createProject()
|
||||
val aarFile = File(project.projectDir, "something.aar")
|
||||
File(tempFolder.root, "jni/libsomething.so").apply {
|
||||
parentFile.mkdirs()
|
||||
createNewFile()
|
||||
}
|
||||
val output = tempFolder.newFolder("output")
|
||||
ZipOutputStream(BufferedOutputStream(FileOutputStream(aarFile.absolutePath))).use { out ->
|
||||
FileInputStream(aarFile).use { fi ->
|
||||
BufferedInputStream(fi).use { origin ->
|
||||
out.putNextEntry(ZipEntry("jni/"))
|
||||
out.putNextEntry(ZipEntry("jni/libsomething.so"))
|
||||
origin.copyTo(out, 1024)
|
||||
}
|
||||
}
|
||||
}
|
||||
val task =
|
||||
createTestTask<ExtractJniAndHeadersTask>(project = project) {
|
||||
it.extractJniConfiguration.setFrom(aarFile)
|
||||
it.baseOutputDir.set(output)
|
||||
}
|
||||
|
||||
task.taskAction()
|
||||
|
||||
assertTrue(File(output, "something/jni/libsomething.so").exists())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user