包括自定义源集的依赖项



我有一个小型纯 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"
}

这没什么区别。

对我来说奇怪的是,演示内容最初在testsourceSet 中,将上面的内容改回该内容(通过删除定义,将 jar 任务中的from(sourceSets["demo"]...更改为from(sourceSets.test...,并移动源文件(使问题消失。它有效。

我不希望这些东西与自动化测试一起使用。 我想我可以把它们放在maintest集的分支中,然后使用from() { exclude(...模式来构建罐子, 但这似乎很尴尬和没有必要。

如何获取自定义源代码集以针对默认项目依赖项进行编译?


  1. 请参阅我最近关于罐子任务中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实际存在,但您无法像这样访问它。如果您查看扩展函数源compileKotlincompileTestKotlin,它们如下所示:

    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"
    }
    

我不知道这是否回答了你的问题。如果我错过了什么,请告诉我。

最新更新