electron-builder 自带的 fpm 打包在 arm64 Kylin 板子上必现 "tar failed (exit code 2)",改用 electron-builder 的 dir target 产出 unpacked 目录后手工用 dpkg-deb 拼装,包含 chrome-sandbox setuid 修复(缺失会导致 Electron 沙箱初始化失败,启动即崩溃)。 版本号解析与 electron-builder.config.ts / electron.vite.config.ts 保持一致(git tag -> .app-version -> package.json 三级回退)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
127 lines
4.3 KiB
Bash
Executable File
127 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
||
# 在 Kylin V10 (RK3588, arm64) 上构建 elec_rag_ui 的 deb 安装包。
|
||
#
|
||
# 背景:electron-builder 自带的 fpm 打包路径在这类 arm64 Kylin 板子上有已知 bug——
|
||
# fpm 内部调用 tar 归档 data.tar.gz 时报 "tar failed (exit code 2)",无法通过
|
||
# `electron-builder --linux deb` 直接产出 deb。此脚本改用 electron-builder 的
|
||
# `dir` target 先产出 unpacked 应用目录,再手工拼装 DEBIAN 控制文件用 dpkg-deb 打包,
|
||
# 这条路径已在真机上验证可行。
|
||
#
|
||
# 必须在 arm64 Linux(如目标 pad 本身)上执行,依赖 dpkg-deb。
|
||
#
|
||
# 用法:bash scripts/package-kylin-arm64-deb.sh
|
||
|
||
set -e
|
||
|
||
cd "$(dirname "$0")/.."
|
||
|
||
if ! command -v dpkg-deb >/dev/null 2>&1; then
|
||
echo "错误:找不到 dpkg-deb,本脚本只能在 Debian/Kylin 系 arm64 Linux 上运行" >&2
|
||
exit 1
|
||
fi
|
||
|
||
if [ "$(uname -m)" != "aarch64" ]; then
|
||
echo "警告:当前架构不是 aarch64(实测为 $(uname -m)),继续执行但产物大概率无法在 arm64 pad 上运行" >&2
|
||
fi
|
||
|
||
# 版本号解析:优先 git tag,其次 .app-version(rsync 到无 .git 的 pad 时使用),
|
||
# 最后回退 package.json 里的版本号。与 electron-builder.config.ts / electron.vite.config.ts
|
||
# 的解析逻辑保持一致,确保三处版本号(deb 文件名、界面显示、控制文件)永远一致。
|
||
VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//') || true
|
||
if [ -z "$VERSION" ] && [ -f .app-version ]; then
|
||
VERSION=$(cat .app-version | tr -d '[:space:]')
|
||
fi
|
||
if [ -z "$VERSION" ]; then
|
||
VERSION=$(node -p "require('./package.json').version")
|
||
fi
|
||
echo "=== 打包版本号: $VERSION ==="
|
||
|
||
PRODUCT_NAME="智能电子手册"
|
||
EXE_NAME="elec_rag_ui"
|
||
PKG_NAME="elec-rag-ui"
|
||
APP_DIR="dist/linux-arm64-unpacked"
|
||
STAGING="dist/deb-staging"
|
||
OUT="dist/${PKG_NAME}_${VERSION}_arm64.deb"
|
||
|
||
echo "=== 1/4 electron-vite build ==="
|
||
npx electron-vite build
|
||
cp resources/asr-worker.cjs out/main/asr-worker.cjs
|
||
|
||
echo "=== 2/4 electron-builder(仅 dir target,跳过 fpm)==="
|
||
ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/ \
|
||
npx electron-builder --config electron-builder.config.ts --linux dir --arm64
|
||
|
||
if [ ! -d "$APP_DIR" ]; then
|
||
echo "错误:electron-builder 没有产出 $APP_DIR" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "=== 3/4 手工拼装 deb 结构 ==="
|
||
rm -rf "$STAGING"
|
||
mkdir -p "$STAGING/DEBIAN" \
|
||
"$STAGING/opt/$PRODUCT_NAME" \
|
||
"$STAGING/usr/bin" \
|
||
"$STAGING/usr/share/applications" \
|
||
"$STAGING/usr/share/icons/hicolor/1024x1024/apps"
|
||
|
||
cp -a "$APP_DIR/." "$STAGING/opt/$PRODUCT_NAME/"
|
||
# chrome-sandbox 必须是 setuid root,否则 Electron 沙箱初始化失败,
|
||
# 启动即崩溃报 "Failed sending zygote boot message: 断开的管道"
|
||
chmod 4755 "$STAGING/opt/$PRODUCT_NAME/chrome-sandbox"
|
||
|
||
cp resources/icon.png "$STAGING/usr/share/icons/hicolor/1024x1024/apps/$PKG_NAME.png"
|
||
|
||
cat > "$STAGING/usr/share/applications/$PKG_NAME.desktop" <<EOF
|
||
[Desktop Entry]
|
||
Name=$PRODUCT_NAME
|
||
Exec=/opt/$PRODUCT_NAME/$EXE_NAME %U
|
||
Terminal=false
|
||
Type=Application
|
||
Icon=$PKG_NAME
|
||
StartupWMClass=$PRODUCT_NAME
|
||
Comment=RAG 知识库查询桌面应用
|
||
Categories=Utility;
|
||
EOF
|
||
|
||
INSTALLED_SIZE=$(du -sk "$STAGING/opt" | cut -f1)
|
||
cat > "$STAGING/DEBIAN/control" <<EOF
|
||
Package: $PKG_NAME
|
||
Version: $VERSION
|
||
Section: utils
|
||
Priority: optional
|
||
Architecture: arm64
|
||
Installed-Size: $INSTALLED_SIZE
|
||
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0
|
||
Recommends: libappindicator3-1
|
||
Maintainer: EdgeRhythm <ssurui@gmail.com>
|
||
Homepage: https://gitee.com/EdgeRhythm/elec_rag_ui
|
||
Description: 本地化 RAG 问答桌面前端
|
||
EOF
|
||
|
||
cat > "$STAGING/DEBIAN/postinst" <<EOF
|
||
#!/bin/sh
|
||
set -e
|
||
ln -sf "/opt/$PRODUCT_NAME/$EXE_NAME" /usr/bin/$PKG_NAME
|
||
if [ -x /usr/bin/update-desktop-database ]; then
|
||
update-desktop-database /usr/share/applications >/dev/null 2>&1 || true
|
||
fi
|
||
if [ -x /usr/bin/gtk-update-icon-cache ]; then
|
||
gtk-update-icon-cache -q /usr/share/icons/hicolor >/dev/null 2>&1 || true
|
||
fi
|
||
EOF
|
||
|
||
cat > "$STAGING/DEBIAN/postrm" <<EOF
|
||
#!/bin/sh
|
||
set -e
|
||
rm -f /usr/bin/$PKG_NAME
|
||
EOF
|
||
|
||
chmod 755 "$STAGING/DEBIAN/postinst" "$STAGING/DEBIAN/postrm"
|
||
|
||
echo "=== 4/4 dpkg-deb --build ==="
|
||
dpkg-deb --root-owner-group -Zgzip --build "$STAGING" "$OUT"
|
||
|
||
echo "=== 完成: $OUT ==="
|
||
ls -la "$OUT"
|
||
dpkg-deb -I "$OUT" | head -20
|