博客 / 詳情

返回

一篇文章讓你學會 Compose Multiplatform 推薦的桌面應用打包工具 Conveyor

對於希望將 Compose Multiplatform Desktop 應用部構建發佈的開發者而言,跨平台打包、簽名、更新機制等環節常常是巨大的挑戰。本文將深入探討 Conveyor 這一強大的打包工具,並以我的開源項目 CrossPaste 為例,為您詳細解析其在實際項目中的應用,幫助您輕鬆實現應用的跨平台發佈。

1. 為什麼選擇 Conveyor?

Conveyor 是一個出色的工具,它旨在讓桌面應用的發佈像發佈 Web 應用一樣簡單。對於 Compose Multiplatform 項目來説,選擇 Conveyor 有以下關鍵優勢:

官方推薦與緊密集成:Compose Multiplatform 的開源項目 文檔 中直接提及並列舉了 Conveyor 一些列強大功能,這表明它是一個官方推薦的打包工具。Conveyor 特別為 JVM 應用提供了優化,包括捆綁 jlink 優化的 JVM、自定義原生啓動器以及大量針對桌面應用的可用性改進。

跨平台打包與自更新:Conveyor 能夠為 Windows、macOS 和 Linux 生成並簽名自更新的軟件包,而且無需您擁有這些操作系統即可完成。它支持平台原生的包格式和更新系統,提供 Chrome 風格的靜默後台更新和 Web 風格的同步啓動更新,以及高級增量更新功能。這意味着您的應用可以自動更新,且無需修改代碼。

簡化複雜流程:Conveyor 極大地簡化了代碼簽名、公證、圖標生成等繁瑣過程。它甚至可以從任何操作系統為所有支持的 OS 簽名/公證應用。

出色的 CI/CD 支持:您可以在任何 Linux 構建代理上為所有支持的平台直接打包和部署您的應用,而無需 Mac/Windows 工作機。

免費與定價模式:Conveyor 對開源應用免費,對商業應用則採用簡單的按項目定價模式。由於 CrossPaste 是一個開源項目,這使其成為一個經濟高效的選擇。

conveyor 的安裝

使用前你必須先安裝 conveyor,https://conveyor.hydraulic.dev/ 它們提供了 macOS、Windows、Linux 多平台安裝包,按照提示安裝完畢後,打開應用將 conveyor 命令添加到環境變量即可

2. CrossPaste 中的實踐案例

CrossPaste 是一個旨在實現跨設備剪貼板通用同步的開源項目。

接下來以 CrossPaste 項目的配置為例子詳細講解 conveyor 如何使用

conveyor.conf

include "#!./gradlew -q printConveyorConfig -PappEnv=PRODUCTION"

include file("extract-native-libraries.conf")

app {
  compression-level = high
  contact-email = "compile.future@gmail.com"
  license = "AGPL-3.0-or-later"
  display-name = "CrossPaste"
  rdns-name = "com.crosspaste"
  url-schemes = [ crosspaste ]
  vcs-url = "https://github.com/CrossPaste/crosspaste-desktop"

  site {
    consistency-checks = warn
  }

  jvm {
    mac.amd64.inputs += "app/jbr/jbrsdk-21.0.7-osx-x64-b968.13.tar.gz"
    mac.aarch64.inputs += "app/jbr/jbrsdk-21.0.7-osx-aarch64-b968.13.tar.gz"
    windows.amd64.inputs += "app/jbr/jbrsdk-21.0.7-windows-x64-b968.13.tar.gz"
    linux.amd64.inputs += "app/jbr/jbrsdk-21.0.7-linux-x64-b968.13.tar.gz"
  }

  mac {
    bundle-extras += "app/script/mac_start.sh" -> "bin/start.sh"

    icons = "app/src/desktopMain/composeResources/drawable/crosspaste_mac.png"

    info-plist.CFBundleIdentifier = "com.crosspaste.mac"
    info-plist.LSMinimumSystemVersion = 13.0.0
    info-plist.LSUIElement = true
    updates = background
    sparkle-options.SUScheduledCheckInterval = 3600
  }

  windows {
    inputs += "app/script/win_start.bat" -> "bin/start.bat"

    icons = "app/src/desktopMain/composeResources/drawable/crosspaste.png"
    updates = {
      launch-check-frequency = 1
      block-start = false
      automatic-updates = true
    }
  }

  linux {
    debian.distribution.name = jammy

    install-path = /usr/lib/crosspaste

    icons = "app/src/desktopMain/composeResources/drawable/crosspaste.png"

    root-inputs += "app/script/linux_start.sh" -> "/usr/lib/crosspaste/bin/start.sh"
  }
}
conveyor.compatibility-level = 18

3.1 基礎信息獲取與配置

Conveyor 可以從您的 build.gradle.kts 中獲取基礎信息,避免重複配置。CrossPaste 的配置通過以下方式引入 Gradle 信息:

include "#!./gradlew -q printConveyorConfig -PappEnv=PRODUCTION":這條命令讓 Conveyor 在構建時執行 Gradle 任務,獲取項目的基本配置信息。

include file("extract-native-libraries.conf"):這用於處理 Mac 在沙箱內運行應用時,需要提前標記可執行文件的問題,以防止應用被 macOS 禁用。在 extract-native-libraries.conf 中,可以看到 app.jvm.extract-native-libraries = true 的配置,以及針對 jna.nosysskiko.library.path 的系統屬性設置。

3.2 應用通用配置 (app 區塊)

conveyor.confapp 區塊中,定義了應用的通用元數據和行為:

compression-level = high:指定包的壓縮級別。

contact-email = "compile.future@gmail.com":聯繫郵箱。

license = "AGPL-3.0-or-later":應用許可證。

display-name = "CrossPaste":應用顯示名稱。

rdns-name = "com.crosspaste":反向域名,通常用於唯一標識應用。

url-schemes = [ crosspaste ]:定義應用支持的 URL scheme。

vcs-url = "https://github.com/CrossPaste/crosspaste-desktop":版本控制系統 URL,指向 GitHub 倉庫。

conveyor.compatibility-level = 18:指定 Conveyor 的兼容性級別,實際也就是 conveyor 的大版本號。

3.3 JVM 特定配置

Conveyor 可以捆綁具體的 JDK,來確保應用在不同系統上的運行環境一致性。CrossPaste 選擇使用 JBR (JetBrains Runtime) 作為運行環境,JBR 作為 Jetbrains 一系列 IDE 桌面應用的環境,經過了長期使用驗證,並且官方維護合併了許多桌面環境補丁,相比作為服務器環境的很多開源 JDK 版本,它更適合桌面環境,因此也推薦大家選擇 JBR

通過 jvm.mac.amd64.inputs 等配置指定了不同操作系統和架構的 JBR 路徑:

mac.amd64.inputs += "app/jbr/jbrsdk-21.0.7-osx-x64-b968.13.tar.gz"

mac.aarch64.inputs += "app/jbr/jbrsdk-21.0.7-osx-aarch64-b968.13.tar.gz"

windows.amd64.inputs += "app/jbr/jbrsdk-21.0.7-windows-x64-b968.13.tar.gz"

linux.amd64.inputs += "app/jbr/jbrsdk-21.0.7-linux-x64-b968.13.tar.gz"

這些 JBR 文件通常是通過 Gradle 腳本(如 CrossPaste 的 build.gradle.kts 中的 getJbrReleasesdownJbrReleases 函數)下載到本地 jbr 目錄的。

3.4 平台特定配置

Conveyor 允許為每個平台定製詳細的配置,以確保應用能夠完美融入目標操作系統環境。

macOS (mac 區塊)

  • bundle-extras += "app/script/mac_start.sh" -> "bin/start.sh":捆綁額外的啓動腳本。
  • icons = "app/src/desktopMain/composeResources/drawable/crosspaste_mac.png":應用圖標路徑。
  • info-plist.CFBundleIdentifier = "com.crosspaste.mac":CFBundleIdentifier,用於唯一標識 Mac 應用。
  • info-plist.LSMinimumSystemVersion = 13.0.0:最低系統版本要求。
  • info-plist.LSUIElement = true:設置為 true 表示應用不在 Dock 中顯示圖標,通常用於後台工具或無界面應用。在 build.gradle.kts 中,Compose Desktop 也提供了 infoPlist 區塊來配置這些 Info.plist 條目。
  • updates = background:啓用後台更新。Conveyor 為 macOS 輸出包含 Sparkle 框架的 .app 包,appcast.rss 文件用於廣告更新。
  • sparkle-options.SUScheduledCheckInterval = 3600:設置 Sparkle 檢查更新的頻率(單位秒)。
  • 公證 (Notarization):Mac 應用的公證配置,這些敏感信息通常通過環境變量傳入。

Windows (windows 區塊)

  • inputs += "app/script/win_start.bat" -> "bin/start.bat":捆綁啓動腳本。
  • icons = "app/src/desktopMain/composeResources/drawable/crosspaste.png":應用圖標路徑。
  • updates:Windows 的更新配置:

    • launch-check-frequency = 1:啓動時檢查更新頻率。
    • block-start = false:不阻塞啓動。
    • automatic-updates = true:啓用自動更新。
  • Conveyor 使用 Windows 內置的 MSIX 打包技術,它支持增量下載、後台自動升級和輕量級容器化,確保應用安裝和卸載的潔淨性。
  • Microsoft Store 集成:同樣,商店相關的敏感信息通過環境變量設置。

Linux (linux 區塊)

  • debian.distribution.name = jammy:指定 Debian/Ubuntu 的發行版,注意此配置直接影響應用與系統的兼容性,不宜選擇過高。
  • install-path = /usr/lib/crosspaste:應用安裝路徑。
  • icons = "app/src/desktopMain/composeResources/drawable/crosspaste.png":應用圖標路徑。
  • root-inputs += "app/script/linux_start.sh" -> "/usr/lib/crosspaste/bin/start.sh":捆綁啓動腳本並指定其在根文件系統中的安裝路徑。
  • Conveyor 會為 Debian/Ubuntu 生成 .deb 包,並將其放在一個 apt 倉庫中。安裝 .deb 包會自動安裝倉庫描述文件,從而實現依賴解析和後續更新。

3.5 Gradle 構建腳本中的 Conveyor 整合

CrossPaste 的 build.gradle.kts 文件展示了 Compose Multiplatform 項目如何與 Conveyor 插件協同工作:

alias(libs.plugins.conveyor):在 plugins 部分聲明 Conveyor Gradle 插件。

JBR 管理getJbrReleasesdownJbrReleases 函數負責從 jbr.yaml 文件中讀取 JBR 的下載 URL 和 SHA512 校驗和,並下載 JBR 包到指定目錄。這些 JBR 文件隨後被 Conveyor 捆綁到最終的應用包中。

JVM 參數 (jvmArgs):在 nativeDistributions 配置中,可以為所有平台添加 JVM 啓動參數,例如 --add-opens 用於模塊開放,以及設置系統屬性如 loggerLevelappEnvjava.net.preferIPv4Stack 等。

平台特定構建邏輯

  • macOS Swift 編譯:CrossPaste 在 build.gradle.kts 中定義了 compileSwift 任務,用於編譯 MacosApi.swift 生成 libMacosApi.dylib,這個動態庫對於實現原生 macOS API 交互至關重要。desktopJardesktopTest 任務都依賴於此編譯步驟。
  • targetFormats(TargetFormat.Dmg):macOS 目標格式設置為 DMG。
  • targetFormats(TargetFormat.Msi):Windows 目標格式設置為 MSI。
  • targetFormats(TargetFormat.Deb):Linux 目標格式設置為 Deb。

4. 運行與構建 Conveyor 任務

Conveyor 是一個構建系統,它通過配置和任務來生成最終的應用包和下載站點。

生成打包後的應用目錄/Bundle 並執行

  • conveyor run
  • 加速運行 (跳過簽名):conveyor -Kapp.sign = false run

將應用目錄輸出到 output 文件夾

  • conveyor make app

為所有可用平台構建下載站點

  • conveyor make site
  • 生成的下載站點包含各種元數據文件、軟件包和一個簡單的 HTML 下載頁面,所有文件都必須上傳以確保更新和增量生成正常工作。

5. 增量更新:優化用户體驗

Conveyor 的核心優勢之一是其增量更新功能。當 Conveyor 打包的應用在 Windows 和 macOS 上更新時,它們不會從頭下載整個應用,而是僅下載已安裝版本與最新版本之間的差異。這大大節省了帶寬和更新時間。

Windows:MSIX 包會自動進行增量更新。即使用户已經安裝了其他通過 Microsoft Store 或 Conveyor 構建的應用,新應用的首次安裝也可以複用這些已安裝應用的文件或數據塊,從而顯著提升首次運行時間和降低下載放棄率。

macOS:Conveyor 會自動生成增量補丁文件(*.delta 文件),並作為站點文件的一部分。這些文件支持 Sparkle 框架進行增量更新。

Linux:通過 Debian/Ubuntu 的 apt 倉庫機制,用户可以通過 apt-get update; apt-get upgrade 命令無縫更新應用。

6. 結語

Conveyor 為 Compose Multiplatform Desktop 應用提供了一站式的打包、分發和更新解決方案,極大地簡化了桌面應用開發的複雜性。通過 CrossPaste 這樣一個真實世界的開源項目,您可以更直觀地理解 Conveyor 的強大功能和靈活配置。

如果您正在尋求構建和打包 Compose Multiplatform Desktop 應用的解決方案,強烈建議您嘗試 Conveyor。

🔥 助力 CrossPaste 項目!

如果您覺得 CrossPaste 這個項目對您有幫助,或者您對跨平台剪貼板同步工具感興趣,請訪問 【CrossPaste 的 GitHub 倉庫併為它點亮一顆 Star!您的支持是我們持續開發和維護的最大動力。
👉 CrossPaste GitHub 倉庫
此外,CrossPaste 致力於提供無縫的跨設備體驗,目前已推出適用於 Android 設備的付費應用。雖然本文的資料主要側重於桌面應用打包,但 CrossPaste 的願景是實現所有設備間的剪貼板無縫同步。如果您希望在您的 Android 設備上體驗更便捷的剪貼板功能,請前往應用 Google Play CrossPaste 瞭解並下載。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.