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 1 commit
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
42 changes: 32 additions & 10 deletions VERSIONING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,40 @@ 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 next version)
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 garantied.
Copy link
Collaborator

Choose a reason for hiding this comment

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

garantied should be guaranteed

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 Jetpack Compose Compiler

Compose Multiplatform uses Compose Compiler to compile Compose code, and its version is strictly bound to the version of Kotlin. By default it chooses appropriate `org.jetbrains.compose.compiler:compiler` version by the Kotlin version applied to the Gradle project. But there is a way to choose another version of Compose Compiler. For example, you can use Jetpack Compose Compiler published by Google
Copy link
Collaborator

Choose a reason for hiding this comment

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

Compose Multiplatform uses Compose Compiler to compile Compose code, and its version is strictly bound to the version of Kotlin.

This sentence repeats the word "Compose" a bit too often. At the same time, the whole paragraph might be a bit confusing, when someone does not understand how the Gradle plugin and the compiler plugin relate to each other.

By default it chooses

By default needs a comma , in the beginning of a sentence (By default,). Also, it might be confusing, what it refers to.

chooses appropriate .. version by the Kotlin version applied to the Gradle project`.

I'm not sure about articles here. appropriate definitely needs one. Also, I'm not sure, why the Kotlin version and the Gradle project?

My suggestion:

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:
Copy link
Collaborator

Choose a reason for hiding this comment

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

First,

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

```
compose {
kotlinCompilerPlugin.set("androidx.compose.compiler:compiler:1.4.0-alpha02")
}
```
(`1.4.0-alpha02` corresponds Kotlin 1.7.21)

#### Disabling Kotlin compatability check

If there is no compatible version of Jetpack Compose Compiler, or you encounter errors, you can try to use Compose Compiler for another version of Kotlin, but disable the Kotlin version check:
Copy link
Collaborator

Choose a reason for hiding this comment

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

or you encounter errors

Seems like a very broad suggestion. Ideally, I would like to describe the specific issues, which might be solved by disabling the compatibility check.

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 we need a really big warning about this, so people would not try this for a new major 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.

or you encounter errors

It is about errors when you try Jetpack Compose Compiler.

There is no list of specific issues, which we can write here. We can encounter any errors in compile time and runtime, when we using a Jetpack Compose Compiler version that is not tested with Compose Multiplatform.

One of the recent examples - Jetpack Compose Compiler didn't work in the JS target. First we had a compilation error. We fixed that, but recently discovered a runtime error.

I think we need a really big warning about this

I added an additional note. Not sure that for major version of Kotlin we should write a separate warning. I wouldn't recommend overwriting compiler even for minor Kotlin's.


```
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.

}
```

If you use the hotfix version of Kotlin, it probably will work.

The `kotlinCompilerPluginArgs` here configures the applied Compose Compiler and disables the internal Kotlin check that happens inside it.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure this sentence explains anything. I mean it's obvious, that suppressKotlinVersionCompatibilityCheck disables the check. However, it might be not obvious why it needs a 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.

However, it might be not obvious why it needs a version.

Is it better in the new version of the doc?


### 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 +73,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.