原生分发
在这里,您将了解原生分发的相关知识:如何为所有支持的系统创建安装程序和软件包,以及如何以与分发相同的设置本地运行应用程序。
继续阅读以下主题的详细信息:
什么是 Compose Multiplatform Gradle 插件?
关于基本任务 (如本地运行应用程序)和高级任务 (如代码压缩和混淆)的详细信息。
如何包含 JDK 模块并处理
ClassNotFoundException
。如何指定分发属性 :软件包版本、JDK 版本、输出目录、启动器属性和元数据。
如何管理资源 :使用资源库、JVM 资源加载或将文件添加到打包的应用程序中。
如何自定义源集 :使用 Gradle 源集、Kotlin JVM 目标或手动配置。
如何为每个操作系统指定应用程序图标。
平台特定选项 ,例如 Linux 上的软件包维护者电子邮件和 macOS 上 Apple App Store 的应用程序类别。
macOS 特定配置 :签名、公证和
Info.plist
。
Gradle 插件
本指南主要介绍如何使用 Compose Multiplatform Gradle 插件打包 Compose 应用程序。 org.jetbrains.compose
插件提供了基本打包、混淆和 macOS 代码签名的任务。
该插件简化了使用 jpackage
将应用程序打包为原生分发以及在本地运行应用程序的过程。可分发的应用程序是自包含的可安装二进制文件,包含所有必要的 Java 运行时组件,无需在目标系统上安装 JDK。
为了最小化软件包大小,Gradle 插件使用 jlink 工具,确保仅将必要的 Java 模块捆绑在可分发包中。然而,您仍然需要配置 Gradle 插件以指定所需的模块。更多信息,请参阅 配置包含的 JDK 模块
部分。
作为替代方案,您可以使用 Conveyor ,这是一个非 JetBrains 开发的外部工具。Conveyor 支持在线更新、交叉构建和各种其他功能,但非开源项目需要许可证 。更多信息,请参阅 Conveyor 文档。
基本任务
插件中的基本可配置单元是 application
。 application
DSL 方法定义了一组最终二进制文件的共享配置,这意味着它允许您将一组文件与 JDK 分发一起打包成各种格式的压缩二进制安装程序。
支持的操作系统有以下格式:
macOS:
.dmg
(TargetFormat.Dmg
),.pkg
(TargetFormat.Pkg
)Windows:
.exe
(TargetFormat.Exe
),.msi
(TargetFormat.Msi
)Linux:
.deb
(TargetFormat.Deb
),.rpm
(TargetFormat.Rpm
)
以下是一个带有基本桌面配置的 build.gradle.kts
文件示例:
构建项目时,插件会创建以下任务:
Gradle 任务 | 描述 |
---|---|
| 将应用程序打包为相应的 |
| 聚合应用程序的所有打包任务。这是一个生命周期任务。 |
| 为当前操作系统创建一个包含所有依赖项的单个 jar 文件。该任务期望 |
| 从 |
| 创建最终的应用程序映像,而不创建安装程序。 |
| 运行预打包的应用程序映像。 |
所有可用任务都列在 Gradle 工具窗口中。执行任务后,Gradle 会在 ${project.buildDir}/compose/binaries
目录中生成输出二进制文件。
包含 JDK 模块
为了减少分发大小,Gradle 插件使用 jlink 来帮助仅捆绑必要的 JDK 模块。
目前,Gradle 插件不会自动确定必要的 JDK 模块。虽然这不会导致编译问题,但未能提供必要的模块可能会导致运行时出现 ClassNotFoundException
。
如果在运行打包应用程序或 runDistributable
任务时遇到 ClassNotFoundException
,您可以使用 modules
DSL 方法包含其他 JDK 模块:
您可以手动指定所需的模块,或运行 suggestModules
。 suggestModules
任务使用 jdeps 静态分析工具来确定可能缺少的模块。请注意,该工具的输出可能不完整或列出不必要的模块。
如果分发大小不是关键因素并且可以忽略,您可以选择使用 includeAllModules
DSL 属性包含所有运行时模块。
指定分发属性
软件包版本
原生分发软件包必须具有特定的软件包版本。要指定软件包版本,您可以使用以下 DSL 属性,按优先级从高到低排列:
nativeDistributions.<os>.<packageFormat>PackageVersion
为单个软件包格式指定版本。nativeDistributions.<os>.packageVersion
为单个目标操作系统指定版本。nativeDistributions.packageVersion
为所有软件包指定版本。
在 macOS 上,您还可以使用以下 DSL 属性指定构建版本,同样按优先级从高到低排列:
nativeDistributions.macOS.<packageFormat>PackageBuildVersion
为单个软件包格式指定构建版本。nativeDistributions.macOS.packageBuildVersion
为所有 macOS 软件包指定构建版本。
如果未指定构建版本,Gradle 将使用软件包版本。有关 macOS 版本控制的更多信息,请参阅 CFBundleShortVersionString
和 CFBundleVersion
文档。
以下是按优先级指定软件包版本的模板:
定义软件包版本时,请遵循以下规则:
文件类型 | 版本格式 | 详情 |
---|---|---|
|
|
|
|
|
|
|
|
更多详情,请参阅 Debian 文档。 |
| 任何格式 | 版本不能包含 |
JDK 版本
插件使用 jpackage
,它需要不低于 JDK 17 的 JDK 版本。指定 JDK 版本时,请确保满足以下至少一个要求:
JAVA_HOME
环境变量指向兼容的 JDK 版本。通过 DSL 设置
javaHome
属性:compose.desktop { application { javaHome = System.getenv("JDK_17") } }
输出目录
要为原生分发使用自定义输出目录,请按如下方式配置 outputBaseDir
属性:
启动器属性
为了定制应用程序启动过程,您可以自定义以下属性:
属性 | 描述 |
---|---|
| 包含 |
| 应用程序 |
| 应用程序 JVM 的参数。 |
以下是一个配置示例:
元数据
在 nativeDistributions
DSL 块中,您可以配置以下属性:
属性 | 描述 | 默认值 |
---|---|---|
| 应用程序的名称。 | Gradle 项目的 名称 |
| 应用程序的版本。 | Gradle 项目的 版本 |
| 应用程序的描述。 | 无 |
| 应用程序的版权信息。 | 无 |
| 应用程序的供应商。 | 无 |
| 应用程序的许可证文件。 | 无 |
以下是一个配置示例:
管理资源
要打包和加载资源,您可以使用 Compose Multiplatform 资源库、JVM 资源加载或将文件添加到打包的应用程序中。
资源库
为项目设置资源的最简单方法是使用资源库。通过资源库,您可以在所有支持的平台的通用代码中访问资源。详情请参阅 Multiplatform resources。
JVM 资源加载
Compose Multiplatform for desktop 运行在 JVM 平台上,这意味着您可以使用 java.lang.Class
API 从 .jar
文件中加载资源。您可以通过 Class::getResource
或 Class::getResourceAsStream
访问 src/main/resources
目录中的文件。
将文件添加到打包的应用程序
在某些情况下,从 .jar
文件加载资源可能不太实用,例如当您有特定于目标的资源并且需要仅在 macOS 软件包中包含文件而不在 Windows 中包含时。
在这种情况下,您可以配置 Gradle 插件以在安装目录中包含其他资源文件。使用 DSL 指定根资源目录,如下所示:
在上面的示例中,根资源目录定义为 <PROJECT_DIR>/resources
。
Gradle 插件将按以下方式包含资源子目录中的文件:
通用资源: 位于
<RESOURCES_ROOT_DIR>/common
的文件将包含在所有软件包中,无论目标操作系统或架构如何。操作系统特定资源: 位于
<RESOURCES_ROOT_DIR>/<OS_NAME>
的文件将仅包含在为特定操作系统构建的软件包中。<OS_NAME>
的有效值为:windows
、macos
和linux
。操作系统和架构特定资源: 位于
<RESOURCES_ROOT_DIR>/<OS_NAME>-<ARCH_NAME>
的文件将仅包含在为特定操作系统和 CPU 架构组合构建的软件包中。<ARCH_NAME>
的有效值为:x64
和arm64
。 例如,<RESOURCES_ROOT_DIR>/macos-arm64
中的文件将仅包含在为 Apple Silicon Mac 设计的软件包中。
您可以使用 compose.application.resources.dir
系统属性访问包含的资源:
自定义源集
如果您使用 org.jetbrains.kotlin.jvm
或 org.jetbrains.kotlin.multiplatform
插件,您可以依赖默认配置:
使用
org.jetbrains.kotlin.jvm
的配置包括来自main
源集 的内容。使用
org.jetbrains.kotlin.multiplatform
的配置包括来自单个 JVM 目标 的内容。如果定义多个 JVM 目标,默认配置将被禁用。在这种情况下,您需要手动配置插件或指定单个目标(见下文)。
如果默认配置不明确或不充分,您可以通过以下几种方式自定义:
使用 Gradle 源集:
使用 Kotlin JVM 目标:
手动配置:
使用
disableDefaultConfiguration
禁用默认设置。使用
fromFiles
指定要包含的文件。指定
mainJar
文件属性以指向包含主类的.jar
文件。使用
dependsOn
为所有插件任务添加任务依赖。
应用程序图标
确保您的应用程序图标以以下操作系统特定格式提供:
.icns
用于 macOS.ico
用于 Windows.png
用于 Linux
平台特定选项
平台特定设置可以使用相应的 DSL 块进行配置:
下表描述了所有支持的平台特定选项。 不建议使用未记录的属性。
平台 | 选项 | 描述 |
---|---|---|
所有平台 |
| 指定应用程序的平台特定图标的路径。详情请参阅 应用程序图标 部分。 |
| 设置平台特定的软件包版本。详情请参阅 软件包版本 部分。 | |
| 指定默认安装目录的绝对或相对路径。在 Windows 上,您还可以使用 | |
Linux |
| 覆盖默认的应用程序名称。 |
| 指定软件包维护者的电子邮件。 | |
| 为应用程序定义一个菜单组。 | |
| 为 rpm 软件包设置发布值或为 deb 软件包设置修订值。 | |
| 为 rpm 软件包分配组值或为 deb 软件包分配部分值。 | |
| 指示 rpm 软件包的许可证类型。 | |
| 设置 deb 特定的软件包版本。详情请参阅 软件包版本 部分。 | |
| 设置 rpm 特定的软件包版本。详情请参阅 软件包版本 部分。 | |
macOS |
| 指定唯一的应用程序标识符,只能包含字母数字字符( |
| 应用程序的名称。 | |
| 在菜单栏、“关于 <App>”菜单项和 Dock 中显示的应用程序名称。默认值为 | |
| 运行应用程序所需的最低 macOS 版本。详情请参阅 | |
| 请参阅 macOS 上的签名和公证分发 教程。 | |
| 指定是否为 Apple App Store 构建和签名应用程序。至少需要 JDK 17。 | |
| Apple App Store 的应用程序类别。为 App Store 构建时,默认值为 | |
| 指定包含签名时使用的权限的文件路径。提供自定义文件时,请确保添加 Java 应用程序所需的权限。请参阅 sandbox.plist 获取为 App Store 构建时使用的默认文件。请注意,此默认文件可能因 JDK 版本而异。如果未指定文件,插件将使用 | |
| 指定包含签名 JVM 运行时使用的权限的文件路径。提供自定义文件时,请确保添加 Java 应用程序所需的权限。请参阅 sandbox.plist 获取为 App Store 构建时使用的默认文件。请注意,此默认文件可能因 JDK 版本而异。如果未指定文件,插件将使用 | |
| 设置 DMG 特定的软件包版本。详情请参阅 软件包版本 部分。 | |
| 设置 PKG 特定的软件包版本。详情请参阅 软件包版本 部分。 | |
| 设置软件包的构建版本。详情请参阅 软件包版本 部分。 | |
| 设置 DMG 特定的软件包构建版本。详情请参阅 软件包版本 部分。 | |
| 设置 PKG 特定的软件包构建版本。详情请参阅 软件包版本 部分。 | |
| 请参阅 macOS 上的 | |
Windows |
| 为应用程序添加控制台启动器。 |
| 在安装期间启用自定义安装路径。 | |
| 启用按用户安装应用程序。 | |
| 将应用程序添加到指定的“开始”菜单组。 | |
| 指定一个唯一 ID,使用户能够通过安装程序更新应用程序,当有比已安装版本更新的版本时。该值必须为单个应用程序保持恒定。详情请参阅 如何生成 GUID。 | |
| 设置 MSI 特定的软件包版本。详情请参阅 软件包版本 部分。 | |
| 设置 EXE 特定的软件包版本。详情请参阅 软件包版本 部分。 |
macOS 特定配置
macOS 上的签名和公证
现代 macOS 版本不允许用户执行从互联网下载的未签名应用程序。如果您尝试运行此类应用程序,您会遇到以下错误:“YourApp 已损坏,无法打开。您应该弹出磁盘映像”。
要了解如何签名和公证您的应用程序,请参阅我们的教程。
macOS 上的信息属性列表
虽然 DSL 支持基本的平台特定自定义,但仍可能存在超出提供功能的情况。如果需要指定 DSL 中未表示的 Info.plist
值,您可以包含原始 XML 片段作为解决方法。此 XML 将附加到应用程序的 Info.plist
。
示例:深度链接
在
build.gradle.kts
文件中定义自定义 URL 方案:
使用
java.awt.Desktop
类在src/main/main.kt
文件中设置 URI 处理程序:
执行 `