You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Prefab打包含预构建librga.so的Android本地库为AAR时,如何让librga.so进入Prefab目录并支持用户链接

Prefab打包含预构建librga.so的Android本地库为AAR时,如何让librga.so进入Prefab目录并支持用户链接

我来帮你解决这个问题,看起来你已经摸到了正确的方向,但有几个关键配置没到位,导致librga.so被AGP自动打包到了AAR的jni目录而非Prefab模块,还出现了重复的libmlrga.so。下面我一步步拆解问题根源并给出可落地的解决方案:

问题根源分析

  1. librga.so未进入Prefab:你当前仅将rga作为本地导入库链接到mlrga,但未在Gradle的Prefab配置中声明rga为独立模块,AGP会默认将导入的预构建SO打包到jni目录,而非Prefab模块。
  2. 重复的libmlrga.so:jni目录中的是AGP自动收集的未经过Prefab处理的编译产物,prefab目录中的是CMake install生成的标准模块库,二者因编译/打包逻辑不同导致大小差异。我们需要确保只有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
    # ... 其他依赖
)

注意事项

  1. 确保Gradle中prefab.rga.headers的路径与CMake中头文件目录完全一致,否则用户无法找到rga的头文件。
  2. 如果你使用的是build.gradle.kts,只需将Groovy配置转换为Kotlin语法即可,核心逻辑完全一致。
  3. 测试时务必解压AAR检查结构,确认jni目录为空,prefab目录下同时存在mlrga和rga两个模块。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 13:29:31