前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gradle Kotlin DSL 的 accessors 生成问题

Gradle Kotlin DSL 的 accessors 生成问题

作者头像
bennyhuo
发布2020-02-20 13:19:31
1.4K0
发布2020-02-20 13:19:31
举报
文章被收录于专栏:BennyhuoBennyhuo

概要

如果你想用 gradle kotlin DSL,那么请注意,accessors 的支持从 0.8.0 开始(gradle 3.5),后续也做了一些完善和更新,目前已经默认开启了这一项功能。使用时由于 accessors 是动态生成的,因此要注意使用 plugins{...} 可以直接触发 accessors 的动态生成,其他情况下就比较麻烦了。

正文

昨天也是手欠,非要用 Gradle Kotlin DSL 构建工程,还看到现在连 settings.gradle 也支持用 kts 了,于是乎:

不过这个需要 Gradle 的版本在 4.4 以上,gradle-wrapper.properties 的版本修改为:

代码语言:javascript
复制
...
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

看上去也没啥毛病啊,我的 build.gradle.kts 是这个样子:

代码语言:javascript
复制
buildscript {
    var kotlin_version: String by extra
    kotlin_version = "1.2.10"

    repositories {
        mavenCentral()
    }

    dependencies {
        classpath(kotlin("gradle-plugin", kotlin_version))
    }
}

apply {
    plugin("java")
    plugin("kotlin")
}

val kotlin_version: String by extra

repositories {
    mavenCentral()
}

dependencies {
    compile(kotlin("stdlib"))
}

然而一运行,出事儿了,compile 不识别。。

代码语言:javascript
复制
e: .../kotlinspecificsJvm/app/build.gradle.kts:42:5: Unresolved reference: compile

额,这就尴尬了,哪儿说理去。。由于 Kotlin 是静态语言,能够在这个地方写出来 compile 那么一定是定义了这个方法,就像:

代码语言:javascript
复制
dependencies {
        classpath(kotlin("gradle-plugin", kotlin_version))
    }

这里的 classpath 就是一个方法:

代码语言:javascript
复制
class ScriptHandlerScope(scriptHandler: ScriptHandler) : ScriptHandler by scriptHandler {
    ...
    fun DependencyHandler.classpath(dependencyNotation: Any): Dependency =
        add(CLASSPATH_CONFIGURATION, dependencyNotation)
}

那么 compile 的定义哪儿去了?其实,compile 和 classpath 不一样,前者是构建插件的 configuration,而 classpath 则是 gradle 本身的一个方法。

那么 compile 到底是什么,gradle 自己没有定义就不能用了吗?那倒也不是,gradle kotlin DSL 会帮我们根据插件的 configuration 定义生成这样的代码。这在 gradle kotlin dsl 0.8.0 中就做了支持,官方把他们称作:Type-safe accessors,这个版本也跟随 gradle 3.5 发版。

我本来用 4.0 用得好好的,非要因为 settings.gradle.kts 改用了 4.4 的版本,导致出现了这个问题,我就想难道新版本做了调整?于是我又换了 4.5、4.5.1,果然问题还是有。

后来查了一下官方 demo "hello-kotlin":

代码语言:javascript
复制
plugins {
    application
    kotlin("jvm") version "1.2.0"
}

application {
    mainClassName = "samples.HelloWorldKt"
}

dependencies {
    compile(kotlin("stdlib"))
}

repositories {
    jcenter()
}

对比了一下才发现,原来人家用的 是 plugins{} 这种写法,而我的工程仍然用的是 apply plugin 的写法,就这么点儿区别。。难道真的是因为这个?

果然,我把我的配置修改了一下:

代码语言:javascript
复制
- apply {
-    plugin("java")
-    plugin("kotlin")
- }

+ plugins {
+    java
+    kotlin("jvm") version "1.2.10"
+ }

这时候果然没问题了:

而且我们也能找到 compile 的定义:

代码语言:javascript
复制
fun DependencyHandler.`compile`(dependencyNotation: Any): Dependency =
    add("compile", dependencyNotation)

原来,这些 gradle 帮我们动态生成的 accessors,生成的时机就是 plugins{} 调用之后。也就是说我们需要使用这种方式来应用插件才会生成上述的方法。

详细说明在 gradle kotlin DSL 0.8.0 的更新说明当中:https://github.com/gradle/kotlin-dsl/releases/tag/v0.8.0 ,不过其中提到的 gskGenerateAccessors 我在 gradle 4.5 当中已经找不到了。

小结

kotlin 和 groovy 也算是各有所长,如果我们对于 gradle 的语法非常熟悉,那么我个人认为用 groovy 写 DSL 倒也灵活,kotlin 的约束毕竟多一些——而这也正是 Kotlin DSL 的优点,静态类型安全有保障。。


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-02-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Kotlin 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概要
  • 正文
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档