Files
endorphin-tessera-gui/scripts/build-macos-app.sh
T

43 lines
2.5 KiB
Bash
Executable File

#!/bin/sh
# macOS 应用打包入口:构建 release 可执行文件并组装最小 Tessera.app;脚本本身不运行测试或部署。
# 执行会产生构建产物,应在已确认的 macOS 构建环境中调用。
# 任一命令失败或使用未定义变量即退出,避免在失败编译后继续打包旧文件。
set -eu
# 此入口只能在 macOS 使用;构建授权由调用方确认,脚本不自动执行测试或部署。
if [ "$(uname -s)" != Darwin ]; then
echo "Build this app bundle on macOS." >&2
exit 1
fi
# 以脚本所在目录的父目录作为仓库根;清空这一次 cd 的 CDPATH,防止用户 shell 配置改变目录解析。
cd "$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
# 锁定依赖并生成 release 可执行文件;附加参数原样交给 Cargo。
cargo build --release --locked "$@"
# 从 Cargo 包元数据读取首个 version 值,空值由 test 拒绝,不生成缺版本的 bundle。
version=$(awk -F '"' '$1 ~ /^version[[:space:]]*=/ { print $2; exit }' Cargo.toml)
test -n "$version"
# macOS bundle 约定:Contents/MacOS 保存入口二进制,Contents/Info.plist 保存系统识别信息。
bundle="$(pwd)/target/release/Tessera.app"
mkdir -p "$bundle/Contents/MacOS"
# 先写临时文件再重命名,避免复制途中将半个二进制留作 bundle 的主程序。
cp target/release/tessera "$bundle/Contents/MacOS/tessera.new"
mv -f "$bundle/Contents/MacOS/tessera.new" "$bundle/Contents/MacOS/tessera"
# 生成最小 macOS bundle 元数据;应用名、入口与高分辨率标志供系统启动/显示使用。
cat > "$bundle/Contents/Info.plist.new" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>CFBundleIdentifier</key><string>com.entroia.tessera</string>
<key>CFBundleName</key><string>Tessera</string>
<key>CFBundleDisplayName</key><string>Tessera</string>
<key>CFBundleExecutable</key><string>tessera</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleShortVersionString</key><string>$version</string>
<key>CFBundleVersion</key><string>$version</string>
<key>NSHighResolutionCapable</key><true/>
</dict></plist>
PLIST
# 元数据完整写入后再替换正式文件;这只是单文件替换,不表示整个 bundle 的构建具有事务回滚。
mv -f "$bundle/Contents/Info.plist.new" "$bundle/Contents/Info.plist"
# 标准输出返回最终 app 路径,便于构建调用方定位产物。
printf '%s\n' "$bundle"