mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-11 17:09:45 +08:00
- Kingbase:在 current_schema() 为 public 时探测候选 schema,并通过 DSN search_path 重连,兼容未限定 schema 的查询 - 候选优先级:数据库名/用户名同名 schema(存在性校验),否则仅在“唯一用户 schema 有表”场景兜底 - 避免连接污染:每次 Connect 重置探测结果,重连成功后替换连接并关闭旧连接 - 打包脚本:create-dmg 增加 --sandbox-safe,避免构建时自动弹出/打开挂载窗口 - 产物格式:强制 --format UDZO,并将 rw.*.dmg/UDRW 中间产物转换为可分发 DMG - 校验门禁:增加 hdiutil verify,失败时保留 .app 便于排查,同时修正卷图标探测并补 ad-hoc 签名
350 lines
14 KiB
Bash
Executable File
350 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# 配置
|
||
APP_NAME="GoNavi"
|
||
DIST_DIR="dist"
|
||
BUILD_BIN_DIR="build/bin"
|
||
DEFAULT_BINARY_NAME="GoNavi" # 对应 wails.json 中的 outputfilename
|
||
|
||
# 提取版本号
|
||
VERSION=$(grep '"version":' frontend/package.json | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
|
||
if [ -z "$VERSION" ]; then
|
||
VERSION="0.0.0"
|
||
fi
|
||
echo "ℹ️ 检测到版本号: $VERSION"
|
||
LDFLAGS="-s -w -X GoNavi-Wails/internal/app.AppVersion=$VERSION"
|
||
|
||
# 颜色配置
|
||
GREEN='\033[0;32m'
|
||
RED='\033[0;31m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m'
|
||
|
||
MAC_VOLICON_PATH="build/darwin/icon.icns"
|
||
if [ ! -f "$MAC_VOLICON_PATH" ]; then
|
||
MAC_VOLICON_PATH=""
|
||
fi
|
||
|
||
echo -e "${GREEN}🚀 开始构建 $APP_NAME $VERSION...${NC}"
|
||
|
||
# 清理并创建输出目录
|
||
rm -rf $DIST_DIR
|
||
mkdir -p $DIST_DIR
|
||
|
||
# --- macOS ARM64 构建 ---
|
||
echo -e "${GREEN}🍎 正在构建 macOS (arm64)...${NC}"
|
||
wails build -platform darwin/arm64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
APP_SRC="$BUILD_BIN_DIR/$DEFAULT_BINARY_NAME.app"
|
||
APP_DEST_NAME="${APP_NAME}-${VERSION}-mac-arm64.app"
|
||
DMG_NAME="${APP_NAME}-${VERSION}-mac-arm64.dmg"
|
||
|
||
# 移动 .app 到 dist
|
||
mv "$APP_SRC" "$DIST_DIR/$APP_DEST_NAME"
|
||
|
||
# Ad-hoc 代码签名(无 Apple Developer 账号时防止 Gatekeeper 报已损坏)
|
||
echo " 🔏 正在对 .app 进行 ad-hoc 签名 (arm64)..."
|
||
codesign --force --deep --sign - "$DIST_DIR/$APP_DEST_NAME"
|
||
|
||
# 创建 DMG
|
||
if command -v create-dmg &> /dev/null; then
|
||
echo " 📦 正在打包 DMG (arm64)..."
|
||
# 移除已存在的 DMG (以防万一)
|
||
rm -f "$DIST_DIR/$DMG_NAME"
|
||
|
||
# --sandbox-safe 会跳过 Finder 的 AppleScript 排版,避免打包过程中弹出/打开挂载窗口(CI/本地静默打包更友好)。
|
||
CREATE_DMG_ARGS=(--volname "${APP_NAME} ${VERSION}" --format UDZO --sandbox-safe)
|
||
if [ -n "$MAC_VOLICON_PATH" ]; then
|
||
CREATE_DMG_ARGS+=(--volicon "$MAC_VOLICON_PATH")
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 未找到 macOS 卷图标 (build/darwin/icon.icns),跳过 --volicon。${NC}"
|
||
fi
|
||
|
||
create-dmg "${CREATE_DMG_ARGS[@]}" \
|
||
--window-pos 200 120 \
|
||
--window-size 800 400 \
|
||
--icon-size 100 \
|
||
--icon "$APP_DEST_NAME" 200 190 \
|
||
--hide-extension "$APP_DEST_NAME" \
|
||
--app-drop-link 600 185 \
|
||
"$DIST_DIR/$DMG_NAME" \
|
||
"$DIST_DIR/$APP_DEST_NAME"
|
||
|
||
CREATE_DMG_EXIT_CODE=$?
|
||
|
||
if [ $CREATE_DMG_EXIT_CODE -ne 0 ]; then
|
||
echo -e "${RED} ❌ create-dmg 执行失败 (exit=$CREATE_DMG_EXIT_CODE),保留 .app 以便排查。${NC}"
|
||
else
|
||
# create-dmg 可能会在失败时遗留 rw.*.dmg 中间产物;不要直接当作最终产物使用
|
||
if [ ! -f "$DIST_DIR/$DMG_NAME" ]; then
|
||
RW_FILE=$(find "$DIST_DIR" -maxdepth 1 -name "rw.*.dmg" -print -quit)
|
||
if [ -n "$RW_FILE" ]; then
|
||
echo -e "${YELLOW} ⚠️ 检测到 create-dmg 中间产物: $(basename "$RW_FILE"),正在转换为可分发 DMG...${NC}"
|
||
hdiutil convert "$RW_FILE" -format UDZO -o "$DIST_DIR/$DMG_NAME" >/dev/null 2>&1
|
||
rm -f "$RW_FILE"
|
||
fi
|
||
fi
|
||
|
||
# 防御性:即使生成了目标文件,也要确保不是 UDRW(UDRW 在 Finder 下可能表现为“已损坏/无法打开”)
|
||
if [ -f "$DIST_DIR/$DMG_NAME" ] && command -v hdiutil &> /dev/null; then
|
||
DMG_FORMAT=$(hdiutil imageinfo "$DIST_DIR/$DMG_NAME" 2>/dev/null | awk -F': ' '/^Format:/{print $2; exit}')
|
||
if [ "$DMG_FORMAT" = "UDRW" ]; then
|
||
echo -e "${YELLOW} ⚠️ 检测到 UDRW(可写原始映像),正在转换为 UDZO...${NC}"
|
||
TMP_UDZO="$DIST_DIR/.tmp.$DMG_NAME"
|
||
rm -f "$TMP_UDZO"
|
||
hdiutil convert "$DIST_DIR/$DMG_NAME" -format UDZO -o "$TMP_UDZO" >/dev/null 2>&1 && mv "$TMP_UDZO" "$DIST_DIR/$DMG_NAME"
|
||
fi
|
||
fi
|
||
|
||
if [ -f "$DIST_DIR/$DMG_NAME" ] && command -v hdiutil &> /dev/null; then
|
||
hdiutil verify "$DIST_DIR/$DMG_NAME" >/dev/null 2>&1
|
||
if [ $? -ne 0 ]; then
|
||
echo -e "${RED} ❌ DMG 校验失败,保留 .app 以便排查。${NC}"
|
||
else
|
||
# 删除中间的 .app 文件,保持目录整洁
|
||
rm -rf "$DIST_DIR/$APP_DEST_NAME"
|
||
echo " ✅ 已生成 $DMG_NAME"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ ! -f "$DIST_DIR/$DMG_NAME" ]; then
|
||
echo -e "${RED} ❌ DMG 生成失败,请检查 create-dmg 输出。${NC}"
|
||
fi
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 未找到 create-dmg 工具,跳过 DMG 打包,仅保留 .app。${NC}"
|
||
echo " 安装命令: brew install create-dmg"
|
||
fi
|
||
else
|
||
echo -e "${RED} ❌ macOS arm64 构建失败。${NC}"
|
||
fi
|
||
|
||
# --- macOS AMD64 构建 ---
|
||
echo -e "${GREEN}🍎 正在构建 macOS (amd64)...${NC}"
|
||
wails build -platform darwin/amd64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
APP_SRC="$BUILD_BIN_DIR/$DEFAULT_BINARY_NAME.app"
|
||
APP_DEST_NAME="${APP_NAME}-${VERSION}-mac-amd64.app"
|
||
DMG_NAME="${APP_NAME}-${VERSION}-mac-amd64.dmg"
|
||
|
||
mv "$APP_SRC" "$DIST_DIR/$APP_DEST_NAME"
|
||
|
||
# Ad-hoc 代码签名
|
||
echo " 🔏 正在对 .app 进行 ad-hoc 签名 (amd64)..."
|
||
codesign --force --deep --sign - "$DIST_DIR/$APP_DEST_NAME"
|
||
|
||
if command -v create-dmg &> /dev/null; then
|
||
echo " 📦 正在打包 DMG (amd64)..."
|
||
rm -f "$DIST_DIR/$DMG_NAME"
|
||
|
||
# --sandbox-safe 会跳过 Finder 的 AppleScript 排版,避免打包过程中弹出/打开挂载窗口(CI/本地静默打包更友好)。
|
||
CREATE_DMG_ARGS=(--volname "${APP_NAME} ${VERSION}" --format UDZO --sandbox-safe)
|
||
if [ -n "$MAC_VOLICON_PATH" ]; then
|
||
CREATE_DMG_ARGS+=(--volicon "$MAC_VOLICON_PATH")
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 未找到 macOS 卷图标 (build/darwin/icon.icns),跳过 --volicon。${NC}"
|
||
fi
|
||
|
||
create-dmg "${CREATE_DMG_ARGS[@]}" \
|
||
--window-pos 200 120 \
|
||
--window-size 800 400 \
|
||
--icon-size 100 \
|
||
--icon "$APP_DEST_NAME" 200 190 \
|
||
--hide-extension "$APP_DEST_NAME" \
|
||
--app-drop-link 600 185 \
|
||
"$DIST_DIR/$DMG_NAME" \
|
||
"$DIST_DIR/$APP_DEST_NAME"
|
||
|
||
CREATE_DMG_EXIT_CODE=$?
|
||
|
||
if [ $CREATE_DMG_EXIT_CODE -ne 0 ]; then
|
||
echo -e "${RED} ❌ create-dmg 执行失败 (exit=$CREATE_DMG_EXIT_CODE),保留 .app 以便排查。${NC}"
|
||
else
|
||
if [ ! -f "$DIST_DIR/$DMG_NAME" ]; then
|
||
RW_FILE=$(find "$DIST_DIR" -maxdepth 1 -name "rw.*.dmg" -print -quit)
|
||
if [ -n "$RW_FILE" ]; then
|
||
echo -e "${YELLOW} ⚠️ 检测到 create-dmg 中间产物: $(basename "$RW_FILE"),正在转换为可分发 DMG...${NC}"
|
||
hdiutil convert "$RW_FILE" -format UDZO -o "$DIST_DIR/$DMG_NAME" >/dev/null 2>&1
|
||
rm -f "$RW_FILE"
|
||
fi
|
||
fi
|
||
|
||
if [ -f "$DIST_DIR/$DMG_NAME" ] && command -v hdiutil &> /dev/null; then
|
||
DMG_FORMAT=$(hdiutil imageinfo "$DIST_DIR/$DMG_NAME" 2>/dev/null | awk -F': ' '/^Format:/{print $2; exit}')
|
||
if [ "$DMG_FORMAT" = "UDRW" ]; then
|
||
echo -e "${YELLOW} ⚠️ 检测到 UDRW(可写原始映像),正在转换为 UDZO...${NC}"
|
||
TMP_UDZO="$DIST_DIR/.tmp.$DMG_NAME"
|
||
rm -f "$TMP_UDZO"
|
||
hdiutil convert "$DIST_DIR/$DMG_NAME" -format UDZO -o "$TMP_UDZO" >/dev/null 2>&1 && mv "$TMP_UDZO" "$DIST_DIR/$DMG_NAME"
|
||
fi
|
||
fi
|
||
|
||
if [ -f "$DIST_DIR/$DMG_NAME" ] && command -v hdiutil &> /dev/null; then
|
||
hdiutil verify "$DIST_DIR/$DMG_NAME" >/dev/null 2>&1
|
||
if [ $? -ne 0 ]; then
|
||
echo -e "${RED} ❌ DMG 校验失败,保留 .app 以便排查。${NC}"
|
||
else
|
||
rm -rf "$DIST_DIR/$APP_DEST_NAME"
|
||
echo " ✅ 已生成 $DMG_NAME"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ ! -f "$DIST_DIR/$DMG_NAME" ]; then
|
||
echo -e "${RED} ❌ DMG 生成失败。${NC}"
|
||
fi
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 未找到 create-dmg 工具。${NC}"
|
||
fi
|
||
else
|
||
echo -e "${RED} ❌ macOS amd64 构建失败。${NC}"
|
||
fi
|
||
|
||
# --- Windows AMD64 构建 ---
|
||
echo -e "${GREEN}🪟 正在构建 Windows (amd64)...${NC}"
|
||
if command -v x86_64-w64-mingw32-gcc &> /dev/null; then
|
||
wails build -platform windows/amd64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}.exe" "$DIST_DIR/${APP_NAME}-${VERSION}-windows-amd64.exe"
|
||
echo " ✅ 已生成 ${APP_NAME}-${VERSION}-windows-amd64.exe"
|
||
else
|
||
echo -e "${RED} ❌ Windows amd64 构建失败。${NC}"
|
||
fi
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 未找到 MinGW 工具 (x86_64-w64-mingw32-gcc),跳过 Windows amd64 构建。${NC}"
|
||
fi
|
||
|
||
# --- Windows ARM64 构建 ---
|
||
echo -e "${GREEN}🪟 正在构建 Windows (arm64)...${NC}"
|
||
if command -v aarch64-w64-mingw32-gcc &> /dev/null; then
|
||
wails build -platform windows/arm64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}.exe" "$DIST_DIR/${APP_NAME}-${VERSION}-windows-arm64.exe"
|
||
echo " ✅ 已生成 ${APP_NAME}-${VERSION}-windows-arm64.exe"
|
||
else
|
||
echo -e "${RED} ❌ Windows arm64 构建失败。${NC}"
|
||
fi
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 未找到 MinGW ARM64 工具 (aarch64-w64-mingw32-gcc),跳过 Windows arm64 构建。${NC}"
|
||
echo " 安装命令: brew install mingw-w64 (需要支持 ARM64 的版本)"
|
||
fi
|
||
|
||
# --- Linux AMD64 构建 ---
|
||
echo -e "${GREEN}🐧 正在构建 Linux (amd64)...${NC}"
|
||
# 检测当前系统
|
||
CURRENT_OS=$(uname -s)
|
||
CURRENT_ARCH=$(uname -m)
|
||
|
||
if [ "$CURRENT_OS" = "Linux" ] && [ "$CURRENT_ARCH" = "x86_64" ]; then
|
||
# 本机 Linux amd64,直接构建
|
||
wails build -platform linux/amd64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64"
|
||
chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64"
|
||
# 打包为 tar.gz
|
||
cd "$DIST_DIR"
|
||
tar -czvf "${APP_NAME}-${VERSION}-linux-amd64.tar.gz" "${APP_NAME}-${VERSION}-linux-amd64"
|
||
rm "${APP_NAME}-${VERSION}-linux-amd64"
|
||
cd ..
|
||
echo " ✅ 已生成 ${APP_NAME}-${VERSION}-linux-amd64.tar.gz"
|
||
else
|
||
echo -e "${RED} ❌ Linux amd64 构建失败。${NC}"
|
||
fi
|
||
elif command -v x86_64-linux-gnu-gcc &> /dev/null; then
|
||
# macOS 或其他系统,尝试交叉编译
|
||
export CC=x86_64-linux-gnu-gcc
|
||
export CXX=x86_64-linux-gnu-g++
|
||
export CGO_ENABLED=1
|
||
wails build -platform linux/amd64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64"
|
||
chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64"
|
||
cd "$DIST_DIR"
|
||
tar -czvf "${APP_NAME}-${VERSION}-linux-amd64.tar.gz" "${APP_NAME}-${VERSION}-linux-amd64"
|
||
rm "${APP_NAME}-${VERSION}-linux-amd64"
|
||
cd ..
|
||
echo " ✅ 已生成 ${APP_NAME}-${VERSION}-linux-amd64.tar.gz"
|
||
else
|
||
echo -e "${RED} ❌ Linux amd64 交叉编译失败。${NC}"
|
||
fi
|
||
unset CC CXX CGO_ENABLED
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 非 Linux 系统且未找到交叉编译工具,跳过 Linux amd64 构建。${NC}"
|
||
echo " 在 Linux 上运行此脚本可直接构建,或安装交叉编译工具链。"
|
||
fi
|
||
|
||
# --- Linux ARM64 构建 ---
|
||
echo -e "${GREEN}🐧 正在构建 Linux (arm64)...${NC}"
|
||
if [ "$CURRENT_OS" = "Linux" ] && [ "$CURRENT_ARCH" = "aarch64" ]; then
|
||
# 本机 Linux arm64,直接构建
|
||
wails build -platform linux/arm64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64"
|
||
chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64"
|
||
cd "$DIST_DIR"
|
||
tar -czvf "${APP_NAME}-${VERSION}-linux-arm64.tar.gz" "${APP_NAME}-${VERSION}-linux-arm64"
|
||
rm "${APP_NAME}-${VERSION}-linux-arm64"
|
||
cd ..
|
||
echo " ✅ 已生成 ${APP_NAME}-${VERSION}-linux-arm64.tar.gz"
|
||
else
|
||
echo -e "${RED} ❌ Linux arm64 构建失败。${NC}"
|
||
fi
|
||
elif command -v aarch64-linux-gnu-gcc &> /dev/null; then
|
||
# 交叉编译
|
||
export CC=aarch64-linux-gnu-gcc
|
||
export CXX=aarch64-linux-gnu-g++
|
||
export CGO_ENABLED=1
|
||
wails build -platform linux/arm64 -clean -ldflags "$LDFLAGS"
|
||
if [ $? -eq 0 ]; then
|
||
mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64"
|
||
chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64"
|
||
cd "$DIST_DIR"
|
||
tar -czvf "${APP_NAME}-${VERSION}-linux-arm64.tar.gz" "${APP_NAME}-${VERSION}-linux-arm64"
|
||
rm "${APP_NAME}-${VERSION}-linux-arm64"
|
||
cd ..
|
||
echo " ✅ 已生成 ${APP_NAME}-${VERSION}-linux-arm64.tar.gz"
|
||
else
|
||
echo -e "${RED} ❌ Linux arm64 交叉编译失败。${NC}"
|
||
fi
|
||
unset CC CXX CGO_ENABLED
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 非 Linux ARM64 系统且未找到交叉编译工具,跳过 Linux arm64 构建。${NC}"
|
||
echo " 安装命令 (Ubuntu): sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu"
|
||
echo " 安装命令 (macOS): brew install aarch64-linux-gnu-gcc (需要第三方 tap)"
|
||
fi
|
||
|
||
# 清理中间构建目录
|
||
rm -rf "build/bin"
|
||
|
||
echo -e "${GREEN}🔐 生成 SHA256SUMS...${NC}"
|
||
if command -v sha256sum &> /dev/null; then
|
||
cd "$DIST_DIR"
|
||
: > SHA256SUMS
|
||
for f in *; do
|
||
[ -f "$f" ] || continue
|
||
sha256sum "$f" >> SHA256SUMS
|
||
done
|
||
cd ..
|
||
elif command -v shasum &> /dev/null; then
|
||
cd "$DIST_DIR"
|
||
: > SHA256SUMS
|
||
for f in *; do
|
||
[ -f "$f" ] || continue
|
||
shasum -a 256 "$f" >> SHA256SUMS
|
||
done
|
||
cd ..
|
||
else
|
||
echo -e "${YELLOW} ⚠️ 未找到 sha256sum/shasum,跳过校验文件生成。${NC}"
|
||
fi
|
||
|
||
echo ""
|
||
echo -e "${GREEN}🎉 所有任务完成!构建产物在 'dist/' 目录下:${NC}"
|
||
ls -lh "$DIST_DIR"
|
||
echo ""
|
||
echo -e "${GREEN}📋 支持的平台:${NC}"
|
||
echo " • macOS (Intel/Apple Silicon): .dmg"
|
||
echo " • Windows (x64/ARM64): .exe"
|
||
echo " • Linux (x64/ARM64): .tar.gz"
|
||
echo ""
|
||
echo -e "${YELLOW}💡 提示:Linux AppImage 包请使用 GitHub Actions CI/CD 构建。${NC}"
|