Spec-Zone.ru › Kotlin 2

Сборка финальных нативных бинарных файлов

По умолчанию цель Kotlin/Native компилируется в артефакт библиотеки *.klib, который может использоваться самим Kotlin/Native как зависимость, но не может быть запущен или использован в качестве нативной библиотеки.

Чтобы объявить финальные нативные бинарные файлы, например исполняемые файлы или динамические библиотеки, используйте свойство binaries нативной цели. Это свойство представляет собой коллекцию нативных бинарных файлов, собираемых для этой цели в дополнение к артефакту *.klib, создаваемому по умолчанию, и предоставляет набор методов для их объявления и настройки.

Плагин kotlin-multiplatform по умолчанию не создает бинарные файлы для production-сборки. Единственный бинарный файл, доступный по умолчанию, — это исполняемый файл тестов для отладки, который позволяет запускать модульные тесты из компиляции test.

Бинарные файлы, созданные компилятором Kotlin/Native, могут содержать сторонний код, данные или производные работы. Поэтому при распространении финального бинарного файла, скомпилированного Kotlin/Native, всегда включайте необходимые файлы лицензий в дистрибутив с бинарными файлами.

Объявление бинарных файлов

Используйте следующие фабричные методы, чтобы объявить элементы коллекции binaries.

Фабричный метод

Тип бинарного файла

Доступно для

executable

Исполняемый файл приложения

Всех нативных целей

test

Исполняемый файл тестов

Всех нативных целей

sharedLib

Динамическая нативная библиотека

Всех нативных целей

staticLib

Статическая нативная библиотека

Всех нативных целей

framework

Фреймворк Objective-C

Только целей macOS, iOS, watchOS и tvOS

В простейшем варианте дополнительные параметры не требуются, а для каждого типа сборки создается один бинарный файл. Сейчас доступны два типа сборки:

  • DEBUG — создает неоптимизированный бинарный файл с дополнительными метаданными, полезными при работе с инструментами отладки

  • RELEASE — создает оптимизированный бинарный файл без отладочной информации

Следующий фрагмент кода создает два исполняемых бинарных файла: для отладки и выпуска:

kotlin {
    linuxX64 { // Define your target instead.
        binaries {
            executable {
                // Binary configuration.
            }
        }
    }
}

Если дополнительная настройка не требуется, лямбду можно опустить:

binaries {
    executable()
}

Можно указать, для каких типов сборки создавать бинарные файлы. В следующем примере создается только исполняемый файл debug:

binaries {
    executable(listOf(DEBUG)) {
        // Binary configuration.
    }
}
binaries {
    executable([DEBUG]) {
        // Binary configuration.
    }
}

Также можно объявлять бинарные файлы с пользовательскими именами:

binaries {
    executable("foo", listOf(DEBUG)) {
        // Binary configuration.
    }

    // It's possible to drop the list of build types
    // (in this case, all the available build types will be used).
    executable("bar") {
        // Binary configuration.
    }
}
binaries {
    executable('foo', [DEBUG]) {
        // Binary configuration.
    }

    // It's possible to drop the list of build types
    // (in this case, all the available build types will be used).
    executable('bar') {
        // Binary configuration.
    }
}

Первый аргумент задает префикс имени, который используется как имя бинарного файла по умолчанию. Например, в Windows код создает файлы foo.exe и bar.exe. Также можно использовать префикс имени, чтобы обратиться к бинарному файлу в скрипте сборки.

Доступ к бинарным файлам

К бинарным файлам можно обращаться, чтобы настроить их или получить их свойства (например, путь к выходному файлу).

Получить бинарный файл можно по его уникальному имени. Оно формируется на основе префикса имени (если он указан), типа сборки и типа бинарного файла по шаблону: <optional-name-prefix><build-type><binary-kind>, например, releaseFramework или testDebugExecutable.

Статические и динамические библиотеки имеют суффиксы static и shared соответственно, например, fooDebugStatic или barReleaseShared.

// Fails if there is no such binary.
binaries["fooDebugExecutable"]
binaries.getByName("fooDebugExecutable")

// Returns null if there is no such binary.
binaries.findByName("fooDebugExecutable")
// Fails if there is no such binary.
binaries['fooDebugExecutable']
binaries.fooDebugExecutable
binaries.getByName('fooDebugExecutable')

// Returns null if there is no such binary.
binaries.findByName('fooDebugExecutable')

В качестве альтернативы можно получить бинарный файл по префиксу имени и типу сборки с помощью типизированных методов получения.

// Fails if there is no such binary.
binaries.getExecutable("foo", DEBUG)
binaries.getExecutable(DEBUG)          // Skip the first argument if the name prefix isn't set.
binaries.getExecutable("bar", "DEBUG") // You also can use a string for build type.

// Similar getters are available for other binary kinds:
// getFramework, getStaticLib and getSharedLib.

// Returns null if there is no such binary.
binaries.findExecutable("foo", DEBUG)

// Similar getters are available for other binary kinds:
// findFramework, findStaticLib and findSharedLib.
// Fails if there is no such binary.
binaries.getExecutable('foo', DEBUG)
binaries.getExecutable(DEBUG)          // Skip the first argument if the name prefix isn't set.
binaries.getExecutable('bar', 'DEBUG') // You also can use a string for build type.

// Similar getters are available for other binary kinds:
// getFramework, getStaticLib and getSharedLib.

// Returns null if there is no such binary.
binaries.findExecutable('foo', DEBUG)

// Similar getters are available for other binary kinds:
// findFramework, findStaticLib and findSharedLib.

Экспорт зависимостей в бинарные файлы

При сборке фреймворка Objective-C или нативной библиотеки (динамической или статической) может потребоваться включить в нее не только классы текущего проекта, но и классы его зависимостей. Укажите, какие зависимости нужно экспортировать в бинарный файл, с помощью метода export.

kotlin {
    //...
    sourceSets {
        macosMain.dependencies {
            // Will be exported.
            api(project(":dependency"))
            api("org.example:exported-library:1.0")
            // Will not be exported.
            api("org.example:not-exported-library:1.0")
        }
    }
    macosArm64("macos").binaries {
        framework {
            export(project(":dependency"))
            export("org.example:exported-library:1.0")
        }
        sharedLib {
            // It's possible to export different sets of dependencies to different binaries.
            export(project(':dependency'))
        }
    }
}
kotlin {
    //...
    sourceSets {
        macosMain.dependencies {
            // Will be exported.
            api project(':dependency')
            api 'org.example:exported-library:1.0'
            // Will not be exported.
            api 'org.example:not-exported-library:1.0'
        }
    }
    macosArm64("macos").binaries {
        framework {
            export project(':dependency')
            export 'org.example:exported-library:1.0'
        }
        sharedLib {
            // It's possible to export different sets of dependencies to different binaries.
            export project(':dependency')
        }
    }
}

Например, вы реализуете несколько модулей на Kotlin и хотите использовать их из Swift. Использование нескольких фреймворков Kotlin/Native в приложении Swift ограничено, но можно создать объединяющий фреймворк и экспортировать в него все эти модули.

Экспортировать можно только зависимости api соответствующего набора исходного кода.

При экспорте зависимости весь ее API включается в API фреймворка. Компилятор добавляет код этой зависимости во фреймворк, даже если используется лишь небольшая его часть. Это отключает удаление неиспользуемого кода для экспортированной зависимости (и в некоторой степени для ее зависимостей).

По умолчанию экспорт не является транзитивным. Это означает, что если вы экспортируете библиотеку foo, зависящую от библиотеки bar, в выходной фреймворк добавляются только методы foo.

Это поведение можно изменить с помощью параметра transitiveExport. Если задать значение true, объявления библиотеки bar также будут экспортированы.

Не рекомендуется использовать transitiveExport: этот параметр добавляет во фреймворк все транзитивные зависимости экспортированных зависимостей. Это может увеличить время компиляции и размер бинарного файла.

В большинстве случаев нет необходимости добавлять все эти зависимости в API фреймворка. Явно используйте export для зависимостей, к которым нужно обращаться непосредственно из кода Swift или Objective-C.

binaries {
    framework {
        export(project(":dependency"))
        // Export transitively.
        transitiveExport = true
    }
}
binaries {
    framework {
        export project(':dependency')
        // Export transitively.
        transitiveExport = true
    }
}

Сборка универсальных фреймворков

По умолчанию фреймворк Objective-C, созданный Kotlin/Native, поддерживает только одну платформу. Однако такие фреймворки можно объединить в один универсальный (fat) бинарный файл с помощью инструмента lipo. Это особенно полезно для 32- и 64-разрядных фреймворков iOS. В этом случае полученный универсальный фреймворк можно использовать как на 32-разрядных, так и на 64-разрядных устройствах.

Имя fat-фреймворка должно совпадать с базовым именем исходных фреймворков. В противном случае возникнет ошибка.

import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask

kotlin {
    // Create and configure the targets.
    val watchos32 = watchosArm32("watchos32")
    val watchos64 = watchosArm64("watchos64")
    configure(listOf(watchos32, watchos64)) {
        binaries.framework {
            baseName = "MyFramework"
        }
    }
    // Create a task to build a fat framework.
    tasks.register<FatFrameworkTask>("debugFatFramework") {
        // The fat framework must have the same base name as the initial frameworks.
        baseName = "MyFramework"
        // The default destination directory is "<build directory>/fat-framework".
        destinationDirProperty.set(layout.buildDirectory.dir("fat-framework/debug"))
        // Specify the frameworks to be merged.
        from(
            watchos32.binaries.getFramework("DEBUG"),
            watchos64.binaries.getFramework("DEBUG")
        )
    }
}
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask

kotlin {
    // Create and configure the targets.
    targets {
        watchosArm32("watchos32")
        watchosArm64("watchos64")
        configure([watchos32, watchos64]) {
            binaries.framework {
                baseName = "MyFramework"
            }
        }
    }
    // Create a task building a fat framework.
    tasks.register("debugFatFramework", FatFrameworkTask) {
        // The fat framework must have the same base name as the initial frameworks.
        baseName = "MyFramework"
        // The default destination directory is "<build directory>/fat-framework".
        destinationDirProperty.set(layout.buildDirectory.dir("fat-framework/debug"))
        // Specify the frameworks to be merged.
        from(
            targets.watchos32.binaries.getFramework("DEBUG"),
            targets.watchos64.binaries.getFramework("DEBUG")
        )
    }
}

Сборка XCFramework

Все проекты Kotlin Multiplatform могут использовать XCFramework в качестве выходного артефакта, чтобы объединить логику для всех целевых платформ и архитектур в одном пакете. В отличие от универсальных (fat) фреймворков, перед публикацией приложения в App Store не нужно удалять все ненужные архитектуры.

import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

plugins {
    kotlin("multiplatform") version "2.4.20"
}

kotlin {
    val xcf = XCFramework()
    val iosTargets = listOf(iosArm64(), iosSimulatorArm64())
    
    iosTargets.forEach {
        it.binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
}
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFrameworkConfig

plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '2.4.20'
}

kotlin {
    def xcf = new XCFrameworkConfig(project)
    def iosTargets = [iosArm64(), iosSimulatorArm64()]
    
    iosTargets.forEach {
        it.binaries.framework {
            baseName = 'shared'
            xcf.add(it)
        }
    }
}

При объявлении XCFramework плагин Kotlin Gradle зарегистрирует несколько задач Gradle:

  • assembleXCFramework

  • assemble<Framework name>DebugXCFramework

  • assemble<Framework name>ReleaseXCFramework

Если в проекте используется интеграция с CocoaPods, XCFramework можно собрать с помощью плагина Kotlin CocoaPods Gradle. Он включает следующие задачи, которые собирают XCFramework со всеми зарегистрированными целями и создают файлы podspec:

  • podPublishReleaseXCFramework — создает XCFramework для выпуска вместе с файлом podspec.

  • podPublishDebugXCFramework — создает XCFramework для отладки вместе с файлом podspec.

  • podPublishXCFramework — создает XCFramework для отладки и выпуска вместе с файлом podspec.

Это позволяет распространять общие части проекта отдельно от мобильных приложений через CocoaPods. XCFramework также можно использовать для публикации в частных или общедоступных репозиториях podspec.

Не рекомендуется публиковать фреймворки Kotlin в общедоступных репозиториях, если они собраны для разных версий Kotlin. Это может привести к конфликтам в проектах конечных пользователей.

Настройка файла Info.plist

При создании фреймворка компилятор Kotlin/Native генерирует файл списка информационных свойств Info.plist. Его свойства можно настроить с помощью соответствующих параметров бинарного файла:

Свойство

Параметр бинарного файла

CFBundleIdentifier

bundleId

CFBundleShortVersionString

bundleShortVersionString

CFBundleVersion

bundleVersion

Чтобы включить эту возможность, передайте флаг компилятора -Xbinary=$option=$value или задайте DSL Gradle binaryOption("option", "value") для нужного фреймворка:

binaries {
    framework {
        binaryOption("bundleId", "com.example.app")
        binaryOption("bundleVersion", "2")
    }
}
13 мая 2026 г.
Настройка компиляцийТестирование мультиплатформенного приложения — руководство

© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/multiplatform/multiplatform-build-native-binaries.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API