HOWTO-Release/macOS release package
The main macOS release package is created using the following steps:
- Build single-arch bundle in the normal way for the desired architectures.
- Create a universal bundle from those.
- Create the disk image.
- Sign and notarize using the Apple Developer certificate.
- Generate the Sparkle signatures for the app cast file.
Compile ScummVM
x86_64 build that targets macOS 10.13
export LDFLAGS="-arch=x86_64 -mmacosx-version-min=10.13"
export CXXFLAGS="-arch=x86_64 -mmacosx-version-min=10.13"
export CPPFLAGS="-arch=x86_64 -mmacosx-version-min=10.13"
export CFLAGS="-arch=x86_64 -mmacosx-version-min=10.13"
./configure --enable-release --with-staticlib-prefix=/path/to/scummvm-libs-x86_64 --enable-updates --with-sparkle-prefix=/path/to/Sparkle-2.6.4
make -j8
make osxsnap
arm64 build that targets macOS 11.0
export LDFLAGS="-arch=arm64 -mmacosx-version-min=11.0"
export CXXFLAGS="-arch=arm64 -mmacosx-version-min=11.0"
export CPPFLAGS="-arch=arm64 -mmacosx-version-min=11.0"
export CFLAGS="-arch=arm64 -mmacosx-version-min=11.0"
$ ./configure --enable-release --with-staticlib-prefix=/path/to/scummvm-libs-arm64 --enable-updates --with-sparkle-prefix=/path/to/Sparkle-2.6.4
$ make -j8
$ make osxsnap
Create universal bundle, sign, notarize and get Sparkle signatures
Prepare the data
Copy the ScummVM.app bundle from the previous steps into the same directory named
- ScummVM-x86_64.app
- ScummVM-arm64.app
Copy also the disk image from the previous step. It does not matter which one is used as the ScummVM.app will be replaced by the universal one.
- ScummVM-snapshot.dmg
Pre-requisites
- An Apple Developer certificate named "Developer ID Application" in the user keychain
- The team ID for this same Developer account.
- An app specific password for notary tool in the user's Apple Account (see https://support.apple.com/en-us/102654)
- The sparkle ed25519 private key in the user keychain
- The old Sparkle dsa private key. Alternatively we can remove the dsa signature from the appcast enclosure, it is only needed for auto-update from very old versions that only had the dsa key.
Script
Edit the following script if needed and run it. The current directory should be the one that contains the data prepared above.
#!/bin/bash
# This script expect to have:
# - Two separate ScummVM builds to merge
# - A ScummVM dmg image to modify (typically created with `make osxsnap`
# - An Apple Developer certificate named "Developer ID Application" in the user keychain
# - The team ID for this same Developer account.
# - The user to have generated an app specific password in his Apple Account for notarytool (see https://support.apple.com/en-us/102654)
build1=ScummVM-x86_64.app
build2=ScummVM-arm64.app
bundle=ScummVM.app
disk_img=ScummVM-snapshot.dmg
appleid=XXXXXXX
teamid=XXXXXXXXXX
notarypasswd=xxxx-xxxx-xxxx-xxxx
sparkle_path=~/Dev/Sparkle-2.6.4
# Check the two builds are present
if [ ! -d $build1 ]; then
echo "Missing $build1"
exit 1
fi
if [ ! -d $build2 ]; then
echo "Missing $build2"
exit 1
fi
if [ ! -e $disk_img ]; then
echo "Missing $disk_img"
exit1
fi
if [ -d $bundle ]; then
echo "$bundle already exists."
exit 1
fi
# Make sure there is no quarantine flag on the builds in case it was downloaded
xattr -r -d com.apple.quarantine $build1
xattr -r -d com.apple.quarantine $build2
# Create universal executables
echo "Building universal $bundle..."
lipo -create $build1/Contents/MacOS/scummvm $build2/Contents/MacOS/scummvm -output scummvm
lipo -create $build1/Contents/PlugIns/scummvm.docktileplugin/Contents/MacOS/ScummVMDockTilePlugin $build2/Contents/PlugIns/scummvm.docktileplugin/Contents/MacOS/ScummVMDockTilePlugin -output ScummVMDockTilePlugin
cp -RP $build1 $bundle
mv scummvm $bundle/Contents/MacOS/
mv ScummVMDockTilePlugin $bundle/Contents/PlugIns/scummvm.docktileplugin/Contents/MacOS/
# Sign with Apple Developer Certificate
# It is expected to be in the current user keychain under the name "Developer ID Application"
echo "Signing $bundle..."
codesign -vvv --deep -o runtime --timestamp -f -s "Developer ID Application" $bundle/Contents/Frameworks/Sparkle.framework/Versions/B/Autoupdate
codesign -vvv --deep -o runtime --timestamp -f -s "Developer ID Application" $bundle/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app
codesign -vvv --deep -o runtime --timestamp -f -s "Developer ID Application" $bundle/Contents/Frameworks/Sparkle.framework
codesign -vvv --deep -o runtime --timestamp -f -s "Developer ID Application" $bundle
echo "Checking signature..."
codesign --deep -vvv --strict --verify $bundle
# Generate disk image
# This is the same as the osxsnap make target
echo "Updating disk image..."
basename="${disk_img%.*}"
hdiutil attach -mountpoint ./ScummVM_img $disk_img
cp -RP ./ScummVM_img ./ScummVM_snapshot_universal
hdiutil detach ./ScummVM_img
rm -rf ./ScummVM_snapshot_universal/ScummVM.app
cp -RP $bundle ./ScummVM_snapshot_universal/ScummVM.app
hdiutil create -ov -format UDZO -imagekey zlib-level=9 -fs HFS+ -srcfolder ./ScummVM_snapshot_universal -volname "ScummVM" ${basename}-universal.dmg
rm -rf ./ScummVM_snapshot_universal
# Notarisation
echo "Uploading ${basename}-universal.dmg... Notarization in progress..."
xcrun notarytool submit ${basename}-universal.dmg --apple-id ${appleid} --team-id ${teamid} --password ${notarypasswd} --wait
# In case of failure:
# xcrun notarytool log <submission-id> --apple-id ${appleid} --team-id ${teamid} --password ${notarypasswd}
xcrun stapler staple ${basename}-universal.dmg
# Sparkles signatures:
echo "Getting Sparkle signatures"
${sparkle_path}/bin/old_dsa_scripts/sign_update ${basename}-universal.dmg ${sparkle_path}/keys/dsa_priv.pem
${sparkle_path}/bin/sign_update ${basename}-universal.dmg