Gradle Kotlin DSL 无法识别 buildscript 中的 ext

Posted

技术标签:

【中文标题】Gradle Kotlin DSL 无法识别 buildscript 中的 ext【英文标题】:ext in buildscript can not be recognised by Gradle Kotlin DSL 【发布时间】:2018-01-26 23:14:06 【问题描述】:

这几天,我正在尝试写一些代码来体验Spring 5中的Spring响应式特性和kotlin扩展,我还准备了一个gradle Kotlin DSL build.gradle.kt来配置gradle build。

build.gradle.kt由http://start.spring.io生成的Spring Boot模板代码转换而来。

但是Gradle检测不到buildscript中的ext

buildscript 
  ext  

ext 会导致 Gradle 构建错误。

为了使classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")compile("org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlinVersion") 中的变量能够正常工作,我以艰难的方式添加了变量。

val kotlinVersion = "1.1.4"
val springBootVersion = "2.0.0.M3"

但我必须在全局顶部位置声明它们并在buildscript 中复制它们。

代码:https://github.com/hantsy/spring-reactive-sample/blob/master/kotlin-gradle/build.gradle.kts

有没有优雅的方法让ext 工作?

更新:有一些丑陋的方法:

    来自 Gradle Kotlin DSL 示例,https://github.com/gradle/kotlin-dsl/tree/master/samples/project-properties,在gradel.properties 中声明属性。

    kotlinVersion = 1.1.4
    springBootVersion = 2.0.0.M3
    

    并在 build.gradle.kts 中使用它。

    buildScript
       val kotlinVersion by project
    
    
     val kotlinVersion by project //another declare out of buildscript block.
    

    与上述类似,在 buildScript 块中声明它们:

    buildScript
       extra["kotlinVersion"] = "1.1.4"
       extra["springBootVersion"] = "2.0.0.M3"
       val kotlinVersion: String by extra
    
    
     val kotlinVersion: String by extra//another declare out of buildscript block.
    

如何避免重复val kotlinVersion: String by extra

【问题讨论】:

不知道如何避免重复,不过可以加入:extra["kotlinVersion"] = "1.1.4" val kotlinVersion: String by extra to val kotlinVersion: String by extra("1.1.4") @ClausHolst 很好的说明! 【参考方案1】:

使用 Kotlin DSL ext 已更改为 extra,可以在 buildscript 下使用。

例如:-

buildscript 
    // Define versions in a single place
    extra.apply
        set("minSdkVersion", 26)
        set("targetSdkVersion", 27)
    

【讨论】:

如果我想向 extras 对象添加一个函数,这将如何工作? 您能否添加一个有关如何使用该属性的示例?只是implementation("org.library:library:$myVersion") 不起作用。 不幸的是,它在 buildscript 中对我不起作用。 读取额外属性:val myVersion: String by rootProject.extraimplementation("org.library:library:$myVersion") 这并不比使用 groovy 更容易,即使它确实有效......【参考方案2】:

可以在.gradle.kts 文件中使用.kt 文件中定义的常量。

在项目的根文件夹中创建buildSrc 文件夹

使用以下内容创建buildSrc/build.gradle.kts 文件

plugins 
    `kotlin-dsl`


repositories 
    mavenCentral()

使用以下内容创建文件buildSrc/src/main/kotlin/Constants.kt

object Constants 
    const val kotlinVersion = "1.3.70"
    const val targetSdkVersion = 28

同步。现在您可以像这样在各种.gradle.kts 文件中引用创建的常量

...
classpath(kotlin("gradle-plugin", version = Constants.kotlinVersion))
...

...
targetSdkVersion(Constants.targetSdkVersion)
...

【讨论】:

这可以完美运行,即使对于多模块项目也是如此,并且不需要构建脚本中的丑陋代码。太棒了! 喜欢这个解决方案,谢谢!您对如何将 buildSrc 作为工件共享以便可以在独立项目之间重用有任何指示吗?只是一些文档的链接就可以了,我只是不确定从哪里开始寻找 @EmilKantis,对不起,不知道这样的解决方案。尝试在 *** 上搜索/询问 @EmilKantis buildSrc 本质上就像一个自动应用到所有子项目的 Gradle 插件,所以您要做的是创建一个 Gradle 插件。 :) 我遇到的最大问题是,ext 在较旧的迭代 gradle 文件中定义的版本可以与新版本库的 lint 检查器一起使用,例如android Studio,但它不适用于这些常量文件,因此您不知道是否有可用的更新版本(如果您想知道)【参考方案3】:

对我有用的是在allprojects 中使用ext 而不是buildscript,所以在你的***build.gradle.kts

allprojects 
  ext 
    set("supportLibraryVersion", "26.0.1")
  

然后你可以在模块中的build.gradle.kts 文件中使用它,如下所示:

val supportLibraryVersion = ext.get("supportLibraryVersion") as String

【讨论】:

或者稍微简洁一点:val supportLibraryVersion : String? by ext 这甚至无法编译。【参考方案4】:

我们可以使用 Kotlin 的新可能性:

object DependencyVersions 
    const val JETTY_VERSION = "9.4.12.v20180830"


dependencies
    implementation("org.eclipse.jetty:jettyserver:$DependencyVersions.JETTY_VERSION")

这里,DependencyVersions 是我选择的名称。您可以选择其他名称, 像“MyProjectVariables”。这是一种避免使用 extra 或 ext 属性的方法。

【讨论】:

我认为使用伴随对象会更符合 kotlin 风格 @MattKerr 一点也不,如果你需要一个单例,你应该使用object 你能在子项目中引用这个吗?【参考方案5】:

kotlin-gradle-dsl 中的全局属性:https://***.com/a/53594357/3557894


Kotlin 版本嵌入到 kotlin-gradle-dsl 中。 您可以使用嵌入式版本的依赖项,如下所示:

implementation(embeddedKotlin("stdlib-jdk7"))

classpath(embeddedKotlin("gradle-plugin"))

【讨论】:

较新的方法是添加到插件:kotlin("jvm") 和添加到部门:implementation(kotlin("stdlib-jdk8")【参考方案6】:

这些答案对我来说都不是很清楚。 所以这是我的解释:

/build.gradle.kts

buildscript 
    extra.apply 
        set("compose_version", "1.0.3")
    
    ...

/app/build.gradle.kts

val composeVersion = rootProject.extra["compose_version"]
implementation("androidx.compose.ui:ui:$composeVersion")
implementation("androidx.compose.material:material:$composeVersion")

【讨论】:

【参考方案7】:
val junitVersion by extra("4.13.2")
testImplementation("junit:junit:$junitVersion")

【讨论】:

【参考方案8】:

可以在 gradle.properties 中定义全局属性:

xyzVersion=1.0.0

然后在你的模块的 build.gradle.kts 中使用它们:

val xyzVersion: String by project

【讨论】:

以上是关于Gradle Kotlin DSL 无法识别 buildscript 中的 ext的主要内容,如果未能解决你的问题,请参考以下文章

在 buildSrc 中定义的 Gradle Kotlin DSL 未解析的引用

如何使用 Gradle Kotlin DSL 对 Spring Boot 应用程序进行 Dockerize

Gradle Kotlin DSL:在独特的地方定义 Kotlin 版本

如何从非 build-gradle 文件访问 Kotlin DSL 扩展?

使用 Gradle Kotlin DSL 发布 Kotlin MPP 元数据

如何使用 gradle kotlin-dsl 添加新的源集