11.1.5 Kotlin Gradle 插件中的编译器选项
10 分钟阅读
原文链接: https://kotlinlang.org/docs/gradle-compiler-options.html
11.1.5 Kotlin Gradle 插件中的编译器选项
Kotlin 的每个版本都包含面向受支持目标的编译器:JVM、JavaScript,以及面向受支持平台的本地二进制文件。
这些编译器会被以下场景使用:
- 当你在 IDE 中为 Kotlin 项目点击 Compile 或 Run 按钮时。
- 当你在控制台或 IDE 中调用
gradle build时,由 Gradle 使用。 - 当你在控制台或 IDE 中调用
mvn compile或mvn test-compile时,由 Maven 使用。
你也可以按照使用命令行编译器教程中的说明,从命令行手动运行 Kotlin 编译器。
如何定义选项
Kotlin 编译器有许多选项,可用于定制编译过程。
Gradle DSL 允许对编译器选项进行全面配置。它适用于 Kotlin Multiplatform 和 JVM/Android 项目。
借助 Gradle DSL,你可以在构建脚本中从三个级别配置编译器选项:
较高层级的设置会作为较低层级的约定(默认值):
- 在扩展级别设置的编译器选项是目标级别选项的默认值,包括
commonMain、nativeMain和commonTest等共享源集。 - 在目标级别设置的编译器选项是编译单元(任务)级别选项的默认值,例如
compileKotlinJvm和compileTestKotlinJvm任务。
相应地,较低层级的配置会覆盖较高层级的相关设置:
- 任务级编译器选项会覆盖目标级别或扩展级别的相关配置。
- 目标级编译器选项会覆盖扩展级别的相关配置。
要了解应用了哪个级别的编译器参数,请使用 Gradle 日志的 DEBUG 级别。对于 JVM 和 JS/WASM 任务,请在日志中搜索字符串 "Kotlin compiler args:";对于 Native 任务,请搜索字符串 "Arguments ="。
提示: 如果你是第三方插件作者,最好在项目级别应用你的配置,以避免覆盖问题。为此,你可以使用新的 Kotlin 插件 DSL 扩展类型。建议你在自己这一侧明确记录这一配置。
扩展级别
你可以在顶层的 compilerOptions {} 块中为所有目标和共享源集配置通用的编译器选项:
| |
目标级别
你可以在 target {} 块内的 compilerOptions {} 块中为 JVM/Android 目标配置编译器选项:
| |
在 Kotlin Multiplatform 项目中,你可以在特定目标内部配置编译器选项。例如 jvm { compilerOptions {}}。更多信息请参阅 Multiplatform Gradle DSL 参考。
编译单元级别
你可以在任务配置内的 compilerOptions {} 块中为特定的编译单元或任务配置编译器选项:
| |
你也可以通过 KotlinCompilation 在编译单元级别访问并配置编译器选项:
| |
如果你想配置的插件针对的不是 JVM/Android 和 Kotlin Multiplatform 目标,请使用相应 Kotlin 编译任务的 compilerOptions {} 属性。下面的示例展示了如何在 Kotlin 和 Groovy 两种 DSL 中进行这一配置:
Kotlin
| |
Groovy
| |
从 kotlinOptions {} 迁移到 compilerOptions {}
在 Kotlin 2.2.0 之前,你可以使用 kotlinOptions {} 块配置编译器选项。由于从 Kotlin 2.0.0 起 kotlinOptions {} 块已被弃用,本节为你把构建脚本迁移到使用 compilerOptions {} 块提供指导和建议:
集中管理编译器选项并使用类型
只要有可能,请在扩展级别配置编译器选项,并在编译单元级别为特定任务覆盖它们。
你不能在 compilerOptions {} 块中使用原始字符串,因此请把它们转换为有类型的值。例如,如果你有:
Kotlin
| |
Groovy
| |
迁移后应为:
Kotlin
| |
Groovy
| |
从 android.kotlinOptions 迁移
如果你的构建脚本之前使用 android.kotlinOptions,请改为迁移到 kotlin.compilerOptions,可以在扩展级别,也可以在目标级别。
例如,如果你有一个 Android 项目:
Kotlin
| |
Groovy
| |
请把它更新为:
Kotlin
| |
Groovy
| |
再例如,如果你有一个带 Android 目标的 Kotlin Multiplatform 项目:
Kotlin
| |
Groovy
| |
请把它更新为:
Kotlin
| |
Groovy
| |
迁移 freeCompilerArgs
- 把所有
+=操作替换为add()或addAll()函数。 - 如果你使用
-opt-in编译器选项,请检查 KGP API 参考中是否已有专用的 DSL,若有则改用它。 - 把对
-progressive编译器选项的任何使用迁移为专用 DSL:progressiveMode.set(true)。 - 把对
-Xjvm-default编译器选项的任何使用迁移为使用专用 DSL:jvmDefault.set()。这些选项使用以下映射:
| 之前 | 之后 |
| -Xjvm-default=all-compatibility | jvmDefault.set(JvmDefaultMode.ENABLE) |
| -Xjvm-default=all | jvmDefault.set(JvmDefaultMode.NO_COMPATIBILITY) |
| -Xjvm-default=disable | jvmDefault.set(JvmDefaultMode.DISABLE) |
例如,如果你有:
Kotlin
| |
Groovy
| |
请迁移为:
Kotlin
| |
Groovy
| |
以 JVM 为目标
如前所述,你可以在扩展、目标和编译单元(任务)级别为 JVM/Android 项目定义编译器选项。
默认的 JVM 编译任务中,生产代码为 compileKotlin,测试代码为 compileTestKotlin。自定义源集的任务按 compile<Name>Kotlin 模式命名。
你可以在终端中运行 gradlew tasks --all 命令,并在 Other tasks 组中搜索 compile*Kotlin 任务名称,查看 Android 编译任务的列表。
需要注意的一些重要细节:
kotlin.compilerOptions会配置项目中的每一个 Kotlin 编译任务。- 你可以使用
tasks.named<KotlinJvmCompile>("compileKotlin") { }(或tasks.withType<KotlinJvmCompile>().configureEach { })的方式覆盖kotlin.compilerOptionsDSL 所应用的配置。
以 JavaScript 为目标
JavaScript 编译任务中,生产代码为 compileKotlinJs,测试代码为 compileTestKotlinJs,自定义源集为 compile<Name>KotlinJs。
要配置单个任务,请使用它的名称:
Kotlin
| |
Groovy
| |
请注意,使用 Gradle Kotlin DSL 时,你应首先从项目的 tasks 中获取该任务。
对于 JS 和 common 目标,请分别使用 Kotlin2JsCompile 和 KotlinCompileCommon 类型。
你可以在终端中运行 gradlew tasks --all 命令,并在 Other tasks 组中搜索 compile*KotlinJS 任务名称,查看 JavaScript 编译任务的列表。
所有 Kotlin 编译任务
也可以配置项目中的所有 Kotlin 编译任务:
Kotlin
| |
Groovy
| |
所有编译器选项
以下是 Gradle 编译器选项的完整列表:
通用属性
| 名称 | 说明 | 可能的值 | 默认值 |
| optIn | 用于配置一组选择启用编译器参数的属性 | listOf( /* 选择启用项 */ ) | emptyList() |
| progressiveMode | 启用渐进式编译器模式 | true、false | false |
| extraWarnings | 启用额外的声明、表达式和类型编译器检查,若为 true 则在有问题时发出警告 | true、false | false |
JVM 特有的属性
| 名称 | 说明 | 可能的值 | 默认值 |
| javaParameters | 为方法参数生成 Java 1.8 反射所需的元数据 | | false |
| jvmTarget | 生成的 JVM 字节码的目标版本 | “1.8”、“9”、“10”、…、“25”、26"。另请参阅编译器选项的类型 | “1.8” |
| noJdk | 不要自动把 Java 运行时包含到 classpath 中 | | false |
| jvmTargetValidationMode | 校验 Kotlin 与 Java 之间 JVM 目标兼容性 的属性,用于 KotlinCompile 类型的任务。 | WARNING、ERROR、IGNORE | ERROR |
| jvmDefault | 控制接口中声明的函数如何编译为 JVM 上的默认方法 | ENABLE、NO_COMPATIBILITY、DISABLE | ENABLE |
JVM 与 JavaScript 共有的属性
| 名称 | 说明 | 可能的值 | 默认值 |
| allWarningsAsErrors | 如果有任何警告则报告为错误 | | false |
| suppressWarnings | 不生成警告 | | false |
| verbose | 启用详细的日志输出。仅在启用 Gradle 调试日志级别时有效 | | false |
| freeCompilerArgs | 额外的编译器参数列表。你也可以在这里使用实验性的 -X 参数。参见示例 | | [] |
| apiVersion | 控制你的代码可以使用哪些 Kotlin API。更多信息请参阅 -api-version。 | “2.0”、“2.1”、“2.2”、“2.3”、“2.4”、“2.5”(实验性) | |
| languageVersion | 控制编译期间可用的 Kotlin 语言特性和语法。更多信息请参阅 -language-version。 | “2.0”、“2.1”、“2.2”、“2.3”、“2.4”、“2.5”(实验性) | |
警告: 我们将在未来的版本中弃用
freeCompilerArgs属性。如果你在 Kotlin Gradle DSL 中缺少某些选项,请提交 issue。
通过 freeCompilerArgs 使用额外参数的示例
使用 freeCompilerArgs 属性可以提供额外的(包括实验性的)编译器参数。你可以向该属性添加单个参数,也可以添加参数列表:
Kotlin
| |
Groovy
| |
设置 languageVersion 的示例
要设置语言版本,请使用以下语法:
Kotlin
| |
Groovy
| |
另请参阅编译器选项的类型。
JavaScript 特有的属性
| 名称 | 说明 | 可能的值 | 默认值 |
| friendModulesDisabled | 禁用 internal 声明的导出 | | false |
| main | 指定执行时是否应调用 main 函数 | JsMainFunctionExecutionMode.CALL、JsMainFunctionExecutionMode.NO_CALL | JsMainFunctionExecutionMode.CALL |
| moduleKind | 编译器生成的 JS 模块类型 | JsModuleKind.MODULE_AMD、JsModuleKind.MODULE_PLAIN、JsModuleKind.MODULE_ES、JsModuleKind.MODULE_COMMONJS、JsModuleKind.MODULE_UMD | null |
| sourceMap | 生成 source map | | false |
| sourceMapEmbedSources | 把源文件嵌入 source map | JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_INLINING、JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_NEVER、JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_ALWAYS | null |
| sourceMapNamesPolicy | 把你所声明的变量名和函数名从 Kotlin 代码加入 source map。关于该行为的更多信息,请参阅我们的编译器参考 | JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_FQ_NAMES、JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_SIMPLE_NAMES、JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_NO | null |
| sourceMapPrefix | 为 source map 中的路径添加指定前缀 | | null |
| target | 为特定的 ECMA 版本生成 JS 文件 | "es5"、"es2015" | "es5" |
| useEsClasses | 让生成的 JavaScript 代码使用 ES2015 类。在使用 ES2015 目标时默认启用 | | null |
编译器选项的类型
部分 compilerOptions 使用新的类型而不是 String 类型:
| 选项 | 类型 | 示例 |
| jvmTarget | JvmTarget | compilerOptions.jvmTarget.set(JvmTarget.JVM_11) |
| apiVersion 和 languageVersion | KotlinVersion | compilerOptions.languageVersion.set(KotlinVersion.KOTLIN_2_4) |
| main | JsMainFunctionExecutionMode | compilerOptions.main.set(JsMainFunctionExecutionMode.NO_CALL) |
| moduleKind | JsModuleKind | compilerOptions.moduleKind.set(JsModuleKind.MODULE_ES) |
| sourceMapEmbedSources | JsSourceMapEmbedMode | compilerOptions.sourceMapEmbedSources.set(JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_INLINING) |
| sourceMapNamesPolicy | JsSourceMapNamesPolicy | compilerOptions.sourceMapNamesPolicy.set(JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_FQ_NAMES) |
接下来做什么?
进一步了解: