Kotlin 多平台 Gradle DSL 参考

多平台项目处于 Alpha 版。语言特性与工具都可能在未来的 Kotlin 版本中发生变化。

Kotlin 多平台 Gradle 插件是用于创建 Kotlin 多平台 项目的工具。这里我们提供了它的参考;在为 Kotlin 多平台项目编写 Gradle 构建脚本时, 用它作提醒。 Learn the concepts of Kotlin multiplatform projects, how to create and configure them.

目录

id 与版本

Kotlin 多平台 Gradle 插件的全限定名是 org.jetbrains.kotlin.multiplatform。 如果你使用 Kotlin Gradle DSL,那么你可以通过 kotlin("multiplatform") 来应用插件。 插件版本与 Kotlin 发行版本相匹配。最新的版本是:1.4.20。

  1. plugins {
  2. id 'org.jetbrains.kotlin.multiplatform' version '1.4.20'
  3. }
  1. plugins {
  2. kotlin("multiplatform") version "1.4.20"
  3. }

顶层块

kotlin 是在 Gradle 构建脚本中用于配置多平台项目的顶层块。 kotlin 块内,你可以使用以下块:

介绍
<目标名称>声明项目的特定目标,所有可用的目标名称已陈列在目标部分中.
targets项目的所有目标。
presets所有预定义的目标。使用这个同时配置多个预定义目标
sourceSets配置预定义和声明自定义项目的源集

目标

目标 是构建的一部分,负责构建编译、测试、以及针对某个已支持平台打包软件。

Each target can have one or more compilations. In addition to default compilations for test and production purposes, you can create custom compilations.

多平台项目的目标在 kotlin 块中的相应代码块中描述,例如:jvmandroid 以及 iosArm64。 以下是可用目标的完整列表:

名称描述
jvmJava 虚拟机
jsJavaScript
androidAndroid(APK)
androidNativeArm32Android NDK 基于 ARM(ARM32)平台
androidNativeArm64Android NDK 基于 ARM64 平台
androidNativeX86Android NDK 基于 x86 平台
androidNativeX64Android NDK 基于 x86_64 平台
iosArm32Apple iOS 基于 ARM(ARM32)平台(Apple iPhone 5 或更早)
iosArm64Apple iOS 基于 ARM64 平台(Apple iPhone 5s 或更新)
iosX64Apple iOS 64-bit 模拟器
watchosArm32Apple watchOS 基于 ARM(ARM32)平台(Apple Watch Series 3 或更早)
watchosArm64Apple watchOS 基于 ARM64_32 平台(Apple Watch Series 4 或更新)
watchosX86Apple watchOS 模拟器
tvosArm64Apple tvOS 基于 ARM64 平台(Apple TV 4th generation 或更新)
tvosX64Apple tvOS 模拟器
linuxArm64Linux 基于 ARM64 平台,例如:树莓派
linuxArm32HfpLinux 基于 hard-float ARM(ARM32)平台
linuxMips32Linux 基于 MIPS 平台
linuxMipsel32Linux 基于 little-endian MIPS(mipsel)平台
linuxX64Linux 基于 x86_64 平台
macosX64Apple macOS
mingwX6464-bit 微软 Windows
mingwX8632-bit 微软 Windows
wasm32WebAssembly
  1. kotlin {
  2. jvm()
  3. iosX64()
  4. macosX64()
  5. js().browser()
  6. }

目标的配置项可以包含这两个部分:

Each target can have one or more compilations.

公共目标配置

In any target block, you can use the following declarations:

NameDescription
attributesAttributes used for disambiguating targets for a single platform.
presetThe preset that the target has been created from, if any.
platformTypeDesignates the Kotlin platform of this target. Avaiable values: jvm, androidJvm, js, native, common.
artifactsTaskNameThe name of the task that builds the resulting artifacts of this target.
componentsThe components used to setup Gradle publications.

JVM 目标

In addition to common target configuration, jvm targets have a specific function:

NameDescription
withJava()Includes Java sources into the JVM target’s compilations.

Use this function for projects that contain both Java and Kotlin source files. Note that the default source directories for Java sources don’t follow the Java plugin’s defaults. Instead, they are derived from the Kotlin source sets. For example, if the JVM target has the default name jvm, the paths are src/jvmMain/java (for production Java sources) and src/jvmTest/java for test Java sources. Learn how to include Java sources in JVM compilations.

  1. kotlin {
  2. jvm {
  3. withJava()
  4. }
  5. }

JavaScript 目标

The js block describes the configuration of JavaScript targets. It can contain one of two blocks depending on the target execution environment:

NameDescription
browserConfiguration of the browser target.
nodejsConfiguration of the Node.js target.

Learn more about configuring Kotlin/JS projects.

Browser

browser can contain the following configuration blocks:

NameDescription
testRunsConfiguration of test execution.
runTaskConfiguration of project running.
webpackTaskConfiguration of project bundling with Webpack.
dceTaskConfiguration of Dead Code Elimination.
distributionPath to output files.
  1. kotlin {
  2. js().browser {
  3. webpackTask { /* ... */ }
  4. testRuns { /* ... */ }
  5. dceTask {
  6. keep("myKotlinJsApplication.org.example.keepFromDce")
  7. }
  8. distribution {
  9. directory = File("$projectDir/customdir/")
  10. }
  11. }
  12. }

Node.js

nodejs can contain configurations of test and run tasks:

NameDescription
testRunsConfiguration of test execution.
runTaskConfiguration of project running.
  1. kotlin {
  2. js().nodejs {
  3. runTask { /* ... */ }
  4. testRuns { /* ... */ }
  5. }
  6. }

Native 目标

For native targets, the following specific blocks are available:

NameDescription
binariesConfiguration of binaries to produce.
cinteropsConfiguration of interop with C libraries.

Binaries

There are the following kinds of binaries:

NameDescription
executableProduct executable.
testTest executable.
sharedLibShared library.
staticLibStatic library.
frameworkObjective-C framework.
  1. kotlin {
  2. linuxX64 { // Use your target instead.
  3. binaries {
  4. executable {
  5. // Binary configuration.
  6. }
  7. }
  8. }
  9. }

For binaries configuration, the following parameters are available:

NameDescription
compilationThe compilation from which the binary is built. By default, test binaries are based on the test compilation while other binaries - on the main compilation.
linkerOptsOptions passed to a system linker during binary building.
baseNameCustom base name for the output file. The final file name will be formed by adding system-dependent prefix and postfix to this base name.
entryPointThe entry point function for executable binaries. By default, it’s main() in the root package.
outputFileAccess to the output file.
linkTaskAccess to the link task.
runTaskAccess to the run task for executable binaries. For targets other than linuxX64, macosX64, or mingwX64 the value is null.
isStaticFor Objective-C frameworks. Includes a static library instead of a dynamic one.
  1. binaries {
  2. executable('my_executable', [RELEASE]) {
  3. // Build a binary on the basis of the test compilation.
  4. compilation = compilations.test
  5. // Custom command line options for the linker.
  6. linkerOpts = ['-L/lib/search/path', '-L/another/search/path', '-lmylib']
  7. // Base name for the output file.
  8. baseName = 'foo'
  9. // Custom entry point function.
  10. entryPoint = 'org.example.main'
  11. // Accessing the output file.
  12. println("Executable path: ${outputFile.absolutePath}")
  13. // Accessing the link task.
  14. linkTask.dependsOn(additionalPreprocessingTask)
  15. // Accessing the run task.
  16. // Note that the runTask is null for non-host platforms.
  17. runTask?.dependsOn(prepareForRun)
  18. }
  19. framework('my_framework' [RELEASE]) {
  20. // Include a static library instead of a dynamic one into the framework.
  21. isStatic = true
  22. }
  23. }
  1. binaries {
  2. executable("my_executable", listOf(RELEASE)) {
  3. // Build a binary on the basis of the test compilation.
  4. compilation = compilations["test"]
  5. // Custom command line options for the linker.
  6. linkerOpts = mutableListOf("-L/lib/search/path", "-L/another/search/path", "-lmylib")
  7. // Base name for the output file.
  8. baseName = "foo"
  9. // Custom entry point function.
  10. entryPoint = "org.example.main"
  11. // Accessing the output file.
  12. println("Executable path: ${outputFile.absolutePath}")
  13. // Accessing the link task.
  14. linkTask.dependsOn(additionalPreprocessingTask)
  15. // Accessing the run task.
  16. // Note that the runTask is null for non-host platforms.
  17. runTask?.dependsOn(prepareForRun)
  18. }
  19. framework("my_framework" listOf(RELEASE)) {
  20. // Include a static library instead of a dynamic one into the framework.
  21. isStatic = true
  22. }
  23. }

Learn more about building native binaries.

CInterops

cinterops is a collection of descriptions for interop with native libraries. To provide an interop with a library, add an entry to cinterops and define its parameters:

NameDescription
defFiledef file describing the native API.
packageNamePackage prefix for the generated Kotlin API.
compilerOptsOptions to pass to the compiler by the cinterop tool.
includeDirsDirectories to look for headers.

Learn more how to configure interop with native languages.

  1. kotlin {
  2. linuxX64 { // Replace with a target you need.
  3. compilations.main {
  4. cinterops {
  5. myInterop {
  6. // Def-file describing the native API.
  7. // The default path is src/nativeInterop/cinterop/<interop-name>.def
  8. defFile project.file("def-file.def")
  9. // Package to place the Kotlin API generated.
  10. packageName 'org.sample'
  11. // Options to be passed to compiler by cinterop tool.
  12. compilerOpts '-Ipath/to/headers'
  13. // Directories for header search (an analogue of the -I<path> compiler option).
  14. includeDirs.allHeaders("path1", "path2")
  15. // A shortcut for includeDirs.allHeaders.
  16. includeDirs("include/directory", "another/directory")
  17. }
  18. anotherInterop { /* ... */ }
  19. }
  20. }
  21. }
  22. }
  1. kotlin {
  2. linuxX64 { // Replace with a target you need.
  3. compilations.getByName("main") {
  4. val myInterop by cinterops.creating {
  5. // Def-file describing the native API.
  6. // The default path is src/nativeInterop/cinterop/<interop-name>.def
  7. defFile(project.file("def-file.def"))
  8. // Package to place the Kotlin API generated.
  9. packageName("org.sample")
  10. // Options to be passed to compiler by cinterop tool.
  11. compilerOpts("-Ipath/to/headers")
  12. // Directories for header search (an analogue of the -I<path> compiler option).
  13. includeDirs.allHeaders("path1", "path2")
  14. // A shortcut for includeDirs.allHeaders.
  15. includeDirs("include/directory", "another/directory")
  16. }
  17. val anotherInterop by cinterops.creating { /* ... */ }
  18. }
  19. }
  20. }

Android 目标

The Kotlin multiplatform plugin contains two specific functions for android targets. Two functions help you configure build variants:

NameDescription
publishLibraryVariants()Specifies build variants to publish. Learn more about publishing Android libraries.
publishAllLibraryVariants()Publishes all build variants.
  1. kotlin {
  2. android {
  3. publishLibraryVariants("release", "debug")
  4. }
  5. }

Learn more about compilation for Android.

The android configuration inside kotlin doesn’t replace the build configuration of any Android project. Learn more about writing build scripts for Android projects in Android developer documentation.

源集

The sourceSets block describes source sets of the project. A source set contains Kotlin source files that participate in compilations together, along with their resources, dependencies, and language settings.

A multiplatform project contains predefined source sets for its targets; developers can also create custom source sets for their needs.

预定义源集

Predefined source sets are set up automatically upon creation of a multiplatform project. Available predefined source sets are the following:

NameDescription
commonMainCode and resources shared between all platforms. Available in all multiplatform projects. Used in all main compilations of a project.
commonTestTest code and resources shared between all platforms. Available in all multiplatform projects. Used in all test compilations of a project.
<targetName><compilationName>Target-specific sources for a compilation. <targetName> is the name of a predefined target and <compilationName> is the name of a compilation for this target. Examples: jsTest, jvmMain.

With Kotlin Gradle DSL, the sections of predefined source sets should be marked by getting.

  1. kotlin {
  2. sourceSets {
  3. commonMain { /* ... */ }
  4. }
  5. }
  1. kotlin {
  2. sourceSets {
  3. val commonMain by getting { /* ... */ }
  4. }
  5. }

Learn more about source sets.

自定义源集

Custom source sets are created by the project developers manually. To create a custom source set, add a section with its name inside the sourceSets section. If using Kotlin Gradle DSL, mark custom source sets by creating.

  1. kotlin {
  2. sourceSets {
  3. myMain { /* ... */ } // create or configure a source set by the name 'myMain'
  4. }
  5. }
  1. kotlin {
  2. sourceSets {
  3. val myMain by creating { /* ... */ } // create a new source set by the name 'MyMain'
  4. }
  5. }

Note that a newly created source set isn’t connected to other ones. To use it in the project’s compilations, connect it with other source sets.

源集参数

Configurations of source sets are stored inside the corresponding blocks of sourceSets. A source set has the following parameters:

NameDescription
kotlin.srcDirLocation of Kotlin source files inside the source set directory.
resources.srcDirLocation of resources inside the source set directory.
dependsOnConnection with another source set.
dependencies依赖项 of the source set.
languageSettings语言设置 applied to the source set.
  1. kotlin {
  2. sourceSets {
  3. commonMain {
  4. kotlin.srcDir('src')
  5. resources.srcDir('res')
  6. dependencies {
  7. /* ... */
  8. }
  9. }
  10. }
  11. }
  1. kotlin {
  2. sourceSets {
  3. val commonMain by getting {
  4. kotlin.srcDir("src")
  5. resources.srcDir("res")
  6. dependencies {
  7. /* ... */
  8. }
  9. }
  10. }
  11. }

编译项

A target can have one or more compilations, for example, for production or testing. There are predefined compilations that are added automatically upon target creation. You can additionally create custom compilations.

To refer to all or some particular compilations of a target, use the compilations object collection. From compilations, you can refer to a compilation by its name.

Learn more about configuring compilations.

预定义编译项

Predefined compilations are created automatically for each target of a project except for Android targets. Available predefined compilations are the following:

NameDescription
mainCompilation for production sources.
testCompilation for tests.
  1. kotlin {
  2. jvm {
  3. compilations.main.output // get the main compilation output
  4. compilations.test.runtimeDependencyFiles // get the test runtime classpath
  5. }
  6. }
  1. kotlin {
  2. jvm {
  3. val main by compilations.getting {
  4. output // get the main compilation output
  5. }
  6. compilations["test"].runtimeDependencyFiles // get the test runtime classpath
  7. }
  8. }

自定义编译项

In addition to predefined compilations, you can create your own custom compilations. To create a custom compilation, add a new item into the compilations collection. If using Kotlin Gradle DSL, mark custom compilations by creating.

Learn more about creating a custom compilation.

  1. kotlin {
  2. jvm() {
  3. compilations.create('integrationTest') {
  4. defaultSourceSet {
  5. dependencies {
  6. /* ... */
  7. }
  8. }
  9. // Create a test task to run the tests produced by this compilation:
  10. tasks.register('jvmIntegrationTest', Test) {
  11. /* ... */
  12. }
  13. }
  14. }
  15. }
  1. kotlin {
  2. jvm() {
  3. compilations {
  4. val integrationTest by compilations.creating {
  5. defaultSourceSet {
  6. dependencies {
  7. /* ... */
  8. }
  9. }
  10. // Create a test task to run the tests produced by this compilation:
  11. tasks.register<Test>("integrationTest") {
  12. /* ... */
  13. }
  14. }
  15. }
  16. }
  17. }

编译项参数

A compilation has the following parameters:

NameDescription
defaultSourceSetThe compilation’s default source set.
kotlinSourceSetsSource sets participating in the compilation.
allKotlinSourceSetsSource sets participating in the compilation and their connections via dependsOn().
kotlinOptionsCompiler options applied to the compilation. For the list of available options, see Compiler options.
compileKotlinTaskGradle task for compiling Kotlin sources.
compileKotlinTaskNameName of compileKotlinTask.
compileAllTaskNameName of the Gradle task for compiling all sources of a compilation.
outputThe compilation output.
compileDependencyFilesCompile-time dependency files (classpath) of the compilation.
runtimeDependencyFilesRuntime dependency files (classpath) of the compilation.
  1. kotlin {
  2. jvm {
  3. compilations.main.kotlinOptions {
  4. // Setup the Kotlin compiler options for the 'main' compilation:
  5. jvmTarget = "1.8"
  6. }
  7. compilations.main.compileKotlinTask // get the Kotlin task 'compileKotlinJvm'
  8. compilations.main.output // get the main compilation output
  9. compilations.test.runtimeDependencyFiles // get the test runtime classpath
  10. }
  11. // Configure all compilations of all targets:
  12. targets.all {
  13. compilations.all {
  14. kotlinOptions {
  15. allWarningsAsErrors = true
  16. }
  17. }
  18. }
  19. }
  1. kotlin {
  2. jvm {
  3. val main by compilations.getting {
  4. kotlinOptions {
  5. // Setup the Kotlin compiler options for the 'main' compilation:
  6. jvmTarget = "1.8"
  7. }
  8. compileKotlinTask // get the Kotlin task 'compileKotlinJvm'
  9. output // get the main compilation output
  10. }
  11. compilations["test"].runtimeDependencyFiles // get the test runtime classpath
  12. }
  13. // Configure all compilations of all targets:
  14. targets.all {
  15. compilations.all {
  16. kotlinOptions {
  17. allWarningsAsErrors = true
  18. }
  19. }
  20. }
  21. }

依赖项

The dependencies block of the source set declaration contains the dependencies of this source set.

Learn more about configuring dependencies.

There are four types of dependencies:

NameDescription
apiDependencies used in the API of the current module.
implementationDependencies used in the module but not exposed outside it.
compileOnlyDependencies used only for compilation of the current module.
runtimeOnlyDependencies available at runtime but not visible during compilation of any module.
  1. kotlin {
  2. sourceSets {
  3. commonMain {
  4. dependencies {
  5. api 'com.example:foo-metadata:1.0'
  6. }
  7. }
  8. jvm6Main {
  9. dependencies {
  10. implementation 'com.example:foo-jvm6:1.0'
  11. }
  12. }
  13. }
  14. }
  1. kotlin {
  2. sourceSets {
  3. val commonMain by getting {
  4. dependencies {
  5. api("com.example:foo-metadata:1.0")
  6. }
  7. }
  8. val jvm6Main by getting {
  9. dependencies {
  10. implementation("com.example:foo-jvm6:1.0")
  11. }
  12. }
  13. }
  14. }

Additionally, source sets can depend on each other and for a hierarchy. In this case, the dependsOn() relation is used.

Source set dependencies can also be declared in the top-level dependencies block of the build script. In this case, their declarations follow the pattern <sourceSetName><DependencyKind>, for example, commonMainApi.

  1. dependencies {
  2. commonMainApi 'com.example:foo-common:1.0'
  3. jvm6MainApi 'com.example:foo-jvm6:1.0'
  4. }
  1. dependencies {
  2. "commonMainApi"("com.example:foo-common:1.0")
  3. "jvm6MainApi"("com.example:foo-jvm6:1.0")
  4. }

语言设置

The languageSettings block of a source set defines certain aspects of project analysis and build. The following language settings are available:

NameDescription
languageVersionProvides source compatibility with the specified version of Kotlin.
apiVersionAllows using declarations only from the specified version of Kotlin bundled libraries.
enableLanguageFeatureEnables the specified language feature. The available values correspond to the language features that are currently experimental or have been introduced as such at some point.
useExperimentalAnnotationAllows using the specified opt-in annotation.
progressiveModeEnables the progressive mode.
  1. kotlin {
  2. sourceSets.all {
  3. languageSettings {
  4. languageVersion = '1.4' // possible values: '1.0', '1.1', '1.2', '1.3', '1.4'
  5. apiVersion = '1.4' // possible values: '1.0', '1.1', '1.2', '1.3', '1.4'
  6. enableLanguageFeature('InlineClasses') // language feature name
  7. useExperimentalAnnotation('kotlin.ExperimentalUnsignedTypes') // annotation FQ-name
  8. progressiveMode = true // false by default
  9. }
  10. }
  11. }
  1. kotlin {
  2. sourceSets.all {
  3. languageSettings.apply {
  4. languageVersion = "1.4" // possible values: "1.0", "1.1", "1.2", "1.3", "1.4"
  5. apiVersion = "1.4" // possible values: "1.0", "1.1", "1.2", "1.3", "1.4"
  6. enableLanguageFeature("InlineClasses") // language feature name
  7. useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes") // annotation FQ-name
  8. progressiveMode = true // false by default
  9. }
  10. }
  11. }