包含自定义 sourceSet 的依赖项

Include dependency for custom sourceSet

我有一个 build.gradle.kts 用于小型纯 kotlin 项目(我知道我使用的是稍微不标准的源路径):

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

}

当我尝试 运行 基于 sourceSet 的“演示”jar 任务之一(“InteractiveClient”和“LockingBufferDemo”)时,1 我得到了一个很长的“无法访问内置...”错误列表表明 kotlin stdlib 未正确运行。

实际失败的任务是 compileDemoKotlin,所以我尝试模拟地添加到 tasks 块:

withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    this.kotlinOptions.jvmTarget = "1.8"
}

这没什么区别。

令我感到奇怪的是,演示内容最初位于 test sourceSet 中,并将上面的内容改回原样(通过删除定义,将 from(sourceSets["demo"]... 更改为 from(sourceSets.test...在 jar 任务中,并移动源文件)使问题消失。有效。

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

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


  1. 有关 jar 任务中的 from(... include(,请参阅

我不完全确定你想用你的 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"
    }
    

我不知道这是否回答了您的问题。如果我遗漏了什么,请告诉我。

在我看来,您似乎缺少使演示源集使用与主集相同的依赖项的配置。像这样:

configurations["demoImplementation"].extendsFrom(configurations.implementation.get())
configurations["demoRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())

用户指南中有一个示例 here 似乎与您的用例非常相似。

此外,从您在 Gradle 存储库中创建的 issue,您提到它失败了:

Unresolved reference: printlin

我很确定这是一个错字println