Files
strawberry/build_tools/macos/make_universal_app.sh
David Helkowski bea094cbf1
Some checks failed
Build / Build openSUSE (leap:15.6) (push) Has been cancelled
Build / Build openSUSE (leap:16.0) (push) Has been cancelled
Build / Build openSUSE (tumbleweed) (push) Has been cancelled
Build / Build Fedora (42) (push) Has been cancelled
Build / Build Fedora (43) (push) Has been cancelled
Build / Build Fedora (44) (push) Has been cancelled
Build / Build OpenMandriva (cooker) (push) Has been cancelled
Build / Build Mageia (9) (push) Has been cancelled
Build / Build Debian (bookworm) (push) Has been cancelled
Build / Build Debian (forky) (push) Has been cancelled
Build / Build Debian (trixie) (push) Has been cancelled
Build / Build Ubuntu (noble) (push) Has been cancelled
Build / Build Ubuntu (questing) (push) Has been cancelled
Build / Build Ubuntu (resolute) (push) Has been cancelled
Build / Upload Ubuntu PPA (noble) (push) Has been cancelled
Build / Upload Ubuntu PPA (questing) (push) Has been cancelled
Build / Upload Ubuntu PPA (resolute) (push) Has been cancelled
Build / Build FreeBSD (push) Has been cancelled
Build / Build OpenBSD (push) Has been cancelled
Build / Build macOS Public (release, macos-15) (push) Has been cancelled
Build / Build macOS Public (release, macos-15-intel) (push) Has been cancelled
Build / Build macOS Private (release, macos-arm64) (push) Has been cancelled
Build / Build Windows MinGW (i686, debug) (push) Has been cancelled
Build / Build Windows MinGW (i686, release) (push) Has been cancelled
Build / Build Windows MinGW (x86_64, debug) (push) Has been cancelled
Build / Build Windows MinGW (x86_64, release) (push) Has been cancelled
Build / Build Windows MSVC (arm64, debug, arm64 debug, windows-11-arm) (push) Has been cancelled
Build / Build Windows MSVC (arm64, release, arm64 release, windows-11-arm) (push) Has been cancelled
Build / Build Windows MSVC (x86, debug, x86 debug, windows-2022) (push) Has been cancelled
Build / Build Windows MSVC (x86, release, x86 release, windows-2022) (push) Has been cancelled
Build / Build Windows MSVC (x86_64, debug, x86_64 debug, windows-2022) (push) Has been cancelled
Build / Build Windows MSVC (x86_64, release, x86_64 release, windows-2022) (push) Has been cancelled
Build / Upload (push) Has been cancelled
Build / Attach to release (push) Has been cancelled
Add architecture guidance for Mac App Store submissions in README_MAS.md
This commit enhances the `README_MAS.md` by providing detailed information on the differences between arm64-only, universal, and x86_64-only app architectures for Mac App Store uploads. It includes recommendations for achieving broad compatibility and clarifies the limitations of submitting multiple builds. This update aims to assist developers in making informed decisions regarding app architecture for their submissions.
2026-01-22 23:37:30 +09:00

171 lines
4.8 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# Create a universal (arm64+x86_64) .app by merging two already-deployed app bundles
# that have identical layouts, one built on Apple Silicon and one built on Intel.
#
# Usage:
# ./build_tools/macos/make_universal_app.sh \
# --arm-app /path/to/arm64/strawberry.app \
# --x86-app /path/to/x86_64/strawberry.app \
# --out-app /path/to/output/strawberry.app \
# [--clean]
#
# Notes:
# - Do NOT sign the per-arch apps first; signatures will be invalidated by lipo anyway.
# - Both inputs must be the same app version/config with the same enabled features,
# so the file lists match.
ts() { date +"%H:%M:%S"; }
usage() {
cat <<'EOF'
Usage:
./build_tools/macos/make_universal_app.sh --arm-app <path> --x86-app <path> --out-app <path> [--clean]
What it does:
- Copies the arm64 app to --out-app
- For every Mach-O file in the copied app, finds the corresponding file in the x86_64 app
- Uses lipo to combine the two slices into a universal binary at the same relative path
Required:
--arm-app <path> Path to arm64 Strawberry.app (built+deployed on Apple Silicon)
--x86-app <path> Path to x86_64 Strawberry.app (built+deployed on Intel)
--out-app <path> Output path for universal Strawberry.app
Optional:
--clean Delete --out-app if it already exists
EOF
}
if [[ "$(uname -s)" != "Darwin" ]]; then
echo "Error: This script is for macOS only." >&2
exit 1
fi
arm_app=""
x86_app=""
out_app=""
do_clean=0
while [[ $# -gt 0 ]]; do
case "$1" in
--arm-app) arm_app="${2:-}"; shift 2 ;;
--x86-app) x86_app="${2:-}"; shift 2 ;;
--out-app) out_app="${2:-}"; shift 2 ;;
--clean) do_clean=1; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown arg: $1" >&2; usage; exit 2 ;;
esac
done
if [[ -z "$arm_app" || -z "$x86_app" || -z "$out_app" ]]; then
echo "Error: missing required args." >&2
usage
exit 2
fi
if [[ ! -d "$arm_app" ]]; then
echo "Error: --arm-app not found: $arm_app" >&2
exit 2
fi
if [[ ! -d "$x86_app" ]]; then
echo "Error: --x86-app not found: $x86_app" >&2
exit 2
fi
for cmd in /usr/bin/file /usr/bin/lipo /usr/bin/ditto; do
if [[ ! -x "$cmd" ]]; then
echo "Error: required tool not found: $cmd" >&2
exit 1
fi
done
out_parent="$(cd -- "$(dirname -- "$out_app")" && pwd)"
out_name="$(basename -- "$out_app")"
out_app="${out_parent}/${out_name}"
if [[ -e "$out_app" && "$do_clean" -eq 1 ]]; then
echo "==> [$(ts)] Removing existing output app: $out_app"
rm -rf "$out_app"
fi
if [[ -e "$out_app" ]]; then
echo "Error: output already exists: $out_app (use --clean to overwrite)" >&2
exit 2
fi
echo "==> [$(ts)] Copying arm64 app to output"
/usr/bin/ditto "$arm_app" "$out_app"
# Remove any existing signatures in the copied app; we'll re-sign after creating universal binaries.
echo "==> [$(ts)] Removing existing code signature metadata (will be re-signed later)"
find "$out_app" -type d -name "_CodeSignature" -print0 2>/dev/null | while IFS= read -r -d '' d; do
rm -rf "$d" || true
done
echo "==> [$(ts)] Merging Mach-O files with lipo"
merged=0
skipped=0
# Traverse output app and lipo-merge any Mach-O file with its counterpart in the x86 app.
while IFS= read -r -d '' f; do
# Only operate on regular files.
if [[ ! -f "$f" ]]; then
continue
fi
ft="$(/usr/bin/file -b "$f" 2>/dev/null || true)"
if [[ "$ft" != *"Mach-O"* ]]; then
skipped=$((skipped + 1))
continue
fi
rel="${f#"$out_app"/}"
other="${x86_app}/${rel}"
if [[ ! -f "$other" ]]; then
echo "Error: missing matching file in x86 app for:" >&2
echo " $rel" >&2
echo "Expected at:" >&2
echo " $other" >&2
exit 1
fi
other_ft="$(/usr/bin/file -b "$other" 2>/dev/null || true)"
if [[ "$other_ft" != *"Mach-O"* ]]; then
echo "Error: file is Mach-O in arm app but not Mach-O in x86 app:" >&2
echo " $rel" >&2
echo "arm64: $ft" >&2
echo "x86_64: $other_ft" >&2
exit 1
fi
# Validate architectures.
arm_archs="$(/usr/bin/lipo -archs "$f" 2>/dev/null || true)"
x86_archs="$(/usr/bin/lipo -archs "$other" 2>/dev/null || true)"
if [[ "$arm_archs" != *"arm64"* ]]; then
echo "Error: expected arm64 slice in arm app file:" >&2
echo " $rel" >&2
echo " archs: $arm_archs" >&2
exit 1
fi
if [[ "$x86_archs" != *"x86_64"* ]]; then
echo "Error: expected x86_64 slice in x86 app file:" >&2
echo " $rel" >&2
echo " archs: $x86_archs" >&2
exit 1
fi
tmp="$(mktemp -t strawberry-universal.XXXXXX)"
/usr/bin/lipo -create "$f" "$other" -output "$tmp"
chmod --reference="$f" "$tmp" 2>/dev/null || true
mv -f "$tmp" "$f"
merged=$((merged + 1))
done < <(find "$out_app" -type f -print0 2>/dev/null)
echo "==> [$(ts)] Done"
echo "Merged Mach-O files: $merged"
echo "Non-Mach-O files skipped: $skipped"
echo "Output app:"
echo " $out_app"