不能直接为单个gradle任务设置编译选项,必须在compilation或target层级配置,因为compilekotlin等任务只是wrapper,真正控制编译行为的是compilation的compileroptions。

不能直接为单个 Gradle 任务设置编译选项,必须作用于 compilation 或 target 层级。 因为 compileKotlin 这类任务本身不持有编译参数,它只是触发底层 KotlinCompile 任务的 wrapper;真正控制字节码版本、警告行为等的是 compilation 的 compilerOptions。
为什么不能在 task.configure 里设 jvmTarget 或 -Werror
你可能会试这样的写法:
tasks.named<org.jetbrains.kotlin.gradle.tasks.kotlincompile>("compileKotlin") {
compilerOptions.jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8)
}</org.jetbrains.kotlin.gradle.tasks.kotlincompile>
这会编译失败或静默忽略——因为 compileKotlin 任务实例在配置阶段尚未关联到任何 compilation 实例,compilerOptions 此时是空壳。Kotlin Gradle Plugin(KGP)把编译逻辑绑定在 compilation 概念上,而非任务名。
-
compileKotlin是 JVM target 下 main compilation 的默认编译任务别名,但它不是唯一入口;compileTestKotlin、compileIntegrationTestKotlin等都对应各自 compilation - 一个 target(如
jvm)可有多个 compilation(main、test、自定义integrationTest),每个 compilation 才拥有独立的compilerOptions - 任务只是 compilation 的“执行代理”,改任务本身无法改变其背后 compilation 的语义
正确做法:通过 compilations.main 或 compilations.getting 配置
必须定位到具体的 compilation 实例,再配置其 compilerOptions。以下两种写法等效,推荐后者(更明确):
kotlin {
jvm {
compilations.main {
compileTaskProvider.configure {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8)
allWarningsAsErrors.set(true)
}
}
}
}
}
-
compilations.main是 Kotlin DSL 中最简洁的写法,适用于标准 main compilation - 若需操作非标准 compilation(如自定义的
integrationTest),必须用compilations.getting("integrationTest") -
compileTaskProvider.configure是安全的延迟配置方式,确保 compilation 已创建后再改选项 - 不要漏掉
set()调用(Kotlin DSL 中属性赋值需显式 set,除非用=语法,但部分旧版 KGP 不支持)
常见错误:混淆了全局、target 和 compilation 三级配置范围
这三个层级的 compilerOptions 优先级从高到低是:compilation > target > allTargets。例如:
kotlin {
compilerOptions { allWarningsAsErrors.set(true) } // 全局生效(所有 target)
jvm {
compilerOptions { jvmTarget.set(JVM_1_8) } // 仅 JVM target 生效
compilations.main {
compileTaskProvider.configure {
compilerOptions { // 仅 main compilation 生效,覆盖上面两个
jvmTarget.set(JVM_17)
freeCompilerArgs.add("-Xjsr305=strict")
}
}
}
}
}
- 如果只在
jvm { }块里设jvmTarget,它不会自动下推到maincompilation —— 必须显式进入compilations.main -
freeCompilerArgs只能在 compilation 级别添加,全局或 target 级别不识别该属性 - Android 项目中,每个 build variant(如
debug、release)会生成独立 compilation,需分别配置,不能只配androidblock
最易被忽略的一点:自定义 compilation(如 integrationTest)默认不继承 commonMain 或 main 的依赖和编译选项,compilerOptions 必须手动设置,否则可能用默认 JVM_1_6 导致运行时报 UnsupportedClassVersionError。











