-
-
Save asmaloney/55d96a8c3558b2f92cb3 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# by Andy Maloney | |
# http://asmaloney.com/2013/07/howto/packaging-a-mac-os-x-application-using-a-dmg/ | |
# make sure we are in the correct dir when we double-click a .command file | |
dir=${0%/*} | |
if [ -d "$dir" ]; then | |
cd "$dir" | |
fi | |
# set up your app name, version number, and background image file name | |
APP_NAME="SuperCoolApp" | |
VERSION="1.0.0" | |
DMG_BACKGROUND_IMG="Background.png" | |
# you should not need to change these | |
APP_EXE="${APP_NAME}.app/Contents/MacOS/${APP_NAME}" | |
VOL_NAME="${APP_NAME} ${VERSION}" # volume name will be "SuperCoolApp 1.0.0" | |
DMG_TMP="${VOL_NAME}-temp.dmg" | |
DMG_FINAL="${VOL_NAME}.dmg" # final DMG name will be "SuperCoolApp 1.0.0.dmg" | |
STAGING_DIR="./Install" # we copy all our stuff into this dir | |
# Check the background image DPI and convert it if it isn't 72x72 | |
_BACKGROUND_IMAGE_DPI_H=`sips -g dpiHeight ${DMG_BACKGROUND_IMG} | grep -Eo '[0-9]+\.[0-9]+'` | |
_BACKGROUND_IMAGE_DPI_W=`sips -g dpiWidth ${DMG_BACKGROUND_IMG} | grep -Eo '[0-9]+\.[0-9]+'` | |
if [ $(echo " $_BACKGROUND_IMAGE_DPI_H != 72.0 " | bc) -eq 1 -o $(echo " $_BACKGROUND_IMAGE_DPI_W != 72.0 " | bc) -eq 1 ]; then | |
echo "WARNING: The background image's DPI is not 72. This will result in distorted backgrounds on Mac OS X 10.7+." | |
echo " I will convert it to 72 DPI for you." | |
_DMG_BACKGROUND_TMP="${DMG_BACKGROUND_IMG%.*}"_dpifix."${DMG_BACKGROUND_IMG##*.}" | |
sips -s dpiWidth 72 -s dpiHeight 72 ${DMG_BACKGROUND_IMG} --out ${_DMG_BACKGROUND_TMP} | |
DMG_BACKGROUND_IMG="${_DMG_BACKGROUND_TMP}" | |
fi | |
# clear out any old data | |
rm -rf "${STAGING_DIR}" "${DMG_TMP}" "${DMG_FINAL}" | |
# copy over the stuff we want in the final disk image to our staging dir | |
mkdir -p "${STAGING_DIR}" | |
cp -rpf "${APP_NAME}.app" "${STAGING_DIR}" | |
# ... cp anything else you want in the DMG - documentation, etc. | |
pushd "${STAGING_DIR}" | |
# strip the executable | |
echo "Stripping ${APP_EXE}..." | |
strip -u -r "${APP_EXE}" | |
# compress the executable if we have upx in PATH | |
# UPX: http://upx.sourceforge.net/ | |
if hash upx 2>/dev/null; then | |
echo "Compressing (UPX) ${APP_EXE}..." | |
upx -9 "${APP_EXE}" | |
fi | |
# ... perform any other stripping/compressing of libs and executables | |
popd | |
# figure out how big our DMG needs to be | |
# assumes our contents are at least 1M! | |
SIZE=`du -sh "${STAGING_DIR}" | sed 's/\([0-9\.]*\)M\(.*\)/\1/'` | |
SIZE=`echo "${SIZE} + 1.0" | bc | awk '{print int($1+0.5)}'` | |
if [ $? -ne 0 ]; then | |
echo "Error: Cannot compute size of staging dir" | |
exit | |
fi | |
# create the temp DMG file | |
hdiutil create -srcfolder "${STAGING_DIR}" -volname "${VOL_NAME}" -fs HFS+ \ | |
-fsargs "-c c=64,a=16,e=16" -format UDRW -size ${SIZE}M "${DMG_TMP}" | |
echo "Created DMG: ${DMG_TMP}" | |
# mount it and save the device | |
DEVICE=$(hdiutil attach -readwrite -noverify "${DMG_TMP}" | \ | |
egrep '^/dev/' | sed 1q | awk '{print $1}') | |
sleep 2 | |
# add a link to the Applications dir | |
echo "Add link to /Applications" | |
pushd /Volumes/"${VOL_NAME}" | |
ln -s /Applications | |
popd | |
# add a background image | |
mkdir /Volumes/"${VOL_NAME}"/.background | |
cp "${DMG_BACKGROUND_IMG}" /Volumes/"${VOL_NAME}"/.background/ | |
# tell the Finder to resize the window, set the background, | |
# change the icon size, place the icons in the right position, etc. | |
echo ' | |
tell application "Finder" | |
tell disk "'${VOL_NAME}'" | |
open | |
set current view of container window to icon view | |
set toolbar visible of container window to false | |
set statusbar visible of container window to false | |
set the bounds of container window to {400, 100, 920, 440} | |
set viewOptions to the icon view options of container window | |
set arrangement of viewOptions to not arranged | |
set icon size of viewOptions to 72 | |
set background picture of viewOptions to file ".background:'${DMG_BACKGROUND_IMG}'" | |
set position of item "'${APP_NAME}'.app" of container window to {160, 205} | |
set position of item "Applications" of container window to {360, 205} | |
close | |
open | |
update without registering applications | |
delay 2 | |
end tell | |
end tell | |
' | osascript | |
sync | |
# unmount it | |
hdiutil detach "${DEVICE}" | |
# now make the final image a compressed disk image | |
echo "Creating compressed image" | |
hdiutil convert "${DMG_TMP}" -format UDZO -imagekey zlib-level=9 -o "${DMG_FINAL}" | |
# clean up | |
rm -rf "${DMG_TMP}" | |
rm -rf "${STAGING_DIR}" | |
echo 'Done.' | |
exit |
@alexlee002 Sorry - I didn't get a notice when you commented here.
I also don't know how to do what you're asking since I've never had to do it. There's probably a hook somewhere in the DMG that you can specify something to run when it's opened. I would look into the docs for hdiutil
.
If you figure it out please let me know!
I am facing an error while creating the .dmg, "No space left on device" even though I have enough space.
Try to alter the .sh with this part of code:
# figure out how big our DMG needs to be
# assumes our contents are at least 1M!
SIZE=`du -sh "${STAGING_DIR}" | sed 's/\([0-9\.]*\)M\(.*\)/\1/'`
SIZE=`echo "${SIZE} + 1.0" | bc | awk '{print int($1+0.5)}'`
let SIZE++ # add 1M to SIZE
or you can remove calculating the SIZE and set it as 0
Hey,
great script, thanks for sharing!
I think the following line need to be modified:
hdiutil create -srcfolder "${STAGING_DIR}" -volname "${VOL_NAME}" -fs HFS+
The problem is "HFS+" converts UTF-8 to UTF-8 NFD that spoils Apple Notarization.
i.e. when trying to notarize this bundle the following error is produced:
The signature of the binary is invalid
I think changing HFS+ onto APFS should fix the issue.
How to show the licence when open the dmg?