diff --git a/packages/react-native-nitro-modules/android/fix-prefab.gradle b/packages/react-native-nitro-modules/android/fix-prefab.gradle index d6c010ef7..97f8300d1 100644 --- a/packages/react-native-nitro-modules/android/fix-prefab.gradle +++ b/packages/react-native-nitro-modules/android/fix-prefab.gradle @@ -1,19 +1,16 @@ tasks.configureEach { task -> // Make sure that we generate our prefab publication file only after having built the native library // so that not a header publication file, but a full configuration publication will be generated, which - // will include the .so file - + // will include the .so file. def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/ def matcher = task.name =~ prefabConfigurePattern if (matcher.matches()) { def variantName = matcher[0][1] - task.outputs.upToDateWhen { false } task.dependsOn("externalNativeBuild${variantName}") } } afterEvaluate { - def abis = reactNativeArchitectures() rootProject.allprojects.each { proj -> if (proj === rootProject) return @@ -29,23 +26,22 @@ afterEvaluate { } def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants - // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to - // generate a libnameConfig.cmake file that will contain our native library (.so). - // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue + + // Wire dependent native builds to prefab packaging task outputs instead of mutating .cxx files. + // This keeps Gradle inputs deterministic and avoids blanket cache invalidation. variants.all { variant -> - def variantName = variant.name - abis.each { abi -> - def searchDir = new File(proj.projectDir, ".cxx/${variantName}") - if (!searchDir.exists()) return - def matches = [] - searchDir.eachDir { randomDir -> - def prefabFile = new File(randomDir, "${abi}/prefab_config.json") - if (prefabFile.exists()) matches << prefabFile - } - matches.each { prefabConfig -> - prefabConfig.setLastModified(System.currentTimeMillis()) - } - } + def capitalizedVariant = variant.name.substring(0, 1).toUpperCase() + variant.name.substring(1) + def consumerNativeTaskName = "externalNativeBuild${capitalizedVariant}" + def producerPrefabTaskName = "prefab${capitalizedVariant}ConfigurePackage" + + def consumerNativeTask = proj.tasks.findByName(consumerNativeTaskName) + def producerPrefabTask = project.tasks.findByName(producerPrefabTaskName) + + if (consumerNativeTask == null || producerPrefabTask == null) return + + consumerNativeTask.dependsOn(producerPrefabTask) + consumerNativeTask.inputs.files(producerPrefabTask.outputs.files) + .withPathSensitivity(org.gradle.api.tasks.PathSensitivity.RELATIVE) } } } diff --git a/packages/react-native-nitro-test-external/android/fix-prefab.gradle b/packages/react-native-nitro-test-external/android/fix-prefab.gradle index d6c010ef7..97f8300d1 100644 --- a/packages/react-native-nitro-test-external/android/fix-prefab.gradle +++ b/packages/react-native-nitro-test-external/android/fix-prefab.gradle @@ -1,19 +1,16 @@ tasks.configureEach { task -> // Make sure that we generate our prefab publication file only after having built the native library // so that not a header publication file, but a full configuration publication will be generated, which - // will include the .so file - + // will include the .so file. def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/ def matcher = task.name =~ prefabConfigurePattern if (matcher.matches()) { def variantName = matcher[0][1] - task.outputs.upToDateWhen { false } task.dependsOn("externalNativeBuild${variantName}") } } afterEvaluate { - def abis = reactNativeArchitectures() rootProject.allprojects.each { proj -> if (proj === rootProject) return @@ -29,23 +26,22 @@ afterEvaluate { } def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants - // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to - // generate a libnameConfig.cmake file that will contain our native library (.so). - // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue + + // Wire dependent native builds to prefab packaging task outputs instead of mutating .cxx files. + // This keeps Gradle inputs deterministic and avoids blanket cache invalidation. variants.all { variant -> - def variantName = variant.name - abis.each { abi -> - def searchDir = new File(proj.projectDir, ".cxx/${variantName}") - if (!searchDir.exists()) return - def matches = [] - searchDir.eachDir { randomDir -> - def prefabFile = new File(randomDir, "${abi}/prefab_config.json") - if (prefabFile.exists()) matches << prefabFile - } - matches.each { prefabConfig -> - prefabConfig.setLastModified(System.currentTimeMillis()) - } - } + def capitalizedVariant = variant.name.substring(0, 1).toUpperCase() + variant.name.substring(1) + def consumerNativeTaskName = "externalNativeBuild${capitalizedVariant}" + def producerPrefabTaskName = "prefab${capitalizedVariant}ConfigurePackage" + + def consumerNativeTask = proj.tasks.findByName(consumerNativeTaskName) + def producerPrefabTask = project.tasks.findByName(producerPrefabTaskName) + + if (consumerNativeTask == null || producerPrefabTask == null) return + + consumerNativeTask.dependsOn(producerPrefabTask) + consumerNativeTask.inputs.files(producerPrefabTask.outputs.files) + .withPathSensitivity(org.gradle.api.tasks.PathSensitivity.RELATIVE) } } } diff --git a/packages/template/android/fix-prefab.gradle b/packages/template/android/fix-prefab.gradle index d6c010ef7..97f8300d1 100644 --- a/packages/template/android/fix-prefab.gradle +++ b/packages/template/android/fix-prefab.gradle @@ -1,19 +1,16 @@ tasks.configureEach { task -> // Make sure that we generate our prefab publication file only after having built the native library // so that not a header publication file, but a full configuration publication will be generated, which - // will include the .so file - + // will include the .so file. def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/ def matcher = task.name =~ prefabConfigurePattern if (matcher.matches()) { def variantName = matcher[0][1] - task.outputs.upToDateWhen { false } task.dependsOn("externalNativeBuild${variantName}") } } afterEvaluate { - def abis = reactNativeArchitectures() rootProject.allprojects.each { proj -> if (proj === rootProject) return @@ -29,23 +26,22 @@ afterEvaluate { } def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants - // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to - // generate a libnameConfig.cmake file that will contain our native library (.so). - // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue + + // Wire dependent native builds to prefab packaging task outputs instead of mutating .cxx files. + // This keeps Gradle inputs deterministic and avoids blanket cache invalidation. variants.all { variant -> - def variantName = variant.name - abis.each { abi -> - def searchDir = new File(proj.projectDir, ".cxx/${variantName}") - if (!searchDir.exists()) return - def matches = [] - searchDir.eachDir { randomDir -> - def prefabFile = new File(randomDir, "${abi}/prefab_config.json") - if (prefabFile.exists()) matches << prefabFile - } - matches.each { prefabConfig -> - prefabConfig.setLastModified(System.currentTimeMillis()) - } - } + def capitalizedVariant = variant.name.substring(0, 1).toUpperCase() + variant.name.substring(1) + def consumerNativeTaskName = "externalNativeBuild${capitalizedVariant}" + def producerPrefabTaskName = "prefab${capitalizedVariant}ConfigurePackage" + + def consumerNativeTask = proj.tasks.findByName(consumerNativeTaskName) + def producerPrefabTask = project.tasks.findByName(producerPrefabTaskName) + + if (consumerNativeTask == null || producerPrefabTask == null) return + + consumerNativeTask.dependsOn(producerPrefabTask) + consumerNativeTask.inputs.files(producerPrefabTask.outputs.files) + .withPathSensitivity(org.gradle.api.tasks.PathSensitivity.RELATIVE) } } }