From 46f4e27df1508db4dc6553dc7fba21a51690002e Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Thu, 6 Aug 2026 23:04:55 -0400 Subject: [PATCH 1/2] feat: allow extending the list of libs kept out of the AAR The plugin embeds .so files from the app's dependencies into the AAR, and separately declares those same dependencies in the published module metadata. When a host App resolves one of them from Maven it ends up with two copies of the library and mergeNativeLibs fails on the duplicate. IGNORE_EMBEDDED_LIBS already covers this for React Native's own libraries, but it is a fixed list, so any other dependency in that position has no way out. Add reactBrownfield.ignoreEmbeddedLibs so a project can extend it. --- .changeset/tidy-moons-shave.md | 7 +++++++ .../react/brownfield/processors/JNILibsProcessor.kt | 8 +++++++- .../callstack/react/brownfield/utils/Extension.kt | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 .changeset/tidy-moons-shave.md diff --git a/.changeset/tidy-moons-shave.md b/.changeset/tidy-moons-shave.md new file mode 100644 index 00000000..50425886 --- /dev/null +++ b/.changeset/tidy-moons-shave.md @@ -0,0 +1,7 @@ +--- +"@callstack/react-native-brownfield": patch +--- + +feat: allow extending the list of .so files kept out of the AAR + +Adds a `reactBrownfield.ignoreEmbeddedLibs` option so a project can name additional native libraries that should not be embedded, next to the built-in `IGNORE_EMBEDDED_LIBS` list. diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/JNILibsProcessor.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/JNILibsProcessor.kt index fa53fc59..d76bb485 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/JNILibsProcessor.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/JNILibsProcessor.kt @@ -9,6 +9,7 @@ import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input @@ -50,6 +51,9 @@ abstract class ProcessAndCopyJniLibsTask : DefaultTask() { @get:Input abstract val useStrippedSoFiles: Property + @get:Input + abstract val extraIgnoredLibs: ListProperty + @get:OutputDirectory abstract val outputDirectory: DirectoryProperty @@ -125,7 +129,8 @@ abstract class ProcessAndCopyJniLibsTask : DefaultTask() { private fun matchesAllowedLib(name: String): Boolean { val isCodegenLib = name.startsWith("libreact_codegen_") && name.endsWith(".so") - val isIgnoredLib = IGNORE_EMBEDDED_LIBS.any { lib -> name == lib || name.contains(lib) } + val ignoredLibs = IGNORE_EMBEDDED_LIBS + extraIgnoredLibs.getOrElse(emptyList()) + val isIgnoredLib = ignoredLibs.any { lib -> name == lib || name.contains(lib) } return name == "libappmodules.so" || isCodegenLib || !isIgnoredLib } @@ -161,6 +166,7 @@ class JNILibsProcessor(val project: Project) { val processJniTask = project.tasks.register("processCustomJniLibsFor$capitalizedVariantName", ProcessAndCopyJniLibsTask::class.java) { it.useStrippedSoFiles.set(projectExt.useStrippedSoFiles) + it.extraIgnoredLibs.set(projectExt.ignoreEmbeddedLibs) val jniDirs = aarLibraries.map { aarLib -> diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt index e613e04b..b792129c 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt @@ -40,4 +40,16 @@ open class Extension { * listOf("type", "alpha") */ var missingDimensionStrategies = listOf() + + /** + * Additional .so file names to keep out of the AAR, on top of [IGNORE_EMBEDDED_LIBS]. + * + * Use this for libraries that stay declared as dependencies of the published AAR: the + * host App resolves those from Maven, so embedding them as well leaves two copies of + * the same .so and the host's native library merge fails. + * + * Provide in this format: + * listOf("libdatadog-ndk.so") + */ + var ignoreEmbeddedLibs = listOf() } From f6662d5e7a80ff9bdfa013aa678c93fe58c5c633 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Thu, 6 Aug 2026 23:37:41 -0400 Subject: [PATCH 2/2] docs: fully qualify the KDoc link to IGNORE_EMBEDDED_LIBS --- .../kotlin/com/callstack/react/brownfield/utils/Extension.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt index b792129c..5bebbfac 100644 --- a/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt +++ b/gradle-plugins/react/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt @@ -42,7 +42,8 @@ open class Extension { var missingDimensionStrategies = listOf() /** - * Additional .so file names to keep out of the AAR, on top of [IGNORE_EMBEDDED_LIBS]. + * Additional .so file names to keep out of the AAR, on top of + * [com.callstack.react.brownfield.processors.IGNORE_EMBEDDED_LIBS]. * * Use this for libraries that stay declared as dependencies of the published AAR: the * host App resolves those from Maven, so embedding them as well leaves two copies of