3 # Syntax: make_dmg.sh <environment> <builddir> <type> <apple-id> <apple-password>
4 # where <type> is universal or thin
6 # e.g. make_dmg.sh /Users/carl/osx-environment /Users/carl/cdist universal foo@bar.net opensesame
8 # Don't set -e here as egrep (used a few times) returns 1 if no matches
11 version=`git describe --tags --abbrev=0 | sed -e "s/v//"`
13 # DMG size in megabytes
21 if [ "$TYPE" != "universal" -a "$TYPE" != "thin" ]; then
22 echo "Syntax: $0 <builddir> <type>"
23 echo "where <type> is universal or thin"
27 # This is our work area for making up the .dmgs
28 mkdir -p build/platform/osx
36 ln -s $(readlink $f) "$3/`basename $f`"
38 g=`echo $f | sed -e "s/\/32\//\/64\//g"`
40 lipo -create $f $g -output "$3/`basename $f`"
46 ln -s $(readlink $1/$2) "$3/`basename $f`"
54 function copy_lib_root {
57 for f in $ROOT/32/lib/$1*.dylib; do
59 ln -s $(readlink $f) "$2/`basename $f`"
61 g=`echo $f | sed -e "s/\/32\//\/64\//g"`
63 lipo -create $f $g -output "$2/`basename $f`"
68 for f in $ROOT/lib/$1*.dylib; do
70 ln -s $(readlink $f) "$2/`basename $f`"
78 to_relink="$to_relink|$1"
81 function copy_lib_env {
84 for f in $ENV/32/lib/$1*.dylib; do
86 ln -s $(readlink $f) "$2/`basename $f`"
88 g=`echo $f | sed -e "s/\/32\//\/64\//g"`
90 lipo -create $f $g -output "$2/`basename $f`"
95 for f in $ENV/64/lib/$1*.dylib; do
97 ln -s $(readlink $f) "$2/`basename $f`"
105 to_relink="$to_relink|$1"
108 # @param #1 directory to copy to
111 copy_lib_root libcxml "$dest"
112 copy_lib_root libdcp-1.0 "$dest"
113 copy_lib_root libasdcp-carl "$dest"
114 copy_lib_root libkumu-carl "$dest"
115 copy_lib_root libsub "$dest"
116 copy_lib_root libopenjp2 "$dest"
117 copy_lib_root libavdevice "$dest"
118 copy_lib_root libavformat "$dest"
119 copy_lib_root libavfilter "$dest"
120 copy_lib_root libavutil "$dest"
121 copy_lib_root libavcodec "$dest"
122 copy_lib_root libswscale "$dest"
123 copy_lib_root libpostproc "$dest"
124 copy_lib_root libswresample "$dest"
125 copy_lib_root liblwext4 "$dest"
126 copy_lib_root libblockdev "$dest"
127 copy $ROOT src/dcpomatic/build/src/lib/libdcpomatic2.dylib "$dest"
128 copy $ROOT src/dcpomatic/build/src/wx/libdcpomatic2-wx.dylib "$dest"
129 copy_lib_env libboost_system "$dest"
130 copy_lib_env libboost_filesystem "$dest"
131 copy_lib_env libboost_thread "$dest"
132 copy_lib_env libboost_date_time "$dest"
133 copy_lib_env libboost_locale "$dest"
134 copy_lib_env libboost_regex "$dest"
135 copy_lib_env libxml++ "$dest"
136 copy_lib_env libxslt "$dest"
137 copy_lib_env libxml2 "$dest"
138 copy_lib_env libglibmm-2.4 "$dest"
139 copy_lib_env libgobject "$dest"
140 copy_lib_env libgthread "$dest"
141 copy_lib_env libgmodule "$dest"
142 copy_lib_env libsigc "$dest"
143 copy_lib_env libglib-2 "$dest"
144 copy_lib_env libintl "$dest"
145 copy_lib_env libsndfile "$dest"
146 copy_lib_env libssh "$dest"
147 copy_lib_env libwx "$dest"
148 copy_lib_env libfontconfig "$dest"
149 copy_lib_env libfreetype "$dest"
150 copy_lib_env libexpat "$dest"
151 copy_lib_env libltdl "$dest"
152 copy_lib_env libxmlsec1 "$dest"
153 copy_lib_env libcurl "$dest"
154 copy_lib_env libffi "$dest"
155 copy_lib_env libpango "$dest"
156 copy_lib_env libcairo "$dest"
157 copy_lib_env libpixman "$dest"
158 copy_lib_env libharfbuzz "$dest"
159 copy_lib_env libsamplerate "$dest"
160 copy_lib_env libicui18n "$dest"
161 copy_lib_env libicudata "$dest"
162 copy_lib_env libicuio "$dest"
163 copy_lib_env libicule "$dest"
164 copy_lib_env libiculx "$dest"
165 copy_lib_env libicutest "$dest"
166 copy_lib_env libicutu "$dest"
167 copy_lib_env libicuuc "$dest"
168 copy_lib_env libFLAC "$dest"
169 copy_lib_env libvorbis "$dest"
170 copy_lib_env libogg "$dest"
171 copy_lib_env libxerces-c "$dest"
172 copy_lib_env libnanomsg "$dest"
175 # @param #1 directory to copy to
176 function copy_resources {
180 local prefix=$ROOT/32
186 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic_small.png "$dest"
187 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2.icns "$dest"
188 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_kdm.icns "$dest"
189 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_server.icns "$dest"
190 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_player.icns "$dest"
191 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_batch.icns "$dest"
192 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_playlist.icns "$dest"
193 cp $prefix/src/dcpomatic/graphics/osx/dcpomatic2_disk.icns "$dest"
194 cp $prefix/src/dcpomatic/graphics/osx/preferences/colour_conversions.png "$dest"
195 cp $prefix/src/dcpomatic/graphics/osx/preferences/defaults.png "$dest"
196 cp $prefix/src/dcpomatic/graphics/osx/preferences/kdm_email.png "$dest"
197 cp $prefix/src/dcpomatic/graphics/osx/preferences/email.png "$dest"
198 cp $prefix/src/dcpomatic/graphics/osx/preferences/servers.png "$dest"
199 cp $prefix/src/dcpomatic/graphics/osx/preferences/tms.png "$dest"
200 cp $prefix/src/dcpomatic/graphics/osx/preferences/keys.png "$dest"
201 cp $prefix/src/dcpomatic/graphics/osx/preferences/cover_sheet.png "$dest"
202 cp $prefix/src/dcpomatic/graphics/osx/preferences/notifications.png "$dest"
203 cp $prefix/src/dcpomatic/graphics/osx/preferences/locations.png "$dest"
204 cp $prefix/src/dcpomatic/graphics/osx/preferences/sound.png "$dest"
205 cp $prefix/src/dcpomatic/fonts/LiberationSans-Regular.ttf "$dest"
206 cp $prefix/src/dcpomatic/fonts/LiberationSans-Italic.ttf "$dest"
207 cp $prefix/src/dcpomatic/fonts/LiberationSans-Bold.ttf "$dest"
208 cp $prefix/src/dcpomatic/fonts/fonts.conf.osx "$dest"/fonts.conf
209 cp $prefix/src/dcpomatic/graphics/splash.png "$dest"
210 cp $prefix/src/dcpomatic/graphics/zoom.png "$dest"
211 cp $prefix/src/dcpomatic/graphics/zoom_all.png "$dest"
212 cp $prefix/src/dcpomatic/graphics/select.png "$dest"
213 cp $prefix/src/dcpomatic/graphics/snap.png "$dest"
214 cp $prefix/src/dcpomatic/graphics/sequence.png "$dest"
215 cp $prefix/src/dcpomatic/graphics/me.jpg "$dest"
216 cp -r $prefix/share/libdcp/xsd "$dest"
218 # i18n: DCP-o-matic .mo files
219 for lang in de_DE es_ES fr_FR it_IT sv_SE nl_NL ru_RU pl_PL da_DK pt_PT pt_BR sk_SK cs_CZ uk_UA zh_CN tr_TR; do
220 mkdir -p "$dest/$lang/LC_MESSAGES"
221 cp $prefix/src/dcpomatic/build/src/lib/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
222 cp $prefix/src/dcpomatic/build/src/wx/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
223 cp $prefix/src/dcpomatic/build/src/tools/mo/$lang/*.mo "$dest/$lang/LC_MESSAGES"
226 # i18n: wxWidgets .mo files
227 for lang in de es fr it sv nl ru pl da cs; do
229 cp $ENV/64/share/locale/$lang/LC_MESSAGES/wxstd.mo "$dest/$lang"
233 # param $1 list of things that link to other things
235 to_relink=`echo $to_relink | sed -e "s/\+//g"`
238 for obj in "${linkers[@]}"; do
239 deps=`otool -L "$obj" | awk '{print $1}' | egrep "($to_relink)" | egrep "($ENV|$ROOT|boost|libicu)"`
243 if [ "$TYPE" == "universal" ]; then
244 # $dep will be a path within 64/; make a 32/ path too
245 dep32=`echo $dep | sed -e "s/\/64\//\/32\//g"`
246 changes="$changes -change $dep @executable_path/../Frameworks/$base -change $dep32 @executable_path/../Frameworks/$base"
248 changes="$changes -change $dep @executable_path/../Frameworks/$base"
251 if test "x$changes" != "x"; then
252 install_name_tool $changes -id `basename "$obj"` "$obj"
257 # @param #1 .app directory
258 # @param #2 full name e.g. DCP-o-matic Batch Converter
259 # @param #3 bundle id e.g. com.dcpomatic.batch
264 tmp_dmg=dcpomatic_tmp.dmg
265 dmg="$full_name $version.dmg"
266 vol_name=DCP-o-matic-$version
268 codesign --deep --force --verify --verbose --options runtime --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$appdir"
269 if [ "$?" != "0" ]; then
270 echo "Failed to sign .app"
275 cp -a "$appdir" $vol_name
276 ln -s /Applications "$vol_name/Applications"
277 cat<<EOF > "$vol_name/READ ME.txt"
278 Welcome to DCP-o-matic! The first time you run the program there may be
279 a long (several-minute) delay while OS X checks the code for viruses and
280 other malware. Please be patient!
282 cat<<EOF > "$vol_name/READ ME.de_DE.txt"
283 Beim erstmaligen Start der DCP-o-matic Anwendungen kann ein längerer
284 Verifikationsvorgang auftreten. Dies ist von der OS X Sicherheitsumgebung
285 'Gatekeeper' verursacht. Dieser je nach Rechner teils minutenlange
286 Verifikationsvorgang ist gegenwärtig normal und nicht zu umgehen,
287 es ist kein Programmfehler. Warten sie die Verifikation für jede der
288 DCP-o-matic Anwendungen ab, bei weiteren Programmstarts wird sie nicht
292 rm -f $tmp_dmg "$dmg"
293 hdiutil create -srcfolder $vol_name -volname $vol_name -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size $DMG_SIZE $tmp_dmg
294 attach=$(hdiutil attach -readwrite -noverify -noautoopen $tmp_dmg)
295 device=`echo $attach | egrep '^/dev/' | sed 1q | awk '{print $5}'`
299 tell application "Finder"
300 tell disk "'$vol_name'"
302 set current view of container window to icon view
303 set toolbar visible of container window to false
304 set statusbar visible of container window to false
305 set the bounds of container window to {400, 200, 940, 300}
306 set theViewOptions to the icon view options of container window
307 set arrangement of theViewOptions to not arranged
308 set icon size of theViewOptions to 64
309 set position of item "'$appdir'" of container window to {90, 80}
310 set position of item "Applications" of container window to {265, 80}
311 set position of item "READ ME.txt" of container window to {430, 80}
312 set position of item "READ ME.de_DE.txt" of container window to {595, 80}
315 update without registering applications
321 chmod -Rf go-w /Volumes/"$vol_name"/"$appdir"
324 hdiutil eject $device
325 hdiutil convert -format UDZO $tmp_dmg -imagekey zlib-level=9 -o "$dmg"
326 sips -i "$appdir/Contents/Resources/dcpomatic2.icns"
327 DeRez -only icns "$appdir/Contents/Resources/dcpomatic2.icns" > "$appdir/Contents/Resources/DCP-o-matic.rsrc"
328 Rez -append "$appdir/Contents/Resources/DCP-o-matic.rsrc" -o "$dmg"
333 codesign --verify --verbose --options runtime --sign "Developer ID Application: Carl Hetherington (R82DXSR997)" "$dmg"
335 # We only notarize thin builds, as if we're building universal binaries we must be on an OS
336 # sufficiently old that it can't notarize anyway
337 if [ "$TYPE" == "thin" ]; then
339 id=$(xcrun altool --notarize-app -t osx -f "$dmg" --primary-bundle-id $bundle_id -u $APPLE_ID -p $APPLE_PASSWORD --output-format xml | grep -C1 RequestUUID | tail -n 1 | sed -e "s/<string>//g" | sed -e "s/<\/string>//g")
342 echo "Checking up on $id"
343 status=$(xcrun altool --notarization-info $id -u $APPLE_ID -p $APPLE_PASSWORD --output-format xml)
344 summary=$(echo "$status" | grep -C1 "<key>Status</key>" | tail -n 1 | sed -e "s/ .//g")
346 if [ "$summary" == "<string>invalid</string>" ]; then
347 echo "Notarization failed."
351 if [ "$summary" == "<string>success</string>" ]; then
356 if [ "$N" == "30" ]; then
357 echo "Timed out waiting for notarization"
362 xcrun stapler staple "$dmg"
373 approot="$appdir/Contents"
375 mkdir -p "$approot/MacOS"
376 mkdir -p "$approot/Frameworks"
377 mkdir -p "$approot/Resources"
379 to_relink="dcpomatic"
380 copy_libs "$approot/Frameworks"
381 copy_resources "$approot/Resources"
394 setup "DCP-o-matic 2.app"
395 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2 "$approot/MacOS"
396 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_cli "$approot/MacOS"
397 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_create "$approot/MacOS"
398 copy $ROOT bin/ffprobe "$approot/MacOS"
399 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
400 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2.Info.plist "$approot/Info.plist"
401 rl=("$approot/MacOS/dcpomatic2" "$approot/MacOS/dcpomatic2_cli" "$approot/MacOS/dcpomatic2_create" "$approot/MacOS/ffprobe" "$approot/Frameworks/"*.dylib)
403 make_dmg "$appdir" "DCP-o-matic" com.dcpomatic
405 # DCP-o-matic KDM Creator
406 setup "DCP-o-matic 2 KDM Creator.app"
407 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm "$approot/MacOS"
408 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_kdm_cli "$approot/MacOS"
409 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
410 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_kdm.Info.plist "$approot/Info.plist"
411 rl=("$approot/MacOS/dcpomatic2_kdm" "$approot/MacOS/dcpomatic2_kdm_cli" "$approot/Frameworks/"*.dylib)
413 make_dmg "$appdir" "DCP-o-matic KDM Creator" com.dcpomatic.kdm
415 # DCP-o-matic Encode Server
416 setup "DCP-o-matic 2 Encode Server.app"
417 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server "$approot/MacOS"
418 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_server_cli "$approot/MacOS"
419 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
420 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_server.Info.plist "$approot/Info.plist"
421 rl=("$approot/MacOS/dcpomatic2_server" "$approot/MacOS/dcpomatic2_server_cli" "$approot/Frameworks/"*.dylib)
423 make_dmg "$appdir" "DCP-o-matic Encode Server" com.dcpomatic.server
425 # DCP-o-matic Batch Converter
426 setup "DCP-o-matic 2 Batch converter.app"
427 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_batch "$approot/MacOS"
428 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
429 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_batch.Info.plist "$approot/Info.plist"
430 rl=("$approot/MacOS/dcpomatic2_batch" "$approot/Frameworks/"*.dylib)
432 make_dmg "$appdir" "DCP-o-matic Batch Converter" com.dcpomatic.batch
435 setup "DCP-o-matic 2 Player.app"
436 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_player "$approot/MacOS"
437 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
438 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_player.Info.plist "$approot/Info.plist"
439 rl=("$approot/MacOS/dcpomatic2_player" "$approot/Frameworks/"*.dylib)
441 make_dmg "$appdir" "DCP-o-matic Player" com.dcpomatic.player
443 # DCP-o-matic Playlist Editor
444 setup "DCP-o-matic 2 Playlist Editor.app"
445 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_playlist "$approot/MacOS"
446 copy $ROOT src/openssl/apps/openssl "$approot/MacOS"
447 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_playlist.Info.plist "$approot/Info.plist"
448 rl=("$approot/MacOS/dcpomatic2_playlist" "$approot/Frameworks/"*.dylib)
450 make_dmg "$appdir" "DCP-o-matic Playlist Editor" com.dcpomatic.playlist
452 # DCP-o-matic Disk Writer
453 setup "DCP-o-matic 2 Disk Writer.app"
454 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_disk "$approot/MacOS"
455 copy $ROOT src/dcpomatic/build/src/tools/dcpomatic2_disk_writer "$approot/MacOS"
456 cp $prefix/src/dcpomatic/build/platform/osx/dcpomatic2_disk.Info.plist "$approot/Info.plist"
457 rl=("$approot/MacOS/dcpomatic2_disk" "$approot/Frameworks/"*.dylib)
459 rl=("$approot/MacOS/dcpomatic2_disk_writer" "$approot/Frameworks/"*.dylib)
461 make_dmg "$appdir" "DCP-o-matic Disk Writer" com.dcpomatic.disk