Kotlin 多平台兼容性指南
This guide summarizes incompatible changes you might encounter while developing projects with Kotlin Multiplatform.
Mind the deprecation cycle of a specific change in relation to the Kotlin version you have in your projects. The current Stable version of Kotlin is 1.8.10.
New approach to auto-generated targets
What's changed?
Target accessors auto-generated by Gradle are no longer available inside the kotlin.targets
block. Use
the findByName("targetName")
method instead.
Note that such accessors are still available in the kotlin.targets
case, for example, kotlin.targets.linuxX64
.
What's the best practice now?
Before | Now |
```kotlin kotlin { targets { configure(['windows', 'linux']) { } } } ``` | ```kotlin kotlin { targets { configure([findByName('windows'), findByName('linux')]) { } } } ``` |
When do the changes take effect?
In Kotlin 1.7.20, an error is introduced when using target accessors in the kotlin.targets
block.
For more information, see the corresponding issue in YouTrack.
Changes in Gradle input and output compile tasks
What's changed?
Kotlin compile tasks no longer inherit the Gradle AbstractCompile
task that has the sourceCompatibility
and
targetCompatibility
inputs, making them unavailable in Kotlin users' scripts.
Other breaking changes in compile tasks:
What's the best practice now?
Before | Now |
---|---|
The SourceTask.stableSources input is no longer available. |
Use the sources input instead. Also, the setSource() methods are still available. |
The sourceFilesExtensions input was removed. |
Compile tasks still implement the PatternFilterable interface. Use its methods for filtering Kotlin sources. |
The Gradle destinationDir: File output was deprecated. |
Use the destinationDirectory: DirectoryProperty output instead. |
The classpath property of the KotlinCompile task is deprecated. |
All compile tasks now use the libraries input for a list of libraries required for compilation. |
When do the changes take effect?
In Kotlin 1.7.20, inputs are not available, the output is replaced, and the classpath
property is deprecated.
For more information, see the corresponding issue in YouTrack.
New configuration names for dependencies on the compilation
What's changed?
Compilation configurations created by the Kotlin Multiplatform Gradle Plugin received new names.
A target in the Kotlin Multiplatform project has two default compilations, main
and test
. Each of these compilations
has its own default source set, for example, jvmMain
and jvmTest
. Previously the configuration names for the test
compilation and its default source set were the same, which might lead to a name clash resulting in issues when a
configuration marked with platform-specific attributes is included in another configuration.
Now compilation configurations have an extra Compilation
postfix, while projects and plugins that use old hard-coded
configuration names no longer compile.
Configuration names for dependencies on the corresponding source set stay the same.
What's the best practice now?
Before | Now | |
Dependencies of the jvmMain compilation |
```kotlin
jvm |
```kotlin
jvmCompilation |
```kotlin dependencies { add("jvmImplementation", "foo.bar.baz:1.2.3") } ``` | ```kotlin dependencies { add("jvmCompilationImplementation", "foo.bar.baz:1.2.3") } ``` | |
Dependencies of the jvmMain source set |
```kotlin
jvmMain |
|
Dependencies of the jvmTest compilation |
```kotlin
jvmTest |
```kotlin
jvmTestCompilation |
Dependencies of the jvmTest source set |
```kotlin
jvmTest |
The available scopes are Api
, Implementation
, CompileOnly
, and RuntimeOnly
.
When do the changes take effect?
In Kotlin 1.8.0, an error is introduced when using old configuration names in hard-coded strings.
For more information, see the corresponding issue in YouTrack.
Deprecated Gradle properties for hierarchical structure support
What's changed?
Throughout its evolution, Kotlin was gradually introducing the support for hierarchical structure,
in multiplatform projects, an ability to have intermediate source sets between the common source set commonMain
and
any platform-specific one, for example, jvmMain
.
For the transition period, while the toolchain wasn't stable enough, a couple of Gradle properties were introduced, allowing granular opt-ins and opt-outs.
Since Kotlin 1.6.20, the hierarchical project structure support has been enabled by default. However, these properties were kept for opting out in case of blocking issues. After processing all the feedback, we're now starting to phase out those properties completely.
The following properties are now deprecated and will be removed in Kotlin 1.9.0:
kotlin.internal.mpp.hierarchicalStructureByDefault
kotlin.mpp.enableCompatibilityMetadataVariant
kotlin.mpp.hierarchicalStructureSupport
kotlin.mpp.enableGranularSourceSetsMetadata
kotlin.native.enableDependencyPropagation
What's the best practice now?
- Remove these properties from your
gradle.properties
andlocal.properties
files. - Avoid setting them programmatically in the Gradle build scripts or your Gradle plugins.
- In case deprecated properties are set by some third-party Gradle plugin used in your build, ask the plugin maintainers not to set these properties.
As the default behavior of the Kotlin toolchain doesn't include such properties since 1.6.20, we don't expect any serious impact from removing them. Most possible consequences will be visible immediately after the project rebuild.
If you're a library author and want to be extra safe, check that consumers can work with your library.
When do the changes take effect?
In 1.8.20, the Kotlin Gradle plugin shows a warning if the build sets these properties. Starting with Kotlin 1.9.0, the properties are silently ignored.
In the unlikely case you face some problems after removing these properties, create an issue in YouTrack.