summaryrefslogtreecommitdiff
path: root/site/macos-app.sh
blob: e7b9bc360860ab3b323e14b39d8b957956b8e4b9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/bin/sh
# Builds Rookery.app for macOS without a Mac: a macOS Java runtime made by jlink from the macOS JDK's
# jmods, the universal jar, an Info.plist and a small launcher. It is not signed or notarized.
#   usage: site/macos-app.sh <version> [dir holding aarch64/ and x64/ macOS JDKs (jmods only is enough)]
set -eu

root=$(cd "$(dirname "$0")/.." && pwd)
version=${1:?usage: macos-app.sh <version> [jdk dir]}
jdks=${2:-/opt/macjdk}
jar=$root/desktop/build/libs/rookery-universal.jar
out=$root/desktop/build/macos

# Use the same modules the desktop build decided the app needs (Compose records them in the runtime's release file).
release=$(ls "$root"/desktop/build/compose/binaries/main/app/rookery/lib/runtime/release \
             "$root"/desktop/build/compose/binaries/main/app/rookery.app/Contents/runtime/Contents/Home/release 2>/dev/null | head -1)
modules=$(sed -n 's/^MODULES="\(.*\)"/\1/p' "$release" | tr ' ' ',')
[ -n "$modules" ] || { echo "no module list in $release" >&2; exit 1; }

work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT
mkdir -p "$out"

for pair in aarch64:arm64 x64:x64; do
  jdk=${pair%%:*}; name=${pair##*:}
  app=$work/$name/Rookery.app
  mkdir -p "$app/Contents/MacOS" "$app/Contents/Resources" "$app/Contents/app"

  cp "$root/site/assets/rookery.icns" "$app/Contents/Resources/rookery.icns"
  jlink --module-path "$jdks/$jdk/Contents/Home/jmods" --add-modules "$modules" \
        --strip-java-debug-attributes --no-header-files --no-man-pages --compress zip-6 --output "$app/Contents/runtime"
  cp "$jar" "$app/Contents/app/rookery.jar"
  # the universal jar carries every platform's graphics library; this app only needs its own
  case $name in arm64) other=x64 ;; *) other=arm64 ;; esac
  zip -qd "$app/Contents/app/rookery.jar" 'libskiko-linux-*' 'skiko-windows-*' "libskiko-macos-$other*" > /dev/null || true

  cat > "$app/Contents/MacOS/rookery" <<'LAUNCHER'
#!/bin/sh
here=$(cd "$(dirname "$0")/.." && pwd)
exec "$here/runtime/bin/java" -Xdock:name=Rookery -Xmx256m -XX:+UseSerialGC -jar "$here/app/rookery.jar" "$@"
LAUNCHER
  chmod +x "$app/Contents/MacOS/rookery"

  cat > "$app/Contents/Info.plist" <<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>CFBundleName</key><string>Rookery</string>
  <key>CFBundleDisplayName</key><string>Rookery</string>
  <key>CFBundleIdentifier</key><string>coffee.liz.rookery</string>
  <key>CFBundleExecutable</key><string>rookery</string>
  <key>CFBundlePackageType</key><string>APPL</string>
  <key>CFBundleIconFile</key><string>rookery</string>
  <key>CFBundleShortVersionString</key><string>$version</string>
  <key>CFBundleVersion</key><string>$version</string>
  <key>LSMinimumSystemVersion</key><string>11.0</string>
  <key>NSHighResolutionCapable</key><true/>
  <key>NSBluetoothAlwaysUsageDescription</key><string>Connects to your smart cube.</string>
  <key>NSMicrophoneUsageDescription</key><string>Listens to a stackmat timer on an audio input.</string>
</dict>
</plist>
PLIST

  rm -f "$out/rookery-macos-$name.zip"
  (cd "$work/$name" && zip -qry "$out/rookery-macos-$name.zip" Rookery.app)
  echo "macos: rookery-macos-$name.zip $(du -h "$out/rookery-macos-$name.zip" | cut -f1)"
done