如何处理同时集成多个声网 SDK 时遇到的库冲突问题?

更新时间不可用

aosl 是声网 SDK 的基础设施库,包含在 RTC SDK、RTM SDK 和即时通讯 IM SDK 等声网产品中。

aosl 库在不同平台的文件名如下:

  • Android: libaosl.so
  • iOS/macOS: aosl.xcframework
  • Windows: libaosl.dll
  • HarmonyOS: libaosl.so

如果你的项目同时集成了多个声网 SDK,由于不同版本的声网 SDK 中 aosl 的版本和集成方式不同,你可能会遇到库冲突问题。

问题现象

依赖库版本冲突

使用包管理工具(如 Maven 或 CocoaPods)集成声网 SDK 时,不同声网 SDK 都依赖 aosl,但依赖的版本不同,包管理工具会检查并报告依赖版本冲突错误。

Shell
2 files found with path 'lib/arm64-v8a/libaosl.so' from inputs:
- /Users/admin/.gradle/caches/9.2.1/transforms/a2b0a7c8a27b3cbfeee17900a2a7c022/transformed/full-sdk-4.4.0/jni/arm64-v8a/libaosl.so
- /Users/admin/.gradle/caches/9.2.1/transforms/10f4ec8f241601284facfc671b4dbc2f/transformed/aosl-1.3.0/jni/arm64-v8a/libaosl.so

具体场景:

  • io.agora.rtc:full-sdk:4.4.x 包含 aosl 库
  • rtm:android-java:2.2.7 依赖 aosl 1.3.0
  • Maven 无法自动处理依赖冲突
Shell
[!] CocoaPods could not find compatible versions for pod "AgoraInfra_iOS":
  In Podfile:
    AgoraRtcEngine_iOS (= 4.5.2) was resolved to 4.5.2, which depends on
      AgoraRtcEngine_iOS/RtcBasic (= 4.5.2) was resolved to 4.5.2, which depends on
        AgoraInfra_iOS (= 1.2.13.1)

    HyphenateChat (= 4.17.0) was resolved to 4.17.0, which depends on
      AgoraInfra_iOS (~> 1.3.0)

具体场景:

  • AgoraRtcEngine_iOS 4.5.2 要求 AgoraInfra_iOS = 1.2.13.1
  • HyphenateChat 4.17.0 要求 AgoraInfra_iOS ~> 1.3.0
  • 两个版本约束无法同时满足

动态库重复

aosl 库因以下原因存在于多个 SDK 包中,编译工具会报动态库重复错误:

  • 当 aosl 以非依赖方式集成(如使用 CDN 下载 SDK 包并手动集成)并添加到不同的 module 中(gradle)
  • SDK 提供商会发布不同品牌名称的 pod(如 AgoraInfra_iOS 和 ShengwangInfra_iOS),但它们实际上包含相同的 aosl 库文件
Shell
com.android.builder.merge.DuplicateRelativeFileException: More than one file was found with OS independent path 'lib/x86/libaosl.so'
Shell
Unexpected duplicate tasks:
Multiple commands produce '<your_app_build_path>/Contents/Frameworks/aosl.framework'
Shell
The 'XXX' target has duplicate frameworks with the name 'aosl.xcframework'

具体场景:

  • AgoraInfra_iOS 和 ShengwangInfra_iOS 是同一个库的不同品牌名称
  • 两者都包含相同的 aosl.xcframework
  • CocoaPods 不允许同一个 framework 被多次引入
Shell
Error Message: Duplicated files found in module xxx. This may cause unexpected errors at runtime.
'<your_app_build_path>/@shengwang/rtm-full/libs/arm64-v8a/libaosl.so'
'<your_app_build_path>/@shengwang/rtc-full/libs/arm64-v8a/libaosl.so'

解决方案

本节根据你集成声网 SDK 的方式,提供不同的 aosl 库冲突解决方案。

使用包管理工具集成 SDK

本节介绍使用 Maven 或 CocoaPods 集成声网 SDK 时,如何解决库冲突问题。

指定依赖库版本(适用于 Maven)

如果你使用 Maven Central 集成声网 SDK,你可以修改 build.gradle 文件,显式集成最新的 aosl 库,确保 dependencies 中 aosl 库的引入语句排在其他声网 SDK 之前,然后使用 pickFirst 来确保引用第一顺位的 aosl 组件。

信息

groovy
android {
  // ...
  packagingOptions {
    // 确保引用第一顺位的 `aosl` 组件
    pickFirst 'lib/**/libaosl.so'
  }
}

dependencies {
  // 集成 `aosl` 库,排在声网 SDK 之前
  implementation 'cn.shengwang.infra:aosl:x.y.z'
  // 集成其他声网 SDK,排在 `aosl` 库之后
  implementation 'cn.shengwang.rtm:android-java:x.y.z'
  implementation 'io.agora.rtc:full-sdk:x.y.z'

}

修改保存后,等待 Gradle 文件同步完成,之后重新构建项目,即可解决依赖库版本冲突问题。

使用 pod 脚本(适用于 CocoaPods)

如果你使用 CocoaPods 集成声网 SDK,可以使用声网提供的脚本自动解决冲突。

脚本工作原理

脚本实际是一个 CocoaPods 命令包装器,对 install 和 update 命令:自动处理依赖和 framework 冲突,对其他命令(如 --version, trunk 等):直接透传,不做处理。

通过临时修改 CocoaPods 本地缓存中的 podspec 文件,将严格的版本约束(=、~>)改为宽松的最低版本约束(>=),使依赖解析器能够选择一个兼容的版本。同时自动检测并移除重复的 vendored_frameworks,解决 framework 名称冲突。

准备脚本

新建一个 pod.sh 文件,将以下代码保存到文件中。

按项目类型使用
  1. 在 macOS 终端中为 pod.sh 添加执行权限:

    Bash
    chmod +x pod.sh
  2. 在项目的 iOS 或 macOS 工程目录中,使用 pod.sh 替代原有的 pod install 或 pod update 命令:

    Bash
    # 替代 pod install
    ./pod.sh install
    
    # 替代 pod update
    ./pod.sh update
    
    # 支持原生选项
    ./pod.sh install --repo-update
    ./pod.sh update --verbose
    
    # 其他 pod 命令直接透传
    ./pod.sh --version
    ./pod.sh trunk push

对于 Flutter 项目,由于 flutter build ios 和 flutter run 会由 Flutter CLI 自己去调用 pod install,不会调用手动执行过的 ./pod.sh,除了 pod.sh 之外,还需要额外添加一个名为 pod 的代理脚本。

新建一个名为 pod 的文件,将以下代码保存到文件中。

确保 pod 和 pod.sh 位于同一目录,并在 macOS 终端中为两个脚本添加执行权限:

Bash
chmod +x pod.sh pod

在执行 Flutter 命令前,将脚本所在目录放到 PATH 最前面:

Bash
PATH="<代理脚本目录>:$PATH" flutter build ios
Bash
PATH="<代理脚本目录>:$PATH" flutter run

其中,<代理脚本目录> 表示同时存放 pod 和 pod.sh 的目录,pod 这个文件名不能修改。

注意事项
  1. 临时修改:脚本会在执行后恢复原始 podspec,不会永久改变 CocoaPods 缓存

  2. 版本兼容性:确保放宽版本约束后选择的版本确实兼容(通常高版本向下兼容)

  3. Podfile 优先:如果 Podfile 中指定了 aosl 库的版本(如 pod 'AgoraInfra_iOS', '1.3.0'),则使用指定版本,脚本不会修改 Podfile 中的版本约束。

    信息

    如果脚本无法解决你的问题,请联系技术支持获取帮助。

集成 Lite SDK(适用于 RTM)

自 v2.2.2 起,RTM Java/Objective-C SDK 提供了不包含 aosl 库的轻量版本(Lite SDK)。 如果你同时集成了 v2.2.2 及之后的 RTM SDK 和其他声网 SDK,且 RTM SDK 中的 aosl 库版本较低,你可以集成 RTM Lite SDK 来避免与其他声网 SDK 中的 aosl 库版本冲突问题。

信息

你可以前往RTM 发版说明和RTC 发版说明查看各 SDK 中 aosl 库的版本信息。

groovy
// ...
dependencies {
    // 如果你使用的是 2.2.2 及之后版本的 RTM SDK
    // 将 x.y.z 替换为具体的 SDK 版本号,如 2.2.7
    // 可通过发版说明获取最新版本号
    implementation 'cn.shengwang.rtm:android-java-lite:2.2.7'
}

修改完成后,清理并重新构建项目,即可解决依赖库版本冲突问题。

Ruby
platform :ios, '11.0'
target 'Your App' do
    # 如果你使用的是 2.2.2 及之后版本的 RTM SDK
    # 将 x.y.z 替换为具体的 SDK 版本号,如 2.2.7
    # 可通过发版说明获取最新版本号
    pod 'ShengwangRtm', 'x.y.z', :subspecs => ['RtmKit']
end

修改完成后,清理并重新构建项目,即可解决依赖库版本冲突问题。

手动集成 SDK

本节介绍使用 CDN 链接下载 SDK 包并手动集成声网 SDK 时,如何解决库冲突问题。

手动删除较低版本的库 (Android/iOS/macOS/Windows)

目标平台为 Android/iOS/macOS/Windows 时,你可以在 SDK 包中手动删除较低版本的 aosl 库文件。

信息

你可以前往 SDK 发版说明页查看各 SDK 中 aosl 库的版本信息:

aosl 库位于 SDK 包的 lib/{arch} 目录下,不同平台的文件名如下:

  • Android: libaosl.so
  • iOS/macOS: aosl.xcframework
  • Windows: libaosl.dll

你需要在较低版本 aosl 库的 SDK 包中删除所有架构目录下的 aosl 库文件。

配置过滤规则 (HarmonyOS)

目标平台为 HarmonyOS 时,你需要在项目根目录的 entry 文件夹中,修改 build-profile.json5 文件中原生库的过滤规则(buildOption.nativeLib.filter.select),确保项目引用的 libaosl.so 为较高版本。

信息

你可以前往 SDK 发版说明页查看各 SDK 中 aosl 库的版本信息:

以下为 RTM SDK 的 aosl 库版本高于 RTC SDK 的 aosl 库版本时的配置示例代码:

JSON
{
  "apiType": "stageMode",
  "buildOption": {
    "nativeLib": {
      "filter": {
        "select": [
          {
            "package": "@shengwang/rtm-full",
            "include": [
              "libaosl.so"
            ]
          }
        ]
      }
    }
  }
}