Edit Page

配置 Gradle 项目

最终更新: 2024/03/21

Gradle 使用来构建 Kotlin 项目, 你需要向你的构建脚本文件 build.gradle(.kts) 添加 Kotlin Gradle plugin,
并在构建脚本文件中 配置项目的依赖项.

关于构建脚本, 更多内容请参见 查看构建脚本 小节.

应用(Apply) Kotlin Gradle Plugin

要应用(Apply) Kotlin Gradle plugin, 请使用 Gradle plugin DSL 的 plugins{} 代码段:

// 请将 `<...>` 替换为 plugin 名称 
plugins {
    kotlin("<...>") version "1.9.23"
}
// 请将 `<...>` 替换为 plugin 名称
plugins {
    id 'org.jetbrains.kotlin.<...>' version '1.9.23'
}

Kotlin Gradle plugin (KGP) 和 Kotlin 的版本号一致.

配置你的项目时, 请检查 Kotlin Gradle plugin (KGP) 是否兼容于你的 Gradle 版本. 下表是, Kotlin 完全支持 的 Gradle 和 Android Gradle plugin (AGP) 最低和最高版本:

KGP 版本 Gradle 最低和最高版本 AGP 最低和最高版本
1.9.20–1.9.23 6.8.3–8.1.1 4.2.2–7.4.0
1.9.0–1.9.10 6.8.3–7.6.0 4.2.2–7.4.0
1.8.20–1.8.22 6.8.3–7.6.0 4.1.3–7.4.0
1.8.0–1.8.11 6.8.3–7.3.3 4.1.3–7.2.1
1.7.20–1.7.22 6.7.1–7.1.1 3.6.4–7.0.4
1.7.0–1.7.10 6.7.1–7.0.2 3.4.3–7.0.2
1.6.20–1.6.21 6.1.1–7.0.2 3.4.3–7.0.2

你也可以使用最新版本之前的 Gradle 和 AGP 版本, 但如果你这样做, 请注意, 你可能会遇到弃用警告, 或者某些新功能可能无法正常工作.

例如, Kotlin Gradle plugin 和 kotlin-multiplatform plugin 1.9.23 最低需要 Gradle 版本 6.8.3 才能编译你的项目.

类似的, 完全支持的最高版本是 8.1.1. 这个版本不包含已废弃的 Gradle 方法和属性, 并且支持目前所有的 Gradle 功能特性.

编译到 JVM 平台

要编译到 JVM 平台, 需要应用 Kotlin JVM plugin.

plugins {
    kotlin("jvm") version "1.9.23"
}
plugins {
    id "org.jetbrains.kotlin.jvm" version "1.9.23"
}

在这段代码中, version 必须是写明的字面值, 不能通过其他编译脚本得到.

Kotlin 源代码与 Java 源代码

Kotlin 源代码与 Java 源代码可以保存在相同的目录下, 也可以放在不同的目录下.

默认的约定是使用不同的目录:

project
    - src
        - main (root)
            - kotlin
            - java

不要将 Java 的 .java 文件放在 src/*/kotlin 目录中, 因为这样的 .java 文件不会被编译.

你应该改为放在 src/main/java 目录中.

如果不使用默认约定的文件夹结构, 那么需要修改相应的 sourceSets 属性:

sourceSets.main {
    java.srcDirs("src/main/myJava", "src/main/myKotlin")
}
sourceSets {
    main.kotlin.srcDirs += 'src/main/myKotlin'
    main.java.srcDirs += 'src/main/myJava'
}

对相关联的编译任务检查 JVM 编译目标的兼容性

在构建模块中, 你可能会有多个相互关联的编译任务, 比如:

  • compileKotlincompileJava
  • compileTestKotlincompileTestJava

maintest 源代码集的编译任务之间没有关联.

对于这种相互关联的编译任务, Kotlin Gradle plugin 会检查 JVM 编译目标的兼容性. kotlin 扩展或任务中的 jvmTarget 属性java 扩展或任务中的 targetCompatibility 如果设置为不同的值, 会导致 JVM 编译目标不兼容. 例如: compileKotlin 任务设置为 jvmTarget=1.8, 而 compileJava 任务设置为 (或 继承得到) targetCompatibility=15.

要对整个项目的这个兼容性检查进行配置, 可以在 build.gradle(.kts) 文件中, 将 kotlin.jvm.target.validation.mode 属性设置为以下几个值:

  • error – plugin 会让构建失败; 对于 Gradle 8.0 以上版本, 这是项目的默认值.
  • warning – plugin 会输出警告信息; 对于低于 Gradle 8.0 的版本, 这是项目的默认值.
  • ignore – plugin 会跳过检查, 不输出任何警告信息.

你也可以在你的 build.gradle(.kts) 文件中对各个编译任务单独进行配置:

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile>().configureEach {
    jvmTargetValidationMode.set(org.jetbrains.kotlin.gradle.dsl.jvm.JvmTargetValidationMode.WARNING)
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile.class).configureEach {
    jvmTargetValidationMode = org.jetbrains.kotlin.gradle.dsl.jvm.JvmTargetValidationMode.WARNING
}

要避免 JVM 编译目标不兼容, 需要 配置工具链, 或手动对齐(Align) JVM 版本.

如果编译目标之间不兼容, 会发生什么问题

有两种方式对 Kotlin 和 Java 源代码集手动设置 JVM 编译目标:

  • 隐含设定, 通过 设置 Java 工具链 来设置.
  • 明确设定, 通过设置 kotlin 扩展或任务中的 jvmTarget 属性, 以及java 扩展或任务中的 targetCompatibility.

如果你做以下设置, 就会发生 JVM 编译目标不兼容:

  • jvmTargettargetCompatibility 明确设置不同的版本.
  • 使用默认配置, 但你的 JDK 不等于 1.8.

如果在你的构建脚本中只有 Kotlin JVM plugin, 并且没有额外设置 JVM 编译目标, 我们来看看这时的默认 JVM 编译目标设置:

plugins {
    kotlin("jvm") version "1.9.23"
}
plugins {
    id "org.jetbrains.kotlin.jvm" version "1.9.23"
}

构建脚本中没有 jvmTarget 值的明确信息, 因此它的默认值为 null, 编译器将这个设置翻译为默认值 1.8. targetCompatibility 等于当前的 Gradle JDK 版本, 也就是你的 JDK 版本 (除非你使用 Java 工具链策略). 假设你的 JDK 版本是 17, 你发布的库文件会 声明它兼容 于 JDK 17 以上版本: org.gradle.jvm.version=17, 实际上是错误的. 这种情况下, 在你的主项目中, 会需要使用 Java 17 才能添加这个库, 尽管它的字节码版本其实是 1.8. 请 配置工具链 来解决这个问题.

Gradle Java 工具链支持

给 Android 使用者的警告. 要使用 Gradle 工具链支持, 需要使用 Android Gradle plugin (AGP) 的 8.1.0-alpha09 或更高版本.

Gradle Java 工具链支持只在 AGP 7.4.0 以上版本 可用. 但是, 由于 这个问题, AGP 8.1.0-alpha09 以前的版本没有将 targetCompatibility 设置为等于工具链的 JDK. 如果你在使用低于 8.1.0-alpha09 的版本, 你需要通过 compileOptions 来手动配置 targetCompatibility. 请将占位符 <MAJOR_JDK_VERSION> 替换为你想要使用的 JDK 版本:

android {
    compileOptions {
        sourceCompatibility = <MAJOR_JDK_VERSION>
        targetCompatibility = <MAJOR_JDK_VERSION>
    }
}

Gradle 6.7 引入了 Java 工具链支持. 通过这个功能, 你可以:

  • 使用与 Gradle 不同的 JDK 和 JRE 来运行编译, 测试, 以及可执行程序.
  • 使用还未发布的语言版本编译和测试代码.

通过工具链支持, Gradle 能够自动查找本地的 JDK, 还能安装 Gradle 运行构建时需要的 JDK. 目前 Gradle 自身能够在任何 JDK 上运行, 而且还对依赖于主要 JDK 版本的任务重用 远程构建缓存功能.

Kotlin Gradle plugin 对 Kotlin/JVM 编译任务支持 Java 工具链. JS 和 Native 任务则不会使用工具链. Kotlin 编译器永远会在运行 Gradle daemon 的 JDK 上运行. Java 工具链会:

可以使用以下代码来设置工具链. 请将占位符 <MAJOR_JDK_VERSION> 替换为你想要使用的 JDK 版本:

kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>))
    }
    // 或者使用更简短的写法:
    jvmToolchain(<MAJOR_JDK_VERSION>)
    // 例如:
    jvmToolchain(17)
}
kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>))
    }
    // 或者使用更简短的写法:
    jvmToolchain(<MAJOR_JDK_VERSION>)
    // 例如:
    jvmToolchain(17)
}

注意, 如果使用 kotlin 扩展设置工具链, 也会改变 Java 编译任务的工具链.

你可以通过 java 扩展设置工具链, Kotlin 编译任务会使用这个设置:

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) 
    }
}
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) 
    }
}

如果你使用 Gradle 8.0.2 或更高版本, 你还需要添加一个 工具链解析器 plugin. 这种 plugin 会管理从哪个仓库下载工具链. 例如, 向你的 settings.gradle(.kts) 文件添加以下 plugin:

plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version("0.5.0")
}
plugins {
    id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0'
}

关于与你的 Gradle 版本对应的 foojay-resolver-convention 版本, 请参见 Gradle 网站.

要确认 Gradle 使用哪个工具链, 请使用 log 级别 --info 来运行你的 Gradle 构建, 并在输出中查找 [KOTLIN] Kotlin compilation 'jdkHome' argument: 开头的字符串. 冒号之后的部分就是工具链使用的 JDK 版本.

要为特定的 Task 设置任意的 JDK (甚至本地 JDK), 请使用 Task DSL.

详情请参见 Kotlin plugin 中对 Gradle JVM 工具链的支持.

使用 Task DSL 设置 JDK 版本

Task DSL 可以对任何实现了 UsesKotlinJavaToolchain 接口的任务, 设置任意的 JDK 版本. 目前, 这些任务只有 KotlinCompileKaptTask. 如果希望 Gradle 搜索主要的 JDK 版本, 请在你的构建脚本中替换 <MAJOR_JDK_VERSION> 占位符:

val service = project.extensions.getByType<JavaToolchainService>()
val customLauncher = service.launcherFor {
    languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>))
}
project.tasks.withType<UsesKotlinJavaToolchain>().configureEach {
    kotlinJavaToolchain.toolchain.use(customLauncher)
}
JavaToolchainService service = project.getExtensions().getByType(JavaToolchainService.class)
Provider<JavaLauncher> customLauncher = service.launcherFor {
    it.languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>))
}
tasks.withType(UsesKotlinJavaToolchain::class).configureEach { task ->
    task.kotlinJavaToolchain.toolchain.use(customLauncher)
}

或者你特也可以指定你的本地 JDK 路径, 然后使用这个 JDK 版本替换 <LOCAL_JDK_VERSION> 占位符:

tasks.withType<UsesKotlinJavaToolchain>().configureEach {
    kotlinJavaToolchain.jdk.use(
        "/path/to/local/jdk", // 这里设置你的 JDK 路径
        JavaVersion.<LOCAL_JDK_VERSION> // 例如, JavaVersion.17
    )
}

关联编译器任务

你可以将编译任务 关联(Associate) 在一起, 方法是在编译任务之间设置关联关系, 一个编译需要使用另一个编译的输出. 关联编译器任务会在编译任务之间建立 internal 的可见度.

Kotlin 编译器会默认的关联某些编译任务, 比如每个编译目标的 testmain 编译任务. 如果你需要表达你的某个自定义编译任务与其它编译任务相关联, 请创建你自己的编译任务关联.

要让 IDE 支持关联编译任务, 在源代码集之间推断可见度, 请向你的 build.gradle(.kts) 添加以下代码:

val integrationTestCompilation = kotlin.target.compilations.create("integrationTest") {
    associateWith(kotlin.target.compilations.getByName("main"))
}
integrationTestCompilation {
    kotlin.target.compilations.create("integrationTest") {
        associateWith(kotlin.target.compilations.getByName("main"))
    }
}

在这个例子中, integrationTest 编译任务关联到 main 编译任务, 可以在功能测试(集成测试)代码中访问 internal 对象.

Java Modules (JPMS) 启用时的配置

要让 Kotlin Gradle plugin 与 Java 模块(Module) 共通工作, 请向你的构建脚本添加以下内容, 并将其中的 YOUR_MODULE_NAME 替换为你的 JPMS 模块的引用, 例如, org.company.module:

// 如果你使用的 Gradle 版本低于 7.0, 请添加以下 3 行
java {
    modularity.inferModulePath.set(true)
}

tasks.named("compileJava", JavaCompile::class.java) {
    options.compilerArgumentProviders.add(CommandLineArgumentProvider {
        // 将编译后的 Kotlin 类提供给 to javac – 需要这样做才能让 Java/Kotlin 混合源代码正常工作
        listOf("--patch-module", "YOUR_MODULE_NAME=${sourceSets["main"].output.asPath}")
    })
}
// 如果你使用的 Gradle 版本低于 7.0, 请添加以下 3 行
java {
    modularity.inferModulePath = true
}

tasks.named("compileJava", JavaCompile.class) {
    options.compilerArgumentProviders.add(new CommandLineArgumentProvider() {
        @Override
        Iterable<String> asArguments() {
            // Provide compiled Kotlin classes to javac – 需要这样做才能让 Java/Kotlin 混合源代码正常工作
            return ["--patch-module", "YOUR_MODULE_NAME=${sourceSets["main"].output.asPath}"]
        }
    })
}

和通常一样, 请将 module-info.java 文件放在 src/main/java 目录内.

对于模块, Kotlin 文件中的包名称应该等于 module-info.java 中的包名称, 否则会出现构建错误 "package is empty or does not exist".

更多详情请参见:

其他细节

详情请参见 Kotlin/JVM.

Kotlin/JVM 编译任务的延迟创建

从 Kotlin 1.8.20 开始, Kotlin Gradle plugin 在试运行(dry run)时会注册所有的编译任务, 但不对它们进行配置.

如果编译任务的输出目录不是默认位置

如果你覆盖了 Kotlin/JVM KotlinJvmCompile/KotlinCompile 编译任务的 destinationDirectory 位置, 请更新你的构建脚本. 在你的 JAR 文件中, 除 sourceSets.main.outputs 之外, 你需要明确添加 sourceSets.main.kotlin.classesDirectories:

tasks.jar(type: Jar) {
    from sourceSets.main.outputs
    from sourceSets.main.kotlin.classesDirectories
}

编译到多个目标平台

编译到 多个目标平台 的项目, 称为 跨平台项目, 需要使用 kotlin-multiplatform 插件.

kotlin-multiplatform 插件要求 Gradle 6.8.3 或更高版本.

plugins {
    kotlin("multiplatform") version "1.9.23"
}
plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.9.23'
}

详情请参见 在不同的平台使用 Kotlin Multiplatform在 iOS 和 Android 平台使用 Kotlin Multiplatform.

编译到 Android 平台

建议使用 Android Studio 来创建 Android 应用程序. 详情请参见 如何使用 Android Gradle plugin.

编译到 JavaScript

如果编译目标平台为 JavaScript, 也可以使用 kotlin-multiplatform 插件. 详情请阅读 如何设置 Kotlin/JS 项目:

plugins {
    kotlin("multiplatform") version "1.9.23"
}
plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.9.23'
}

JavaScript 项目的 Kotlin 源代码与 Java 源代码

这个 plugin 只能编译 Kotlin 源代码文件, 因此推荐将 Kotlin 和 Java 源代码文件放在不同的文件夹内(如果工程内包含 Java 文件的话). 如果不将源代码分开存放, 请在 sourceSets{} 代码段中指定源代码文件夹:

kotlin {
    sourceSets["main"].apply {    
        kotlin.srcDir("src/main/myKotlin") 
    }
}
kotlin {
    sourceSets {
        main.kotlin.srcDirs += 'src/main/myKotlin'
    }
}

使用 KotlinBasePlugin 接口触发配置动作

当任何 Kotlin Gradle plugin (JVM, JS, Multiplatform, Native, 等等) 被适用时, 要触发某些配置动作, 可以使用 KotlinBasePlugin 接口, 所有的 Kotlin plugin 都继承了这个接口:

import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin

// ...

project.plugins.withType<KotlinBasePlugin>() {
    // 在这里配置你的动作
}
import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin

// ...

project.plugins.withType(KotlinBasePlugin.class) {
    // 在这里配置你的动作
}

配置依赖项

如果要添加一个库的依赖, 需要在 source set DSL 中的 dependencies{} 代码段内, 设置必要 类型 的依赖项 (比如, implementation).

kotlin {
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("com.example:my-library:1.0")
            }
        }
    }
}
kotlin {
    sourceSets {
        commonMain {
            dependencies {
                implementation 'com.example:my-library:1.0'
            }
        }
    }
}

或者, 你也可以 在最顶层设置依赖项.

依赖项的类型

请根据你的需要选择依赖项的类型.

类型 解释 使用场景
api 编译期和运行期都会使用, 并导出给库的使用者. 如果在当前模块的公开 API 中使用了一个依赖项中的任何类型, 请使用 api 依赖项.
implementation 对当前模块的编译期和运行期都会使用, 如果其他模块使用 `implementation` 依赖本模块, 那么对于其他模块的编译, 这个依赖项不会导出

对于模块的内部逻辑所需要的依赖项, 请使用这种类型.

如果一个模块是一个终端应用程序(endpoint application), 而且不对外公布(publish), 那么请使用 implementation 依赖项而不是 api 依赖项.

compileOnly 只用来编译当前模块, 在运行期不可用, 在编译其他模块时也不可用. 如果 API 在运行时存在第三方的实现, 那么可以使用这种依赖项.
runtimeOnly 运行时可用, 但在任何模块的编译期都不可用.

对标准库的依赖项

对每个源代码集(Source Set), 会自动添加对标准库 (stdlib) 的依赖项. 使用的标准库版本与 Kotlin Gradle plugin 版本相同.

对于与平台相关的源代码集, 会使用针对这个平台的标准库, 同时, 对其他源代码集会添加共通的标准库. Kotlin Gradle plugin 会根据你的 Gradle 构建脚本的 compilerOptions.jvmTarget 编译器选项 设置, 选择适当的 JVM 标准库.

如果明确的声明一个标准库依赖项(比如, 如果你需要使用不同的版本), Kotlin Gradle plugin 不会覆盖你的设置, 也不会添加第二个标准库.

如果你完全不需要标准库, 可以在你的 gradle.properties 文件中添加以下 Gradle 属性:

kotlin.stdlib.default.dependency=false

传递依赖项的版本对齐

从 Kotlin 标准库 1.9.20 版开始, Gradle 使用包含在标准库中的元数据(metadata), 来自动对齐传递依赖项 kotlin-stdlib-jdk7kotlin-stdlib-jdk8 的版本.

如果你添加了 Kotlin 标准库版本 1.8.0 到 1.9.10 之间的依赖项, 例如: implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.0"), 那么 Kotlin Gradle Plugin 会对传递依赖项 kotlin-stdlib-jdk7kotlin-stdlib-jdk8 使用这个 Kotlin 版本. 这样会避免标准库的不同版本出现重复的类. 详情请参见 kotlin-stdlib-jdk7kotlin-stdlib-jdk8 合并到 kotlin-stdlib. 你可以在你的 gradle.properties 文件中使用 Gradle 属性 kotlin.stdlib.jdk.variants.version.alignment 来禁用这个动作:

kotlin.stdlib.jdk.variants.version.alignment=false
版本对齐的另一种方法
  • 如果版本对齐出现了问题, 你可以使用 Kotlin BOM 来对齐所有依赖项的版本. 在你的构建脚本中声明对 kotlin-bom 的平台依赖项:

    implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.9.23"))
    
    implementation platform('org.jetbrains.kotlin:kotlin-bom:1.9.23')
    
  • 如果你没有添加某个版本的标准库的依赖项, 但你有两个不同的依赖项, 分别带来 Kotlin 标准库不同旧版本的传递依赖, 那么你可以对这些传递依赖的库明确指定 1.9.23 版本:

    dependencies {
        constraints {
            add("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk7") {
                version {
                    require("1.9.23")
                }
            }
            add("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk8") {
                version {
                    require("1.9.23")
                }
            }
        }
    }
    
    dependencies {
        constraints {
            add("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk7") {
                version {
                    require("1.9.23")
                }
            }
            add("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk8") {
                version {
                    require("1.9.23")
                }
            }
        }
    }
    
  • 如果你添加了 Kotlin 标准库 1.9.23 的依赖项: implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.23"), 并且使用了旧版本的 (低于 1.8.0) Kotlin Gradle plugin, 请更新 Kotlin Gradle plugin, 保持与标准库的版本一致:

    plugins {
        // 请将 `<...>` 替换为 plugin 名称
        kotlin("<...>") version "1.9.23"
    }
    
    plugins {
        // 请将 `<...>` 替换为 plugin 名称
        id "org.jetbrains.kotlin.<...>" version "1.9.23"
    }
    
  • 如果你使用旧版本 (低于 1.8.0) 的 kotlin-stdlib-jdk7/kotlin-stdlib-jdk8, 例如, implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:SOME_OLD_KOTLIN_VERSION"), 并且某个依赖项传递依赖到 kotlin-stdlib:1.8+, 请将你的 kotlin-stdlib-jdk<7/8>:SOME_OLD_KOTLIN_VERSION 替换为 kotlin-stdlib-jdk*:1.9.23, 或者在传递依赖它的库中 排除(exclude) kotlin-stdlib:1.8+:

    dependencies {
        implementation("com.example:lib:1.0") {
            exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
        }
    }
    
    dependencies {
         implementation("com.example:lib:1.0") {
          exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib"
      }
    }
    

设置对测试库的依赖项

对于支持的所有平台, Kotlin 项目的测试可以使用 kotlin.test API. 对 commonTest 源代码集添加 kotlin-test 依赖项, 然后 Gradle plugin 会为每个测试源代码集推断出对应的测试库依赖项:

  • 对共通源代码集, 会添加 kotlin-test-commonkotlin-test-annotations-common 依赖项
  • 对 JVM 源代码集, 会添加 kotlin-test-junit 依赖项
  • 对 Kotlin/JS 源代码集, 会添加 kotlin-test-js 依赖项

Kotlin/Native 编译目标已经内建了 kotlin.test API 的实现, 不需要额外的测试依赖项.

kotlin {
    sourceSets {
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test")) // 这个设置会自动引入对应平台的所有依赖项
            }
        }
    }
}
kotlin {
    sourceSets {
        commonTest {
            dependencies {
                implementation kotlin("test") // 这个设置会自动引入对应平台的所有依赖项
            }
        }
    }
}

对 Kotlin 模块的依赖项, 可以使用简写, 比如, 对 "org.jetbrains.kotlin:kotlin-test" 的依赖项可以简写为 kotlin("test").

你也可以在任何共通源代码集或平台相关的源代码集中使用 kotlin-test 依赖项.

对于 Kotlin/JVM, Gradle 默认使用 JUnit 4. 因此, kotlin("test") 依赖项会解析为 JUnit 4 的变体, 名为 kotlin-test-junit.

也可以选择使用 JUnit 5 或 TestNG, 方法是在构建脚本的测试任务中调用 useJUnitPlatform()useTestNG(). 下面是一个 Kotlin Multiplatform 项目的示例:

kotlin {
    jvm {
        testRuns["test"].executionTask.configure {
            useJUnitPlatform()
        }
    }
    sourceSets {
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
    }
}
kotlin {
    jvm {
        testRuns["test"].executionTask.configure {
            useJUnitPlatform()
        }
    }
    sourceSets {
        commonTest {
            dependencies {
                implementation kotlin("test")
            }
        }
    }
}

下面是一个 JVM 项目的示例:

dependencies {
    testImplementation(kotlin("test"))
}

tasks {
    test {
        useTestNG()
    }
}
dependencies {
    testImplementation 'org.jetbrains.kotlin:kotlin-test'
}

test {
    useTestNG()
}

参见 在 JVM 平台上如何使用 JUnit 测试代码.

如果需要使用不同的 JVM 测试框架, 可以在项目的 gradle.properties 文件添加 kotlin.test.infer.jvm.variant=false, 关闭测试框架的自动选择. 然后, 再将需要的测试框架添加为 Gradle 依赖项.

如果你在构建脚本中明确使用了 kotlin("test") 的变体, 而且项目的构建脚本出现兼容性冲突问题, 不再正常工作, 请参见 兼容性指南中的这个问题.

设置对 kotlinx 库的依赖项

如果使用 kotlinx, 并且需要与平台相关的依赖项, 那么可以通过 -jvm-js 之类的后缀, 来指定与平台相关的库版本, 例如, kotlinx-coroutines-core-jvm. 也可以使用库的基本 artifact 名(base artifact name) – kotlinx-coroutines-core.

kotlin {
    sourceSets {
        val jvmMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3")
            }
        }
    }
}
kotlin {
    sourceSets {
        jvmMain {
            dependencies {
                implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3'
            }
        }
    }
}

如果使用跨平台的库, 并且需要依赖共用代码, 那么只需要在共用源代码集中一次性设置依赖项. 请使用库的基本 artifact 名(base artifact name), 例如 kotlinx-coroutines-corektor-client-core.

kotlin {
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
            }
        }
    }
}
kotlin {
    sourceSets {
        commonMain {
            dependencies {
                implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
            }
        }
    }
}

在最顶层设置依赖项

另一种做法是, 可以在最顶层指定依赖项, 方法是使用 <sourceSetName><DependencyType> 格式的配置名称. 对于某些 Gradle 内建的依赖项, 比如 gradleApi(), localGroovy(), 或 gradleTestKit(), 这种方法会很有用, 这些依赖项在 Source Set 依赖项 DSL 中是不能使用的.

dependencies {
    "commonMainImplementation"("com.example:my-library:1.0")
}
dependencies {
    commonMainImplementation 'com.example:my-library:1.0'
}

声明仓库

你可以声明一个可公开访问的仓库, 使用它的 open source 依赖项. 请在 repositories{} 代码段中, 设置仓库的名称:

repositories {
    mavenCentral()
}
repositories {
    mavenCentral()
}

常用的仓库是 Maven CentralGoogle's Maven repository.

如果你同时也在使用 Maven 项目, 我们建议不要将 mavenLocal() 添加为仓库, 因为在 Gradle 和 Maven 项目间切换时, 你可能遇到问题. 如果你一定需要添加 mavenLocal() 仓库, 请在你的 repositories{} 代码段中, 将它添加为最后一个仓库. 更多详情请参见 使用 mavenLocal() 的情况.

如果你需要在多个子项目中声明相同的仓库, 请在你的 settings.gradle(.kts) 文件中, 在 dependencyResolutionManagement{} 代码段中集中声明仓库:

dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}

在子项目中声明的任何仓库, 都会覆盖集中声明的仓库. 关于如何控制这种行为, 有什么解决办法, 详情请参见 Gradle 的文档.

下一步做什么?

学习: