tg-ws-proxy/packaging/build_macos_universal.sh

99 lines
2.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BUILD_DIR="$ROOT_DIR/build/macos"
ICONSET_DIR="$BUILD_DIR/TgWsProxy.iconset"
ICNS_PATH="$BUILD_DIR/TgWsProxy.icns"
APP_PATH="$ROOT_DIR/dist/TgWsProxy.app"
BIN_PATH="$APP_PATH/Contents/MacOS/TgWsProxy"
ZIP_PATH="$ROOT_DIR/dist/TgWsProxy-macos-universal.zip"
VENV_DIR="$ROOT_DIR/.venv-macos-build"
PYTHON_BIN="${PYTHON_BIN:-python3}"
PYTHON_EXE="$("$PYTHON_BIN" -c 'import sys; print(sys.executable)')"
if [[ "$(uname -s)" == "Darwin" ]] && ! file "$PYTHON_EXE" | grep -q "universal binary"; then
if file /usr/bin/python3 | grep -q "universal binary"; then
PYTHON_BIN="/usr/bin/python3"
PYTHON_EXE="/usr/bin/python3"
fi
fi
mkdir -p "$BUILD_DIR"
rm -rf "$VENV_DIR"
"$PYTHON_BIN" -m venv "$VENV_DIR"
source "$VENV_DIR/bin/activate"
if [[ "$(uname -s)" == "Darwin" ]]; then
export ARCHFLAGS="-arch arm64 -arch x86_64"
export CFLAGS="$ARCHFLAGS"
export LDFLAGS="$ARCHFLAGS"
export MACOSX_DEPLOYMENT_TARGET=11.0
export _PYTHON_HOST_PLATFORM="macosx-11.0-universal2"
export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"
fi
echo "Using build Python: $(python --version) [$PYTHON_EXE]"
python -m pip install --upgrade pip
python -m pip install \
--no-binary cffi,Pillow,psutil \
-r "$ROOT_DIR/requirements.txt" \
"pyinstaller==6.13.0"
if command -v iconutil >/dev/null 2>&1; then
if [[ ! -d "$ICONSET_DIR" || -z "$(find "$ICONSET_DIR" -maxdepth 1 -name '*.png' -print -quit 2>/dev/null)" ]]; then
if [[ ! -f "$ROOT_DIR/icon.ico" ]]; then
echo "Missing icon source: $ROOT_DIR/icon.ico" >&2
exit 1
fi
rm -rf "$ICONSET_DIR"
mkdir -p "$ICONSET_DIR"
python3 - "$ROOT_DIR/icon.ico" "$ICONSET_DIR" <<'PY'
from pathlib import Path
import sys
from PIL import Image
src = Path(sys.argv[1])
iconset = Path(sys.argv[2])
img = Image.open(src).convert("RGBA")
for base in (16, 32, 128, 256, 512):
for scale in (1, 2):
size = base * scale
resized = img.resize((size, size), Image.LANCZOS)
suffix = "" if scale == 1 else "@2x"
resized.save(iconset / f"icon_{base}x{base}{suffix}.png")
PY
fi
iconutil -c icns "$ICONSET_DIR" -o "$ICNS_PATH"
fi
rm -rf "$ROOT_DIR/build/pyinstaller" "$ROOT_DIR/dist"
pyinstaller "$ROOT_DIR/packaging/macos.spec" \
--noconfirm \
--clean \
--workpath "$ROOT_DIR/build/pyinstaller"
if [[ ! -f "$BIN_PATH" ]]; then
echo "Missing app binary: $BIN_PATH" >&2
exit 1
fi
ARCHS="$(lipo -archs "$BIN_PATH")"
echo "Built architectures: $ARCHS"
if [[ "$ARCHS" != *"x86_64"* ]] || [[ "$ARCHS" != *"arm64"* ]]; then
echo "Expected a universal binary containing x86_64 and arm64" >&2
exit 1
fi
codesign --force --deep --sign - "$APP_PATH"
codesign --verify --deep --strict "$APP_PATH"
spctl --assess --type execute "$APP_PATH" || true
rm -f "$ZIP_PATH"
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
echo "Built app: $APP_PATH"
echo "Built zip: $ZIP_PATH"