設定編譯
Kotlin 多平台專案使用編譯來產生構件。每個目標可以有一個或多個編譯,例如用於生產和測試目的。
對於每個目標,預設編譯包括:
- JVM、JS 和 Native 目標的
main
和test
編譯。 - 每個 Android 建構變體 的一個 編譯,適用於 Android 目標。
如果您需要編譯生產程式碼和單元測試之外的內容,例如整合測試或效能測試,您可以建立自訂編譯。
您可以配置構件的產生方式:
配置所有編譯
此範例配置了適用於所有目標的通用編譯器選項:
kotlin {
compilerOptions {
allWarningsAsErrors.set(true)
}
}
kotlin {
compilerOptions {
allWarningsAsErrors = true
}
}
配置單一目標的編譯
kotlin {
jvm {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_1_8)
}
}
}
kotlin {
jvm {
compilerOptions {
jvmTarget = JvmTarget.JVM_1_8
}
}
}
配置一個編譯
kotlin {
jvm {
val main by compilations.getting {
compileTaskProvider.configure {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_1_8)
}
}
}
}
}
kotlin {
jvm {
compilations.main {
compileTaskProvider.configure {
compilerOptions {
jvmTarget = JvmTarget.JVM_1_8
}
}
}
}
}
建立自訂編譯
如果您需要編譯生產程式碼和單元測試之外的內容,例如整合測試或效能測試,請建立自訂編譯。
對於自訂編譯,您需要手動設定所有依賴項。自訂編譯的預設原始碼集不依賴於 commonMain
和 commonTest
原始碼集。
例如,要為 jvm
目標的整合測試建立自訂編譯,請在 integrationTest
和 main
編譯之間建立 associateWith
關係:
kotlin {
jvm {
compilations {
val main by getting
val integrationTest by creating {
// Import main and its classpath as dependencies and establish internal visibility
associateWith(main)
defaultSourceSet {
dependencies {
implementation(kotlin("test-junit"))
/* ... */
}
}
// Create a test task to run the tests produced by this compilation:
testRuns.create("integration") {
// Configure the test task
setExecutionSourceFrom(integrationTest)
}
}
}
}
}
kotlin {
jvm {
compilations.create('integrationTest') {
def main = compilations.main
// Import main and its classpath as dependencies and establish internal visibility
associateWith(main)
defaultSourceSet {
dependencies {
implementation kotlin('test-junit')
/* ... */
}
}
// Create a test task to run the tests produced by this compilation
testRuns.create('integration') {
// Configure the test task
setExecutionSourceFrom(compilations.integrationTest)
}
}
}
}
透過關聯編譯,您可以將主要編譯輸出添加為依賴項,並在編譯之間建立 internal
可見性。
自訂編譯在其他情況下也是必要的。例如,如果您想在最終構件中合併不同 JVM 版本的編譯,或者您已經在 Gradle 中設定了原始碼集並希望遷移到多平台專案。
若要為
androidTarget
建立自訂編譯,請透過 Android Gradle plugin 設定建構變體。
JVM 編譯
當您在多平台專案中宣告 jvm
目標時,Kotlin 多平台外掛程式會自動建立 Java 原始碼集並將其包含在 JVM 目標的編譯中。
通用原始碼集不能包含 Java 資源,因此您應該將它們放置在多平台專案的對應子目錄中。例如:
目前,Kotlin 多平台外掛程式會取代由 Java 外掛程式配置的某些任務:
- JAR 任務:它不使用標準的
jar
,而是使用基於構件名稱的目標特定任務,例如,jvm()
目標宣告的jvmJar
和jvm("desktop")
的desktopJar
。 - 測試任務:它不使用標準的
test
,而是使用基於構件名稱的目標特定任務,例如jvmTest
。 - 資源處理:取代
*ProcessResources
任務,資源由對應的編譯任務處理。
當目標被宣告時,這些任務會自動建立。然而,您可以手動定義 JAR 任務並在必要時配置它:
// Shared module's `build.gradle.kts` file
plugins {
kotlin("multiplatform") version "2.2.0"
}
kotlin {
// Specify the JVM target
jvm {
// Add the task for JAR generation
tasks.named<Jar>(artifactsTaskName).configure {
// Configure the task
}
}
sourceSets {
jvmMain {
dependencies {
// Add JVM-specific dependencies
}
}
}
}
// Shared module's `build.gradle` file
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '2.2.0'
}
kotlin {
// Specify the JVM target
jvm {
// Add the task for JAR generation
tasks.named<Jar>(artifactsTaskName).configure {
// Configure the task
}
}
sourceSets {
jvmMain {
dependencies {
// Add JVM-specific dependencies
}
}
}
}
此目標由 Kotlin 多平台外掛程式發佈,且不需要 Java 外掛程式特有的步驟。
配置與原生語言的互通性
Kotlin 提供了與原生語言的互通性以及用於為特定編譯配置此功能的 DSL。
原生語言 | 支援平台 | 註解 |
---|---|---|
C | 所有平台 | |
Objective-C | Apple 平台 (macOS, iOS, watchOS, tvOS) | |
Swift 透過 Objective-C | Apple 平台 (macOS, iOS, watchOS, tvOS) | Kotlin 只能使用標記有 @objc 屬性的 Swift 宣告。 |
一個編譯可以與多個原生函式庫互動。在定義檔中或建構檔的 cinterops
區塊中,配置互通性及可用屬性:
kotlin {
linuxX64 { // 替換為您需要的目標。
compilations.getByName("main") {
val myInterop by cinterops.creating {
// 描述原生 API 的 Def 檔。
// 預設路徑為 src/nativeInterop/cinterop/<interop-name>.def
definitionFile.set(project.file("def-file.def"))
// 放置產生的 Kotlin API 的套件。
packageName("org.sample")
// cinterop 工具傳遞給編譯器的選項。
compilerOpts("-Ipath/to/headers")
// 尋找標頭檔的目錄。
includeDirs.apply {
// 標頭檔搜尋目錄 (等同於 -I<path> 編譯器選項)。
allHeaders("path1", "path2")
// 搜尋 'headerFilter' def 檔選項中列出的標頭檔的額外目錄。
// -headerFilterAdditionalSearchPrefix 命令列選項的等效項。
headerFilterOnly("path1", "path2")
}
// includeDirs.allHeaders 的捷徑。
includeDirs("include/directory", "another/directory")
}
val anotherInterop by cinterops.creating { /* ... */ }
}
}
}
kotlin {
linuxX64 { // 替換為您需要的目標。
compilations.main {
cinterops {
myInterop {
// 描述原生 API 的 Def 檔。
// 預設路徑為 src/nativeInterop/cinterop/<interop-name>.def
definitionFile = project.file("def-file.def")
// 放置產生的 Kotlin API 的套件。
packageName 'org.sample'
// cinterop 工具傳遞給編譯器的選項。
compilerOpts '-Ipath/to/headers'
// 標頭檔搜尋目錄 (等同於 -I<path> 編譯器選項)。
includeDirs.allHeaders("path1", "path2")
// 搜尋 'headerFilter' def 檔選項中列出的標頭檔的額外目錄。
// -headerFilterAdditionalSearchPrefix 命令列選項的等效項。
includeDirs.headerFilterOnly("path1", "path2")
// includeDirs.allHeaders 的捷徑。
includeDirs("include/directory", "another/directory")
}
anotherInterop { /* ... */ }
}
}
}
}
Android 編譯
為 Android 目標建立的預設編譯與 Android 建構變體 綁定:對於每個建構變體,會以相同名稱建立一個 Kotlin 編譯。
然後,對於為每個變體編譯的每個 Android 原始碼集,都會建立一個以目標名稱作為前綴的 Kotlin 原始碼集,例如 Android 原始碼集 debug
和名為 androidTarget
的 Kotlin 目標會對應到 Kotlin 原始碼集 androidDebug
。這些 Kotlin 原始碼集會相應地添加到變體的編譯中。
預設原始碼集 commonMain
會添加到每個生產 (應用程式或函式庫) 變體的編譯中。commonTest
原始碼集也會以類似方式添加到單元測試和儀器化測試變體的編譯中。
也支援透過 kapt
進行註解處理,但由於目前的限制,它要求在配置 kapt
依賴項之前建立 Android 目標,這需要在頂層的 dependencies {}
區塊中完成,而不是在 Kotlin 原始碼集依賴項中。
kotlin {
androidTarget { /* ... */ }
}
dependencies {
kapt("com.my.annotation:processor:1.0.0")
}
原始碼集階層的編譯
Kotlin 可以使用 dependsOn
關係建立原始碼集階層。
如果原始碼集 jvmMain
依賴於原始碼集 commonMain
,則:
- 每當
jvmMain
為特定目標編譯時,commonMain
也會參與該編譯,並被編譯成相同的目標二進位形式,例如 JVM 類別檔。 jvmMain
的原始碼「看得到」commonMain
的宣告,包括內部宣告,並且也看得到commonMain
的依賴項,即使是指定為implementation
依賴項的那些。jvmMain
可以包含commonMain
預期宣告的平台特定實作。commonMain
的資源總是與jvmMain
的資源一起處理和複製。jvmMain
和commonMain
的語言設定應該保持一致。
語言設定會以以下方式檢查一致性:
jvmMain
應該設定一個大於或等於commonMain
的languageVersion
。jvmMain
應該啟用commonMain
啟用的所有不穩定語言功能 (對於錯誤修復功能沒有此類要求)。jvmMain
應該使用commonMain
使用的所有實驗性註解。apiVersion
、錯誤修復語言功能和progressiveMode
可以任意設定。
配置 Gradle 中的獨立專案功能
此功能是實驗性的,目前在 Gradle 中處於預發行版狀態。僅在 Gradle 8.10 或更高版本中使用它,並且僅供評估之用。此功能可能隨時被捨棄或更改。我們感謝您在 YouTrack 中提供回饋。需要選擇加入 (詳情見下文)。
Gradle 提供了獨立專案功能,它透過「隔離」各個專案來提升建構效能。此功能分離了專案之間的建構腳本和外掛程式,允許它們安全地平行執行。
要啟用此功能,請遵循 Gradle 的說明來設定系統屬性。
有關獨立專案功能的更多資訊,請參閱 Gradle 的文件。