我有一个小型纯 kotlin 项目的build.gradle.kts
(我知道我使用的是稍微非标准的源路径(:
plugins {
kotlin("jvm") version "1.3.72"
}
repositories { mavenCentral() }
dependencies {
implementation(kotlin("stdlib-jdk8"))
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}
sourceSets["main"].java.srcDir("src")
sourceSets["test"].java.srcDirs("test")
sourceSets {
create("demo")?.let {
it.java.srcDir("demo")
// Also tried: it.java.srcDirs("src", "demo")
it.compileClasspath += main.get().output
it.runtimeClasspath += main.get().output
}
}
tasks {
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
}
listOf("InteractiveClient", "LockingBufferDemo").forEach {
tasks.register<Jar>(it) {
manifest { attributes["Main-Class"] = "${it}Kt" }
from(sourceSets.main.get().output)
from(sourceSets["demo"].output) {
include("**/${it}Kt.class")
}
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter {
it.name.endsWith("jar") }.map { zipTree(it) }
})
}
}
当我尝试运行基于"演示"源代码集的jar任务之一("交互式客户端"和"锁定缓冲区演示"(时,1我得到了一长串"无法访问内置..."错误表明 Kotlin stdlib 无法正常运行。
实际失败的任务是compileDemoKotlin
,所以我尝试模仿添加到tasks
块:
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
this.kotlinOptions.jvmTarget = "1.8"
}
这没什么区别。
对我来说奇怪的是,演示内容最初在test
sourceSet 中,将上面的内容改回该内容(通过删除定义,将 jar 任务中的from(sourceSets["demo"]...
更改为from(sourceSets.test...
,并移动源文件(使问题消失。它有效。
我不希望这些东西与自动化测试一起使用。 我想我可以把它们放在main
或test
集的分支中,然后使用from() { exclude(...
模式来构建罐子, 但这似乎很尴尬和没有必要。
如何获取自定义源代码集以针对默认项目依赖项进行编译?
- 请参阅我最近关于罐子任务中
from(... include(
的另一个问题。
在我看来,您缺少使演示源代码集使用与主集相同的依赖项的配置。像这样:
configurations["demoImplementation"].extendsFrom(configurations.implementation.get())
configurations["demoRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())
这里的用户指南中有一个示例,它似乎与您的用例非常相似。
此外,从您在 Gradle 存储库中创建的问题中,您提到它失败了:
未解析的参考:普雷克林
我很确定这是println
的错字.
我不完全确定您要对 jar 文件做什么,但我在您的构建脚本中发现了一些问题:
-
您已经像这样设置了源集:
sourceSets["main"].java.srcDir("src") sourceSets["test"].java.srcDirs("src", "test") sourceSets { create("demo")?.let { it.java.srcDir("demo") } }
这意味着您应该具有以下目录结构:
- <module root> - src <-- Belongs to both 'main' and a 'test' source sets! - test <-- Belongs to the 'test' source set - demo <-- Belongs to the 'demo' source set
如您所见,有一个目录属于两个源集。我不确定这在实践中如何,可能一个或另一个被丢弃了。下面是一个更标准的目录结构:
- <module root> - src - main - test - demo
您可以像这样配置它:
sourceSets { main { java.srcDir("src/main") } test { java.srcDir("src/test") } create("demo") { java.srcDir("src/demo") } }
-
该任务
compileDemoKotlin
实际存在,但您无法像这样访问它。如果您查看扩展函数源compileKotlin
和compileTestKotlin
,它们如下所示:val TaskContainer.`compileKotlin`: TaskProvider<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> get() = named<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileKotlin")
所以诀窍是使用
named
来获取任务:named<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileDemoKotlin") { kotlinOptions.jvmTarget = "1.8" }
我不知道这是否回答了你的问题。如果我错过了什么,请告诉我。