Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update README about using custom Compose Compiler #2526

Merged
merged 2 commits into from
Dec 15, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 30 additions & 10 deletions VERSIONING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,38 @@ Kotlin version | Minimal Compose version | Notes
1.5.31 | 1.0.0
1.6.20 | 1.1.1
1.7.10 | 1.2.0
1.7.20 | 1.2.0 | JS is not supported (will be fixed in the next versions)
1.7.20 | 1.2.0 | JS is not supported (fixed in the 1.2.1)
1.7.20 | 1.2.1
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR should be merged only after 1.2.2 is released

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to use the exact version instead of "the next version"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


### Using the latest Kotlin version

When a new version of Kotlin is released, the corresponding Compose Multiplatform release may not yet have been published. There are still ways to use it, although stability is not guarantied. Even if it compiles fine, there can be hidden runtime errors, so it is not recommended to use them for production builds.

#### Using Jetpack Compose Compiler

The compilation process of composable functions is handled by the Compose compiler plugin. Each release of the compiler plugin is strictly bound to a single version of the Kotlin compiler. Normally, the Gradle plugin chooses an appropriate version of the compiler plugin automatically. But there is a way to choose another version of Compose Compiler. For example, you can use Jetpack Compose Compiler published by Google.

First, check [this page](https://developer.android.com/jetpack/androidx/releases/compose-kotlin#pre-release_kotlin_compatibility) to find a compatible version. If there is one, use it this way:
```
compose {
kotlinCompilerPlugin.set("androidx.compose.compiler:compiler:1.4.0-alpha02")
}
```
(`1.4.0-alpha02` corresponds Kotlin 1.7.21)

#### Disabling Kotlin compatibility check

If there is no compatible version of Jetpack Compose Compiler (or you encountered errors), you can try to use Compose Compiler for another version of Kotlin, but disable the Kotlin version check. It can work, if you upgrade to a hotfix version of Kotlin, and most probably won't work if you upgrade to a major version of Kotlin.

```
compose {
kotlinCompilerPlugin.set(dependencies.compiler.forKotlin("1.7.20"))
kotlinCompilerPluginArgs.add("suppressKotlinVersionCompatibilityCheck=1.7.21")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just add suppressKotlinCompatibilityCheck property instead of very generic kotlinCompilerPluginArgs? I'm not sure that giving an ability to pass arbitrary arguments to the compiler plugin just for suppressing the check is worth it.

compose {
    kotlinCompilerPlugin.set(dependencies.compiler.forKotlin("1.7.20"))
    suppressKotlinCompatibilityCheck.set("1.7.21")
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why I added support for arbitrary properties - because there are other useful properties besides suppressKotlinCompatibilityCheck, and I wouldn't want to modify code every time new properties/rules are added. For example, the useful metricsDestination property was added recently.

Keeping API under control is usually good practice, and allows avoiding many issues, but here we explicitly tell that we use a separate entity (Compose Compiler), and so we can support configuration of it bypassing our API, and reusing its own way of configuration (via properties).

Besides that, we should emphasis that we configure the applied Compose Compiler. Without specifying a custom Compose Compiler, arguments don't make sense, because Compiler can be different for each Kotlin and doesn't have required arguments. In case suppressKotlinCompatibilityCheck we have another problem - it won't be used until we set a custom compiler.

So, if we really don't want to pass arbitrary properties (but I still prefer to pass because it is easier to maintain), we should keep somehow connection to Compose Compiler. The alternative are:

compose {
    kotlinCompilerPlugin(dependencies.compiler.forKotlin("1.7.20")) {
        suppressKotlinCompatibilityCheck = "1.7.21"
    }
}

// and we can still write
compose {
    kotlinCompilerPlugin("androidx.compose.compiler:compiler:1.4.0-alpha02")
}

(I am not sure about the style guidelines, maybe it can be written better)

or

compose {
    kotlinCompilerPlugin.set(dependencies.compiler.forKotlin("1.7.20"))
    kotlinCompilerPluginArgs {
        suppressKotlinCompatibilityCheck.set("1.7.21")
    }
}

Copy link
Collaborator Author

@igordmn igordmn Dec 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alternative are

It seems that they won't work well. For example, we have the property metricsDestination. It only makes sense for the latest Compose Compiler, and will be ignored in the previous versions.

}
```

Here we set a fixed version of Compose Compiler and configure it by specifying additional arguments. The argument `suppressKotlinVersionCompatibilityCheck` disables the internal Kotlin check that happens inside the compiler. In this argument you should specify the version of Kotlin that is applied to your project. It is required to avoid situations when you upgraded Kotlin and forgot to update Compose Compiler.

### Relationship between the Jetpack Compose and Compose Multiplatform release cycles

Compose Multiplatform shares a lot of code with [Jetpack Compose](https://developer.android.com/jetpack/compose) for Android, a framework developed by Google.
Expand All @@ -42,12 +71,3 @@ When a new version of Jetpack Compose is released, we pick the release commit, u
The gap between a Compose Multiplatform release and a Jetpack Compose release is usually 1 to 3 months.

When you build your application for Android, the artifacts published by Google are used. For example, if you apply the Compose Multiplatform 1.2.0 Gradle plugin and add `implementation(compose.material3)` to your `dependencies`, then your project will use the `androidx.compose.material3:material3:1.0.0-alpha14` artifact in the Android target (but `org.jetbrains.compose.material3:material3:1.2.0` in the other targets). See the `Updated dependencies` sections in the [CHANGELOG](https://github.com/JetBrains/compose-jb/blob/master/CHANGELOG.md) to know exactly which version of the Jetpack Compose artifact will be used.

The Compose Compiler version can be changed independently of other Compose libraries. In order to support newer versions of Kotlin, you may want to use [the cutting-edge Compose Compiler](https://developer.android.com/jetpack/androidx/releases/compose-kotlin#pre-release_kotlin_compatibility) published by Google in your Compose Multiplatform project. For example, when a new version of Kotlin is released, the corresponding Compose Multiplatform release may not yet have been published, but manually specifying a newer Compose Compiler version can allow you to build your Compose Multiplatform app using the latest Kotlin release. To do so, set `kotlinCompilerPlugin` in the `compose` section of your `build.gradle.kts` file as follows:

```kotlin
compose {
kotlinCompilerPlugin.set("androidx.compose.compiler:compiler:1.3.1")
}
```
However, keep in mind that this compiler version isn't tested with Compose Multiplatform, so stability isn't guaranteed.