Gradle Kotlin DSL中未解决的引用:sourceSets

15
尝试将现有的build.gradle迁移到Kotlin,但我在项目中遇到以下错误:
Script compilation error:

  Line 86:         from(sourceSets["main"].allSource)
                        ^ Unresolved reference: sourceSets

1 error

当我尝试定义 sourcesJar 任务时,错误来自于我的 subprojects 块:

subprojects {
    val sourcesJar by tasks.registering(Jar::class) {
        classifier = "sources"
        from(sourceSets["main"].allSource) // error here
    }

    configure<PublishingExtension> {
        publications {
            register("mavenJava", MavenPublication::class) {
                from(components["java"])
                artifact(sourcesJar.get())
            }
        }
    }

    val implementation by configurations
    val compileOnly by configurations
    val annotationProcessor by configurations

    dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        compileOnly("org.springframework.boot:spring-boot-autoconfigure")
        // ...
    }
}

我正在使用以下内容:

  • Gradle 4.10.2
  • Kotlin 1.2.70

build.gradle.kts 的开始部分,位于 subprojects 块之前:

import com.diffplug.gradle.spotless.KotlinExtension
import com.diffplug.gradle.spotless.SpotlessExtension
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

val kotlinVersion: String by extra
val springBootVersion: String by extra

buildscript {
    val kotlinVersion: String by extra { "1.2.70" }
    val springBootVersion: String by extra { "2.0.6.RELEASE" }
    repositories {
        maven {
            val nexusPublicRepoURL: String by project
            url = uri(nexusPublicRepoURL)
        }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
        classpath("com.diffplug.spotless:spotless-plugin-gradle:3.9.0")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
        classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
        classpath("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.2.70")
    }
}

allprojects {
    val projectGroup: String by project
    group = projectGroup

    apply(plugin = "kotlin")
    apply(plugin = "java-library")
    apply(plugin = "maven-publish")
    apply(plugin = "kotlin-spring")
    apply(plugin = "com.diffplug.gradle.spotless")
    apply(plugin = "io.spring.dependency-management")

    configure<DependencyManagementExtension> {
        imports {
            mavenBom("org.springframework.boot:spring-boot-dependencies:$springBootVersion")
            mavenBom("org.springframework.cloud:spring-cloud-dependencies:Finchley.SR1")
        }
    }

    repositories {
        maven {
            val nexusPublicRepoURL: String by project
            url  = uri(nexusPublicRepoURL)
        }
    }

    tasks.existing(KotlinCompile::class) {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "1.8"
        }
    }

    configure<SpotlessExtension> {
        kotlin {
            ktlint()
        }
    }

    configure<PublishingExtension> {
        repositories {
            maven {
                val nexusReleaseRepoURL: String by project
                val nexusSnapshotRepoURL: String by project
                val nexusUsername: String by project
                val nexusPassword: String by project
                val version = if ((project.version as String).contains("SNAPSHOT")) nexusReleaseRepoURL else nexusSnapshotRepoURL
                url = uri(version)
                credentials {
                    username = nexusUsername
                    password = nexusPassword
                }
            }
        }
    }
}

如果我没记错的话,你应该能够使用 the<SourceSetContainer>()["main"] - JB Nizet
@JBNizet 这样做会产生一个新的错误:“类型'SourceSetContainer'的扩展不存在。当前已注册的扩展类型为:[ExtraPropertiesExtension]”。 - Cisco
你是否在每个子项目上应用了一个插件,该插件实际上向项目添加了sourceSets(例如java插件)? - JB Nizet
我已经在 allprojects 块中应用了 java-library 插件。请查看我的编辑,其中显示了我整个 build.gradle.kts 的其余部分。 - Cisco
抱歉:这是一个简单的作用域问题。the()被解析为this.the(),即Task::the()。请将其更改为project.the<SourceSetContainer>()["main"] - JB Nizet
那个完美地运行了。请发布为答案,以便我可以标记为已接受。 - Cisco
1个回答

17

由于插件是在同一个构建脚本中命令式应用的,Gradle 无法知道插件已被应用,因此无法生成扩展函数以允许访问源集。

因此,您需要以编程方式获取源集:

project.the<SourceSetContainer>()["main"]

不要使用

the<SourceSetContainer>()["main"]
否则,the()函数将会在当前任务中被解析而不是项目中。

只是为了明确一下,我应该用 from(project.the<SourceSetContainer>()["main"]) 替换 from(sourceSets["main"].allSource) 吗? - ThanosFisherman
不应该使用 sourceSets["main"],而应该使用 <SourceSetContainer>()["main"]。 - JB Nizet
2
谢谢!现在它可以工作了。有趣的是GitHub的示例没有提到它。https://github.com/gradle-guides/building-kotlin-jvm-libraries/blob/master/samples/code/my-kotlin-library/build.gradle.kts#L51 - ThanosFisherman
但是对于 sourcesJar.get() 这一行应该怎么处理呢? - Floaz
仍然对我失败 :( - GuilhE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接