如何让Gradle仅从指定AAR中选取对应版本的原生库libc++_shared.so
问题解答
1. 如何获取Gradle打包阶段所有原生库的真实路径
你可以在模块级build.gradle中添加如下自定义任务钩子,执行构建时会自动打印所有参与打包的libc++_shared.so的完整路径,不需要手动猜测AAR的缓存结构:
// 放在android块外即可 tasks.whenTaskAdded { task -> // 匹配所有合并原生库的构建任务 if (task.name.startsWith('merge') && task.name.endsWith('NativeLibs')) { task.doFirst { println "======== 所有libc++_shared.so路径 ========" it.inputs.files.filter { f -> f.name == "libc++_shared.so" }.each { f -> println f.absolutePath } println "==========================================" } } }
执行常规打包命令(比如./gradlew assembleDebug)后,在构建日志中就能看到所有待打包的so的完整路径,直接复制对应你需要的AAR的路径特征即可。
2. 强制打包指定AAR提供的libc++_shared.so的两种方案
你之前的配置不生效,是因为packagingOptions的路径匹配规则对应APK内部的文件路径,不是AAR在本地缓存的路径,所以写缓存路径匹配不到任何文件,自然最终APK里不会包含该so。可使用以下两种稳定方案:
方案1:精准过滤任务(兼容性最好)
直接修改mergeNativeLibs任务的输入文件,只保留你需要的AAR中的so,其他全部过滤,配置如下:
tasks.withType(com.android.build.gradle.tasks.MergeNativeLibs).configureEach { eachFile { file -> if (file.name == "libc++_shared.so") { // 路径里包含你要保留的AAR的标识,比如com/mycompany/mymodule,就保留 if (!file.sourcePath.contains("com/mycompany/mymodule")) { file.exclude() } } } }
注意把com/mycompany/mymodule替换成上一步打印的路径里对应你目标AAR的唯一标识即可。
方案2:调整依赖顺序(简单快捷)
你之前的临时方案是符合AGP逻辑的:pickFirst默认按依赖声明的先后顺序选择资源,先声明的依赖优先级更高。只要你把内置了正确版本libc++_shared.so的依赖,放在所有其他会引入该so的依赖之前声明,就能保证优先选到正确的版本。
内容的提问来源于stack exchange,提问作者CCJ
相关产品推荐
相关产品推荐

