Skip to content

Kotlin Gradle 外掛程式中的編譯器選項

Kotlin 的每個版本都包含適用於支援目標的編譯器: JVM、JavaScript 以及針對支援平台的 Native 二進位檔。

這些編譯器會被以下對象使用:

  • 當您在 Kotlin 專案中點擊 編譯 (Compile)執行 (Run) 按鈕時的 IDE。
  • 當您在主控台或 IDE 中呼叫 gradle build 時的 Gradle。
  • 當您在主控台或 IDE 中呼叫 mvn compilemvn test-compile 時的 Maven。

您也可以按照使用命令列編譯器教學中的說明,從命令列手動執行 Kotlin 編譯器。

如何定義選項

Kotlin 編譯器具有多個選項,用於自訂編譯過程。

Gradle DSL 允許對編譯器選項進行全面的組建組態。它適用於 Kotlin MultiplatformJVM/Android 專案。

透過 Gradle DSL,您可以在建置指令碼中於三個層級配置編譯器選項:

Kotlin 編譯器選項層級

較高層級的設定會作為較低層級的慣例(預設值):

  • 在擴充層級設定的編譯器選項是目標層級選項的預設值,包括 commonMainnativeMaincommonTest 等共用原始碼集。
  • 在目標層級設定的編譯器選項是編譯單元(任務)層級選項的預設值,例如 compileKotlinJvmcompileTestKotlinJvm 任務。

反之,在較低層級進行的配置會覆蓋較高層級的相關設定:

  • 任務層級的編譯器選項會覆蓋目標或擴充層級的相關配置。
  • 目標層級的編譯器選項會覆蓋擴充層級的相關配置。

若要了解編譯時套用了哪個層級的編譯器引數,請使用 Gradle 記錄DEBUG 層級。 對於 JVM 和 JS/WASM 任務,請在記錄中搜尋 "Kotlin compiler args:" 字串;對於 Native 任務,請搜尋 "Arguments =" 字串。

如果您是第三方外掛程式作者,最好將您的配置套用於專案層級,以避免覆蓋問題。您可以為此使用新的 Kotlin 外掛程式 DSL 擴充類型。建議您在自家的文件中明確說明此配置。

擴充層級

您可以在最上層的 compilerOptions {} 區塊中,為所有目標和共用原始碼集配置通用的編譯器選項:

kotlin
kotlin {
    compilerOptions {
        optIn.add("kotlin.RequiresOptIn")
    }
}

目標層級

您可以在 target {} 區塊內的 compilerOptions {} 區塊中,為 JVM/Android 目標配置編譯器選項:

kotlin
kotlin {
    target {
        compilerOptions {
            optIn.add("kotlin.RequiresOptIn")
        }
    }
}

在 Kotlin Multiplatform 專案中,您可以在特定目標內配置編譯器選項。例如 jvm { compilerOptions {}}。如需更多資訊,請參閱 Multiplatform Gradle DSL 參考

編譯單元層級

您可以在任務配置內的 compilerOptions {} 區塊中,為特定的編譯單元或任務配置編譯器選項:

kotlin
tasks.named<KotlinJvmCompile>("compileKotlin"){
    compilerOptions {
        optIn.add("kotlin.RequiresOptIn")
    }
}

您也可以透過 KotlinCompilation 在編譯單元層級存取並配置編譯器選項:

kotlin
kotlin {
    target {
        val main by compilations.getting {
            compileTaskProvider.configure {
                compilerOptions {
                    optIn.add("kotlin.RequiresOptIn")
                }
            }
        }
    }
}

如果您想要配置 JVM/Android 和 Kotlin Multiplatform 以外的目標外掛程式,請使用相應 Kotlin 編譯任務的 compilerOptions {} 屬性。以下範例顯示如何在 Kotlin 和 Groovy DSL 中進行此設定:

kotlin
tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask::class.java) {
    compilerOptions {
        apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
    }
}
groovy
tasks.named('compileKotlin', org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask.class) {
    compilerOptions {
        apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
    }
}

kotlinOptions {} 遷移至 compilerOptions {}

在 Kotlin 2.2.0 之前,您可以使用 kotlinOptions {} 區塊配置編譯器選項。由於 kotlinOptions {} 區塊自 Kotlin 2.0.0 起已被棄用,本節提供了將建置指令碼遷移為使用 compilerOptions {} 區塊的指引與建議:

集中化編譯器選項並使用型別

盡可能在 擴充層級 配置編譯器選項,並在 編譯單元層級 為特定任務覆蓋它們。

您不能在 compilerOptions {} 區塊中使用原始字串,因此請將其轉換為型別值。例如,如果您原本有:

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

tasks.withType<KotlinCompile>().configureEach {
    kotlinOptions {
        jvmTarget = "17"
        languageVersion = "2.3"
        apiVersion = "2.3"
    }
}
kotlin
plugins {
    id 'org.jetbrains.kotlin.jvm' version '2.3.0'
}

tasks.withType(KotlinCompile).configureEach {
    kotlinOptions {
        jvmTarget = '17'
        languageVersion = '2.3'
        apiVersion = '2.3'
    }
}

遷移之後,應該改為:

kotlin
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion

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

kotlin {
    // 擴充層級
    compilerOptions {
        jvmTarget = JvmTarget.fromTarget("17")
        languageVersion = KotlinVersion.fromVersion("2.3")
        apiVersion = KotlinVersion.fromVersion("2.3")
    }
}

// 在編譯單元層級覆蓋的範例
tasks.named<KotlinJvmCompile>("compileKotlin"){
    compilerOptions {
        apiVersion = KotlinVersion.fromVersion("2.3")
    }
}
kotlin
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion

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

kotlin {
  // 擴充層級
    compilerOptions {
        jvmTarget = JvmTarget.fromTarget("17")
        languageVersion = KotlinVersion.fromVersion("2.3")
        apiVersion = KotlinVersion.fromVersion("2.3")
    }
}

// 在編譯單元層級覆蓋的範例
tasks.named("compileKotlin", KotlinJvmCompile).configure {
    compilerOptions {
        apiVersion = KotlinVersion.fromVersion("2.3")
    }
}

不再使用 android.kotlinOptions

如果您的建置指令碼先前使用了 android.kotlinOptions,請遷移至使用 kotlin.compilerOptions。可以在擴充層級或目標層級進行遷移。

例如,如果您有一個 Android 專案:

kotlin
plugins {
    id("com.android.application")
    kotlin("android")
}

android {
    kotlinOptions {
        jvmTarget = "17"
    }
}
kotlin
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    kotlinOptions {
        jvmTarget = '17'
    }
}

將其更新為:

kotlin
plugins {
    id("com.android.application")
    kotlin("android")
}

kotlin {
    compilerOptions {
        jvmTarget = JvmTarget.fromTarget("17")
    }
}
kotlin
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

kotlin {
    compilerOptions {
        jvmTarget = JvmTarget.fromTarget("17")
    }
}

例如,如果您有一個帶有 Android 目標的 Kotlin Multiplatform 專案:

kotlin
plugins {
    kotlin("multiplatform")
    id("com.android.application")
}

kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions.jvmTarget = "17"
        }
    }
}
kotlin
plugins {
    id 'org.jetbrains.kotlin.multiplatform'
    id 'com.android.application'
}

kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = '17'
            }
        }
    }
}

將其更新為:

kotlin
plugins {
    kotlin("multiplatform")
    id("com.android.application")
}

kotlin {
    androidTarget {
        compilerOptions {
            jvmTarget = JvmTarget.fromTarget("17")
        }
    }
}
kotlin
plugins {
    id 'org.jetbrains.kotlin.multiplatform'
    id 'com.android.application'
}

kotlin {
    androidTarget {
        compilerOptions {
            jvmTarget = JvmTarget.fromTarget("17")
        }
    }
}

遷移 freeCompilerArgs

  • 將所有的 += 操作替換為 add()addAll() 函式。

  • 如果您使用 -opt-in 編譯器選項,請檢查 KGP API 參考 中是否已有專門的 DSL 可供使用,並改用該 DSL。

  • 將任何 -progressive 編譯器選項的使用遷移至專用的 DSL:progressiveMode.set(true)

  • 將任何 -Xjvm-default 編譯器選項的使用遷移至 使用專用 DSLjvmDefault.set()。使用以下選項對應:

    之前之後
    -Xjvm-default=all-compatibilityjvmDefault.set(JvmDefaultMode.ENABLE)
    -Xjvm-default=alljvmDefault.set(JvmDefaultMode.NO_COMPATIBILITY)
    -Xjvm-default=disablejvmDefault.set(JvmDefaultMode.DISABLE)

例如,如果您原本有:

kotlin
kotlinOptions {
    freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
    freeCompilerArgs += listOf("-Xcontext-receivers", "-Xinline-classes", "-progressive", "-Xjvm-default=all")
}
kotlin
kotlinOptions {
    freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
    freeCompilerArgs += ["-Xcontext-receivers", "-Xinline-classes", "-progressive", "-Xjvm-default=all"]
}

遷移至:

kotlin
kotlin {
    compilerOptions {
        optIn.add("kotlin.RequiresOptIn")
        freeCompilerArgs.addAll(listOf("-Xcontext-receivers", "-Xinline-classes"))
        progressiveMode.set(true)
        jvmDefault.set(JvmDefaultMode.NO_COMPATIBILITY)
    }
}
kotlin
kotlin {
    compilerOptions {
        optIn.add("kotlin.RequiresOptIn")
        freeCompilerArgs.addAll(["-Xcontext-receivers", "-Xinline-classes"])
        progressiveMode.set(true)
        jvmDefault.set(JvmDefaultMode.NO_COMPATIBILITY)
    }
}

目標為 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.compilerOptions DSL 套用的配置。

目標為 JavaScript

JavaScript 編譯任務對於生產程式碼稱為 compileKotlinJs,對於測試程式碼稱為 compileTestKotlinJs,對於自訂原始碼集則稱為 compile<Name>KotlinJs

若要配置單一任務,請使用其名稱:

kotlin
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...

val compileKotlin: KotlinCompilationTask<*> by tasks

compileKotlin.compilerOptions.suppressWarnings.set(true)
groovy
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...

tasks.named('compileKotlin', KotlinCompilationTask) {
    compilerOptions {
        suppressWarnings = true
    }
}

請注意,在使用 Gradle Kotlin DSL 時,您應該先從專案的 tasks 中獲取任務。

請分別為 JS 和通用目標使用 Kotlin2JsCompileKotlinCompileCommon 類型。

您可以透過在終端機執行 gradlew tasks --all 指令,並在 Other tasks 組中搜尋 compile*KotlinJS 任務名稱,來查看 JavaScript 編譯任務清單。

所有 Kotlin 編譯任務

也可以配置專案中所有的 Kotlin 編譯任務:

kotlin
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...

tasks.named<KotlinCompilationTask<*>>("compileKotlin").configure {
    compilerOptions { /*...*/ }
}
groovy
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...

tasks.named('compileKotlin', KotlinCompilationTask) {
    compilerOptions { /*...*/ }
}

所有編譯器選項

以下是 Gradle 編譯器的完整選項列表:

常用屬性

名稱描述可能的值預設值
optIn用於配置 加入編譯器引數 列表的屬性listOf( /* opt-ins */ )emptyList()
progressiveMode啟用 漸進式編譯器模式true, falsefalse
extraWarnings如果為 true,則啟用 額外的宣告、運算式和型別編譯器檢查,這些檢查會發出警告true, falsefalse

JVM 特定屬性

名稱描述可能的值預設值
javaParameters為方法參數上的 Java 1.8 反射產生元資料false
jvmTarget產生的 JVM 位元組碼的目標版本"1.8", "9", "10", ..., "24", 25"。另請參閱 編譯器選項的類型"1.8"
noJdk不要自動將 Java 執行階段包含到類別路徑中false
jvmTargetValidationModeWARNING, ERROR, IGNOREERROR
jvmDefault控制如何將介面中宣告的函式編譯為 JVM 上的預設方法ENABLE, NO_COMPATIBILITY, DISABLEENABLE

JVM 和 JavaScript 共有屬性

名稱描述可能的值預設值
allWarningsAsErrors如果有任何警告,則回報錯誤false
suppressWarnings不要產生警告false
verbose啟用詳細的記錄輸出。僅在 啟用 Gradle 偵錯記錄層級 時有效false
freeCompilerArgs額外編譯器引數的列表。您也可以在此處使用實驗性的 -X 引數。請參閱 透過 freeCompilerArgs 使用額外引數的範例[]
apiVersion限制宣告的使用僅限於指定的隨附程式庫版本"1.9", "2.0", "2.1", "2.2", "2.3", "2.4" (實驗性)
languageVersion提供與指定 Kotlin 版本的原始碼相容性"1.9", "2.0", "2.1", "2.2", "2.3", "2.4" (實驗性)

我們將在未來的版本中棄用 freeCompilerArgs 屬性。如果您在 Kotlin Gradle DSL 中缺少某些選項,請 提交問題 (Issue)

透過 freeCompilerArgs 使用額外引數的範例

使用 freeCompilerArgs 屬性提供額外的(包括實驗性的)編譯器引數。 您可以向此屬性新增單個引數或引數列表:

kotlin
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...

kotlin {
    compilerOptions {
        // 指定 Kotlin API 版本和 JVM 目標
        apiVersion.set(KotlinVersion.KOTLIN_2_3)
        jvmTarget.set(JvmTarget.JVM_1_8)
        
        // 單個實驗性引數
        freeCompilerArgs.add("-Xexport-kdoc")

        // 單個額外引數
        freeCompilerArgs.add("-Xno-param-assertions")

        // 引數列表
        freeCompilerArgs.addAll(
            listOf(
                "-Xno-receiver-assertions",
                "-Xno-call-assertions"
            )
        ) 
    }
}
groovy
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...

tasks.named('compileKotlin', KotlinCompilationTask) {
    compilerOptions {
        // 指定 Kotlin API 版本和 JVM 目標
        apiVersion = KotlinVersion.KOTLIN_2_3
        jvmTarget = JvmTarget.JVM_1_8
        
        // 單個實驗性引數
        freeCompilerArgs.add("-Xexport-kdoc")
        
        // 單個額外引數,可以是鍵值對
        freeCompilerArgs.add("-Xno-param-assertions")
        
        // 引數列表
        freeCompilerArgs.addAll(["-Xno-receiver-assertions", "-Xno-call-assertions"])
    }
}

freeCompilerArgs 屬性可在 擴充目標編譯單元(任務) 層級使用。

設定 languageVersion 的範例

若要設定語言版本,請使用以下語法:

kotlin
kotlin {
    compilerOptions {
        languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_3)
    }
}
groovy
tasks
    .withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask.class)
    .configureEach {
        compilerOptions.languageVersion =
            org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_3
    }

另請參閱 編譯器選項的類型

JavaScript 特定屬性

名稱描述可能的值預設值
friendModulesDisabled停用內部宣告匯出false
main指定執行時是否應呼叫 main 函式JsMainFunctionExecutionMode.CALL, JsMainFunctionExecutionMode.NO_CALLJsMainFunctionExecutionMode.CALL
moduleKind編譯器產生的 JS 模組類型JsModuleKind.MODULE_AMD, JsModuleKind.MODULE_PLAIN, JsModuleKind.MODULE_ES, JsModuleKind.MODULE_COMMONJS, JsModuleKind.MODULE_UMDnull
sourceMap產生原始碼對應檔false
sourceMapEmbedSources將原始碼檔案嵌入原始碼對應檔中JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_INLINING, JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_NEVER, JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_ALWAYSnull
sourceMapNamesPolicy將您在 Kotlin 程式碼中宣告的變數和函式名稱新增到原始碼對應檔中。如需關於此行為的更多資訊,請參閱我們的 編譯器參考JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_FQ_NAMES, JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_SIMPLE_NAMES, JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_NOnull
sourceMapPrefix向原始碼對應檔中的路徑新增指定的前綴null
target為特定的 ECMA 版本產生 JS 檔案"es5", "es2015""es5"
useEsClasses讓產生的 JavaScript 程式碼使用 ES2015 類別。在使用 ES2015 目標的情況下預設啟用null

編譯器選項的類型

部分 compilerOptions 使用新型別而非 String 型別:

選項型別範例
jvmTargetJvmTargetcompilerOptions.jvmTarget.set(JvmTarget.JVM_11)
apiVersionlanguageVersionKotlinVersioncompilerOptions.languageVersion.set(KotlinVersion.KOTLIN_2_3)
mainJsMainFunctionExecutionModecompilerOptions.main.set(JsMainFunctionExecutionMode.NO_CALL)
moduleKindJsModuleKindcompilerOptions.moduleKind.set(JsModuleKind.MODULE_ES)
sourceMapEmbedSourcesJsSourceMapEmbedModecompilerOptions.sourceMapEmbedSources.set(JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_INLINING)
sourceMapNamesPolicyJsSourceMapNamesPolicycompilerOptions.sourceMapNamesPolicy.set(JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_FQ_NAMES)

接下來做什麼?

進一步了解: