# TauriClient 多个 Tauri 2 + Vue 子项目的仓库,在 **Ubuntu 24.04.x(x86_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`。 ## 交叉编译 arm64(multiarch + :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-ports(Noble)** 将类似内容写入 `/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-ports(arm64)+ Node.js(Ubuntu 官方仓库)+ 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_64(amd64)**:`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 ...` 列表。