117 lines
4.8 KiB
Bash
Executable File
117 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 打包 macOS 完整客户端(登录 → 选人 → 进游戏)。
|
||
#
|
||
# ./build-macos-client.sh [debug|release]
|
||
#
|
||
# 产物:build/export/mtgodot-poc.app(40250 Client/pack 和 BGM 自包含)。
|
||
# 依赖:Godot 4.7.1 的 macOS 导出模板(editor 里 “管理导出模板” 装,或放
|
||
# ~/Library/Application Support/Godot/export_templates/4.7.1.stable/macos.zip)。
|
||
set -euo pipefail
|
||
cd "$(dirname "$0")"
|
||
REPO="$(pwd)"
|
||
SOURCE_CLIENT="${MT_40250_CLIENT:-$REPO/Client}"
|
||
if [ ! -f "$SOURCE_CLIENT/pack/Index" ] && [ -f "$REPO/../40250/Server Client TMP4/Client/pack/Index" ]; then
|
||
SOURCE_CLIENT="$REPO/../40250/Server Client TMP4/Client"
|
||
fi
|
||
CFG="${1:-debug}"
|
||
OUT="${MT_MAC_OUTPUT_DIR:-$REPO/build/export}"
|
||
APP="$OUT/mtgodot-poc.app"
|
||
GODOT="${GODOT:-godot}"
|
||
MAC_ARCHES="${MT_MAC_ARCHES:-universal}"
|
||
ENGINE_OVERRIDE="${MT_MAC_ENGINE:-}"
|
||
test -f "$SOURCE_CLIENT/pack/Index" || {
|
||
echo "错误:缺少 40250 Client/pack/Index:$SOURCE_CLIENT" >&2
|
||
exit 1
|
||
}
|
||
if [ -n "$ENGINE_OVERRIDE" ]; then
|
||
test -x "$ENGINE_OVERRIDE"
|
||
ENGINE_INFO="$(lipo -info "$ENGINE_OVERRIDE")"
|
||
case "$MAC_ARCHES:$ENGINE_INFO" in
|
||
universal:*x86_64*arm64*|universal:*arm64*x86_64*|arm64:*arm64*|x86_64:*x86_64*) ;;
|
||
*) echo "错误:自定义引擎架构不匹配:$ENGINE_INFO" >&2; exit 1 ;;
|
||
esac
|
||
echo "自定义引擎:$ENGINE_OVERRIDE"
|
||
"$ENGINE_OVERRIDE" --version
|
||
fi
|
||
BUILD_TYPE="Debug"
|
||
if [ "$CFG" = release ]; then
|
||
BUILD_TYPE="Release"
|
||
fi
|
||
|
||
echo "== 1. GDExtension .dylib =="
|
||
if [ "$MAC_ARCHES" = universal ]; then
|
||
CMAKE_ARCHES="arm64;x86_64"
|
||
else
|
||
CMAKE_ARCHES="$MAC_ARCHES"
|
||
fi
|
||
cmake -S . -B build -DCMAKE_BUILD_TYPE="$BUILD_TYPE" -DCMAKE_OSX_ARCHITECTURES="$CMAKE_ARCHES"
|
||
cmake --build build --target mtgodot -j8
|
||
DYLIB="project/bin/libmtgodot.macos.template_${CFG}.dylib"
|
||
if [ ! -f "$DYLIB" ]; then
|
||
# CMake 目前只出 debug 名;release 就复用它
|
||
cp -f project/bin/libmtgodot.macos.template_debug.dylib "$DYLIB"
|
||
fi
|
||
if [ "$MAC_ARCHES" = universal ]; then
|
||
LIPO_INFO="$(lipo -info "$DYLIB")"
|
||
case "$LIPO_INFO" in
|
||
*x86_64*arm64*|*arm64*x86_64*) ;;
|
||
*) echo "错误:GDExtension 不是 universal:$LIPO_INFO" >&2; exit 1 ;;
|
||
esac
|
||
fi
|
||
|
||
echo "== 2. 导出 =="
|
||
mkdir -p "$OUT"
|
||
if [ "$CFG" = release ]; then
|
||
"$GODOT" --headless --path project --export-release macOS "$APP"
|
||
else
|
||
"$GODOT" --headless --path project --export-debug macOS "$APP"
|
||
fi
|
||
|
||
echo "== 3. 40250 资源(自包含)=="
|
||
BUNDLE_CLIENT="$APP/Contents/Resources/40250/Client"
|
||
mkdir -p "$BUNDLE_CLIENT"
|
||
ditto "$SOURCE_CLIENT/pack" "$BUNDLE_CLIENT/pack"
|
||
if [ -d "$SOURCE_CLIENT/BGM" ]; then ditto "$SOURCE_CLIENT/BGM" "$BUNDLE_CLIENT/BGM"; fi
|
||
if [ -f "$SOURCE_CLIENT/locale.cfg" ]; then cp "$SOURCE_CLIENT/locale.cfg" "$BUNDLE_CLIENT/locale.cfg"; fi
|
||
if [ -d "$SOURCE_CLIENT/sound" ]; then
|
||
ditto "$SOURCE_CLIENT/sound" "$BUNDLE_CLIENT/sound"
|
||
elif [ -d "$REPO/assets/Sound/sound" ]; then
|
||
ditto "$REPO/assets/Sound/sound" "$BUNDLE_CLIENT/sound"
|
||
fi
|
||
test -s "$BUNDLE_CLIENT/pack/Index"
|
||
|
||
# Record the exact source revision inside the signed bundle. A Beta release is built only
|
||
# after its changes are committed, so the identity remains useful when the checkout moves on.
|
||
python3 - "$REPO" "$APP/Contents/Resources/beta-build.json" <<'PY'
|
||
import json, pathlib, subprocess, sys
|
||
repo, output = sys.argv[1:]
|
||
commit = subprocess.check_output(['git', '-C', repo, 'rev-parse', 'HEAD'], text=True).strip()
|
||
dirty = bool(subprocess.check_output(['git', '-C', repo, 'status', '--porcelain', '--untracked-files=normal'], text=True).strip())
|
||
pathlib.Path(output).write_text(json.dumps({'source_commit': commit, 'source_dirty': dirty}, indent=2) + '\n')
|
||
PY
|
||
|
||
echo "== 4. 签名(默认 ad-hoc;CODESIGN_IDENTITY 可切正式证书)=="
|
||
if [ -n "$ENGINE_OVERRIDE" ]; then
|
||
cp "$ENGINE_OVERRIDE" "$APP/Contents/MacOS/mtgodot-poc"
|
||
fi
|
||
CODESIGN_IDENTITY="${CODESIGN_IDENTITY:--}"
|
||
ENTITLEMENTS="$REPO/macos.entitlements"
|
||
test -f "$ENTITLEMENTS"
|
||
|
||
# The exported Godot executable loads the GDExtension from Contents/Frameworks.
|
||
# Because this package uses hardened runtime, the main executable must carry
|
||
# disable-library-validation or macOS rejects the ad-hoc/formally signed dylib
|
||
# at runtime even when the bundle passes a static codesign verification.
|
||
find "$APP/Contents/Frameworks" -type f \( -name '*.dylib' -o -name '*.so' \) -exec \
|
||
codesign --force --options runtime --timestamp=none --sign "$CODESIGN_IDENTITY" {} \;
|
||
codesign --force --options runtime --timestamp=none --entitlements "$ENTITLEMENTS" \
|
||
--sign "$CODESIGN_IDENTITY" "$APP/Contents/MacOS/mtgodot-poc"
|
||
codesign --force --options runtime --timestamp=none --entitlements "$ENTITLEMENTS" \
|
||
--sign "$CODESIGN_IDENTITY" "$APP"
|
||
xattr -dr com.apple.quarantine "$APP" 2>/dev/null || true
|
||
|
||
echo
|
||
echo "OK -> $APP"
|
||
echo "跑: open '$APP'"
|
||
echo "开发覆盖资源:MT_ASSETS='$REPO/assets' '$APP/Contents/MacOS/mtgodot-poc'"
|