深夜提醒

现在是深夜,建议您注意休息,不要熬夜哦~

🏮 🏮 🏮

新年快乐

祝君万事如意心想事成!

2024 桐庐半程马拉松
00:00:00
时间
0.00
距离(公里)
--:--
配速
--
步频
--
心率 (bpm)
--
配速
步频
|
share-image
永远怀念
ESC

Tauri 跨平台构建避坑指南:从 Biome 到 Rust 链接的全流程踩坑记录

Tauri 跨平台构建

在开发 ClipVault 这款跨平台剪贴板管理工具时,我经历了从代码规范检查到多平台编译的完整踩坑过程。本文记录了从 Biome CI 检查失败到 Rust 跨平台链接错误的完整解决方案。

项目背景

  • 技术栈: Tauri 2.0 + React + Rust
  • 目标平台: Windows (x86/x64/ARM64) + macOS (Intel/Apple Silicon) + Linux (x64/ARM64)
  • CI/CD: GitHub Actions

坑点一:Biome CI 版本不匹配与代码规范

问题现象

GitHub Actions 运行 biome ci . 时报错:

Notice: The configuration schema version does not match the CLI version 2.4.6
Expected: 2.4.6, Found: 2.2.6

同时伴随大量代码风格错误:

  • Error: The properties are not sorted. (CSS 属性未排序)
  • Error: The object properties are not sorted by key. (对象键未排序)
  • Error: Provide an explicit type attribute for the button element. (按钮缺少 type 属性)

原因分析

  1. 版本不一致: 本地 Biome 版本 (2.2.6) 与 CI 环境 (2.4.6) 不匹配
  2. 严格规则: Biome 默认启用 useSortedPropertiesuseSortedKeys 等严格规则
  3. dist 目录: 构建输出目录被错误地纳入检查范围

解决方案

1. 统一版本

// biome.json
{
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json"
}
# 升级本地 Biome
pnpm add -D @biomejs/biome@2.4.6

2. 排除不需要检查的文件

// biome.json
{
"files": {
"includes": ["**", "!package.json", "!.release-it.ts", "!dist/**", "!scripts/auto-fix.js"]
}
}

3. 自动修复代码风格

pnpm biome check --write --unsafe .

关键配置

{
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
"assist": {
"actions": {
"source": {
"organizeImports": "on",
"useSortedAttributes": "on",
"useSortedKeys": "on",
"useSortedProperties": "on"
}
}
},
"files": {
"includes": ["**", "!package.json", "!.release-it.ts", "!dist/**"]
}
}

坑点二:Rust 跨平台链接器配置错误

问题现象

Linux 构建时报错:

error: linking with `cc` failed: exit status: 1
rust-lld: error: cannot open /FORCE:MULTIPLE: No such file or directory
collect2: error: ld returned 1 exit status

原因分析

/FORCE:MULTIPLEWindows MSVC 链接器专用选项,用于强制允许多个定义。当该选项被错误地传递给 Linux 的 ld 链接器时会导致构建失败。

错误配置

# .cargo/config.toml ❌ 错误
[build]
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE", "-C", "prefer-dynamic"]

解决方案

使用 Cargo 的条件目标配置,仅在 Windows 目标下应用该选项:

# .cargo/config.toml ✅ 正确

# Windows 目标需要 /FORCE:MULTIPLE 链接器选项
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

[target.i686-pc-windows-msvc]
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

[target.aarch64-pc-windows-msvc]
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

# Linux ARM 目标配置
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"

坑点三:LTO 与动态链接冲突

问题现象

macOS 和 Linux 构建报错:

error: cannot prefer dynamic linking when performing LTO
note: only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO

原因分析

prefer-dynamic(偏好动态链接)与 lto = true(链接时优化)存在冲突:

  • Fat LTO (lto = true) 要求静态链接
  • 动态链接 会生成动态库依赖

解决方案

方案 1:使用 Thin LTO(推荐)

[profile.release]
strip = true
lto = "thin" # 从 true 改为 "thin"
opt-level = 3

方案 2:完全禁用 LTO

[profile.release]
strip = true
# lto 完全禁用(构建更快,但二进制更大)

最终配置

# .cargo/config.toml
[profile.release]
strip = true
lto = "thin"
opt-level = 3

坑点四:Ubuntu ARM64 交叉编译 apt 源配置

问题现象

Linux ARM64 交叉编译时 apt 安装失败:

E: Failed to fetch https://security.ubuntu.com/ubuntu/dists/jammy/main/binary-arm64/Packages  404  Not Found
E: Failed to fetch https://security.ubuntu.com/ubuntu/dists/jammy-updates/main/binary-arm64/Packages 404 Not Found

原因分析

Ubuntu 22.04 的默认源 archive.ubuntu.comsecurity.ubuntu.com 仅包含 x86_64 架构的软件包。ARM64 架构的软件包托管在 ports.ubuntu.com 上。

解决方案

1. 切换 apt 源到 ports.ubuntu.com

# .github/workflows/release.yml
- name: Install ARM cross-compile dependencies
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo dpkg --add-architecture arm64
# 关键:切换 apt 源到 ports.ubuntu.com(支持 ARM64)
sudo sed -i 's|http://archive.ubuntu.com/ubuntu/|http://ports.ubuntu.com/ubuntu-ports/|g' /etc/apt/sources.list
sudo sed -i 's|http://security.ubuntu.com/ubuntu/|http://ports.ubuntu.com/ubuntu-ports/|g' /etc/apt/sources.list
sudo apt-get update || true
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
sudo apt-get install -y libwebkit2gtk-4.1-dev:arm64 libappindicator3-dev:arm64 librsvg2-dev:arm64 patchelf || true

2. 配置交叉编译环境变量

- name: Setup ARM cross-compile env
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++" >> $GITHUB_ENV
echo "PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu" >> $GITHUB_ENV
echo "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig" >> $GITHUB_ENV
echo "PKG_CONFIG_ALLOW_CROSS=1" >> $GITHUB_ENV

3. Cargo 配置

# .cargo/config.toml
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"

完整配置参考

.github/workflows/release.yml

name: Release CI

on:
push:
tags:
- "v*"

jobs:
build-app:
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: "macos-latest"
target: "aarch64-apple-darwin"
- platform: "macos-latest"
target: "x86_64-apple-darwin"
- platform: "windows-latest"
target: "x86_64-pc-windows-msvc"
- platform: "windows-latest"
target: "i686-pc-windows-msvc"
- platform: "windows-latest"
target: "aarch64-pc-windows-msvc"
- platform: "ubuntu-22.04"
target: "x86_64-unknown-linux-gnu"
- platform: "ubuntu-22.04"
target: "aarch64-unknown-linux-gnu"

runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v3
with:
version: latest

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf

- name: Install ARM cross-compile dependencies
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo dpkg --add-architecture arm64
# 切换 apt 源到 ports.ubuntu.com
sudo sed -i 's|http://archive.ubuntu.com/ubuntu/|http://ports.ubuntu.com/ubuntu-ports/|g' /etc/apt/sources.list
sudo sed -i 's|http://security.ubuntu.com/ubuntu/|http://ports.ubuntu.com/ubuntu-ports/|g' /etc/apt/sources.list
sudo apt-get update || true
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
sudo apt-get install -y libwebkit2gtk-4.1-dev:arm64 libappindicator3-dev:arm64 librsvg2-dev:arm64 patchelf || true

- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: src-tauri/target
key: ${{ matrix.target }}

- name: Setup ARM cross-compile env
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
echo "CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++" >> $GITHUB_ENV
echo "PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu" >> $GITHUB_ENV
echo "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig" >> $GITHUB_ENV
echo "PKG_CONFIG_ALLOW_CROSS=1" >> $GITHUB_ENV

- name: Build the app
uses: tauri-apps/tauri-action@v0
env:
CI: false
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tagName: ${{ github.ref_name }}
releaseName: "ClipVault ${{ github.ref_name }}"
releaseDraft: false
prerelease: false
args: --target ${{ matrix.target }}

.cargo/config.toml

# Windows 目标需要 /FORCE:MULTIPLE 链接器选项
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

[target.i686-pc-windows-msvc]
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

[target.aarch64-pc-windows-msvc]
rustflags = ["-C", "link-arg=/FORCE:MULTIPLE"]

# Linux ARM 目标配置
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"

# macOS 目标配置
[target.aarch64-apple-darwin]
linker = "clang"
rustflags = ["-C", "link-arg=-arch", "-C", "link-arg=arm64"]

[target.x86_64-apple-darwin]
linker = "clang"
rustflags = ["-C", "link-arg=-arch", "-C", "link-arg=x86_64"]

[profile.release]
strip = true
lto = "thin"
opt-level = 3

构建矩阵总结

平台 架构 Rust Target 特殊配置
Windows x86_64 x86_64-pc-windows-msvc /FORCE:MULTIPLE
Windows x86 i686-pc-windows-msvc /FORCE:MULTIPLE
Windows ARM64 aarch64-pc-windows-msvc /FORCE:MULTIPLE
macOS Intel x86_64-apple-darwin clang + arch 标志
macOS Apple Silicon aarch64-apple-darwin clang + arch 标志
Linux x86_64 x86_64-unknown-linux-gnu 默认配置
Linux ARM64 aarch64-unknown-linux-gnu ports.ubuntu.com + 交叉编译工具链

总结

Tauri 跨平台构建的核心要点:

  1. 代码规范: 保持 Biome/Prettier 版本一致,排除构建输出目录
  2. 链接器配置: 使用 Cargo 条件目标配置,避免将 Windows 专用选项应用到其他平台
  3. LTO 策略: 使用 thin LTO 平衡构建速度和二进制优化
  4. 交叉编译: Ubuntu ARM64 需要切换到 ports.ubuntu.com

完整代码可参考 ClipVault GitHub 仓库


本文基于 Tauri 2.0 + GitHub Actions 的实战经验编写,希望能帮助更多开发者避开这些坑。

文章作者:阿文
文章链接: https://www.awen.me/post/dc6c9fdb.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 阿文的博客

评论

0 条评论
😀😃😄 😁😅😂 🤣😊😇 🙂🙃😉 😌😍🥰 😘😗😙 😚😋😛 😝😜🤪 🤨🧐🤓 😎🥸🤩 🥳😏😒 😞😔😟 😕🙁☹️ 😣😖😫 😩🥺😢 😭😤😠 😡🤬🤯 😳🥵🥶 😱😨😰 😥😓🤗 🤔🤭🤫 🤥😶😐 😑😬🙄 😯😦😧 😮😲🥱 😴🤤😪 😵🤐🥴 🤢🤮🤧 😷🤒🤕 🤑🤠😈 👿👹👺 🤡💩👻 💀☠️👽 👾🤖🎃 😺😸😹 😻😼😽 🙀😿😾 👍👎👏 🙌👐🤲 🤝🤜🤛 ✌️🤞🤟 🤘👌🤏 👈👉👆 👇☝️ 🤚🖐️🖖 👋🤙💪 🦾🖕✍️ 🙏💅🤳 💯💢💥 💫💦💨 🕳️💣💬 👁️‍🗨️🗨️🗯️ 💭💤❤️ 🧡💛💚 💙💜🖤 🤍🤎💔 ❣️💕💞 💓💗💖 💘💝💟 ☮️✝️☪️ 🕉️☸️✡️ 🔯🕎☯️ ☦️🛐 🆔⚛️🉑 ☢️☣️📴 📳🈶🈚 🈸🈺🈷️ ✴️🆚💮 🉐㊙️㊗️ 🈴🈵🈹 🈲🅰️🅱️ 🆎🆑🅾️ 🆘 🛑📛 🚫💯💢 ♨️🚷🚯 🚳🚱🔞 📵🚭 ‼️⁉️🔅 🔆〽️⚠️ 🚸🔱⚜️ 🔰♻️ 🈯💹❇️ ✳️🌐 💠Ⓜ️🌀 💤🏧🚾 🅿️🈳 🈂🛂🛃 🛄🛅🛗 🚀🛸🚁 🚉🚆🚅 ✈️🛫🛬 🛩️💺🛰️
您的评论由 AI 智能审核,一般1分钟内会展示,若不展示请确认你的评论是否符合社区和法律规范
加载中...

选择联系方式

留言反馈

😀😃😄 😁😅😂 🤣😊😇 🙂🙃😉 😌😍🥰 😘😗😙 😚😋😛 😝😜🤪 🤨🧐🤓 😎🥸🤩 🥳😏😒 😞😔😟 😕🙁☹️ 😣😖😫 😩🥺😢 😭😤😠 😡🤬🤯 😳🥵🥶 😱😨😰 😥😓🤗 🤔🤭🤫 🤥😶😐 😑😬🙄 😯😦😧 😮😲🥱 😴🤤😪 😵🤐🥴 🤢🤮🤧 😷🤒🤕 🤑🤠😈 👿👹👺 🤡💩👻 💀☠️👽 👾🤖🎃 😺😸😹 😻😼😽 🙀😿😾 👍👎👏 🙌👐🤲 🤝🤜🤛 ✌️🤞🤟 🤘👌🤏 👈👉👆 👇☝️ 🤚🖐️🖖 👋🤙💪 🦾🖕✍️ 🙏💅🤳 💯💢💥 💫💦💨 🕳️💣💬 👁️‍🗨️🗨️🗯️ 💭💤❤️ 🧡💛💚 💙💜🖤 🤍🤎💔 ❣️💕💞 💓💗💖 💘💝💟 ☮️✝️☪️ 🕉️☸️✡️ 🔯🕎☯️ ☦️🛐 🆔⚛️🉑 ☢️☣️📴 📳🈶🈚 🈸🈺🈷️ ✴️🆚💮 🉐㊙️㊗️ 🈴🈵🈹 🈲🅰️🅱️ 🆎🆑🅾️ 🆘 🛑📛 🚫💯💢 ♨️🚷🚯 🚳🚱🔞 📵🚭 ‼️⁉️🔅 🔆〽️⚠️ 🚸🔱⚜️ 🔰♻️ 🈯💹❇️ ✳️🌐 💠Ⓜ️🌀 💤🏧🚾 🅿️🈳 🈂🛂🛃 🛄🛅🛗 🚀🛸🚁 🚉🚆🚅 ✈️🛫🛬 🛩️💺🛰️