-
-
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?