diff --git a/docs/topics/multiplatform/multiplatform-compatibility-guide.md b/docs/topics/multiplatform/multiplatform-compatibility-guide.md
index 2f6cd353c49..2219f797860 100644
--- a/docs/topics/multiplatform/multiplatform-compatibility-guide.md
+++ b/docs/topics/multiplatform/multiplatform-compatibility-guide.md
@@ -1,17 +1,22 @@
[//]: # (title: Compatibility guide for Kotlin Multiplatform)
+
+
This guide summarizes [incompatible changes](kotlin-evolution-principles.md#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 %kotlinVersion%.
->
-{style="note"}
+The current Stable version of Kotlin is %kotlinVersion%. Mind the deprecation cycle of a specific change in relation to
+the Kotlin version you have in your projects, for example:
+
+* When upgrading from Kotlin 1.7.0 to Kotlin 1.9.0, check incompatible changes that came into effect both in
+ [Kotlin 1.9.0](#kotlin-1-9-0-1-9-25) and in [Kotlin 1.7.0−1.8.22](#kotlin-1-7-0-1-8-22).
+* When upgrading from Kotlin 1.9.0 to Kotlin 2.0.0, check incompatible changes that came into effect both in
+ [Kotlin 2.0.0](#kotlin-2-0-0-and-later) and in [Kotlin 1.9.0−1.9.25](#kotlin-1-9-0-1-9-25).
## Version compatibility
-When configuring your project, check the compatibility of a particular version of the Kotlin Multiplatform Gradle plugin (same as the Kotlin version in your project)
-with available Gradle, Xcode, and Android Gradle plugin versions:
+When configuring your project, check the compatibility of a particular version of the Kotlin Multiplatform Gradle plugin
+(same as the Kotlin version in your project) with Gradle, Xcode, and Android Gradle plugin versions:
| Kotlin Multiplatform plugin version | Gradle | Android Gradle plugin | Xcode |
|-------------------------------------|----------------------------------------|---------------------------------|---------|
@@ -28,308 +33,206 @@ with available Gradle, Xcode, and Android Gradle plugin versions:
>
{style="warning"}
-## Deprecated compatibility with Kotlin Multiplatform Gradle plugin and Gradle Java plugins
-
-**What's changed?**
-
-Due to compatibility issues between the Kotlin Multiplatform Gradle plugin and the Gradle plugins
-[Java](https://docs.gradle.org/current/userguide/java_plugin.html),
-[Java Library](https://docs.gradle.org/current/userguide/java_library_plugin.html),
-and [Application](https://docs.gradle.org/current/userguide/application_plugin.html),
-there is now a deprecation warning when you apply these plugins to the same project. The warning also appears when another
-Gradle plugin in your multiplatform project applies a Gradle Java plugin. For example, the [Spring Boot Gradle Plugin](https://docs.spring.io/spring-boot/gradle-plugin/index.html)
-automatically applies the Application plugin.
-In future Kotlin releases, the warning will be increased to an error.
+## Kotlin 2.0.0 and later
-We've added this deprecation warning due to fundamental compatibility issues between Kotlin Multiplatform's project model
-and Gradle's Java ecosystem plugins. Gradle's Java ecosystem plugins currently don't take into account that other plugins may:
+This section covers incompatible changes that end their deprecation cycle and come into effect in Kotlin 2.0.0−%kotlinVersion%.
-* Also publish or compile for the JVM target in a different way than the Java ecosystem plugins.
-* Have two different JVM targets in the same project, such as JVM and Android.
-* Have a complex multiplatform project structure with potentially multiple non-JVM targets.
+
+### Rename of `android` target to `androidTarget`
-Unfortunately, Gradle doesn't currently provide any API to address these issues.
+**What's changed?**
-We previously used some workarounds in Kotlin Multiplatform to help with the integration of Java ecosystem plugins.
-However, these workarounds never truly solved the compatibility issues, and since the release of Gradle 8.8, these workarounds
-are no longer possible. For more information, see our [YouTrack issue](https://youtrack.jetbrains.com/issue/KT-66542/Gradle-JVM-target-with-withJava-produces-a-deprecation-warning).
+We continue our efforts to make Kotlin Multiplatform more stable. An essential step in this direction is to provide first-class
+support for the Android target. In the future, this support will be provided via a separate plugin, developed by the
+Android team from Google.
-While we don't yet know exactly how to resolve this compatibility problem, we are committed to continuing support for
-some form of Java source compilation in your Kotlin Multiplatform projects. At a minimum, we will support the compilation
-of Java sources and using Gradle's [`java-base`](https://docs.gradle.org/current/javadoc/org/gradle/api/plugins/JavaBasePlugin.html) plugin within your multiplatform projects.
+To open the way for the new solution, we're renaming the `android` block to `androidTarget` in the current
+Kotlin DSL. This is a temporary change that is necessary to free the short `android` name for the upcoming DSL
+from Google.
**What's the best practice now?**
-If you see this deprecation warning in your multiplatform project, we recommend that you:
-1. Determine whether you actually need the Gradle Java plugin in your project. If not, consider removing it.
-2. Check if the Gradle Java plugin is only used for a single task. If so, you might be able to remove the plugin without
- much effort. For example, if the task uses a Gradle Java plugin to create a Javadoc JAR file, you can define the Javadoc
- task manually instead.
-
-Otherwise, if you want to use both the Kotlin Multiplatform Gradle plugin and these Gradle plugins for Java in your multiplatform
-project, we recommend that you:
-
-1. Create a separate subproject in your multiplatform project.
-2. In the separate subproject, apply the Gradle plugin for Java.
-3. In the separate subproject, add a dependency on your parent multiplatform project.
+Rename all the occurrences of the `android` block to `androidTarget`. When the new plugin for the Android target support
+is available, migrate to the DSL from Google. It will be the preferred option to work with Android in Kotlin Multiplatform
+projects.
-> The separate subproject must **not** be a multiplatform project, and you must only use it to set up a dependency on your multiplatform project.
->
-{style="warning"}
+**When do the changes take effect?**
-For example, you have a multiplatform project called `my-main-project` and you want
-to use the [Application](https://docs.gradle.org/current/userguide/application_plugin.html) Gradle plugin to run a JVM application.
+Here's the planned deprecation cycle:
-Once you've created a subproject, let's call it `subproject-A`, your parent project structure should look like this:
+* 1.9.0: introduce a deprecation warning when the `android` name is used in Kotlin Multiplatform projects
+* 2.1.0: raise this warning to an error
+* 2.2.0: remove the `android` target DSL from the Kotlin Multiplatform Gradle plugin
-```text
-.
-├── build.gradle
-├── settings.gradle.kts
-├── subproject-A
- └── build.gradle.kts
- └── src
- └── Main.java
-```
+
+### Declaring several similar targets
-In your subproject's `build.gradle.kts` file, apply the Application plugin in the `plugins {}` block:
+**What's changed?**
-
-
+We discourage declaring several similar targets in a single Gradle project. For example:
```kotlin
-plugins {
- id("application")
-}
-```
-
-
-
-
-```groovy
-plugins {
- id('application')
+kotlin {
+ jvm("jvmKtor")
+ jvm("jvmOkHttp") // Not recommended and produces a deprecation warning
}
```
-
-
-
-In your subproject's `build.gradle.kts` file, add a dependency on your parent multiplatform project:
-
-
-
+One popular case is having two related pieces of code together. For example, you might want to use
+`jvm("jvmKtor")` and `jvm("jvmOkHttp")` in your `:shared` Gradle project to implement networking using the Ktor
+or OkHttp libraries:
```kotlin
-dependencies {
- implementation(project(":my-main-project")) // The name of your parent multiplatform project
-}
-```
-
-
-
+// shared/build.gradle.kts:
+kotlin {
+ jvm("jvmKtor") {
+ attributes.attribute(/* ... */)
+ }
+ jvm("jvmOkHttp") {
+ attributes.attribute(/* ... */)
+ }
-```groovy
-dependencies {
- implementation project(':my-main-project') // The name of your parent multiplatform project
+ sourceSets {
+ val commonMain by getting
+ val commonJvmMain by sourceSets.creating {
+ dependsOn(commonMain)
+ dependencies {
+ // Shared dependencies
+ }
+ }
+ val jvmKtorMain by getting {
+ dependsOn(commonJvmMain)
+ dependencies {
+ // Ktor dependencies
+ }
+ }
+ val jvmOkHttpMain by getting {
+ dependsOn(commonJvmMain)
+ dependencies {
+ // OkHttp dependencies
+ }
+ }
+ }
}
```
-
-
-
+The implementation comes with non-trivial configuration complexity:
-Your parent project is now set up to work with both plugins.
+* You have to set up Gradle attributes on the `:shared` side and each consumer's side. Otherwise, Gradle can't
+ resolve dependencies in such projects because without additional information it's not clear whether the consumer
+ should receive the Ktor-based or the OkHttp-based implementation.
+* You have to set up the `commonJvmMain` source set manually.
+* The configuration involves a handful of low-level Gradle and Kotlin Gradle plugin abstractions and APIs.
-## New approach to auto-generated targets
+**What's the best practice now?**
-**What's changed?**
+The configuration is complex because Ktor-based and OkHttp-based implementations are
+_in the same Gradle project_. In many cases, it's possible to extract those parts into separate Gradle projects.
+Here's a general outline of such as a refactoring:
-Target accessors auto-generated by Gradle are no longer available inside the `kotlin.targets {}` block. Use
-the `findByName("targetName")` method instead.
+1. Replace two duplicated targets from the original project with a single target. If you had a shared source set between
+ these targets, move its sources and configuration to the default source set of the newly created target:
-Note that such accessors are still available in the `kotlin.targets {}` case, for example, `kotlin.targets.linuxX64`.
+ ```kotlin
+ // shared/build.gradle.kts:
+ kotlin {
+ jvm()
+
+ sourceSets {
+ jvmMain {
+ // Copy the configuration of jvmCommonMain here
+ }
+ }
+ }
+ ```
-**What's the best practice now?**
+2. Add two new Gradle projects, usually by calling `include` in your `settings.gradle.kts` file. For example:
-
-
- Before |
- Now |
-
-
-
+ ```kotlin
+ include(":okhttp-impl")
+ include(":ktor-impl")
+ ```
-```kotlin
-kotlin {
- targets {
- configure(['windows',
- 'linux']) {
- }
- }
-}
-```
+3. Configure each new Gradle project:
- |
-
+ * Most likely, you don't need to apply the `kotlin("multiplatform")` plugin, as these projects compile only to one
+ target. In this example, you can apply `kotlin("jvm")`.
+ * Move the content of original target-specific source sets to their respective projects, for example,
+ from `jvmKtorMain` to `ktor-impl/src`.
+ * Copy the configuration of source sets: dependencies, compiler options, and so on.
+ * Add a dependency from the new Gradle project to the original project.
-```kotlin
-kotlin {
- targets {
- configure([findByName('windows'),
- findByName('linux')]) {
+ ```kotlin
+ // ktor-impl/build.gradle.kts:
+ plugins {
+ kotlin("jvm")
+ }
+
+ dependencies {
+ project(":shared") // Add dependency on the original project
+ // Copy dependencies of jvmKtorMain here
+ }
+
+ kotlin {
+ compilerOptions {
+ // Copy compiler options of jvmKtorMain here
}
}
-}
-```
+ ```
- |
-
-
+While this approach requires more work on the initial setup, it doesn't use any low-level entities of Gradle and
+the Kotlin Gradle plugin, making it easier to use and maintain the resulting build.
+
+> Unfortunately, we can't provide detailed migration steps for each case. If the instructions above don't work
+> for you, describe your use case in this [YouTrack issue](https://youtrack.jetbrains.com/issue/KT-59316).
+>
+{style="tip"}
**When do the changes take effect?**
-In Kotlin 1.7.20, an error is introduced when using target accessors in the `kotlin.targets {}` block.
+Here's the planned deprecation cycle:
-For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-47047).
+* 1.9.20: introduce a deprecation warning when multiple similar targets are used in Kotlin Multiplatform projects
+* 2.1.0: report an error in such cases, except for Kotlin/JS targets; to learn more about this exception, see the issue in [YouTrack](https://youtrack.jetbrains.com/issue/KT-47038/KJS-MPP-Split-JS-target-into-JsBrowser-and-JsNode)
-## Changes in Gradle input and output compile tasks
+
+### Deprecated support of multiplatform libraries published in the legacy mode
**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.
+Previously, we [have deprecated
+the legacy mode](#deprecated-gradle-properties-for-hierarchical-structure-support) in Kotlin Multiplatform projects
+preventing the publication of "legacy" binaries and encouraged you to migrate your projects to the [hierarchical structure](multiplatform-hierarchy.md).
-Other breaking changes in compile tasks:
+To continue phasing out "legacy" binaries from the ecosystem, starting with Kotlin 1.9.0, the use of legacy libraries
+is also discouraged. If your project uses dependencies on legacy libraries, you'll see the following warning:
+
+```none
+The dependency group:artifact:1.0 was published in the legacy mode. Support for such dependencies will be removed in the future
+```
**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. |
+_If you use multiplatform libraries_, most of them have already migrated to the "hierarchical structure" mode,
+so you only need to update the library version. See the documentation of the respective libraries for details.
-**When do the changes take effect?**
+If the library doesn't support non-legacy binaries yet, you can contact the maintainers and tell them about this
+compatibility issue.
-In Kotlin 1.7.20, inputs are not available, the output is replaced, and the `classpath` property is deprecated.
+_If you're a library author_, update the Kotlin Gradle plugin to the latest version and ensure you've fixed the [deprecated Gradle properties](#deprecated-gradle-properties-for-hierarchical-structure-support).
-For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-32805).
-
-## 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`.
+The Kotlin team is eager to help the ecosystem migrate, so if you face any issues, don't hesitate to create an [issue in YouTrack](https://kotl.in/issue).
**When do the changes take effect?**
-In Kotlin 1.8.0, an error is introduced when using old configuration names in hard-coded strings.
+Here's the planned deprecation cycle:
-For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-35916/).
+* 1.9: introduce a deprecation warning for dependencies on legacy libraries
+* 2.0: raise the warning for dependencies on legacy libraries to an error
+* >2.0: remove support for dependencies on legacy libraries; using such dependencies can cause build failures
-
-## Deprecated Gradle properties for hierarchical structure support
+### Deprecated Gradle properties for hierarchical structure support
**What's changed?**
@@ -374,44 +277,137 @@ Here's the planned deprecation cycle:
In the unlikely case you face some problems after removing these properties, create an [issue in YouTrack](https://kotl.in/issue).
-
-## Deprecated support of multiplatform libraries published in the legacy mode
+
+### Deprecated target presets API
**What's changed?**
-Previously, we [have deprecated
-the legacy mode](#deprecated-gradle-properties-for-hierarchical-structure-support) in Kotlin Multiplatform projects
-preventing the publication of "legacy" binaries and encouraged you to migrate your projects to the [hierarchical structure](multiplatform-hierarchy.md).
+In the very early development stages, Kotlin Multiplatform introduced an API for working with so-called _target presets_.
+Each target preset essentially represented a factory for Kotlin Multiplatform targets. This API turned out to be largely
+redundant, as DSL functions like `jvm()` or `iosSimulatorArm64()` cover the same use cases while being much more
+straightforward and concise.
-To continue phasing out "legacy" binaries from the ecosystem, starting with Kotlin 1.9.0, the use of legacy libraries
-is also discouraged. If your project uses dependencies on legacy libraries, you'll see the following warning:
+To reduce the confusion and provide clearer guidelines, all presets-related APIs are now deprecated and will be
+removed from the public API of the Kotlin Gradle plugin in future releases. This includes:
-```none
-The dependency group:artifact:1.0 was published in the legacy mode. Support for such dependencies will be removed in the future
+* The `presets` property in `org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension`
+* The `org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset` interface and all its inheritors
+* The `fromPreset` overloads
+
+**What's the best practice now?**
+
+Use respective [Kotlin targets](multiplatform-dsl-reference.md#targets) instead, for example:
+
+
+
+ Before |
+ Now |
+
+
+
+
+```kotlin
+kotlin {
+ targets {
+ fromPreset(presets.iosArm64, 'ios')
+ }
+}
+```
+
+ |
+
+
+```kotlin
+kotlin {
+ iosArm64()
+}
```
+ |
+
+
+
+**When do the changes take effect?**
+
+Here's the planned deprecation cycle:
+
+* 1.9.20: report a warning on any usages of the presets-related API
+* 2.0: raise this warning to an error
+* >2.0: remove the presets-related API from the public API of the Kotlin Gradle plugin; sources that still use it fail
+ with "unresolved reference" errors, and binaries (for example, Gradle plugins) might fail with linkage errors
+ unless recompiled against the latest versions of the Kotlin Gradle plugin
+
+
+### Deprecated Apple target shortcuts
+
+**What's changed?**
+
+We're deprecating `ios()`, `watchos()`, and `tvos()` target shortcuts in Kotlin Multiplatform DSL. They were designed to
+partially create a source set hierarchy for Apple targets. However, they proved to be difficult to expand and sometimes confusing.
+
+For example, the `ios()` shortcut created both the `iosArm64` and `iosX64` targets but didn't include the `iosSimulatorArm64`
+target, which is necessary when working on hosts with Apple M chips. However, changing this shortcut was hard to implement
+and could cause issues in existing user projects.
+
**What's the best practice now?**
-_If you use multiplatform libraries_, most of them have already migrated to the "hierarchical structure" mode,
-so you only need to update the library version. See the documentation of the respective libraries for details.
+The Kotlin Gradle plugin now provides a built-in hierarchy template. Since Kotlin 1.9.20, it's enabled by default
+and contains predefined intermediate source sets for popular use cases.
-If the library doesn't support non-legacy binaries yet, you can contact the maintainers and tell them about this
-compatibility issue.
+Instead of shortcuts, you should specify the list of targets, and then the plugin automatically sets up intermediate
+source sets based on this list.
-_If you're a library author_, update the Kotlin Gradle plugin to the latest version and ensure you've fixed the [deprecated Gradle properties](#deprecated-gradle-properties-for-hierarchical-structure-support).
+For example, if you have `iosArm64` and `iosSimulatorArm64` targets in your project, the plugin automatically creates
+the `iosMain` and `iosTest` intermediate source sets. If you have `iosArm64` and `macosArm64` targets, the `appleMain` and
+`appleTest` source sets are created.
-The Kotlin team is eager to help the ecosystem migrate, so if you face any issues, don't hesitate to create an [issue in YouTrack](https://kotl.in/issue).
+For more information, see [Hierarchical project structure](multiplatform-hierarchy.md)
**When do the changes take effect?**
Here's the planned deprecation cycle:
-* 1.9: introduce a deprecation warning for dependencies on legacy libraries
-* 2.0: raise the warning for dependencies on legacy libraries to an error
-* >2.0: remove support for dependencies on legacy libraries; using such dependencies can cause build failures
+* 1.9.20: report a warning when `ios()`, `watchos()`, and `tvos()` target shortcuts are used;
+ the default hierarchy template is enabled by default instead
+* 2.1.0: report an error when target shortcuts are used
+* 2.2.0: remove target shortcut DSL from the Kotlin Multiplatform Gradle plugin
+
+### Incorrect version of iOS framework after Kotlin upgrade
+
+**What's the issue?**
+
+Changes in Kotlin code might not be reflected in the iOS app in Xcode when direct integration
+is used. The direct integration is set up with the `embedAndSignAppleFrameworkForXcode` task, which connects the iOS
+framework from your multiplatform project to the iOS app in Xcode.
+
+This can happen when you upgrade the Kotlin version from 1.9.2x to 2.0.0 in your multiplatform project (or downgrade it
+from 2.0.0 to 1.9.2x), then make changes in Kotlin files and try building the app, Xcode may incorrectly use the previous
+version of the iOS framework. So, the changes won't be visible in the iOS app in Xcode.
+
+**What's the workaround?**
+
+1. In Xcode, clean build directories using **Product** | **Clean Build Folder**.
+2. In the terminal, run the following command:
+
+ ```none
+ ./gradlew clean
+ ```
+
+3. Build the app again to ensure that the new version of the iOS framework is used.
+
+**When will the issue be fixed?**
+
+We're planning to fix this issue in Kotlin 2.0.10. You can check if any preview versions of
+Kotlin 2.0.10 are already available in the [Participate in the Kotlin Early Access Preview](eap.md) section.
+
+For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-68257).
+
+## Kotlin 1.9.0−1.9.25
+
+This section covers incompatible changes that end their deprecation cycle and come into effect in Kotlin 1.9.0−1.9.25.
-## Deprecated API for adding Kotlin source sets directly to the Kotlin compilation
+### Deprecated API for adding Kotlin source sets directly to the Kotlin compilation {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
@@ -480,7 +476,7 @@ Here's the planned deprecation cycle:
reference" errors during the buildscript compilation
-## Migration from kotlin-js Gradle plugin to kotlin-multiplatform Gradle plugin
+### Migration from `kotlin-js` Gradle plugin to `kotlin-multiplatform` Gradle plugin {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
@@ -591,7 +587,7 @@ load on the Kotlin team. We encourage you to migrate to the `kotlin-multiplatfor
// No need for the js prefix here, you can just copy and paste it from the top-level block
implementation("org.jetbrains.kotlinx:kotlinx-html:0.8.0")
}
- }
+ }
}
}
@@ -612,272 +608,286 @@ load on the Kotlin team. We encourage you to migrate to the `kotlin-multiplatfor
In 1.9.0, the use of the `kotlin-js` Gradle plugin produces a deprecation warning.
-
-## Rename of android target to androidTarget
+
+### Deprecated `jvmWithJava` preset {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
-We continue our efforts to stabilize Kotlin Multiplatform. An essential step in this way is to provide first-class
-support for the Android target. In the future, this support will be provided via a separate plugin, developed by the
-Android team from Google.
-
-To open the way for the new solution from Google, we're renaming the `android` block to `androidTarget` in the current
-Kotlin DSL. This is a temporary change that is necessary to free the short `android` name for the upcoming DSL
-from Google.
+`targetPresets.jvmWithJava` is deprecated, and its usage is discouraged.
**What's the best practice now?**
-Rename all the occurrences of the `android` block to `androidTarget`. When the new plugin for the Android target support
-is available, migrate to the DSL from Google. It will be the preferred option to work with Android in Kotlin Multiplatform
-projects.
+Use `jvm { withJava() }` target instead. Note that after switching to `jvm { withJava() }`, you'll need to adjust
+the paths to source directories with `.java` sources.
+
+For example, if you use a `jvm` target with the default name "jvm":
+
+| Before | Now |
+|-----------------|--------------------|
+| `src/main/java` | `src/jvmMain/java` |
+| `src/test/java` | `src/jvmTest/java` |
**When do the changes take effect?**
Here's the planned deprecation cycle:
-* 1.9.0: introduce a deprecation warning when the `android` name is used in Kotlin Multiplatform projects
-* 2.1.0: raise this warning to an error
-* 2.2.0: remove the `android` target DSL from the Kotlin Multiplatform Gradle plugin
+* 1.3.40: introduce a warning when `targetPresets.jvmWithJava` is used
+* 1.9.20: raise this warning to an error
+* >1.9.20: remove `targetPresets.jvmWithJava` API; attempts to use it lead to the buildscript compilation failure
-
-## Declaring several similar targets
+> Even though the whole `targetPresets` API is deprecated, the `jvmWithJava` preset has a different deprecation timeline.
+>
+{style="note"}
+
+
+### Deprecated legacy Android source set layout {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
-We discourage declaring several similar targets in a single Gradle project. For example:
+The [new Android source set layout](multiplatform-android-layout.md) is used by default since Kotlin 1.9.0.
+Support for the legacy layout is deprecated, and the use of the `kotlin.mpp.androidSourceSetLayoutVersion` Gradle property
+now triggers a deprecation diagnostic.
-```kotlin
-kotlin {
- jvm("jvmKtor")
- jvm("jvmOkHttp") // Not recommended and produces a deprecation warning
-}
-```
+**When do the changes take effect?**
-One popular case is having two related pieces of code together. For example, you might want to use
-`jvm("jvmKtor")` and `jvm("jvmOkHttp")` in your `:shared` Gradle project to implement networking using the Ktor
-or OkHttp libraries:
+Here's the planned deprecation cycle:
-```kotlin
-// shared/build.gradle.kts:
-kotlin {
- jvm("jvmKtor") {
- attributes.attribute(/* ... */)
- }
- jvm("jvmOkHttp") {
- attributes.attribute(/* ... */)
- }
+* <=1.9.0: report a warning when `kotlin.mpp.androidSourceSetLayoutVersion=1` is used; the warning can be suppressed with
+ `kotlin.mpp.androidSourceSetLayoutVersion1.nowarn=true` Gradle property
+* 1.9.20: raise this warning to an error; the error **cannot** be suppressed
+* >1.9.20: remove support for `kotlin.mpp.androidSourceSetLayoutVersion=1`; the Kotlin Gradle plugin ignores the property
- sourceSets {
- val commonMain by getting
- val commonJvmMain by sourceSets.creating {
- dependsOn(commonMain)
- dependencies {
- // Shared dependencies
- }
- }
- val jvmKtorMain by getting {
- dependsOn(commonJvmMain)
- dependencies {
- // Ktor dependencies
- }
- }
- val jvmOkHttpMain by getting {
- dependsOn(commonJvmMain)
- dependencies {
- // OkHttp dependencies
- }
- }
- }
-}
-```
+
+### Deprecated `commonMain` and `commonTest` with custom `dependsOn` {initial-collapse-state="collapsed" collapsible="true"}
-The implementation comes with non-trivial configuration complexity:
+**What's changed?**
-* You have to set up Gradle attributes on the `:shared` side and each consumer's side. Otherwise, Gradle can't
- resolve dependencies in such projects because without additional information it's not clear whether the consumer
- should receive the Ktor-based or the OkHttp-based implementation.
-* You have to set up the `commonJvmMain` source set manually.
-* The configuration involves a handful of low-level Gradle and Kotlin Gradle plugin abstractions and APIs.
+The `commonMain` and `commonTest` source sets usually represent the roots of the `main` and `test` source set hierarchies,
+respectively. However, it was possible to override that by manually configuring `dependsOn` relations of these source sets.
+
+Maintaining such configuration requires extra effort and knowledge about multiplatform build internals. Additionally,
+it decreases code readability and reusability of the code because you need to read the particular buildscript
+to be sure whether `commonMain` is the root of the `main` source set hierarchy.
+
+Therefore, accessing `dependsOn` on `commonMain` and `commonTest` is now deprecated.
**What's the best practice now?**
-The configuration is complex because Ktor-based and OkHttp-based implementations are
-_in the same Gradle project_. In many cases, it's possible to extract those parts into separate Gradle projects.
-Here's a general outline of such as a refactoring:
+Suppose you need to migrate to 1.9.20 the `customCommonMain` source set that uses `commonMain.dependsOn(customCommonMain)`.
+In most cases, `customCommonMain` participates in the same compilations as `commonMain`, so you can merge
+`customCommonMain` into `commonMain`:
-1. Replace two duplicated targets from the original project with a single target. If you had a shared source set between
- these targets, move its sources and configuration to the default source set of the newly created target:
+1. Copy sources of `customCommonMain` into `commonMain`.
+2. Add all dependencies of `customCommonMain` to `commonMain`.
+3. Add all compiler option settings of `customCommonMain` to `commonMain`.
- ```kotlin
- // shared/build.gradle.kts:
- kotlin {
- jvm()
-
- sourceSets {
- jvmMain {
- // Copy the configuration of jvmCommonMain here
- }
- }
- }
- ```
+In rare cases, `customCommonMain` might be participating in more compilations than `commonMain`.
+Such a configuration requires additional low-level configuration of the build script. If you're not sure if that's your
+use case, it most likely isn't.
-2. Add two new Gradle projects, usually by calling `include` in your `settings.gradle.kts` file. For example:
+If it is your use case, "swap" these two source sets by moving the sources and settings of `customCommonMain`
+to `commonMain` and vice versa.
- ```kotlin
- include(":okhttp-impl")
- include(":ktor-impl")
- ```
+**When do the changes take effect?**
-3. Configure each new Gradle project:
+Here's the planned deprecation cycle:
- * Most likely, you don't need to apply the `kotlin("multiplatform")` plugin, as these projects compile only to one
- target. In this example, you can apply `kotlin("jvm")`.
- * Move the content of original target-specific source sets to their respective projects, for example,
- from `jvmKtorMain` to `ktor-impl/src`.
- * Copy the configuration of source sets: dependencies, compiler options, and so on.
- * Add a dependency from the new Gradle project to the original project.
+* 1.9.0: report a warning when `dependsOn` is used in `commonMain`
+* >=1.9.20: report an error when `dependsOn` is used in `commonMain` or `commonTest`
- ```kotlin
- // ktor-impl/build.gradle.kts:
- plugins {
- kotlin("jvm")
- }
-
- dependencies {
- project(":shared") // Add dependency on the original project
- // Copy dependencies of jvmKtorMain here
- }
-
- kotlin {
- compilerOptions {
- // Copy compiler options of jvmKtorMain here
- }
- }
- ```
+### New approach to forward declarations {initial-collapse-state="collapsed" collapsible="true"}
-While this approach requires more work on the initial setup, it doesn't use any low-level entities of Gradle and
-the Kotlin Gradle plugin, making it easier to use and maintain the resulting build.
+**What's changed?**
-> Unfortunately, we can't provide detailed migration steps for each case. If the instructions above don't work
-> for you, describe your use case in this [YouTrack issue](https://youtrack.jetbrains.com/issue/KT-59316).
->
-{style="tip"}
+The JetBrains team has revamped the approach to forward declarations in Kotlin to make their behavior more predictable:
-**When do the changes take effect?**
+* You can only import forward declarations using the `cnames` or ` objcnames` packages.
+* You need to explicitly make a cast to and from the corresponding C and Objective-C forward declaration.
-Here's the planned deprecation cycle:
+**What's the best practice now?**
-* 1.9.20: introduce a deprecation warning when multiple similar targets are used in Kotlin Multiplatform projects
-* 2.1.0: report an error in such cases, except for Kotlin/JS targets; to learn more about this exception, see the issue in [YouTrack](https://youtrack.jetbrains.com/issue/KT-47038/KJS-MPP-Split-JS-target-into-JsBrowser-and-JsNode)
+* Consider a C library with a `library.package` that declares a `cstructName` forward declaration.
+ Previously, it was possible to import it directly from the library with `import library.package.cstructName`.
+ Now, you can only use a special forward declaration package for that: `import cnames.structs.cstructName`.
+ The same is true for `objcnames`.
-
-## Deprecated jvmWithJava preset
+* Consider two objcinterop libraries: one that uses `objcnames.protocols.ForwardDeclaredProtocolProtocol` and another
+ that has an actual definition:
-**What's changed?**
+ ```ObjC
+ // First objcinterop library
+ #import
+
+ @protocol ForwardDeclaredProtocol;
+
+ NSString* consumeProtocol(id s) {
+ return [NSString stringWithUTF8String:"Protocol"];
+ }
+ ```
-`targetPresets.jvmWithJava` is deprecated, and its usage is discouraged.
+ ```ObjC
+ // Second objcinterop library
+ // Header:
+ #import
+ @protocol ForwardDeclaredProtocol
+ @end
+ // Implementation:
+ @interface ForwardDeclaredProtocolImpl : NSObject
+ @end
-**What's the best practice now?**
+ id produceProtocol() {
+ return [ForwardDeclaredProtocolImpl new];
+ }
+ ```
-Use `jvm { withJava() }` target instead. Note that after switching to `jvm { withJava() }`, you'll need to adjust
-the paths to source directories with `.java` sources.
+ Previously, it was possible to transfer objects between them seamlessly. Now, an explicit `as` cast is required
+ for the forward declaration:
-For example, if you use a `jvm` target with the default name "jvm":
+ ```kotlin
+ // Kotlin code:
+ fun test() {
+ consumeProtocol(produceProtocol() as objcnames.protocols.ForwardDeclaredProtocolProtocol)
+ }
+ ```
-| Before | Now |
-|-----------------|--------------------|
-| `src/main/java` | `src/jvmMain/java` |
-| `src/test/java` | `src/jvmTest/java` |
+ > You can only cast to `objcnames.protocols.ForwardDeclaredProtocolProtocol` from the corresponding real class.
+ > Otherwise, you'll get an error.
+ >
+ {style="note"}
**When do the changes take effect?**
-Here's the planned deprecation cycle:
+Starting with Kotlin 1.9.20, you need to explicitly make a cast to and from the corresponding C and Objective-C forward
+declarations. Also, it's now only possible to import forward declarations by using special packages.
-* 1.3.40: introduce a warning when `targetPresets.jvmWithJava` is used
-* 1.9.20: raise this warning to an error
-* >1.9.20: remove `targetPresets.jvmWithJava` API; attempts to use it lead to the buildscript compilation failure
+## Kotlin 1.7.0−1.8.22
-> Even though the whole `targetPresets` API is deprecated, the `jvmWithJava` preset has a different deprecation timeline.
->
-{style="note"}
+This section covers incompatible changes that end their deprecation cycle and come into effect in Kotlin 1.7.0−1.8.22.
-
-## Deprecated legacy Android source set layout
+### Deprecated compatibility with Kotlin Multiplatform Gradle plugin and Gradle Java plugins {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
-The [new Android source set layout](multiplatform-android-layout.md) is used by default since Kotlin 1.9.0.
-Support for the legacy layout is deprecated, and the use of the `kotlin.mpp.androidSourceSetLayoutVersion` Gradle property
-now triggers a deprecation diagnostic.
+Due to compatibility issues between the Kotlin Multiplatform Gradle plugin and the Gradle plugins
+[Java](https://docs.gradle.org/current/userguide/java_plugin.html),
+[Java Library](https://docs.gradle.org/current/userguide/java_library_plugin.html),
+and [Application](https://docs.gradle.org/current/userguide/application_plugin.html),
+there is now a deprecation warning when you apply these plugins to the same project. The warning also appears when another
+Gradle plugin in your multiplatform project applies a Gradle Java plugin. For example, the [Spring Boot Gradle Plugin](https://docs.spring.io/spring-boot/gradle-plugin/index.html)
+automatically applies the Application plugin.
+In future Kotlin releases, the warning will be increased to an error.
-**When do the changes take effect?**
+We've added this deprecation warning due to fundamental compatibility issues between Kotlin Multiplatform's project model
+and Gradle's Java ecosystem plugins. Gradle's Java ecosystem plugins currently don't take into account that other plugins may:
-Here's the planned deprecation cycle:
+* Also publish or compile for the JVM target in a different way than the Java ecosystem plugins.
+* Have two different JVM targets in the same project, such as JVM and Android.
+* Have a complex multiplatform project structure with potentially multiple non-JVM targets.
-* <=1.9.0: report a warning when `kotlin.mpp.androidSourceSetLayoutVersion=1` is used; the warning can be suppressed with
- `kotlin.mpp.androidSourceSetLayoutVersion1.nowarn=true` Gradle property
-* 1.9.20: raise this warning to an error; the error **cannot** be suppressed
-* >1.9.20: remove support for `kotlin.mpp.androidSourceSetLayoutVersion=1`; the Kotlin Gradle plugin ignores the property
+Unfortunately, Gradle doesn't currently provide any API to address these issues.
-
-## Deprecated commonMain and commonTest with custom dependsOn
+We previously used some workarounds in Kotlin Multiplatform to help with the integration of Java ecosystem plugins.
+However, these workarounds never truly solved the compatibility issues, and since the release of Gradle 8.8, these workarounds
+are no longer possible. For more information, see our [YouTrack issue](https://youtrack.jetbrains.com/issue/KT-66542/Gradle-JVM-target-with-withJava-produces-a-deprecation-warning).
-**What's changed?**
+While we don't yet know exactly how to resolve this compatibility problem, we are committed to continuing support for
+some form of Java source compilation in your Kotlin Multiplatform projects. At a minimum, we will support the compilation
+of Java sources and using Gradle's [`java-base`](https://docs.gradle.org/current/javadoc/org/gradle/api/plugins/JavaBasePlugin.html) plugin within your multiplatform projects.
-The `commonMain` and `commonTest` source sets usually represent the roots of the `main` and `test` source set hierarchies,
-respectively. However, it was possible to override that by manually configuring `dependsOn` relations of these source sets.
+**What's the best practice now?**
-Maintaining such configuration requires extra effort and knowledge about multiplatform build internals. Additionally,
-it decreases code readability and reusability of the code because you need to read the particular buildscript
-to be sure whether `commonMain` is the root of the `main` source set hierarchy.
+If you see this deprecation warning in your multiplatform project, we recommend that you:
+1. Determine whether you actually need the Gradle Java plugin in your project. If not, consider removing it.
+2. Check if the Gradle Java plugin is only used for a single task. If so, you might be able to remove the plugin without
+ much effort. For example, if the task uses a Gradle Java plugin to create a Javadoc JAR file, you can define the Javadoc
+ task manually instead.
+
+Otherwise, if you want to use both the Kotlin Multiplatform Gradle plugin and these Gradle plugins for Java in your multiplatform
+project, we recommend that you:
+
+1. Create a separate subproject in your multiplatform project.
+2. In the separate subproject, apply the Gradle plugin for Java.
+3. In the separate subproject, add a dependency on your parent multiplatform project.
+
+> The separate subproject must **not** be a multiplatform project, and you must only use it to set up a dependency on your multiplatform project.
+>
+{style="warning"}
+
+For example, you have a multiplatform project called `my-main-project` and you want
+to use the [Application](https://docs.gradle.org/current/userguide/application_plugin.html) Gradle plugin to run a JVM application.
+
+Once you've created a subproject, let's call it `subproject-A`, your parent project structure should look like this:
+
+```text
+.
+├── build.gradle
+├── settings.gradle.kts
+├── subproject-A
+ └── build.gradle.kts
+ └── src
+ └── Main.java
+```
+
+In your subproject's `build.gradle.kts` file, apply the Application plugin in the `plugins {}` block:
+
+
+
+
+```kotlin
+plugins {
+ id("application")
+}
+```
+
+
+
+
+```groovy
+plugins {
+ id('application')
+}
+```
-Therefore, accessing `dependsOn` on `commonMain` and `commonTest` is now deprecated.
+
+
-**What's the best practice now?**
+In your subproject's `build.gradle.kts` file, add a dependency on your parent multiplatform project:
-Suppose you need to migrate to 1.9.20 the `customCommonMain` source set that uses `commonMain.dependsOn(customCommonMain)`.
-In most cases, `customCommonMain` participates in the same compilations as `commonMain`, so you can merge
-`customCommonMain` into `commonMain`:
+
+
-1. Copy sources of `customCommonMain` into `commonMain`.
-2. Add all dependencies of `customCommonMain` to `commonMain`.
-3. Add all compiler option settings of `customCommonMain` to `commonMain`.
+```kotlin
+dependencies {
+ implementation(project(":my-main-project")) // The name of your parent multiplatform project
+}
+```
-In rare cases, `customCommonMain` might be participating in more compilations than `commonMain`.
-Such a configuration requires additional low-level configuration of the build script. If you're not sure if that's your
-use case, it most likely isn't.
+
+
-If it is your use case, "swap" these two source sets by moving the sources and settings of `customCommonMain`
-to `commonMain` and vice versa.
+```groovy
+dependencies {
+ implementation project(':my-main-project') // The name of your parent multiplatform project
+}
+```
-**When do the changes take effect?**
+
+
-Here's the planned deprecation cycle:
-* 1.9.0: report a warning when `dependsOn` is used in `commonMain`
-* >=1.9.20: report an error when `dependsOn` is used in `commonMain` or `commonTest`
+Your parent project is now set up to work with both plugins.
-
-## Deprecated target presets API
+### New approach to auto-generated targets {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
-In the very early development stages, Kotlin Multiplatform introduced an API for working with so-called _target presets_.
-Each target preset essentially represented a factory for Kotlin Multiplatform targets. This API turned out to be largely
-redundant, as DSL functions like `jvm()` or `iosSimulatorArm64()` cover the same use cases while being much more
-straightforward and concise.
-
-To reduce the confusion and provide clearer guidelines, all presets-related APIs are now deprecated and will be
-removed from the public API of the Kotlin Gradle plugin in future releases. This includes:
+Target accessors auto-generated by Gradle are no longer available inside the `kotlin.targets {}` block. Use
+the `findByName("targetName")` method instead.
-* The `presets` property in `org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension`
-* The `org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset` interface and all its inheritors
-* The `fromPreset` overloads
+Note that such accessors are still available in the `kotlin.targets {}` case, for example, `kotlin.targets.linuxX64`.
**What's the best practice now?**
-Use respective [Kotlin targets](multiplatform-dsl-reference.md#targets) instead, for example:
-
Before |
@@ -889,7 +899,9 @@ Use respective [Kotlin targets](multiplatform-dsl-reference.md#targets) instead,
```kotlin
kotlin {
targets {
- fromPreset(presets.iosArm64, 'ios')
+ configure(['windows',
+ 'linux']) {
+ }
}
}
```
@@ -899,150 +911,154 @@ kotlin {
```kotlin
kotlin {
- iosArm64()
+ targets {
+ configure([findByName('windows'),
+ findByName('linux')]) {
+ }
+ }
}
```
-
+
**When do the changes take effect?**
-Here's the planned deprecation cycle:
+In Kotlin 1.7.20, an error is introduced when using target accessors in the `kotlin.targets {}` block.
-* 1.9.20: report a warning on any usages of the presets-related API
-* 2.0: raise this warning to an error
-* >2.0: remove the presets-related API from the public API of the Kotlin Gradle plugin; sources that still use it fail
- with "unresolved reference" errors, and binaries (for example, Gradle plugins) might fail with linkage errors
- unless recompiled against the latest versions of the Kotlin Gradle plugin
+For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-47047).
-
-## Deprecated Apple target shortcuts
+### Changes in Gradle input and output compile tasks {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
-We're deprecating `ios()`, `watchos()`, and `tvos()` target shortcuts in Kotlin Multiplatform DSL. They were designed to
-partially create a source set hierarchy for Apple targets. However, they proved to be difficult to expand and sometimes confusing.
+Kotlin compile tasks no longer inherit the Gradle `AbstractCompile` task that has the `sourceCompatibility` and
+`targetCompatibility` inputs, making them unavailable in Kotlin users' scripts.
-For example, the `ios()` shortcut created both the `iosArm64` and `iosX64` targets but didn't include the `iosSimulatorArm64`
-target, which is necessary when working on hosts with Apple M chips. However, changing this shortcut was hard to implement
-and could cause issues in existing user projects.
+Other breaking changes in compile tasks:
**What's the best practice now?**
-The Kotlin Gradle plugin now provides a built-in hierarchy template. Since Kotlin 1.9.20, it's enabled by default
-and contains predefined intermediate source sets for popular use cases.
-
-Instead of shortcuts, you should specify the list of targets, and then the plugin automatically sets up intermediate
-source sets based on this list.
-
-For example, if you have `iosArm64` and `iosSimulatorArm64` targets in your project, the plugin automatically creates
-the `iosMain` and `iosTest` intermediate source sets. If you have `iosArm64` and `macosArm64` targets, the `appleMain` and
-`appleTest` source sets are created.
-
-For more information, see [Hierarchical project structure](multiplatform-hierarchy.md)
+| 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?**
-Here's the planned deprecation cycle:
+In Kotlin 1.7.20, inputs are not available, the output is replaced, and the `classpath` property is deprecated.
-* 1.9.20: report a warning when `ios()`, `watchos()`, and `tvos()` target shortcuts are used;
- the default hierarchy template is enabled by default instead
-* 2.1.0: report an error when target shortcuts are used
-* 2.2.0: remove target shortcut DSL from the Kotlin Multiplatform Gradle plugin
+For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-32805).
-## New approach to forward declarations
+### New configuration names for dependencies on the compilation {initial-collapse-state="collapsed" collapsible="true"}
**What's changed?**
-The JetBrains team has revamped the approach to forward declarations in Kotlin to make their behavior more predictable:
+Compilation configurations created by the Kotlin Multiplatform Gradle Plugin received new names.
-* You can only import forward declarations using the `cnames` or ` objcnames` packages.
-* You need to explicitly make a cast to and from the corresponding C and Objective-C forward declaration.
+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?**
-* Consider a C library with a `library.package` that declares a `cstructName` forward declaration.
- Previously, it was possible to import it directly from the library with `import library.package.cstructName`.
- Now, you can only use a special forward declaration package for that: `import cnames.structs.cstructName`.
- The same is true for `objcnames`.
+
+
+ |
+ Before |
+ Now |
+
+
+ Dependencies of the jvmMain compilation |
+
-* Consider two objcinterop libraries: one that uses `objcnames.protocols.ForwardDeclaredProtocolProtocol` and another
- that has an actual definition:
+```kotlin
+jvm
+```
- ```ObjC
- // First objcinterop library
- #import
-
- @protocol ForwardDeclaredProtocol;
-
- NSString* consumeProtocol(id s) {
- return [NSString stringWithUTF8String:"Protocol"];
- }
- ```
+ |
+
- ```ObjC
- // Second objcinterop library
- // Header:
- #import
- @protocol ForwardDeclaredProtocol
- @end
- // Implementation:
- @interface ForwardDeclaredProtocolImpl : NSObject
- @end
+```kotlin
+jvmCompilation
+```
- id produceProtocol() {
- return [ForwardDeclaredProtocolImpl new];
- }
- ```
+ |
+
+
+
- Previously, it was possible to transfer objects between them seamlessly. Now, an explicit `as` cast is required
- for the forward declaration:
+```kotlin
+dependencies {
+ add("jvmImplementation",
+ "foo.bar.baz:1.2.3")
+}
+```
- ```kotlin
- // Kotlin code:
- fun test() {
- consumeProtocol(produceProtocol() as objcnames.protocols.ForwardDeclaredProtocolProtocol)
- }
- ```
+ |
+
- > You can only cast to `objcnames.protocols.ForwardDeclaredProtocolProtocol` from the corresponding real class.
- > Otherwise, you'll get an error.
- >
- {style="note"}
+```kotlin
+dependencies {
+ add("jvmCompilationImplementation",
+ "foo.bar.baz:1.2.3")
+}
+```
-**When do the changes take effect?**
+ |
+
+
+ Dependencies of the jvmMain source set |
+
-Starting with Kotlin 1.9.20, you need to explicitly make a cast to and from the corresponding C and Objective-C forward
-declarations. Also, it's now only possible to import forward declarations by using special packages.
+```kotlin
+jvmMain
+```
-## Incorrect version of iOS framework after Kotlin upgrade
+ |
+
+
+ Dependencies of the jvmTest compilation |
+
-**What's the issue?**
+```kotlin
+jvmTest
+```
-Changes in Kotlin code might not be reflected in the iOS app in Xcode when direct integration
-is used. The direct integration is set up with the `embedAndSignAppleFrameworkForXcode` task, which connects the iOS
-framework from your multiplatform project to the iOS app in Xcode.
+ |
+
-This can happen when you upgrade the Kotlin version from 1.9.2x to 2.0.0 in your multiplatform project (or downgrade it
-from 2.0.0 to 1.9.2x), then make changes in Kotlin files and try building the app, Xcode may incorrectly use the previous
-version of the iOS framework. So, the changes won't be visible in the iOS app in Xcode.
+```kotlin
+jvmTestCompilation
+```
-**What's the workaround?**
+ |
+
+
+ Dependencies of the jvmTest source set |
+
-1. In Xcode, clean build directories using **Product** | **Clean Build Folder**.
-2. In the terminal, run the following command:
+```kotlin
+jvmTest
+```
- ```none
- ./gradlew clean
- ```
+ |
+
+
-3. Build the app again to ensure that the new version of the iOS framework is used.
+The available scopes are `Api`, `Implementation`, `CompileOnly`, and `RuntimeOnly`.
-**When will the issue be fixed?**
+**When do the changes take effect?**
-We're planning to fix this issue in Kotlin 2.0.10. You can check if any preview versions of
-Kotlin 2.0.10 are already available in the [Participate in the Kotlin Early Access Preview](eap.md) section.
+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](https://youtrack.jetbrains.com/issue/KT-68257).
+For more information, see the [corresponding issue in YouTrack](https://youtrack.jetbrains.com/issue/KT-35916/).