在 JAR 文件和运行时库路径中包含子项目 gradle 构建输出

Including subproject gradle build outputs in JAR file and runtime library path

我有一个使用 JNI 的 Java 应用程序,我正在使用 gradle 构建 C++ 共享库,其中包含我作为 JNI 的一部分加载的代码。 C++ 构建是根构建的子项目。我可以从我的根项目的 runjar 任务中依赖 :jnisubproject:assembleRelease,它确实构建了共享库(在 jnisubproject/build/lib/main/release/libjnisubproject.so),但它没有添加共享库到我的 JAR 文件中,它也没有设置我的 Java 库路径以便能够在 运行 时访问共享对象。通过一些 hackery(在我的 运行 任务中明确修改 java.library.path 系统 属性)我可以在使用 gradle run 时让它工作,但我希望能够构建用于重新分发的 JAR 文件。

我尝试通过添加

将子项目添加为运行时间依赖项
dependencies {
    runtime project(":jnisubproject")
    // runtime ":jnisubproject:assembleRelease" also doesn't work
}

我的根项目的依赖项,但这既不足以让 gradle jar 构建子项目,也不足以将其文件包含在 JAR 中;这实际上似乎什么都不做。如果我在 JAR 任务中添加显式依赖项,如下所示:

jar {
    dependsOn ":jnisubproject:assembleRelease"
}

它会在我 运行 gradle jar 时构建我的子项目,但毫不奇怪,共享库最终不会出现在 JAR 中。我尝试的最后一件事是上面的代码片段除了在输出目录上添加文件依赖性之外还具有显式依赖性:

dependencies {
    runtime files('jnisubproject/build/lib/main/release/*')    
}

但是这两者都感觉非常笨拙并且不起作用,这是一个很棒的组合。如果我通过

明确地将构建的文件包含在 JAR 中
jar {
    include 'jnisubproject/build/lib/main/release/*'
}

然后我的 JAR 文件除了清单之外完全是空的。

简而言之,我的问题是:

有什么想法吗?

在你的根项目中试试:

processResources {
    from project(':jnisubproject').buildDir + '/lib/main/release/*'
}

它将告诉主要 processResources 任务包含您的库。

关于 java.library.path 添加,我认为不可能从 Jar 中直接 link 一个库。更多信息 here.