Skip to content

Commit 3fcbf8e

Browse files
authored
fix: Fix prefab linker errors (#776)
1 parent ddde433 commit 3fcbf8e

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

packages/react-native-nitro-modules/android/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def isNewArchitectureEnabled() {
2222

2323
apply plugin: "com.android.library"
2424
apply plugin: 'org.jetbrains.kotlin.android'
25+
apply from: "./fix-prefab.gradle"
2526

2627
if (isNewArchitectureEnabled()) {
2728
apply plugin: "com.facebook.react"
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
tasks.configureEach { task ->
2+
// Make sure that we generate our prefab publication file only after having built the native library
3+
// so that not a header publication file, but a full configuration publication will be generated, which
4+
// will include the .so file
5+
6+
def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
7+
def matcher = task.name =~ prefabConfigurePattern
8+
if (matcher.matches()) {
9+
def variantName = matcher[0][1]
10+
task.outputs.upToDateWhen { false }
11+
task.dependsOn("externalNativeBuild${variantName}")
12+
}
13+
}
14+
15+
afterEvaluate {
16+
def abis = reactNativeArchitectures()
17+
rootProject.allprojects.each { proj ->
18+
if (proj === rootProject) return
19+
20+
def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
21+
config.dependencies.any { dep ->
22+
dep.group == project.group && dep.name == project.name
23+
}
24+
}
25+
if (!dependsOnThisLib && proj != project) return
26+
27+
if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
28+
return
29+
}
30+
31+
def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
32+
// Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
33+
// generate a libnameConfig.cmake file that will contain our native library (.so).
34+
// 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
35+
variants.all { variant ->
36+
def variantName = variant.name
37+
abis.each { abi ->
38+
def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
39+
if (!searchDir.exists()) return
40+
def matches = []
41+
searchDir.eachDir { randomDir ->
42+
def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
43+
if (prefabFile.exists()) matches << prefabFile
44+
}
45+
matches.each { prefabConfig ->
46+
prefabConfig.setLastModified(System.currentTimeMillis())
47+
}
48+
}
49+
}
50+
}
51+
}

packages/template/android/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def isNewArchitectureEnabled() {
2121
apply plugin: "com.android.library"
2222
apply plugin: 'org.jetbrains.kotlin.android'
2323
apply from: '../nitrogen/generated/android/$$androidCxxLibName$$+autolinking.gradle'
24+
apply from: "./fix-prefab.gradle"
2425

2526
if (isNewArchitectureEnabled()) {
2627
apply plugin: "com.facebook.react"
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
tasks.configureEach { task ->
2+
// Make sure that we generate our prefab publication file only after having built the native library
3+
// so that not a header publication file, but a full configuration publication will be generated, which
4+
// will include the .so file
5+
6+
def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
7+
def matcher = task.name =~ prefabConfigurePattern
8+
if (matcher.matches()) {
9+
def variantName = matcher[0][1]
10+
task.outputs.upToDateWhen { false }
11+
task.dependsOn("externalNativeBuild${variantName}")
12+
}
13+
}
14+
15+
afterEvaluate {
16+
def abis = reactNativeArchitectures()
17+
rootProject.allprojects.each { proj ->
18+
if (proj === rootProject) return
19+
20+
def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
21+
config.dependencies.any { dep ->
22+
dep.group == project.group && dep.name == project.name
23+
}
24+
}
25+
if (!dependsOnThisLib && proj != project) return
26+
27+
if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
28+
return
29+
}
30+
31+
def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
32+
// Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
33+
// generate a libnameConfig.cmake file that will contain our native library (.so).
34+
// 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
35+
variants.all { variant ->
36+
def variantName = variant.name
37+
abis.each { abi ->
38+
def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
39+
if (!searchDir.exists()) return
40+
def matches = []
41+
searchDir.eachDir { randomDir ->
42+
def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
43+
if (prefabFile.exists()) matches << prefabFile
44+
}
45+
matches.each { prefabConfig ->
46+
prefabConfig.setLastModified(System.currentTimeMillis())
47+
}
48+
}
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)