Kotlin 跨平台 Gradle 插件是用于创建 Kotlin 跨平台项目的工具。
在这里,我们提供了它的内容参考;在编写 Kotlin 跨平台项目的 Gradle 构建脚本时,可以将其作为提醒。
了解 Kotlin 跨平台项目的概念,以及如何创建和配置它们。
ID 和版本
Kotlin 跨平台 Gradle 插件的完全限定名是 org.jetbrains.kotlin.multiplatform
。 如果使用 Kotlin Gradle DSL,可以通过 kotlin("multiplatform")
应用该插件。 插件版本与 Kotlin 版本相匹配。 最新版本为 2.0.21。
plugins {
kotlin("multiplatform") version "2.0.21"
}
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '2.0.21'
}
顶级块
kotlin {}
是 Gradle 构建脚本中用于跨平台项目配置的顶级块。 在 kotlin {}
中,可以编写以下块:
块 | 描述 |
---|
<targetName> | 声明项目的特定目标。 可用目标的名称列在 目标 部分。 |
targets
| 项目的所有目标。 |
presets
| 所有预定义目标。 用于一次 配置多个预定义目标。 |
sourceSets
| 配置预定义并声明项目的自定义 源代码集。 |
compilerOptions
| 扩展级别的通用 编译器选项 ,作为所有目标和共享源代码集的默认值。 要使用它,请添加以下选择加入: @OptIn(ExperimentalKotlinGradlePluginApi::class) 。 |
目标
目标 是构建的一部分,负责编译、测试和打包针对支持平台的软件。 Kotlin 为每个平台提供目标预设。请查看如何 使用目标预设。
每个目标可以有一个或多个 编译。 除了用于测试和生产目的的默认编译外,还可以 创建自定义编译。
跨平台项目的目标在 kotlin {}
内的相应块中描述,例如 jvm
、 android
、 iosArm64
。 可用目标的完整列表如下:
目标平台 | 目标预设 | 备注 |
---|
Kotlin/JVM | jvm
| |
Kotlin/Wasm | wasmJs
| 如果计划在 JavaScript 运行时运行项目,请使用此选项。 |
wasmWasi
| 如果需要支持 WASI 系统接口,请使用此选项。 |
Kotlin/JS | js
| 选择执行环境: 更多信息请参见 设置 Kotlin/JS 项目。 |
Kotlin/Native | | 了解 macOS、Linux 和 Windows 主机当前支持的目标,请参见 Kotlin/Native 目标支持。 |
Android 应用和库 | android
| 手动应用 Android Gradle 插件: com.android.application 或 com.android.library 。 每个 Gradle 子项目只能创建一个 Android 目标。 |
kotlin {
jvm()
iosArm64()
macosX64()
js().browser()
}
目标的配置可以包括两个部分:
每个目标可以有一个或多个 编译。
通用目标配置
在任何目标块中,可以使用以下声明:
名称 | 描述 |
---|
attributes
| 用于 区分同一平台的多个目标 的属性。 |
preset
| 目标创建时使用的预设(如果有)。 |
platformType
| 指定该目标的 Kotlin 平台。 可用值: jvm 、 androidJvm 、 js 、 wasm 、 native 、 common 。 |
artifactsTaskName
| 生成该目标结果工件的任务名称。 |
components
| 用于设置 Gradle 发布的组件。 |
compilerOptions
| 用于该目标的 编译器选项。 此声明将覆盖在 顶级 配置的任何 compilerOptions {} 。 要使用它,请添加以下选择加入: @OptIn(ExperimentalKotlinGradlePluginApi::class) 。 |
JVM 目标
除了 通用目标配置 之外, jvm
目标具有特定功能函数:
名称 | 描述 |
---|
withJava()
| 将 Java 源文件包含到 JVM 目标的编译中。 |
对于包含 Java 和 Kotlin 源文件的项目,请使用此功能。请注意,Java 源文件的默认源目录不遵循 Java 插件的默认设置。 相反,它们源自 Kotlin 源代码集。例如,如果 JVM 目标的默认名称为 jvm
,则路径为 src/jvmMain/java
(用于生产 Java 源文件)和 src/jvmTest/java
(用于测试 Java 源文件)。 了解有关 JVM 编译中的 Java 源文件 的更多信息。
kotlin {
jvm {
withJava()
}
}
Web 目标
js {}
块描述 Kotlin/JS 目标的配置, wasmJs {}
块描述与 JavaScript 互操作的 Kotlin/Wasm 目标的配置。 根据目标执行环境,它们可以包含以下两个块之一:
了解有关 配置 Kotlin/JS 项目 的更多信息。
单独的 wasmWasi {}
块描述支持 WASI 系统接口的 Kotlin/Wasm 目标的配置。 在这里,仅可用 nodejs
执行环境:
kotlin {
wasmWasi {
nodejs()
binaries.executable()
}
}
所有 Web 目标 js
、 wasmJs
和 wasmWasi
也支持 binaries.executable()
调用。 这明确指示 Kotlin 编译器生成可执行文件。 有关更多信息,请参见 Kotlin/JS 文档中的 执行环境。
浏览器
browser {}
可以包含以下配置块:
名称 | 描述 |
---|
testRuns
| 测试执行的配置。 |
runTask
| 项目运行的配置。 |
webpackTask
| 使用 Webpack 打包项目的配置。 |
distribution
| 输出文件的路径。 |
kotlin {
js().browser {
webpackTask { /* ... */ }
testRuns { /* ... */ }
distribution {
directory = File("$projectDir/customdir/")
}
}
}
Node.js
nodejs {}
可以包含测试和运行任务的配置:
名称 | 描述 |
---|
testRuns
| 测试执行的配置。 |
runTask
| 项目运行的配置。 |
kotlin {
js().nodejs {
runTask { /* ... */ }
testRuns { /* ... */ }
}
}
本地目标
对于本地目标,提供以下特定块:
名称 | 描述 |
---|
binaries
| 要生成的 二进制文件 的配置。 |
cinterops
| 与 C 库的 互操作性 的配置。 |
二进制文件
以下是二进制文件的类型:
名称 | 描述 |
---|
executable
| 产品可执行文件。 |
test
| 测试可执行文件。 |
sharedLib
| 共享库。 |
staticLib
| 静态库。 |
framework
| Objective-C 框架。 |
kotlin {
linuxX64 { // 请使用您的目标。
binaries {
executable {
// 二进制文件配置。
}
}
}
}
对于二进制文件配置,提供以下参数:
名称 | 描述 |
---|
compilation
| 生成二进制文件的编译。默认情况下, test 二进制文件基于 test 编译,而其他二进制文件基于 main 编译。 |
linkerOpts
| 在构建二进制文件时传递给系统链接器的选项。 |
baseName
| 输出文件的自定义基本名称。最终文件名将通过在此基本名称前后添加系统相关的前缀和后缀形成。 |
entryPoint
| 可执行二进制文件的入口点函数。默认情况下,它是根包中的 main() 。 |
outputFile
| 访问输出文件。 |
linkTask
| 访问链接任务。 |
runTask
| 访问可执行二进制文件的运行任务。对于 linuxX64 、 macosX64 或 mingwX64 之外的目标,此值为 null 。 |
isStatic
| 对于 Objective-C 框架,包含静态库而不是动态库。 |
binaries {
executable("my_executable", listOf(RELEASE)) {
// 基于测试编译构建二进制文件。
compilation = compilations["test"]
// 链接器的自定义命令行选项。
linkerOpts = mutableListOf("-L/lib/search/path", "-L/another/search/path", "-lmylib")
// 输出文件的基本名称。
baseName = "foo"
// 自定义入口点函数。
entryPoint = "org.example.main"
// 访问输出文件。
println("可执行文件路径: ${outputFile.absolutePath}")
// 访问链接任务。
linkTask.dependsOn(additionalPreprocessingTask)
// 访问运行任务。
// 注意,非主机平台的 runTask 为 null。
runTask?.dependsOn(prepareForRun)
}
framework("my_framework", listOf(RELEASE)) {
// 在框架中包含静态库而不是动态库。
isStatic = true
}
}
binaries {
executable('my_executable', [RELEASE]) {
// 基于测试编译构建二进制文件。
compilation = compilations.test
// 链接器的自定义命令行选项。
linkerOpts = ['-L/lib/search/path', '-L/another/search/path', '-lmylib']
// 输出文件的基本名称。
baseName = 'foo'
// 自定义入口点函数。
entryPoint = 'org.example.main'
// 访问输出文件。
println("可执行文件路径: ${outputFile.absolutePath}")
// 访问链接任务。
linkTask.dependsOn(additionalPreprocessingTask)
// 访问运行任务。
// 注意,非主机平台的 runTask 为 null。
runTask?.dependsOn(prepareForRun)
}
framework('my_framework' [RELEASE]) {
// 在框架中包含静态库而不是动态库。
isStatic = true
}
}
了解更多关于 构建本地二进制文件 的信息。
CInterops
cinterops
是与原生库互操作的描述集合。要提供与库的互操作性,向 cinterops
添加条目并定义其参数:
名称 | 描述 |
---|
definitionFile
| 描述本地 API 的 .def 文件。 |
packageName
| 生成的 Kotlin API 的包前缀。 |
compilerOpts
| 传递给编译器的选项,通过 cinterop 工具使用。 |
includeDirs
| 查找头文件的目录。 |
header
| 要包含在绑定中的头文件。 |
headers
| 要包含在绑定中的头文件列表。 |
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")
// 头文件搜索目录(类似于 -I<path> 编译器选项)。
includeDirs.allHeaders("path1", "path2")
// includeDirs.allHeaders 的简写。
includeDirs("include/directory", "another/directory")
// Header files to be included in the bindings.
header("path/to/header.h")
headers("path/to/header1.h", "path/to/header2.h")
}
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")
// includeDirs.allHeaders 的简写。
includeDirs("include/directory", "another/directory")
// 要包含在绑定中的头文件。
header("path/to/header.h")
headers("path/to/header1.h", "path/to/header2.h")
}
anotherInterop { /* ... */ }
}
}
}
}
有关更多的 cinterop 属性,请参见 定义文件。
Android 目标
Kotlin 跨平台插件包含两个针对 Android 目标的特定函数。
这两个函数帮助你配置 构建变体:
名称 | 描述 |
---|
publishLibraryVariants()
| 指定要发布的构建变体。了解更多关于 发布 Android 库 的信息。 |
publishAllLibraryVariants()
| 发布所有构建变体。 |
kotlin {
android {
publishLibraryVariants("release", "debug")
}
}
了解更多关于 Android 的编译 的信息。
源代码集
sourceSets {}
块描述了项目的源代码集。源代码集包含了参与一起编译的 Kotlin 源文件,以及它们的资源、依赖项和语言设置。
一个跨平台项目包含为其目标平台 预定义的 源代码集; 开发者也可以根据需要创建 自定义 源代码集。
预定义源代码集
预定义源代码集会在创建跨平台项目时自动设置。可用的预定义源代码集如下:
名称 | 描述 |
---|
commonMain
| 所有平台共享的代码和资源。适用于所有跨平台项目。在项目的所有主要编译中使用。 |
commonTest
| 所有平台共享的测试代码和资源。适用于所有跨平台项目。在项目的所有测试编译中使用。 |
<targetName><compilationName> | 针对特定目标的编译源。 <targetName> 是预定义目标的名称, <compilationName> 是该目标的编译名称。例如: jsTest , jvmMain 。 |
在 Kotlin Gradle DSL 中,预定义源代码集的部分应标记为 by getting
。
kotlin {
sourceSets {
val commonMain by getting { /* ... */ }
}
}
kotlin {
sourceSets {
commonMain { /* ... */ }
}
}
了解更多关于源代码集的内容。
自定义源代码集
自定义源代码集由项目开发者手动创建。 要创建一个自定义源代码集,请在 sourceSets
部分中添加其名称。 如果使用 Kotlin Gradle DSL,需标记自定义源代码集为 by creating
。
kotlin {
sourceSets {
val myMain by creating { /* ... */ } // 创建一个名为 'MyMain' 的新源代码集
}
}
kotlin {
sourceSets {
myMain { /* ... */ } // 创建或配置一个名为 'myMain' 的源代码集
}
}
请注意,新创建的源代码集并不会自动与其他源代码集连接。要在项目编译中使用它,请 将其与其他源代码集连接。
源代码集参数
源代码集的配置存储在对应的 sourceSets {}
块中。一个源代码集包含以下参数:
名称 | 描述 |
---|
kotlin.srcDir
| 源代码集目录中 Kotlin 源文件的位置。 |
resources.srcDir
| 源代码集目录中资源文件的位置。 |
dependsOn
| 与另一个源代码集的连接。 |
dependencies
| 源代码集的依赖项。 |
languageSettings
| 应用于源代码集的语言设置。 |
kotlin {
sourceSets {
val commonMain by getting {
kotlin.srcDir("src")
resources.srcDir("res")
dependencies {
/* ... */
}
}
}
}
kotlin {
sourceSets {
commonMain {
kotlin.srcDir('src')
resources.srcDir('res')
dependencies {
/* ... */
}
}
}
}
编译
一个目标可以有一个或多个编译,例如用于生产或测试。创建目标时会自动添加预定义编译。 你还可以额外创建自定义编译。
要引用某个目标的所有或部分特定编译,使用 compilations
对象集合。 通过 compilations
,你可以根据编译的名称进行引用。
了解更多关于配置编译的内容。
预定义编译
预定义编译会为项目的每个目标自动创建,Android 目标除外。 可用的预定义编译如下:
名称 | 描述 |
---|
main
| 用于生产源代码的编译。 |
test
| 用于测试的编译。 |
kotlin {
jvm {
val main by compilations.getting {
output // 获取 main 编译的输出
}
compilations["test"].runtimeDependencyFiles // 获取测试运行时的类路径
}
}
kotlin {
jvm {
compilations.main.output // 获取 main 编译的输出
compilations.test.runtimeDependencyFiles // 获取测试运行时的类路径
}
}
自定义编译
除了预定义编译,你还可以创建自己的自定义编译。 要创建自定义编译,向 compilations
集合中添加一个新项。 如果使用 Kotlin Gradle DSL,需标记自定义编译为 by creating
。
了解更多关于创建自定义编译的内容。
kotlin {
jvm() {
compilations {
val integrationTest by compilations.creating {
defaultSourceSet {
dependencies {
/* ... */
}
}
// 创建一个测试任务来运行此编译生成的测试:
tasks.register<Test>("integrationTest") {
/* ... */
}
}
}
}
}
kotlin {
jvm() {
compilations.create('integrationTest') {
defaultSourceSet {
dependencies {
/* ... */
}
}
// 创建一个测试任务来运行此编译生成的测试:
tasks.register('jvmIntegrationTest', Test) {
/* ... */
}
}
}
}
编译参数
一个编译包含以下参数:
名称 | 描述 |
---|
defaultSourceSet
| 编译的默认源代码集。 |
kotlinSourceSets
| 参与编译的源代码集。 |
allKotlinSourceSets
| 参与编译的源代码集及其通过 dependsOn() 连接的其他源代码集。 |
compilerOptions
| 应用于编译的编译器选项。可用选项列表请参见编译器选项。 |
compileKotlinTask
| 编译 Kotlin 源代码的 Gradle 任务。 |
compileKotlinTaskName
| compileKotlinTask 的名称。
|
compileAllTaskName
| 编译所有源代码的 Gradle 任务名称。 |
output
| 编译输出。 |
compileDependencyFiles
| 编译时的依赖文件(类路径)。对于所有 Kotlin/Native 编译,这会自动包含标准库和平台依赖项。 |
runtimeDependencyFiles
| 运行时的依赖文件(类路径)。 |
kotlin {
jvm {
val main by compilations.getting {
compilerOptions.configure {
// 为 'main' 编译设置 Kotlin 编译器选项:
jvmTarget.set(JvmTarget.JVM_1_8)
}
compileKotlinTask // 获取 Kotlin 任务 'compileKotlinJvm'
output // 获取 main 编译的输出
}
compilations["test"].runtimeDependencyFiles // 获取测试运行时的类路径
}
// 配置所有目标的所有编译:
targets.all {
compilations.all {
compilerOptions.configure {
allWarningsAsErrors.set(true)
}
}
}
}
kotlin {
jvm {
compilations.main.compilerOptions.configure {
// 为 'main' 编译设置 Kotlin 编译器选项:
jvmTarget = JvmTarget.JVM_1_8
}
compilations.main.compileKotlinTask // 获取 Kotlin 任务 'compileKotlinJvm'
compilations.main.output // 获取 main 编译的输出
compilations.test.runtimeDependencyFiles // 获取测试运行时的类路径
}
// 配置所有目标的所有编译:
targets.all {
compilations.all {
compilerOptions.configure {
allWarningsAsErrors = true
}
}
}
}
或者,要配置适用于所有目标的通用编译器选项,可以使用 compilerOptions {}
顶级块:
kotlin {
// 配置所有目标的所有编译:
@OptIn(ExperimentalKotlinGradlePluginApi::class)
compilerOptions {
allWarningsAsErrors.set(true)
}
}
kotlin {
// 配置所有目标的所有编译:
compilerOptions {
allWarningsAsErrors = true
}
}
依赖
sourceSets {}
声明块中的 dependencies {}
包含了该源代码集的依赖项。
了解更多关于配置依赖项。
依赖项有四种类型:
名称 | 描述 |
---|
api
| 在当前模块的 API 中使用的依赖项。 |
implementation
| 在模块中使用但不会对外暴露的依赖项。 |
compileOnly
| 仅用于当前模块编译的依赖项。 |
runtimeOnly
| 仅在运行时可用,但在编译过程中对任何模块都不可见的依赖项。 |
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
api("com.example:foo-metadata:1.0")
}
}
val jvmMain by getting {
dependencies {
implementation("com.example:foo-jvm:1.0")
}
}
}
}
kotlin {
sourceSets {
commonMain {
dependencies {
api 'com.example:foo-metadata:1.0'
}
}
jvmMain {
dependencies {
implementation 'com.example:foo-jvm:1.0'
}
}
}
}
此外,源代码集之间可以互相依赖并形成层次结构。 在这种情况下,使用 dependsOn()
关系。
源代码集的依赖项也可以在构建脚本的顶级 dependencies {}
块中声明。 在这种情况下,它们的声明遵循 <sourceSetName><DependencyKind>
模式,例如, commonMainApi
。
dependencies {
"commonMainApi"("com.example:foo-common:1.0")
"jvm6MainApi"("com.example:foo-jvm6:1.0")
}
dependencies {
commonMainApi 'com.example:foo-common:1.0'
jvm6MainApi 'com.example:foo-jvm6:1.0'
}
语言设置
sourceSets {}
块中的 languageSettings {}
定义了项目分析和构建的某些方面。以下是可用的语言设置:
名称 | 描述 |
---|
languageVersion
| 提供与指定版本的 Kotlin 源代码兼容性。 |
apiVersion
| 只允许使用指定版本的 Kotlin 捆绑库中的声明。 |
enableLanguageFeature
| 启用指定的语言特性。可用的值对应于当前实验性语言特性或在某个时间点引入的语言特性。 |
optIn
| 允许使用指定的 opt-in 注解。 |
progressiveMode
| 启用 progressive 模式。 |
kotlin {
sourceSets.all {
languageSettings.apply {
languageVersion = "2.0" // 可选值: '1.6', '1.7', '1.8', '1.9', `2.0`
apiVersion = "2.0" // 可选值: '1.6', '1.7', '1.8', '1.9', `2.0`
enableLanguageFeature("InlineClasses") // 语言特性名称
optIn("kotlin.ExperimentalUnsignedTypes") // 注解 FQ 名称
progressiveMode = true // 默认值为 false
}
}
}
kotlin {
sourceSets.all {
languageSettings {
languageVersion = '2.0' // 可选值: '1.6', '1.7', '1.8', '1.9', `2.0`
apiVersion = '2.0' // 可选值: '1.6', '1.7', '1.8', '1.9', `2.0`
enableLanguageFeature('InlineClasses') // 语言特性名称
optIn('kotlin.ExperimentalUnsignedTypes') // 注解 FQ 名称
progressiveMode = true // 默认值为 false
}
}
}
Last modified: 26 十一月 2024