Gradle 与 Kotlin 项目配置

Kotlin 官方推荐使用 Gradle 管理大多数 Kotlin 项目。理解 Kotlin Gradle Plugin、source set、JVM target、Java toolchain 和多平台配置,是稳定构建 Kotlin 项目的基础。

应用 Kotlin Gradle Plugin

Kotlin JVM 项目:

plugins {
    kotlin("jvm") version "2.4.0"
}

Groovy DSL:

plugins {
    id 'org.jetbrains.kotlin.jvm' version '2.4.0'
}

Kotlin Multiplatform 项目:

plugins {
    kotlin("multiplatform") version "2.4.0"
}

Kotlin Gradle Plugin,简称 KGP,和 Kotlin 使用相同版本号。升级 Kotlin 时,本质上也在升级 KGP。

版本兼容

官方文档列出了 KGP 与 Gradle、Android Gradle Plugin 的兼容范围。以 Kotlin/KGP 2.4.0 为例,官方页面显示它要求 Gradle 至少 7.6.3,并完整支持到 Gradle 9.5.0;Android Gradle Plugin 也有对应兼容范围。

实践建议:

  • 不要只升级 Kotlin,不看 Gradle/AGP 兼容矩阵。
  • Android 项目尤其要同时检查 Kotlin、AGP、Gradle、JDK。
  • CI 和本机 Gradle wrapper 必须一致。

不要提交 .kotlin

Kotlin Gradle Plugin 默认会在项目根目录的 .kotlin 目录保存项目级持久数据。

应加入 .gitignore

.kotlin/

这类目录是构建工具缓存,不应进入版本控制。

JVM 项目基本结构

默认结构:

src/
  main/
    kotlin/
    java/
  test/
    kotlin/
    java/

官方建议不要把 Java .java 文件放在 src/*/kotlin 中,因为这些 Java 文件不会被编译。Java 文件应放在 src/main/java 或明确配置的 Java source dir。

Kotlin 与 Java 混合源码

sourceSets {
    main {
        kotlin.srcDirs("src/main/kotlin")
        java.srcDirs("src/main/java")
    }
}

大多数项目无需手动配置,遵循默认目录即可。

Java 对比:Java 项目通常只有 src/main/java。Kotlin/JVM 混合项目建议明确分开 kotlinjava,便于工具链处理。

JVM target 与 Java toolchain

Kotlin 编译目标和 Java 编译目标需要一致。例如 Kotlin 编到 JVM 1.8,Java 编到 17,可能导致构建或运行问题。

推荐使用 toolchain:

kotlin {
    jvmToolchain(21)
}

或结合 Java 插件:

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(21))
    }
}

Kotlin Gradle Plugin 会检查相关编译任务的 JVM target 兼容性。Gradle 8.0+ 默认更倾向于把不兼容视为错误。

compilerOptions

现代 Kotlin Gradle 配置推荐使用 compilerOptions

kotlin {
    compilerOptions {
        jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
        freeCompilerArgs.add("-Xjsr305=strict")
    }
}

模块、source set、task 级别都可能有 compiler options。团队应约定配置层级,避免同一选项在多处冲突。

依赖声明

JVM 项目:

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

现代 Kotlin 项目通常不需要显式添加 stdlib,插件会处理默认依赖;但库项目、特殊构建或版本对齐场景仍可能显式声明。

Multiplatform 配置

kotlin {
    jvm()
    js {
        browser()
    }
    iosArm64()
    iosSimulatorArm64()

    sourceSets {
        commonMain.dependencies {
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0")
        }
        commonTest.dependencies {
            implementation(kotlin("test"))
        }
    }
}

KMP 的关键不是“写很多 target”,而是明确:

  • 哪些代码放 common。
  • 哪些依赖支持哪些 target。
  • 每个 target 产物如何被消费。

Android 项目注意事项

Android 项目要同时考虑:

  • Kotlin version。
  • Android Gradle Plugin version。
  • Gradle version。
  • JDK version。
  • Compose compiler 或 Kotlin compiler plugin 版本。

如果使用 Kotlin Multiplatform + Android,还要关注 Android target 与 KMP plugin 的兼容范围。

构建脚本 Kotlin DSL vs Groovy DSL

Kotlin DSL:

plugins {
    kotlin("jvm") version "2.4.0"
}

Groovy DSL:

plugins {
    id 'org.jetbrains.kotlin.jvm' version '2.4.0'
}

Kotlin DSL 优点:

  • 类型安全。
  • IDE 补全更好。
  • 与 Kotlin 项目语言一致。

Groovy DSL 优点:

  • 老项目存量多。
  • 某些 Gradle 文档和插件示例仍以 Groovy 为主。

新 Kotlin 项目通常优先选择 Kotlin DSL。

常见构建问题

Kotlin 与 Gradle 版本不兼容

表现:

  • 插件应用失败。
  • 构建脚本无法解析。
  • 编译任务报 Gradle API 相关错误。

处理:

  • 查看官方兼容矩阵。
  • 升级 Gradle wrapper。
  • 或降低 Kotlin/KGP 版本。

JVM target 不一致

表现:

  • Kotlin 编译目标和 Java 编译目标冲突。
  • 运行时出现 class file version 问题。

处理:

  • 使用 Java toolchain。
  • 统一 jvmTargettargetCompatibility

Java 文件放错目录

不要把 .java 放进 src/main/kotlin。放到 src/main/java

KMP commonMain 引入 JVM-only 依赖

表现:

  • JS/Native/iOS 目标解析依赖失败。

处理:

  • 把 JVM-only 依赖移动到 jvmMainandroidMain
  • commonMain 使用支持多平台的库。

实践建议

  • 所有项目使用 Gradle wrapper,避免本机 Gradle 版本漂移。
  • 升级 Kotlin 前先查 KGP/Gradle/AGP 兼容矩阵。
  • JVM 项目配置 Java toolchain,减少环境差异。
  • Java 和 Kotlin 源码按默认目录分开。
  • KMP 项目按 source set 管理依赖,不要把平台库塞进 commonMain。
  • .kotlin/.gradle/、build 输出目录不要提交。

参考

  • 官方 Gradle 配置文档:https://kotlinlang.org/docs/gradle-configure-project.html