应用插件的不同方式?(GradleKotlinDSL)

kcwpcxri  于 2022-12-13  发布在  Kotlin
关注(0)|答案(2)|浏览(162)

Trying to migrate this one project's build to GSK. We have this in Groovy:

allprojects {
    apply plugin: 'java'
...
    sourceSets {
        ...
    }
    sourceCompatibility = ...
}

So while figuring out how to access the plugin convention in Kotlin, I found out that:

allprojects {
    plugins {
        java apply true
    }
    ...
    println("Project $name, plugins: ${plugins}") // empty list
    val java = the<JavaPluginConvention>() // throws exception
}

but if you do it like this:

allprojects {
    apply {
        plugin(JavaPlugin::class.java)
    }
}

plugin is applied and convention becomes accessible
WTH?

46qrfjad

46qrfjad1#

这个问题并不是Kotlin特有的,而是由于一个争用条件。当脚本正在被评估时,它可能还没有将插件添加到类路径中。这是为什么创建plugins块的许多原因之一,因为在buildscript阶段,它是在其他脚本评估之前被专门评估的。然而,尽管如此,这种特殊处理仅在该块位于脚本的顶部时进行,而不是在subprojectsallprojects块内时进行,因为这些块在技术上是任意的,稍后将对其进行评估以确保buildscript是幂等的。你只是把它放在allprojects块中,在比赛中取得了进步,而且很幸运。
当处理多项目构建时,这是有问题的,但是如果可能的话,最好是在plugins块中用apply false约束语法声明插件,以便在buildscript阶段将其添加到构建的类路径中。(版本不是必需的,因为它仅用于获取依赖项)。
举个例子:

plugins {
    id("org.gradle.sample.hello") version "1.0.0" apply false
}

subprojects {
    apply(plugin = "org.gradle.sample.hello")
}

Gradle User Guide很好地解释了这些应该如何使用,以及在多模块项目中需要考虑的平衡。
由于一些插件是如何编写的,可能会出现其他问题,但如果插件作者遵循最佳实践指南,你会没事的。

p5fdfcr1

p5fdfcr12#

如果你的插件是Kotlin的,那么现在最好的方法是:

plugins {
    kotlin("jvm") version "1.7.21"
    kotlin("plugin.serialization") version "1.7.21"
}

相关问题