You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

344 lines
15 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# TauriClient
多个 Tauri 2 + Vue 子项目的仓库,在 **Ubuntu 24.04.xx86_64** 上打 **amd64****arm64**`.deb` 使用统一脚本。
## 构建
```bash
cd /path/to/TauriClient
chmod +x scripts/build-linux-deb-all.sh
./scripts/build-linux-deb-all.sh
```
- 不带参数:按 `scripts/build-linux-deb-all.sh``PROJECTS` 依次构建全部项目。
- 只构建部分项目:
```bash
./scripts/build-linux-deb-all.sh call-client
./scripts/build-linux-deb-all.sh call-client broadcast-client
```
在各子目录内也可只打**当前项目**的两种架构:
- `call-client`: `npm run build:deb:all`
- `broadcast-client`: `npm run build:deb:all`
## 本机 amd64 依赖Tauri 官方 Linux 前置)
在 x86_64 上打 amd64 包前,需安装与本机架构一致的开发包(名称以 [Tauri 前置依赖](https://tauri.app/start/prerequisites/) 为准),例如:
```bash
sudo apt update
sudo apt install -y \
libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev \
librsvg2-dev patchelf build-essential curl wget file libssl-dev \
libglib2.0-dev pkg-config
```
## 原生 arm64 真机 / 云主机(直接打 arm64无 `:arm64` / multiarch
**`gio-2.0.pc` / `glib-2.0.pc` 找不到**,提示里写 **`PKG_CONFIG_PATH`**:在**本机就是 arm64** 时,一般**不是**路径配错,而是 **没装 GLib/GTK/WebKit 的开发包**。请先装依赖(**不要**加 `:arm64` 后缀),再构建:
```bash
sudo apt update
sudo apt install -y \
build-essential pkg-config libssl-dev \
libglib2.0-dev \
libgtk-3-dev \
libwebkit2gtk-4.1-dev \
libjavascriptcoregtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf \
curl file
```
自检(应能打印出路径且无报错):
```bash
pkg-config --exists gio-2.0 && pkg-config --cflags gio-2.0
ls /usr/lib/aarch64-linux-gnu/pkgconfig/gio-2.0.pc
```
然后在子项目目录执行 **`npm run build:deb:arm64`**(或 `tauri build --bundles deb --target aarch64-unknown-linux-gnu`)。**不要**在真机上照搬 x86 交叉编译时那套 `PKG_CONFIG_ALLOW_CROSS`、`PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig` 等环境变量,除非你知道自己在改什么——默认 `pkg-config` 即可。
仓库根目录的 **`build-linux-deb-all.sh`** 会先打 **amd64** 再打 **arm64**,适合 **x86_64 宿主机**;在 **纯 arm64 机器**上请**不要**直接跑该全量脚本(缺 amd64 工具链会失败),改为按项目单独 `npm run build:deb:arm64`
## 交叉编译 arm64multiarch + :arm64 开发包)
若在打 arm64 时出现 **`gobject-sys` / `glib-sys` / `gio-sys` 找不到 `glib-2.0.pc`** 等错误,说明宿主机上**没有安装 arm64 架构的 `-dev` 包**。仅设置 `PKG_CONFIG_*` 不够,必须安装带 **`:arm64`** 的包。
**顺序:先 `add-architecture`,再 `apt update`,最后 `apt install`。**
**重要:** 在 x86_64 宿主机上**不要**安装 **`systemd-sysv:arm64`**。它与本机 **`systemd-sysv`amd64在软件包元数据里互相 `Conflicts`**,无法共存;若 apt 因 **Recommends** 试图同时拉两边,就会解算失败。交叉编译只需 arm64 的 **库与 -dev**,应使用 **`--no-install-recommends`** 安装 `:arm64` 包,避免把 `systemd-sysv:arm64` 拉进来。
```bash
sudo dpkg --add-architecture arm64
sudo apt update
sudo apt install -y --no-install-recommends \
gcc-aarch64-linux-gnu \
pkg-config \
libglib2.0-dev:arm64 \
libgtk-3-dev:arm64 \
libcairo2-dev:arm64 \
libpango1.0-dev:arm64 \
libgdk-pixbuf-2.0-dev:arm64 \
libatk1.0-dev:arm64 \
libepoxy-dev:arm64 \
libwebkit2gtk-4.1-dev:arm64 \
libjavascriptcoregtk-4.1-dev:arm64 \
libssl-dev:arm64 \
libayatana-appindicator3-dev:arm64 \
librsvg2-dev:arm64 \
patchelf
```
### 若报 `gdk-3.0` / `gdk-sys` 找不到 `.pc`
`gdk-3.0.pc` 在 Ubuntu 上由 **`libgtk-3-dev:arm64`** 安装到 `/usr/lib/aarch64-linux-gnu/pkgconfig/`。若只装了 `libglib2.0-dev:arm64` 而没有装齐 GTK 栈,就会出现你看到的错误。执行上面的 `apt install`(至少包含 **`libgtk-3-dev:arm64`** 及 cairo/pango/atk 等),然后确认:
```bash
ls /usr/lib/aarch64-linux-gnu/pkgconfig/gdk-3.0.pc
```
### 若 `apt install …:arm64` 报依赖未满足(例如 `libpulse0:arm64` → `libapparmor1:arm64`
先修依赖、再显式装上缺的 arm64 基础库,然后重试安装 GTK/WebKit 开发包:
```bash
sudo apt --fix-broken install
sudo apt install -y --no-install-recommends libapparmor1:arm64
sudo apt install -y --no-install-recommends \
libgtk-3-dev:arm64 libcairo2-dev:arm64 libpango1.0-dev:arm64 \
libgdk-pixbuf-2.0-dev:arm64 libatk1.0-dev:arm64 libepoxy-dev:arm64 \
libwebkit2gtk-4.1-dev:arm64 libjavascriptcoregtk-4.1-dev:arm64
```
若仍失败,查看 apt 是否拒绝安装 `libapparmor1:arm64` 的原因:
```bash
apt-cache policy libapparmor1:arm64
sudo apt install -o Debug::pkgProblemResolver=true libapparmor1:arm64
```
**提示:** 不要把 `ubuntu.sources.bak.*` 留在 `/etc/apt/sources.list.d/`(部分 apt 版本会提示扩展名无效);备份文件请移到 `$HOME` 等目录。
### 若安装任意 `:arm64` 时都报 `init` 预依赖 `systemd-sysv` / pkgProblemResolver 失败
说明 **本机 amd64 的 apt/dpkg 状态已异常**(或关键元包未装全),应先修主系统再装 multiarch。在虚拟机里可先做快照再执行
```bash
sudo apt update
sudo apt install -y systemd-sysv
sudo dpkg --configure -a
sudo apt --fix-broken install
```
仍报错时再查版本与是否被 hold
```bash
apt-cache policy init systemd-sysv
apt-mark showhold
dpkg -l | grep -E '^(..) (init|systemd-sysv) '
```
`systemd-sysv` 无法安装,需在能登录图形/SSH 的前提下对照上述输出排查(有时需 `sudo apt install --reinstall init systemd-sysv`**有风险**,优先快照)。
主系统长期无法通过 `apt install` 修复时,建议在 **原生 arm64 环境** 或 **arm64 容器** 内单独打 arm64 包,避免在损坏的 apt 上叠 multiarch。
### `systemd-sysv` 与 `systemd-sysv:arm64` 冲突(你看到的 Conflicts
在 amd64 宿主机上,**`systemd-sysv`amd64`systemd-sysv:arm64` 互斥**不能同时安装。若某次安装把两者放进同一笔交易apt 会报 **冲突** 或前面那种 **`init` 预依赖** 的误导性提示。
**正确做法:** 只保留本机 **amd64**`systemd-sysv`;装 arm64 的库 / `-dev` 时一律加 **`--no-install-recommends`**,且**不要**执行 `apt install systemd-sysv:arm64`
自测(`libc6:arm64` 应已可装):
```bash
sudo apt install -y --no-install-recommends libapparmor1:arm64
sudo apt install -y --no-install-recommends \
libgtk-3-dev:arm64 libwebkit2gtk-4.1-dev:arm64 libjavascriptcoregtk-4.1-dev:arm64
```
若曾误装 `systemd-sysv:arm64`,先卸掉再装其它 arm64 包:
```bash
dpkg -l | grep systemd-sysv
# 若存在 systemd-sysv:arm64
sudo apt remove -y systemd-sysv:arm64
```
仍失败时保存解算日志:
```bash
sudo apt-get install -o Debug::pkgProblemResolver=true --no-install-recommends libapparmor1:arm64 2>&1 | tee ~/apt-arm64-debug.txt
```
**务实绕过:** 若 `--no-install-recommends` 仍因 **硬依赖** 拉进冲突包,在 **arm64 环境****Docker `--platform linux/arm64`** 内单独打 arm64 包(见下)。
```bash
docker run --rm -it --platform linux/arm64 -v "$PWD:/work" ubuntu:24.04 bash
```
在容器内按本文 **「本机 amd64 依赖」** 装一套 **arm64 的** `apt install`(无需 `:arm64` 后缀),再安装 Node、Rust 与项目依赖后执行 `npm run build:deb:arm64`。主机上继续用脚本打 **amd64** 即可。
### 故障排除:`apt` 提示「无法定位软件包 …:arm64」
说明当前 **apt 没有 arm64 的软件包索引**(与包名写错是两回事)。常见原因:
1. **未启用外架构或未刷新**
- 执行:`sudo dpkg --add-architecture arm64` 后必须再执行 `sudo apt update`
- 自检:`dpkg --print-foreign-architectures` 输出里应有 `arm64`
2. **`sources.list` 里限制了仅 amd64**VM / 公司镜像 / 手动改源时很常见)
若存在类似 `deb [arch=amd64] http://……` 且**没有** `arm64`,则 apt **不会拉 arm64 索引**。
**注意:** 若在**主归档**(如 `archive.ubuntu.com/ubuntu`、`mirrors.tuna…/ubuntu/`)上写 `[arch=amd64,arm64]`apt 会去拉 `dists/…/binary-arm64/`,而**主归档根本没有 arm64**(见下第 4 点)。正确做法是 **amd64 与 arm64 分开写两套 URI**DEB822 里用 `Architectures:`),而不是简单合并 `arch=`
3. **自检索引是否已包含 arm64**
```bash
apt-cache policy libc6:arm64
```
**Candidate 为 (none)**,说明索引仍不对,继续检查第 2 步;若已有版本号,再执行上面的 `apt install …:arm64`
4. **`apt update` 对 arm64 出现 `404``…/dists/noble/…/binary-arm64/Packages`**
**`archive.ubuntu.com/ubuntu` 与清华 `…/ubuntu/` 这类主归档不包含 arm64 的 `binary-arm64`。** 在 x86_64 上启用 `arm64` 做 multiarch 时,**arm64 必须走 ports** `http://ports.ubuntu.com/ubuntu-ports`(国内可用清华等 **ubuntu-ports** 镜像,见 [清华 ubuntu-ports](https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu-ports/))。
**`ubuntu.sources`** 里拆成多段,并写 **`Architectures:`**示例见下方「DEB822主归档 + ports」。**不要**指望把主源改成 `archive.ubuntu.com` 就能解决 arm64 404。
5. **`sources.list``ubuntu.sources` 重复(大量 “被配置了多次” 警告)**
Ubuntu 24.04 默认会用 **`/etc/apt/sources.list.d/ubuntu.sources`**DEB822 格式),若你又手工在 **`/etc/apt/sources.list`** 里写了同一套 `noble / noble-updates …`,两套会**重复指向同一组件**,产生警告且不利于排查。
**建议只保留一套:** 例如注释掉 `sources.list` 里全部 `deb` 行,只在 `ubuntu.sources` 里配置镜像;或反过来禁用 `ubuntu.sources`(改名 `ubuntu.sources.disabled`)后只维护 `sources.list`。 改完后执行 `sudo apt update`404/重复警告应明显减少。
6. **DEB822 示例amd64 用主镜像arm64 用 ubuntu-portsNoble**
将类似内容写入 `/etc/apt/sources.list.d/ubuntu.sources``Signed-By` 路径以本机为准;可与备份的 `ubuntu.sources.bak` 对照):
```text
Types: deb
URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Architectures: amd64
Types: deb
URIs: http://security.ubuntu.com/ubuntu
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Architectures: amd64
Types: deb
URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/
Suites: noble noble-updates noble-backports noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Architectures: arm64
```
然后:`sudo dpkg --add-architecture arm64`、`sudo apt update`,再执行 `apt-cache policy libc6:arm64`
### 无法在宿主机修好 multiarch 时的备选
**原生 arm64 环境**实体机、ARM 云主机、或 `arm64v8/ubuntu:24.04` 容器)里只跑 `npm run build:deb:arm64`(或 `tauri build … --target aarch64-unknown-linux-gnu`),可避免在 x86_64 上做整套 GTK/WebKit 交叉依赖。
并确保已添加 Rust 目标:
```bash
rustup target add aarch64-unknown-linux-gnu
```
安装完成后应存在:
`/usr/lib/aarch64-linux-gnu/pkgconfig/glib-2.0.pc`
构建脚本在开始 arm64 构建前会检查该文件;若缺失会直接退出并重复上述说明。
## 使用 Docker 打包Ubuntu 24.04.x 宿主机 + `build-linux-deb-all.sh`
**x86_64** 上装 Docker用镜像内已配好的 **Ubuntu 24.04 + amd64 主源 + ubuntu-portsarm64+ Node.jsUbuntu 官方仓库)+ Rust**,挂载你的仓库后执行 **`scripts/build-linux-deb-all.sh`**,产物仍在宿主机目录 **`dist/linux-deb/`** 与各项目 **`src-tauri/target/.../bundle/deb/`**。
### 1. 安装 Docker宿主机为 Ubuntu 24.04.4 LTS 示例)
```bash
sudo apt update
sudo apt install -y docker.io
sudo usermod -aG docker "$USER"
```
注销重新登录后,`docker ps` 应不再要求 `sudo`
(若使用 Docker CE可按官方文档安装以下命令以 `docker.io` 为例。)
### 2. 进入仓库根目录(含 `call-client`、`broadcast-client`
```bash
cd /path/to/TauriClient
chmod +x scripts/docker/run-build.sh scripts/docker/container-entry.sh
```
### 3. 一键:构建镜像并运行打包
```bash
./scripts/docker/run-build.sh
```
该脚本会:
1. `docker build -f scripts/docker/Dockerfile -t tauri-linux-deb:24.04 .`(构建上下文为仓库根;`.dockerignore` 会排除 `node_modules`、`target` 以加快传输)
2. `docker run` 挂载当前仓库到容器内 **`/work`**,依次对 **`call-client`、`broadcast-client`** 执行 **`npm ci`**
3. 执行 **`/work/scripts/build-linux-deb-all.sh`**(与宿主机直接跑脚本等价)
只打部分项目(参数原样传给 `build-linux-deb-all.sh`
```bash
./scripts/docker/run-build.sh call-client
```
自定义镜像名:
```bash
IMAGE_TAG=my-tauri-deb:24.04 ./scripts/docker/run-build.sh
```
### 4. 仅构建镜像(不跑打包)
```bash
docker build -f scripts/docker/Dockerfile -t tauri-linux-deb:24.04 .
```
### 5. 手动 `docker run`(已与 `run-build.sh` 等价,便于改参数)
```bash
docker build -f scripts/docker/Dockerfile -t tauri-linux-deb:24.04 .
docker run --rm \
--platform linux/amd64 \
-v "$(pwd):/work" \
-w /work \
-e RUSTUP_HOME=/opt/rustup \
-e CARGO_HOME=/opt/cargo \
tauri-linux-deb:24.04 \
bash /work/scripts/docker/container-entry.sh
```
### 6. 注意
- **宿主机须为 x86_64amd64**`run-build.sh` 使用 `--platform linux/amd64`,与脚本内先打 amd64 再交叉 arm64 一致。若在 **ARM 宿主机**上跑,需安装 QEMU/binfmt 且 **amd64 构建可能极慢或不可用**ARM 上更建议在 **`linux/arm64` 容器里只跑 `npm run build:deb:arm64`**。
- **网络**:镜像内 apt 使用 **Ubuntu官方** `archive.ubuntu.com` / `ports.ubuntu.com`;国内若慢,可自行改 **`scripts/docker/install-build-deps.sh`** 里 `ubuntu.sources` 的镜像地址后重新 `docker build`
- **新增子项目**:除改 **`build-linux-deb-all.sh``PROJECTS`**外,还要在 **`scripts/docker/container-entry.sh`** 的 `for d in ...` 中增加同名目录,否则容器内不会对该目录执行 `npm ci`
## 输出目录
**集中拷贝(便于收取产物):**
- `dist/linux-deb/<项目名>/amd64/*.deb`
- `dist/linux-deb/<项目名>/arm64/*.deb`
**Tauri 默认目录(未改路径):**
- `<项目>/src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/deb/`
- `<项目>/src-tauri/target/aarch64-unknown-linux-gnu/release/bundle/deb/`
## 新增同框架项目
`scripts/build-linux-deb-all.sh``PROJECTS` 数组中增加一行目录名(与子项目目录名一致),并保证该项目的 `package.json` 中仍有 `build:deb:x64``build:deb:arm64`。若使用 **Docker** 打包,还要同步修改 **`scripts/docker/container-entry.sh`** 里的 `for d in ...` 列表。