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.

298 lines
8.4 KiB
Bash

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.

#!/usr/bin/env bash
# 在 Ubuntu 24.04.xx86_64 宿主机)上为多个 Tauri 2 + Vue 项目打出 amd64 与 arm64 的 .deb。
#
# 依赖:
# - Node/npm、Rust、@tauri-apps/cli
# - rustup target add aarch64-unknown-linux-gnu
# - 本机 amd64Tauri Linux 前置依赖libwebkit2gtk-4.1-dev 等)
# - 交叉 arm64必须启用 multiarch 并安装 *:arm64 的 -dev 包,否则 glib/gdk/webkit 等 -sys 会报找不到 .pc
# 见 README.md「交叉编译 arm64」或本脚本 check_arm64_pkgconfig 失败时的提示。
#
# 用法:
# ./scripts/build-linux-deb-all.sh # 构建自动发现的全部项目amd64 + arm64
# ./scripts/build-linux-deb-all.sh --arch amd64 # 仅构建 amd64
# ./scripts/build-linux-deb-all.sh --arch arm64 call-client # 仅构建指定项目的 arm64
# ./scripts/build-linux-deb-all.sh --list-projects # 打印可构建项目列表
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
BUILD_ARCH="all"
LIST_PROJECTS=0
# 统一收集 .deb 的根目录(相对 REPO_ROOT
OUTPUT_ROOT="$REPO_ROOT/dist/linux-deb"
# aarch64 交叉编译时 pkg-config 查找路径(与下方 export 一致)
ARM64_PKGCONFIG_DIR="/usr/lib/aarch64-linux-gnu/pkgconfig"
X64_PKGCONFIG_DIR="/usr/lib/x86_64-linux-gnu/pkgconfig"
AVAILABLE_PROJECTS=()
usage() {
cat <<EOF
用法:
$(basename "$0") [--arch all|amd64|arm64] [项目名...]
$(basename "$0") --list-projects
EOF
}
discover_projects() {
local pkg_file project_dir
shopt -s nullglob
for pkg_file in "$REPO_ROOT"/*/package.json; do
project_dir="${pkg_file#$REPO_ROOT/}"
project_dir="${project_dir%/package.json}"
if node -e '
const fs = require("fs");
const pkg = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
const scripts = pkg.scripts || {};
process.exit(scripts["build:deb:x64"] && scripts["build:deb:arm64"] ? 0 : 1);
' "$pkg_file" >/dev/null 2>&1; then
echo "$project_dir"
fi
done
shopt -u nullglob
}
parse_args() {
while (($# > 0)); do
case "$1" in
--arch)
BUILD_ARCH="${2:-}"
if [[ -z "$BUILD_ARCH" ]]; then
echo "错误: --arch 需要参数all|amd64|arm64" >&2
exit 1
fi
shift 2
;;
--arch=*)
BUILD_ARCH="${1#*=}"
shift
;;
--list-projects)
LIST_PROJECTS=1
shift
;;
--help|-h)
usage
exit 0
;;
--)
shift
break
;;
-*)
echo "错误: 未知参数 $1" >&2
usage >&2
exit 1
;;
*)
break
;;
esac
done
case "$BUILD_ARCH" in
all|amd64|arm64) ;;
*)
echo "错误: --arch 仅支持 all|amd64|arm64当前为 \"$BUILD_ARCH\"" >&2
exit 1
;;
esac
printf '%s\n' "$@"
}
check_x64_pkgconfig() {
local missing=()
local f
for f in glib-2.0.pc gdk-3.0.pc webkit2gtk-4.1.pc; do
if [[ ! -f "$X64_PKGCONFIG_DIR/$f" ]]; then
missing+=( "$f" )
fi
done
if (( ${#missing[@]} == 0 )); then
return 0
fi
cat >&2 <<EOF
错误: amd64 缺少 pkg-config 文件(在 $X64_PKGCONFIG_DIR:
${missing[*]}
请先安装本机 amd64 的开发包:
sudo apt install -y --no-install-recommends \\
libglib2.0-dev libgtk-3-dev \\
libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev \\
libayatana-appindicator3-dev librsvg2-dev libssl-dev
安装后自检:
ls $X64_PKGCONFIG_DIR/glib-2.0.pc $X64_PKGCONFIG_DIR/gdk-3.0.pc $X64_PKGCONFIG_DIR/webkit2gtk-4.1.pc
EOF
exit 1
}
check_arm64_pkgconfig() {
# 缺任一则 cargo 会在不同阶段失败gdk-3.0.pc 由 libgtk-3-dev:arm64 提供
local missing=()
local f
for f in glib-2.0.pc gdk-3.0.pc webkit2gtk-4.1.pc; do
if [[ ! -f "$ARM64_PKGCONFIG_DIR/$f" ]]; then
missing+=( "$f" )
fi
done
if (( ${#missing[@]} == 0 )); then
return 0
fi
cat >&2 <<EOF
错误: arm64 缺少 pkg-config 文件(在 $ARM64_PKGCONFIG_DIR:
${missing[*]}
- glib-2.0.pc → libglib2.0-dev:arm64
- gdk-3.0.pc → libgtk-3-dev:arm64gdk-sys
- webkit2gtk-4.1.pc → libwebkit2gtk-4.1-dev:arm64
请确认已按 README 配置 ubuntu-portsarm64然后安装可整段执行
sudo apt install -y \\
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
安装后自检:
ls $ARM64_PKGCONFIG_DIR/glib-2.0.pc $ARM64_PKGCONFIG_DIR/gdk-3.0.pc $ARM64_PKGCONFIG_DIR/webkit2gtk-4.1.pc
详见 README.md「交叉编译 arm64」与「gdk-3.0 / gdk-sys」。
EOF
exit 1
}
build_one_target() {
local project_dir="$1"
local npm_cmd="$2"
local abs_project="$REPO_ROOT/$project_dir"
if [[ ! -f "$abs_project/package.json" ]]; then
echo "错误: 未找到项目 $project_dir(缺少 package.json" >&2
exit 1
fi
echo "==> [$project_dir] $npm_cmd"
(cd "$abs_project" && npm run "$npm_cmd")
}
collect_debs() {
local project_dir="$1"
local arch_label="$2"
local triple="$3"
local src="$REPO_ROOT/$project_dir/src-tauri/target/$triple/release/bundle/deb"
local dest="$OUTPUT_ROOT/$project_dir/$arch_label"
if [[ ! -d "$src" ]]; then
echo "警告: 未找到输出目录 $src(跳过复制)" >&2
return 0
fi
mkdir -p "$dest"
shopt -s nullglob
local files=( "$src"/*.deb )
shopt -u nullglob
if (( ${#files[@]} == 0 )); then
echo "警告: $src 下没有 .deb 文件" >&2
return 0
fi
cp -v "${files[@]}" "$dest/"
}
build_project() {
local project_dir="$1"
if [[ "$BUILD_ARCH" == "all" || "$BUILD_ARCH" == "amd64" ]]; then
echo ""
echo "######## $project_dir: amd64 ########"
unset PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR PKG_CONFIG_ALLOW_CROSS 2>/dev/null || true
check_x64_pkgconfig
export PKG_CONFIG_PATH="$X64_PKGCONFIG_DIR"
export PKG_CONFIG_LIBDIR="$X64_PKGCONFIG_DIR:/usr/share/pkgconfig"
build_one_target "$project_dir" "build:deb:x64"
collect_debs "$project_dir" "amd64" "x86_64-unknown-linux-gnu"
unset PKG_CONFIG_PATH PKG_CONFIG_LIBDIR
fi
if [[ "$BUILD_ARCH" == "all" || "$BUILD_ARCH" == "arm64" ]]; then
echo ""
echo "######## $project_dir: arm64 (cross) ########"
check_arm64_pkgconfig
export PKG_CONFIG_ALLOW_CROSS=1
export PKG_CONFIG_SYSROOT_DIR=/
export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig
export PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig
build_one_target "$project_dir" "build:deb:arm64"
collect_debs "$project_dir" "arm64" "aarch64-unknown-linux-gnu"
unset PKG_CONFIG_ALLOW_CROSS PKG_CONFIG_SYSROOT_DIR PKG_CONFIG_PATH PKG_CONFIG_LIBDIR
fi
}
select_projects() {
local available=("${AVAILABLE_PROJECTS[@]}")
if (($# == 0)); then
printf '%s\n' "${available[@]}"
return
fi
local name ok p
for name in "$@"; do
ok=0
for p in "${available[@]}"; do
if [[ "$p" == "$name" ]]; then
ok=1
break
fi
done
if [[ "$ok" -eq 0 ]]; then
echo "错误: 未知项目 \"$name\"(可用项目见 --list-projects" >&2
exit 1
fi
echo "$name"
done
}
main() {
local -a positional to_build
mapfile -t positional < <(parse_args "$@")
mapfile -t AVAILABLE_PROJECTS < <(discover_projects)
if (( ${#AVAILABLE_PROJECTS[@]} == 0 )); then
echo "错误: 未发现可构建项目(需包含 build:deb:x64 与 build:deb:arm64 脚本)" >&2
exit 1
fi
if [[ "$LIST_PROJECTS" -eq 1 ]]; then
printf '%s\n' "${AVAILABLE_PROJECTS[@]}"
return
fi
mapfile -t to_build < <(select_projects "${positional[@]}")
mkdir -p "$OUTPUT_ROOT"
for p in "${to_build[@]}"; do
build_project "$p"
done
echo ""
echo "==> 全部完成"
echo " 构建架构: $BUILD_ARCH"
echo " 统一输出目录: $OUTPUT_ROOT"
echo " 每项目下: <项目名>/amd64/*.deb 与 <项目名>/arm64/*.deb"
echo " Tauri 原始路径仍在各项目:"
echo " src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/deb/"
echo " src-tauri/target/aarch64-unknown-linux-gnu/release/bundle/deb/"
}
main "$@"