Skip to content

Kotlin Gradle 插件中的編譯器選項

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

這些編譯器會被以下情境使用:

  • 當您在 Kotlin 專案中點擊 IDE 的「編譯」或「執行」按鈕時。
  • 當您在控制台或 IDE 中呼叫 gradle build 時,Gradle 會使用。
  • 當您在控制台或 IDE 中呼叫 mvn compilemvn test-compile 時,Maven 會使用。

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

如何定義選項

Kotlin 編譯器有許多選項可用於調整編譯過程。

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

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

Kotlin compiler options levels

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

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

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

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

若要找出哪一層級的編譯器引數適用於編譯,請使用 Gradle 日誌DEBUG 層級。 對於 JVM 和 JS/WASM 任務,請在日誌中搜尋 "Kotlin compiler args:" 字串;對於 Native 任務,請搜尋 "Arguments =" 字串。

TIP

如果您是第三方外掛程式作者,最好在專案層級應用您的配置,以避免覆寫問題。您可以為此使用新的 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 {

                }
            }
        }
    }
}

如果您想配置一個與 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)
    }
}

目標 JVM

如前所述,您可以為 JVM/Android 專案在擴充功能、目標和編譯單元層級(任務)定義編譯器選項。

預設的 JVM 編譯任務,生產程式碼稱為 compileKotlin,測試程式碼稱為 compileTestKotlin。自訂來源集的任務會根據其 compile<Name>Kotlin 模式命名。

您可以透過在終端機中執行 gradlew tasks --all 命令,並在「Other tasks」群組中搜尋 compile*Kotlin 任務名稱,來查看 Android 編譯任務的列表。

需要注意的一些重要細節:

  • android.kotlinOptionskotlin.compilerOptions 配置區塊會相互覆寫。最後(最低)的區塊會生效。
  • 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啟用漸進式編譯器模式truefalsefalse
extraWarnings啟用額外的宣告、表達式和類型編譯器檢查,若為 true 則發出警告truefalsefalse

JVM 專屬屬性

名稱描述可能值預設值
javaParameters為 Java 1.8 方法參數上的反射生成中繼資料false
jvmTarget生成 JVM 位元碼的目標版本"1.8", "9", "10", ..., "22", "23"。另請參閱編譯器選項的類型"1.8"
noJdk不要自動將 Java 執行時加入到類別路徑false
jvmTargetValidationModeWARNINGERRORIGNOREERROR

JVM 和 JavaScript 通用屬性

名稱描述可能值預設值
allWarningsAsErrors如果有任何警告,則報告錯誤false
suppressWarnings不生成警告false
verbose啟用詳細日誌輸出。僅當啟用 Gradle 調試日誌級別時有效false
freeCompilerArgs額外編譯器引數的列表。您也可以在此處使用實驗性 -X 引數。請參閱額外引數透過 freeCompilerArgs 使用的範例[]
apiVersion將宣告的使用限制為指定版本捆綁函式庫中的宣告"1.8"、"1.9"、"2.0"、"2.1"、"2.2" (EXPERIMENTAL)
languageVersion提供與指定 Kotlin 版本相容的原始碼"1.8"、"1.9"、"2.0"、"2.1"、"2.2" (EXPERIMENTAL)

DANGER

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

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

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

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

kotlin {
    compilerOptions {
        // Specifies the version of the Kotlin API and the JVM target
        apiVersion.set(KotlinVersion.KOTLIN_2_1)
        jvmTarget.set(JvmTarget.JVM_1_8)
        
        // Single experimental argument
        freeCompilerArgs.add("-Xexport-kdoc")

        // Single additional argument
        freeCompilerArgs.add("-Xno-param-assertions")

        // List of arguments
        freeCompilerArgs.addAll(
            listOf(
                "-Xno-receiver-assertions",
                "-Xno-call-assertions"
            )
        ) 
    }
}
groovy
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
// ...

tasks.named('compileKotlin', KotlinCompilationTask) {
    compilerOptions {
        // Specifies the version of the Kotlin API and the JVM target
        apiVersion = KotlinVersion.KOTLIN_2_1
        jvmTarget = JvmTarget.JVM_1_8
        
        // Single experimental argument
        freeCompilerArgs.add("-Xexport-kdoc")
        
        // Single additional argument, can be a key-value pair
        freeCompilerArgs.add("-Xno-param-assertions")
        
        // List of arguments
        freeCompilerArgs.addAll(["-Xno-receiver-assertions", "-Xno-call-assertions"])
    }
}

TIP

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

設定 languageVersion 的範例

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

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

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

JavaScript 專屬屬性

名稱描述可能值預設值
friendModulesDisabled禁用內部宣告匯出false
main指定 main 函式是否應在執行時被呼叫JsMainFunctionExecutionMode.CALLJsMainFunctionExecutionMode.NO_CALLJsMainFunctionExecutionMode.CALL
moduleKind編譯器生成的 JS 模組類型JsModuleKind.MODULE_AMDJsModuleKind.MODULE_PLAINJsModuleKind.MODULE_ESJsModuleKind.MODULE_COMMONJSJsModuleKind.MODULE_UMDnull
sourceMap生成原始碼對應 (Source Map)false
sourceMapEmbedSources將原始碼檔案嵌入到原始碼對應中JsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_INLININGJsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_NEVERJsSourceMapEmbedMode.SOURCE_MAP_SOURCE_CONTENT_ALWAYSnull
sourceMapNamesPolicy將您在 Kotlin 程式碼中宣告的變數和函式名稱加入到原始碼對應中。有關其行為的更多資訊,請參閱我們的編譯器參考JsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_FQ_NAMESJsSourceMapNamesPolicy.SOURCE_MAP_NAMES_POLICY_SIMPLE_NAMESJsSourceMapNamesPolicy.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)
apiVersion and languageVersionKotlinVersioncompilerOptions.languageVersion.set(KotlinVersion.KOTLIN_2_1)
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)

接下來呢?

了解更多關於: