使用Prefab打包含预构建librga.so的Android本地库为AAR时,如何让librga.so进入Prefab目录并支持用户链接
Prefab打包含预构建librga.so的Android本地库为AAR时,如何让librga.so进入Prefab目录并支持用户链接
我来帮你解决这个问题,看起来你已经摸到了正确的方向,但有几个关键配置没到位,导致librga.so被AGP自动打包到了AAR的jni目录而非Prefab模块,还出现了重复的libmlrga.so。下面我一步步拆解问题根源并给出可落地的解决方案:
问题根源分析
librga.so未进入Prefab:你当前仅将rga作为本地导入库链接到mlrga,但未在Gradle的Prefab配置中声明rga为独立模块,AGP会默认将导入的预构建SO打包到jni目录,而非Prefab模块。- 重复的
libmlrga.so:jni目录中的是AGP自动收集的未经过Prefab处理的编译产物,prefab目录中的是CMakeinstall生成的标准模块库,二者因编译/打包逻辑不同导致大小差异。我们需要确保只有Prefab版本被保留。
具体解决方案
第一步:调整Gradle配置(build.gradle[.kts])
核心是在Gradle中明确声明两个Prefab模块:你自己的mlrga,以及预构建的rga,同时禁止AGP自动打包冗余SO。
Groovy版本示例
android { defaultConfig { // ... 其他基础配置(minSdk、targetSdk等) externalNativeBuild { cmake { arguments "-DANDROID_STL=c++_shared" abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } // 关键:声明Prefab模块,将rga也暴露为独立模块 experimental { prefab { // 声明你的mlrga模块 mlrga { headers = "src/main/cpp/public_headers" // 与CMake中的头目录对应 } // 声明预构建的rga模块 rga { libraryName = "rga" headers = "src/main/cpp/public_headers" // rga的头文件目录 prebuilt = true // 标记为预构建库,无需编译 } } } } externalNativeBuild { cmake { path "src/main/cpp/CMakeLists.txt" } } // 禁止AGP自动打包冗余SO,只保留Prefab模块中的版本 packagingOptions { exclude 'lib/**/librga.so' exclude 'lib/**/libmlrga.so' } }
第二步:重构CMakeLists.txt
不再手动指定librga.so的本地路径,而是通过Prefab引入rga模块,同时确保mlrga的产物被正确安装到Prefab目录。
cmake_minimum_required(VERSION 3.22.1) project(mlrga) # 引入Prefab提供的rga模块 find_package(rga REQUIRED CONFIG) # 配置头文件和源码 include_directories(./ public_headers/) file(GLOB SRC *.cpp) add_library(mlrga SHARED ${SRC}) # 链接Prefab的rga模块(而非本地导入的SO) target_link_libraries(mlrga log android rga::rga # 使用Prefab的标准模块目标 ) # 声明mlrga的公开头文件 target_include_directories(mlrga PUBLIC "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/public_headers" ) # 关键:将mlrga安装到Prefab指定目录 install(TARGETS mlrga LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_ABI}" ) install(DIRECTORY public_headers/ DESTINATION "${CMAKE_INSTALL_PREFIX}/include" )
第三步:验证AAR结构
调整完成后,生成的AAR结构应该是这样的(解压后):
your-library.aar ├── prefab │ ├── mlrga │ │ ├── include │ │ │ └── [你的公开头文件] │ │ └── libs │ │ ├── arm64-v8a │ │ │ └── libmlrga.so │ │ └── [其他ABI目录] │ ├── rga │ │ ├── include │ │ │ └── [rga的公开头文件] │ │ └── libs │ │ ├── arm64-v8a │ │ │ └── librga.so │ │ └── [其他ABI目录] │ └── prefab.json └── [其他AAR标准文件]
用户侧使用方式
你的用户在集成AAR后,就可以在他们的CMake中直接通过find_package链接两个模块:
# 查找mlrga和rga模块 find_package(mlrga REQUIRED CONFIG) find_package(rga REQUIRED CONFIG) # 链接mlrga target_link_libraries(your-app-library mlrga::mlrga # ... 其他依赖 ) # 或者直接链接rga target_link_libraries(your-app-library rga::rga # ... 其他依赖 )
注意事项
- 确保Gradle中
prefab.rga.headers的路径与CMake中头文件目录完全一致,否则用户无法找到rga的头文件。 - 如果你使用的是
build.gradle.kts,只需将Groovy配置转换为Kotlin语法即可,核心逻辑完全一致。 - 测试时务必解压AAR检查结构,确认
jni目录为空,prefab目录下同时存在mlrga和rga两个模块。
内容来源于stack exchange
相关产品推荐
相关产品推荐

