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

Gradle/NDK/CMake:构建可动态引入终端用户已安装外部.aar的.aar库

解决方案:动态链接用户独立安装的Hermes库

我帮你梳理下实现动态链接用户已安装Hermes库的具体步骤,这样既能避免把庞大的Hermes打包进你的JNI库,又能让用户自主更新Hermes版本:

1. 配置CMakeLists.txt,找到Hermes的头文件与动态库

在你的JNI库的CMakeLists.txt中,需要通过Gradle传递的参数定位Hermes的头文件目录和动态库位置,这样编译时就能找到<hermes/hermes.h>:

# 接收从Gradle传递的Hermes路径参数
set(HERMES_INCLUDE_DIR ${CMAKE_ARGS_HERMES_INCLUDE})
set(HERMES_LIB_DIR ${CMAKE_ARGS_HERMES_LIB_DIR})

# 添加Hermes头文件目录
include_directories(${HERMES_INCLUDE_DIR})

# 动态链接Hermes库(注意匹配Hermes的库名称,通常是libhermes.so)
find_library(HERMES_LIB 
             NAMES hermes 
             PATHS ${HERMES_LIB_DIR} 
             NO_CMAKE_FIND_ROOT_PATH)

# 将Hermes库链接到你的JNI库
target_link_libraries(your-jni-library-name  # 替换成你的JNI库目标名称
                      ${HERMES_LIB}
                      android
                      log)

2. 在你的库的build.gradle中传递Hermes路径给CMake

你需要让终端用户的项目能把本地node_modules下的Hermes路径传递给CMake。这里提供两种方式,推荐第二种更灵活的方案:

方式一:固定路径适配用户目录结构

如果用户的Hermes固定在node_modules/hermes-engine下,可以直接在你的库的build.gradle中写死路径逻辑:

android {
    externalNativeBuild {
        cmake {
            arguments = [
                "-DCMAKE_ARGS_HERMES_INCLUDE=${project.rootDir}/node_modules/hermes-engine/include",
                "-DCMAKE_ARGS_HERMES_LIB_DIR=${project.rootDir}/node_modules/hermes-engine/${buildType}/jni/${android.defaultConfig.ndk.abiFilters[0]}"
            ]
        }
    }
}

方式二:让用户自定义路径(更推荐)

如果用户的Hermes路径可能变化,你可以在你的库中添加一个Gradle扩展,让用户在他们的app build.gradle中灵活配置:

// 你的库的build.gradle中定义扩展
project.extensions.create("myJniLibrary", MyJniLibraryExtension)

class MyJniLibraryExtension {
    File hermesIncludeDir = project.file("node_modules/hermes-engine/include")
    File hermesLibDir = project.file("node_modules/hermes-engine/${project.android.buildTypes.release.name}/jni/${project.android.defaultConfig.ndk.abiFilters[0]}")
}

// 然后在externalNativeBuild中使用扩展参数
android {
    externalNativeBuild {
        cmake {
            arguments = [
                "-DCMAKE_ARGS_HERMES_INCLUDE=${project.extensions.myJniLibrary.hermesIncludeDir.absolutePath}",
                "-DCMAKE_ARGS_HERMES_LIB_DIR=${project.extensions.myJniLibrary.hermesLibDir.absolutePath}"
            ]
        }
    }
}

用户在他们的app build.gradle中就可以自定义路径(如果默认路径不匹配):

myJniLibrary {
    hermesIncludeDir = file("custom-path/hermes-engine/include")
    hermesLibDir = file("custom-path/hermes-engine/debug/jni/arm64-v8a")
}

3. 终端用户项目的依赖配置

用户需要在他们的app build.gradle中同时依赖你的JNI库和Hermes的aar,确保Hermes的动态库能被打包到APK中:

dependencies {
    // 依赖你的JNI库
    implementation files("node_modules/my-jni-library/my-jni-library.aar")
    // 依赖用户自己选择的Hermes版本(debug/release)
    implementation files("node_modules/hermes-engine/hermes-release.aar")
}

4. 关键注意事项

  • ABI一致性:确保你的JNI库编译的ABI(比如arm64-v8a、x86_64)和Hermes库的ABI完全一致,否则运行时会出现UnsatisfiedLinkError。
  • 头文件兼容性:你的JNI代码要尽量兼容不同版本的Hermes头文件,避免因为Hermes版本更新导致编译错误。
  • 不要打包Hermes:确保你的aar中不包含任何Hermes的头文件或动态库,保持库的轻量化。

内容的提问来源于stack exchange,提问作者mrousavy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:14:13