使用 Gradle Kotlin DSL Jar.from()

Use of Gradle Kotlin DSL Jar.from()

我正在尝试为 jar 的 Main-Class 添加一个源文件——实际上我有一个此类文件的顶级目录,demo/,但我不想要它们都在一个罐子里。我想要单独的罐子,每个罐子只使用其中一个。

这似乎是 gradle 中的一种反模式,因为基本机制推断或更喜欢我应该将每个放在不同的 sourceSet 中。呃。

随意阅读 the docs 意味着 Jar.from() 可能对这种方式有用:"Specifies the source files or directories..."

事实证明,"source" 可能有点用词不当。这是一个示例,一个典型的 kotlin fat jar 添加了 from("demo/LockingBufferDemo.kt"):

val jar by tasks.getting(Jar::class) {
    manifest { attributes["Main-Class"] = "LockingBufferDemoKt" }
    from(sourceSets.main.get().output)
    from("demo/LockingBufferDemo.kt")
    dependsOn(configurations.runtimeClasspath)
    from({
        configurations.runtimeClasspath.get().filter {
            it.name.endsWith("jar") }.map { zipTree(it) }
    })
}         

原谅我的天真:猜猜什么最终没有出现在罐子里? LockingBufferDemo.class。猜猜是什么? LockingBufferDemo.kt。换句话说,这更像是 a resource,而不是 a source,最简单的答案是死胡同。

另一种解决方法是将 demo 目录添加为独立的 sourceSet,然后使用 from(sourceSets["demo"].get(),但我找不到完成它的方法;根据 IntelliJ get() returns 一个相当不透明的 "Provider" which I can't find mentioned in the actual javadoc: 1, 2 我真的觉得此时我正沿着花园小径前进,周围的树林迅速变暗。

这不应该这么复杂。

如何将单个文件(或从此类导出的 class)添加到 gradle 中的 jar 中,而不必将其单独放在目录中并创建 sourceSet每个这样的目录?

关于您在 post 开头的解释,您应该考虑自己创建多个 Jar 类型的任务,因为每个 Jar 类型的任务只会创建一个单个 JAR 文件,而你 "want separate jars"。我认为您不应该使用不同的源集,因为所有文件最终都是 Java Kotlin 源文件,并且以相同的方式处理(编译、测试、文档...)。多个源集会使这个通用管道复杂化。

"Specifies the source files or directories..." As it turns out, "source" is perhaps a bit of a misnomer.

好吧,文档并不止于此,而是说 "for a copy and creates a child CopySpec"。所以它不是源代码中的源代码,而是复制操作的源代码。在 Gradle 中,创建存档(ZIP、JAR)的任务与复制文件的任务共享它们的 API,因为创建存档可以看作是将文件从源位置复制到目标位置(在存档内)。

所以,from方法可以用来指定复制/归档的文件。但它不仅需要一个 sourcePath 参数,还需要一个闭包或动作来进行配置。使用第二个参数,您可以将源文件或目录缩小到您需要的一个文件,例如使用方法 include:

val jar by tasks.getting(Jar::class) {
    manifest { attributes["Main-Class"] = "LockingBufferDemoKt" }
    from(sourceSets.main.get().output) {
        include("**/LockingBufferDemo.class")
    }
    dependsOn(configurations.runtimeClasspath)
    from({
        configurations.runtimeClasspath.get().filter {
            it.name.endsWith("jar") }.map { zipTree(it) }
    })
}