Rust + Makepad 应用怎么打包发布:Windows、macOS、Linux 全平台交付

前言

我写这个系列的第一天,目标就很明确:不只是学会 Makepad,是能用它做出一个真正交付给别人的桌面应用。

第九期做完工程化重构之后,项目状态是:代码能维护、别人能看懂了。但如果你想把这个 JSON 查看器发给同事用,你的选择是什么?

发源码。让他装 Rust 工具链。cargo run --release

这不算真交付。

真交付是:一个 dmg 拖进 Applications、一个 exe 双击运行、一个 AppImage 给 Linux 用户。或者一个 URL,浏览器打开就能用。

这期我把四条路都走一遍,把踩的坑和当前限制都写清楚。

1. 最简单也最稳:桌面 Native 构建

1.1 cargo build --release

好消息是:对桌面目标,Makepad 不需要任何特殊构建工具。标准 Rust 就够了。

bash 复制代码
cargo build --release

产物在 target/release/ 下:

  • Windows:json-viewer.exe
  • macOS:json-viewer(Unix 可执行文件)
  • Linux:json-viewer

这是我第一反应:居然不需要额外工具链?试了一下,确实。Makepad 的桌面渲染后端(Windows 用 DX11、macOS 用 Metal、Linux 用 OpenGL)在编译时自动选择,不需要手动配置。

1.2 体积

release 构建的实际体积(json-viewer 项目):

平台 二进制大小
macOS (ARM64) ~8 MB
Linux (x86_64) ~12 MB
Windows (x86_64) ~10 MB

比 Tauri 大(Tauri 本体通常 3-5 MB),但比 Electron 小太多。对于一个桌面工具来说完全可以接受。

如果想进一步压缩,可以用 strip

bash 复制代码
strip target/release/json-viewer

还能再减 30-40%。macOS 上 strip 是自带命令;Linux 需要 binutils;Windows 用 --release 编译时 LTO 已经做了大部分优化。

1.3 macOS 的特殊步骤:打包 .app

Unix 可执行文件双击能跑,但它不是一个"像样的 Mac 应用"。你需要把它包成 .app bundle:

bash 复制代码
mkdir -p JsonViewer.app/Contents/MacOS
cp target/release/json-viewer JsonViewer.app/Contents/MacOS/

再写一个最小的 Info.plist

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleName</key>
    <string>JSON Viewer</string>
    <key>CFBundleExecutable</key>
    <string>json-viewer</string>
    <key>CFBundleIdentifier</key>
    <string>com.example.json-viewer</string>
    <key>CFBundleVersion</key>
    <string>0.1.0</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>LSMinimumSystemVersion</key>
    <string>10.15</string>
</dict>
</plist>

要发给别人用,再打成 dmg:

bash 复制代码
hdiutil create -volname "JSON Viewer" -srcfolder JsonViewer.app -ov JsonViewer.dmg

如果要上架 Mac App Store 或做代码签名,那需要 Apple Developer 账号和公证流程。Makepad 本身不提供签名工具,用苹果的 codesign 命令就行。

1.4 Windows:不需要额外打包也能发

Windows 上最简单:把 exe 发给别人就行。但建议附带一个 README 说明最低系统要求(Windows 10+,Visual C++ Redistributable 可能需要)。

如果用 MSI 或 NSIS 做安装包,那就是标准 Windows 打包流程,跟 Makepad 没关系。产物就是一个 exe,随便用哪种打包工具。

1.5 Linux:AppImage 是最友好的格式

Linux 分发的痛点在于 glibc 版本和系统库差异。一个在 Ubuntu 24.04 上编译的二进制,可能在 Debian 12 上报 GLIBC_2.38 not found

缓解方法:

  • 在较老的系统上编译(比如 Docker 里用 Ubuntu 20.04)
  • 或者静态链接 musl:rustup target add x86_64-unknown-linux-musl && cargo build --release --target x86_64-unknown-linux-musl
  • AppImage 打包:把二进制和依赖库打包成一个自包含的镜像

AppImage 工具链跟 Makepad 无关,标准流程。参考 linuxdeployappimage-builder

2. 更轻量的分发:WASM 构建

Makepad 原生支持 WASM 目标。这意味着你可以把应用部署到网页上,用户开浏览器就能用。

2.1 安装 WASM 工具链

bash 复制代码
# 先安装 cargo-makepad(如果还没装)
cargo install --path=./tools/cargo_makepad

# 安装 WASM 目标工具链
cargo makepad wasm install-toolchain

2.2 构建 WASM

bash 复制代码
cargo makepad wasm build -p json-viewer --release

这会在 target/wasm/ 下生成 .wasm 文件和配套的 JS 胶水代码。部署到任何静态文件服务器就行了。

2.3 优化 WASM 体积

WASM 体积默认偏大,有几个优化选项:

bash 复制代码
# 基础优化:strip + small profile
cargo makepad wasm build -p json-viewer --profile=small --strip

# 进阶:wasm-opt + 代码分割 + brotli 压缩
cargo makepad wasm build -p json-viewer --release --wasm-opt --strip --split --brotli

各选项的含义:

  • --strip:去掉符号表和调试信息
  • --profile=small:使用小字体和优化 profile
  • --wasm-opt:用 Binaryen 做 IR 级优化(需要 brew install binaryenapt install binaryen
  • --split:把冷函数拆到第二个 wasm 文件,主文件更快加载
  • --brotli:brotli 压缩 wasm 和资源文件

全部加上的话,一个简单的应用可以从 ~20MB 压缩到 ~3MB 的传输大小。

2.4 WASM 的当前限制

坦诚说,不是所有 Makepad 功能在 WASM 上都可用:

  • 文件系统访问受限(浏览器的安全沙箱)
  • 系统对话框行为可能不一致
  • 性能不如原生构建
  • 一些平台相关的 API(如系统托盘)不可用

但如果你的应用是纯 UI + 计算逻辑(比如 JSON 查看器),WASM 版几乎和原生版功能一致。

3. 移动端:Android 和 iOS

3.1 Android

Makepad 有 Android 支持,需要 cargo-makepad

bash 复制代码
cargo run -p cargo-makepad --release -- android --target=all toolchain-install
cargo run -p cargo-makepad --release -- android run -p json-viewer

需要连接开启了开发者模式的 Android 设备。产物是 APK,可以直接安装。

3.2 iOS / tvOS

bash 复制代码
cargo makepad apple ios install-toolchain
cargo makepad apple tvos install-toolchain

需要 macOS + Xcode。iOS 的签名和分发跟所有 iOS 应用一样,走 Xcode 的 Archive → Distribute 流程。Makepad 不提供额外的 iOS 分发工具。

3.3 移动端的实际状态

移动端支持目前更像是"能跑"而不是"成熟"。官方示例在 Android 和 iOS 上能跑通,但如果你做重度移动端应用,现阶段可能还会遇到各种边缘问题。

建议:如果目标是桌面和 Web,现在就可以用。移动端作为探索和储备,等生态再成熟一些。

4. 自动化构建:GitHub Actions

手工构建一次还行,每次发版都手动就太累了。这里给一个最小的 GitHub Actions 配置,三平台自动构建:

yaml 复制代码
name: Release Build

on:
  push:
    tags: ['v*']

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable

      - name: Install Linux deps
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y libx11-dev libxcursor-dev libxkbcommon-dev \
            libxrandr-dev libxi-dev libxinerama-dev libasound2-dev libpulse-dev \
            libwayland-dev wayland-protocols libegl1-mesa-dev libgl1-mesa-dev

      - name: Build release
        run: cargo build --release

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: json-viewer-${{ runner.os }}
          path: target/release/json-viewer*

每次打 tag 就自动出三平台的二进制,发布 release 时直接挂上去。

Linux 那堆依赖确实多,但这是桌面 GUI 的通病,不是 Makepad 独有的。Tauri 也绕不过 WebKitGTK 那一堆。把这步写进 CI,后面就不用想了。

5. 版本分发策略

5.1 语义化版本号

toml 复制代码
[package]
version = "0.1.0"

每次发布变动类型决定版本号怎么变:

  • 0.1.00.1.1:修 bug
  • 0.1.10.2.0:加新功能
  • 0.2.01.0.0:你觉得稳定了

Cargo.toml 里改,然后 git tag v0.1.0,CI 自动触发构建。

5.2 自动更新

目前的现实是:Makepad 没有内置的自动更新机制。

Tauri 有 tauri-plugin-updater,Electron 有 electron-updater。Makepad 里你需要自己实现。最简单的方案:应用启动时调一个 HTTP 接口检查最新版本号,如果有新版本,弹窗让用户去下载页面。

不算优雅,但对小工具来说够用。如果用户量大了再考虑更完善的方案。

5.3 分发渠道

根据目标用户选渠道:

用户类型 推荐渠道
开发者 GitHub Releases
macOS 普通用户 dmg / Homebrew cask
Windows 普通用户 MSI 安装包 / Scoop / winget
Linux 用户 AppImage / Flatpak / 各发行版包管理器
所有用户(零安装) WASM 部署到网页

对于目前 Makepad 的生态阶段,GitHub Releases 发布三平台二进制是最务实的选择。上包管理器和应用商店可以等用户量起来再说。

6. 当前阶段的实际体验和坦诚总结

这个系列写到这里,我把一个想法变成了一个能真正交付的桌面应用。以下是整个过程的真实感受。

6.1 什么体验是好的

Native 构建体验很好。 cargo build --release 一把出三平台二进制,不需要任何 Makepad 专用工具。这是 Makepad 相对 Tauri 的一个隐藏优势------Tauri 需要 Node.js 和平台 WebView,Makepad 只需要 Rust 工具链。

WASM 构建也还行。 安装工具链多了一步,但整体流程清晰。优化选项丰富,体积极限可以压到很小。

GitHub Actions 集成没障碍。 就是标准 Rust CI,加上 Linux 的系统依赖。没有 Makepad 特有的 CI 痛点。

6.2 什么还需要等

移动端。 "能跑"和"能上架"是两回事。Android 和 iOS 的构建链路可以走通,但生产级的移动端交付还早。

自动更新。 没有内置方案,需要自己搭。

代码签名。 Makepad 不提供签名工具。macOS 公证、Windows 代码签名都得自己手动搞。这是桌面开发的通用痛点,不是 Makepad 特有的。

应用商店上架。 Mac App Store 和 Microsoft Store 的合规要求(沙箱、权限声明)可能和 Makepad 的部分能力冲突。目前需要逐个验证。

6.3 底线判断

如果你的目标是给桌面用户发一个可直接运行的二进制------现在就可以做。而且体验不差。

如果你的目标是上架应用商店、全平台自动更新、百万用户分发------还有路要走,但不妨碍今天开始。

总结:这个系列教会了我什么

十期,从"Makepad 是什么"到"怎么打包交付"。回头看一下,我发现一个有意思的事。

第一期我在比"Tauri vs Makepad 谁更强"。第十期我的判断变了:它们根本不是竞争关系。Tauri 做的是"用 Web 技术快速交付跨平台客户端",Makepad 做的是"用 Rust 原生渲染走另一条 UI 路线"。

选哪个,取决于你的团队和项目。有前端团队、要快速交付,Tauri 仍然更稳。想长期押注 Rust 生态、愿意接受前期摸索成本,Makepad 这条路是值得跟的。

这个系列是我自己从零开始搭建一个 Makepad 项目的完整记录。如果你也在走这条路,希望这个系列能帮你省一些摸索的时间。

相关推荐
Aolith2 小时前
React 路由守卫:我用一个组件替代了 Vue 的 beforeEach
前端·react.js
Daybreak2 小时前
从 PDD、DDD、SDD 到 TDD:我是如何用一套 Agent 工程方法论推进 My-Notion 的
前端
HjhIron2 小时前
从零实现一个待办事项应用:前端必学的Ajax与Node.js实战
前端·后端
yingyima2 小时前
JavaScript 正则表达式:从零开始的实战对比
前端
Sammyyyyy3 小时前
月之暗面 Kimi Code 0.4.0 发布,终端 AI 编码助手全面采用 TypeScript,实现毫秒级启动
前端·javascript·人工智能·ai·typescript·servbay
范什么特西3 小时前
配置文件xml和properties
xml·前端
jnene3 小时前
html 时间、价格筛选样式处理
前端·css·html
slongzhang_3 小时前
jquery 修复怪异模式html未声明“<!DOCTYPE html>”
前端·html·jquery
MageGojo3 小时前
R-Shell开源项目实战解析:用Rust打造命令行SSH工具,支持连接管理、远程执行、SFTP与MCP
运维·rust·开源项目·命令行工具·ssh客户端·mcp