在 Gradle 中使用自定义 SourceSet
Using a Custom SourceSet in Gradle
根据 this from the official docs and ,定义一个新的源集应该像(在 kotlin 中)一样简单:
sourceSets {
create("demo") {
compileClasspath += sourceSets.main.get().output
}
}
第二个参考也明确声称现在可以在构建 jar 时使用它。 然而,虽然上面没有抛出错误,但实际上是在尝试使用新的源集任何地方都可以。最小示例(使用 gradle init
-> "kotlin application" 和项目名称 "foobar" 生成):
plugins {
id("org.jetbrains.kotlin.jvm").version("1.3.21")
application
}
repositories {
jcenter()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
}
application {
mainClassName = "foobar.AppKt"
}
sourceSets {
create("demo") {
compileClasspath += sourceSets.main.get().output
}
}
我删除了 test
源集的配置,因为它与此处无关。 src
目录看起来像这样(有点不标准,但我认为适合讨论):
src
├── demo
│ └── Demo.kt
└── main
└── foobar
└── App.kt
理想情况下,我希望有完全独立的源代码树(但这个问题不是专门针对那个)。相对于上面的配置,这个构建是有意义的,但这并不是真正的目标。为此,我想添加一两个自定义 jar。1
不幸的是,demo
源集无法在 gradle 脚本中引用。
val jar by tasks.getting(Jar::class) {
manifest { attributes["Main-Class"] = "DemoKt" }
// HERE IS THE PROBLEM:
from(sourceSets["demo"].get().output)
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
})
}
这个fat jar任务定义是taken from the gradle docs,我以前用过很多
照原样,gradle 窒息:
Script compilation errors:
Line 28: from(sourceSets["demo"].get().output)
^ Unresolved reference.
如果我将该行更改为:
from(sourceSets.demo.get().output)
与sourceSets.main
一起使用的语法是什么,那么错误就变成了:
Line 28: from(sourceSets.demo.get().output)
^ Unresolved reference: demo
我应该如何使用自定义源集?
- 我知道 gradle
subproject
模式并用它做了很多相同的事情,但我更喜欢简单的独立源集解决方案,我认为它满足所有要求提到的三个标准 in that doc.
sourceSets
属性(Project
的扩展 属性)returns 扩展 NamedDomainObjectContainer<SourceSet>
的 SourceSetContainer
。后一个接口定义了 get(String)
(运算符扩展函数),它允许您使用 ["..."]
语法。该方法 returns T
直接,这意味着您应该只使用:
from(sourceSets["demo"].output)
在使用 sourceSets.main
时必须使用 get()
的原因是因为您得到的 NamedDomainObjectProvider<SourceSet>
包装 源集.
您还可以通过委托获取自定义源集
创建时:
val demo by sourceSets.creating { /* configure */ }
或创建后的某个时间:
val demo by sourceSets
根据 this from the official docs and
sourceSets {
create("demo") {
compileClasspath += sourceSets.main.get().output
}
}
第二个参考也明确声称现在可以在构建 jar 时使用它。 然而,虽然上面没有抛出错误,但实际上是在尝试使用新的源集任何地方都可以。最小示例(使用 gradle init
-> "kotlin application" 和项目名称 "foobar" 生成):
plugins {
id("org.jetbrains.kotlin.jvm").version("1.3.21")
application
}
repositories {
jcenter()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
}
application {
mainClassName = "foobar.AppKt"
}
sourceSets {
create("demo") {
compileClasspath += sourceSets.main.get().output
}
}
我删除了 test
源集的配置,因为它与此处无关。 src
目录看起来像这样(有点不标准,但我认为适合讨论):
src
├── demo
│ └── Demo.kt
└── main
└── foobar
└── App.kt
理想情况下,我希望有完全独立的源代码树(但这个问题不是专门针对那个)。相对于上面的配置,这个构建是有意义的,但这并不是真正的目标。为此,我想添加一两个自定义 jar。1
不幸的是,demo
源集无法在 gradle 脚本中引用。
val jar by tasks.getting(Jar::class) {
manifest { attributes["Main-Class"] = "DemoKt" }
// HERE IS THE PROBLEM:
from(sourceSets["demo"].get().output)
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
})
}
这个fat jar任务定义是taken from the gradle docs,我以前用过很多
照原样,gradle 窒息:
Script compilation errors:
Line 28: from(sourceSets["demo"].get().output)
^ Unresolved reference.
如果我将该行更改为:
from(sourceSets.demo.get().output)
与sourceSets.main
一起使用的语法是什么,那么错误就变成了:
Line 28: from(sourceSets.demo.get().output)
^ Unresolved reference: demo
我应该如何使用自定义源集?
- 我知道 gradle
subproject
模式并用它做了很多相同的事情,但我更喜欢简单的独立源集解决方案,我认为它满足所有要求提到的三个标准 in that doc.
sourceSets
属性(Project
的扩展 属性)returns 扩展 NamedDomainObjectContainer<SourceSet>
的 SourceSetContainer
。后一个接口定义了 get(String)
(运算符扩展函数),它允许您使用 ["..."]
语法。该方法 returns T
直接,这意味着您应该只使用:
from(sourceSets["demo"].output)
在使用 sourceSets.main
时必须使用 get()
的原因是因为您得到的 NamedDomainObjectProvider<SourceSet>
包装 源集.
您还可以通过委托获取自定义源集
创建时:
val demo by sourceSets.creating { /* configure */ }
或创建后的某个时间:
val demo by sourceSets