web24.team

Kotlin Multiplatform: стабильная компиляция общих модулей с 2.5.0-Beta1

В Kotlin 2.5.0-Beta1 появилась экспериментальная раздельная компиляция для Multiplatform. Она устраняет расхождения между IDE и компилятором при вызове платформенного кода из common-исходников.

Схема компиляции Kotlin Multiplatform модуля с раздельными артефактами
Изображение: blog.jetbrains.com

Что нового в раздельной компиляции Kotlin Multiplatform

В Kotlin 2.5.0-Beta1 добавлена экспериментальная функция раздельной компиляции (separate compilation) для KMP. Она делает поведение компилятора строже и согласует его с анализом IntelliJ IDEA при вызове платформенного кода из общих исходников. Включить её можно флагом kotlin.kmp.separateCompilation=true в gradle.properties.

Функция решает две основные проблемы. Первая — расхождение между IDE и компилятором: IDE считает вызов платформенной функции из common-кода ошибкой, а компилятор его пропускает. Вторая — неявное разрешение перегрузок в пользу платформенной версии, из-за чего в рантайме может выполняться не тот код, который показывает IDE.

С раздельной компиляцией common-код компилируется только против метаданных KLIB зависимостей, а не платформенных артефактов. Это гарантирует, что commonMain и commonTest могут обращаться только к декларациям из commonMain библиотеки. Явная связь через expect/actual становится обязательной.

Функция экспериментальная и отключена по умолчанию. Есть известные проблемы с commonization cinterops и ограничение: модули с одним таргетом пока не затронуты раздельной компиляцией.

Стоит ли включать раздельную компиляцию в вашем KMP-проекте

Включать стоит, если вы столкнулись с рассинхроном между IDE и компилятором или хотите сделать компиляцию более предсказуемой. Но сначала проверьте, что все ваши KMP-библиотеки публикуют metadata KLIB — это поведение по умолчанию для Gradle-плагина, но теперь оно критично.

Учтите, что после включения флага часть кода может перестать компилироваться. Например, вызовы платформенных классов из commonTest или commonMain без expect/actual. Придётся явно описывать expect-декларации в commonMain. Если вы используете cinterop или у вас только один таргет, пока лучше подождать стабилизации.

Коротко

Как включить раздельную компиляцию Kotlin Multiplatform?

Добавьте флаг kotlin.kmp.separateCompilation=true в gradle.properties вашего проекта.

Что сломается при включении раздельной компиляции?

Код, который из commonMain или commonTest вызывает платформенные декларации без expect/actual, перестанет компилироваться. Нужно будет добавить expect-классы или функции.

Работает ли раздельная компиляция для модулей с одним таргетом?

Пока нет, модули с одним объявленным таргетом не затронуты этой функцией.

Источник: blog.jetbrains.com ↗