Gradle Kotlin DSL:子项目和插件的问题

Arn*_*lle 6 gradle gradle-kotlin-dsl

摇篮6.1.1

我一直在尝试使用 Kotlin DSL 转换项目的 gradle 文件,但到目前为止失败了。我的所有项目都是用 Java 进行的多项目构建。我在这里遵循插件子项目示例

看起来像这样:

plugins {
    idea
    eclipse
}

subprojects {
    apply(plugin = "java")

    dependencies {
       implementation("com.google.guava:guava:28.1-jre")
       //...
    }
}
Run Code Online (Sandbox Code Playgroud)

java插件似乎在子项目中不被理解,并且所有“实现”行都得到了未解析的引用。

tkr*_*use 4

请参阅此处的文档https://docs.gradle.org/current/userguide/kotlin_dsl.html

类型安全访问器不可用于由以下各项贡献的模型元素:

  • 通过 apply(plugin = "id") 方法应用的插件
  • ...
 implementation()
Run Code Online (Sandbox Code Playgroud)

就是这样一个类型安全的访问器。非类型安全的方式如下所示:

    apply(plugin = "java-library")
    dependencies {
        "api"("javax.measure:unit-api:1.0")
        "implementation"("tec.units:unit-ri:1.0.3")
    }
Run Code Online (Sandbox Code Playgroud)

使用groovy DSL,所有方法都是动态解析的(不是类型安全的),所以这并不重要。

它有助于理解 build.gradle.kts 文件不是纯 kotlin 文件。如果顶部有大量进口产品,它们看起来会更难看。因此,gradle 运行时将“buildscript”和“plugins”块特殊对待。“plugins”被转换为导入语句。这不适用于 apply() 方法,该方法稍后在编译文件时运行。这也是为什么插件块不能在其他地方使用的原因,它是一个特殊的构造,只是假装是一个普通的代码块。这里有更多细节 https://docs.gradle.org/current/dsl/org.gradle.plugin.use.PluginDependencySpec.html

建议

仅从模块设计的角度来看,我通常建议多模块构建中的根模块与子模块的功能无关,即使有很多人像subprojects您的示例一样使用该块。让每个子模块的构建文件都像一个独立的gradle项目一样完整,这样读者就不必阅读2个文件来了解全貌。

有更好的显式方法来在子项目之间共享配置。

根文件中的块subprojects最好用于添加额外的任务(如果需要从项目的根目录添加额外的任务,IMO)。不注入插件或配置。